vanguards.md
1 # Building vanguards in Arti 2 3 Here's a summary of the vanguards design. 4 For canonical information, see the 5 [specification](https://spec.torproject.org/vanguards-spec/index.html) 6 7 8 ## Summary of what we're building. 9 10 The Vanguards design is a change to circuit path construction rules. 11 12 This change applies to HS circuits only. 13 (That is, circuits that are built for hsservice or hsclient. 14 This includes circuits to connect to introduction points, 15 rendezvous points, and hsdirs.) 16 17 We call "circuit stem" the portion of a hidden service circuit 18 that is built differently when vanguards are in use. 19 20 The vanguard design will apply to the "stem" circuits 21 that we build in HsCircPool. These circuits correspond to 22 everything in an HS circuit _before_ we add an introduction point, 23 rendezvous point, or hsdir. For client rendezvous connections, 24 we use the circuits stems unmodified, and use the 25 final hop as our rendezvous point. 26 27 Here's our schema: 28 ``` 29 Client hsdir: GUARDED -> HsDir 30 Client intro: GUARDED -> Ipt 31 Client rend: GUARDED 32 Service hsdir: NAIVE -> HsDir (*) 33 Service intro: NAIVE -> Ipt 34 Service rend: GUARDED -> Rpt 35 ``` 36 37 Note that in some of these cases (marked above with `GUARDED`), 38 we are building a circuit to a final hop 39 that an adversary can easily control. 40 Right now, we don't distinguish these cases, 41 but with vanguards we will. 42 43 > Note: the client rendezvous case is an exception to this rule: 44 > the rendezvous point is selected by the client, so it cannot easily be 45 > controlled by an attacker. 46 > 47 > This type of circuit would more accurately be described as a NAIVE circuit 48 > that gets extended by an extra hop if Full-Vanguards are in use 49 > (this is necessary to avoid using the L3 guard as a rendezvous point). 50 > However, for the sake of simplicity, we define these circuits in terms of 51 > GUARDED. 52 > 53 > Note: in the client rendezvous case, the last node from the GUARDED 54 > circuit stem is the rendezvous point. 55 56 > (I've marked "service hsdir" with a *, 57 > since maybe we want to call that one "guarded" as well.) 58 59 Currently, circuit stems are built by taking a guard node, 60 then two arbitrarily chosen middle nodes: 61 ``` 62 NAIVE = G -> M -> M 63 GUARDED = G -> M -> M 64 ``` 65 66 There two variants of vanguards: "lite" and "full". 67 Both of then introduce pools of additional guards, 68 called "vanguards". 69 The "lite" variant adds a single "L2" pool. 70 The "full" variant adds an "L2" pool and an "L3" pool. 71 72 With "lite", we build circuit stems by taking a guard node, 73 then a vanguard from the "L2" pool, then an arbitrary middle node: 74 ``` 75 NAIVE = G -> L2 -> M 76 GUARDED = G -> L2 -> M 77 ``` 78 79 With "full", we build circuit stems by taking a guard node, 80 a vanguard from the L2 pool, 81 and a vanguard from the L3 pool. 82 For "guarded" circuits, we also add a middle node: 83 ``` 84 NAIVE = G -> L2 -> L3 85 GUARDED = G -> L2 -> L3 -> M 86 ``` 87 88 ### Pool management 89 90 Here's how we maintain L2 and L3 guards. 91 92 In both cases, vanguards are added to each pool 93 up to a target `NUM_GUARDS` number taken from a consensus parameter. 94 This number depends on the variant and the pool in question. 95 96 To be added as a vanguard, a relay must be flagged Stable and Fast. 97 98 The vanguards in single a pool must be distinct from one another. 99 There is no inter-pool restriction. 100 101 Every vanguard gets an "expiration time" when it's added to the pool; 102 when this time expires, we remove the vanguard. 103 We additionally remove a vanguard if it is every unlisted, 104 or if it ever loses the Stable or Fast flag. 105 106 To pick the expiration time when adding a vanguard, 107 we choose from a random distribution. 108 This distribution depends on the variant and the pool in question. 109 110 In vanguards-full, these pools are persistent, 111 and must be stored to disk. 112 113 In vanguards-lite, these pools are not persistent. 114 115 ### Loosened path restirctions 116 117 When building a circuit stem, 118 we no longer apply certain restrictions to the circuits we build. 119 In particular: 120 121 - We no longer apply family or same-subnet restrictions at all. 122 - We do not exclude the guard from appearing as 123 either of the last two hops of the circuit. 124 125 ### Which variant to apply 126 127 By default, "vanguards-lite" applies to every circuit stem. 128 129 We will implement a global option that applies "vanguards-full" 130 to every circuit stem. 131 132 For now, we will share a single L2 pool, 133 no matter which variant is in use: 134 vanguards will not be discarded on a switch 135 from one variant to another. 136 137 > In the future, we might want to apply "full" or "lite" 138 > to specific services, 139 > either when providing those services or connecting to them. 140 > 141 > To do so, our main open design question to answer 142 > would be whether they share an L2 pool. 143 144 145 ----- 146 147 148 ## Implementing vanguards in arti 149 150 Pool maintenance might belong logically in tor-guardmgr, 151 or might belong in a new tor-vanguardmgr crate. 152 It shouldn't share an implementation with the main guard pool though, 153 since the criteria for keeping and using 154 guards and vanguards are completely different. 155 156 New vanguard code will be: 157 * pool maintenance 158 * pool persistence 159 160 We can have a single VanguardPool implementation 161 shared by both variants, and both pools. 162 163 Code to modify will be concentrated in `tor_circmgr`: 164 * `HsCircPool::take_or_launch_stub_circuit`. 165 * `HsCircPool::get_or_launch_client_rend`. 166 * `HsCircPool::get_or_launch_specific`. 167 * `hspool::circuit_compatible_with_target` 168 * `CircMgr::launch_hs_unmanaged` 169 170 * `TargetCircUsage::build_path`. 171 * Anything that touches `SupportedCircUsage::HsOnly`. 172 173 We will also need a new path-selection implementation. 174 This will either be a new implementation 175 similar to `ExitPathBuilder`, 176 or an additional set of options to a possibly renamed 177 `ExitPathBuilder`. 178 It will probably share some code with `ExitPathBuilder`. 179 180 We'll need `CircMgr` to have access to the vanguard pools, 181 either by owning a `VanguardMgr` directly, 182 or by owning it through `GuardMgr`. 183 184 The `VanguardMgr` will need to know which pools 185 will be required. 186 This will depend on whether "full" might be wanted. 187 188 So that we can later support fine-grained decisions 189 about whether to use "lite" or "full", 190 we should have it be a parameter passed to HsCircPool, 191 telling it whether a "lite" or "full" circuit is needed. 192 193 ## Estimated steps: 194 195 * [ ] Implement vanguard pools and a vanguard manager to maintain them. 196 * [ ] Give CircMgr an Arc<VanguardMgr> whenever `onion-service-client` 197 or `onion-service-service` is enabled. 198 * [ ] Implement a global "full-vanguards" configuration option; 199 have it get fed to the vanguardmgr, to tor-hsclient, and to tor-hsservice. 200 * [ ] Give HsCircPool additional arguments to declare whether its 201 circuits are Naive or Guarded 202 (probably not so named in the code!) 203 and whether they are "lite" or "full". 204 * [ ] Implement path selection for (Naive, Guarded) x (lite, full) 205 circuits in CircMgr::launch_hs_unmanaged. 206