Change Travis's Python version to 3.7.
[tor-bridgedb.git] / doc / proposals / XXX-bridgedb-learns-ipv6.txt
blob44191b627ad31c7e36da1be8b6c2ce76308da50f
1 Filename: xxx-bridgedb-learns-ipv6.txt
2 Title: BridgeDB Learns IPv6
3 Author: Aaron Gibson
4 Created: 5 Dec 2011
5 Status: Draft
7 Overview:
9   This document outlines what we'll do to make BridgeDB fully support IPv6
10   bridges, and fully support IPv6 with the email, https, and bucket
11   distributors.
13 Motivation:
15   IPv6 bridges need a BridgeDB too.
17 What needs to change:
19   There are two main tasks that must be completed for BridgeDB to support IPv6.
21     1. BridgeDB must be able to parse IPv6 addresses from router descriptors.
22     (Currently, BridgeDB does not recognize the or-address line described in
23     186-multiple-orports.txt)
24     
25     2. BridgeDB must decide how to hand out IPv6 addresses.  (Currently,
26     BridgeDB distributors are not IPv6 aware, and provide no support for
27     distinguishing bridges by address class)
29     
30 1. BridgeDB learns to parse or-address
32     BridgeDB must learn how to parse the new or-address line from server
33     descriptors. The new or-address line allows a router to specify a list of
34     addresses and ports or port-ranges. 
35     
36     Here is the or-address specification (see: 186-multiple-orports.txt)
37           
38       or-address SP ADDRESS ":" PORTLIST NL
39       ADDRESS = IP6ADDR | IP4ADDR
40       IPV6ADDR = an ipv6 address, surrounded by square brackets.
41       IPV4ADDR = an ipv4 address, represented as a dotted quad.
42       PORTLIST = PORTSPEC | PORTSPEC "," PORTLIST
43       PORTSPEC = PORT | PORT "-" PORT
44       PORT = a number between 1 and 65535 inclusive.
46     BridgeDB must now comprehend and store multiple listening addresses and
47     ports. BridgeDB currently assumes that each bridge has only one listen
48     address. BridgeDB must be modified to take one of the following approaches:
49     
50       a. Treat each ADDRESS:PORT combination as a separate bridge entity
51       b. Display a subset of each bridges ADDRESS:PORT entries in a response
52       c. Display all of each bridges ADDRESS:PORT entries in a response
54     Given any address of the bridge you can learn its fingerprint, and use that
55     to look up its descriptor at tonga and learn the rest of the addresses. so
56     counting a bridge with 5 addresses as 5 bridges makes it more likely to get
57     blocked by a smart adversary. but more useful against a weaker adversary.
58     #XXX: thanks arma!
59     # any other thoughts here? option c. seems to be the simplest to implement.
61     BridgeDB should be able to mark specific IP:port pairs as blocked, and
62     indicate where it is blocked (e.g. by country code). This requirement is
63     complicated by the fact that or-address may specify a range of listening
64     ports.
66     How are IPv6 Addresses stored in BridgeDB?
68       IPv6 Addresses are stored as strings, the same way as IPv4 addresses.
69       #XXX: is this better than using the ipaddr.IPAddress class?
71       As the new or-address specification allows for multiple ADDRESS:PORT
72       BridgeDB's persistent database must also be modified.
74       A new table 'or-address' shall be created with the following fields:
75       ex. from updated BridgeDB schema:
77         CREATE TABLE BridgeOrAddresses (
78             id INTEGER PRIMARY KEY NOT NULL,
79             hex_key,
80             address,
81             or_port,
82             address_class,
83         );
84        
85         CREATE INDEX BridgeOrAddressesKeyIndex on BridgeOrAddresses ( hex_key ); 
86       
87     How are Bridges differentiated by address class?
89       Bridges are differentiated by the string representation of their IP
90       address.
92       When BridgeDB needs to make a distinction between IP address classes, the
93       python module ipaddr-py (https://code.google.com/p/ipaddr-py/) will be
94       used to determine address class.
96 2. BridgeDB learns how to selectively distribute IPv6 bridges
98     BridgeDB's 3 distributors must be able to selectively provide both
99     IPv4 and/or IPv6 bridges to clients. Deployment of these distributors must
100     take care to mitigate reachability issues due partly to the ongoing
101     transition from IPv4 to IPv6. 
103     [One such issue is clients who have IPv6 support on their local network but
104     the client's ISP does not; such a client may try to reach the IPv6 address
105     specified by a AAAA record and fail to connect.]
107     The 3 distributor types that BridgeDB currently features are:
109       1. HTTPS Distributor
110          
111         The HTTPS distributor must be able to selectively offer both IPv4 and
112         IPv6 bridges to its' clients, and BridgeDB must support both IPv4 and
113         IPv6 connections.
114         
115         #XXX the twisted framework does not currently support ipv6. However,
116         # it is possible to place BridgeDB behind a forwarding proxy such as
117         # apache or nginx, which will pass the client address to BridgeDB in the
118         # X_FORWARDED_FOR header. BridgeDB HTTPS distributor must be able to
119         # parse the X_FORWARDED_FOR header for both IPv4 and IPv6 addresses.
120         # Additionally, BridgeDB should eventually support IPv6 natively when
121         # the twisted framework provides adequate IPv6 support.
123         How does bridgedb determine whether to respond with ipv4 or ipv6
124         bridges?
126           Users select IPv4 or IPv6 bridges by visiting different URLs. An
127           informational message added to the BridgeDB response will include the
128           other URL. Two separate BridgeDB instances are run, one for each URL.
130           Alternately, ipv6 bridges could be requested by visiting
131           bridges.tpo/ipv6 or similar URL path scheme.
133         Proposed Additional Hostname For IPv6 Bridges
135           BridgeDB shall listen for requests on two different hostnames,
136           bridges.torproject.org and bridgesv6.torproject.org.
138         DNS Configuration Details
140           bridges.torproject.org shall not have an AAAA record until the
141           addition of the record is determined to be sound.
143           bridgesv6.torproject.org shall have both an AAAA and A record.
144           
145           This is to avoid the confused-client scenario described above.
147         How does BridgeDB know which URL was requested?
149           This section describes how BridgeDB could be modified to support
150           requests to both bridges.torproject.org and bridgesv6.torproject.org
151           with a single BridgeDB instance.
153           A single BridgeDB instance could handle requests to both
154           bridges.torproject.org and bridgesv6.torproject.org by checking the
155           Host header sent by the browser. The Host header is optional. In
156           order to expose the selector explitely BridgeDB must check the query
157           string for the following parameters:
159             q=ipv4  - Request IPv4 bridges.
160             q=ipv6  - Request IPv6 bridges.  
162           Parameters may be repeated to select multiple classes, e.g.
163           
164             q=ipv4&q=ipv6  - Request both IPv4 and IPv6 bridges.
166           When no parameters are set, by default BridgeDB must return addresses
167           of the same class as the client. This default may promote IPv6 use
168           where possible.
170         How does someone end up at bridgesv6.torproject.org?
172           BridgeDB should include a message at the end of its' response.  
173           e.g.
175             "Get IPv4 bridges https://bridges.torproject.org"
176             "Get IPv6 bridges from https://bridgesv6.torproject.org"
177             "You must have IPv6 for these bridges to work."
178           #XXX: will users understand what this means?
180         How does IPv6 affect address datamining of https distribution?
181           A user may be allocated a /128, or a /64.
182           An adversary may control a /32 or perhaps larger
183           Proposal: Enable reCAPTCHA support by default.
185         How do IPv6 addresses work with the IPBasedDistributor?
186         #XXX: I need feedback on this
187         # do we use all 128 bits here?
188         # upper N bits? lower N bits? random or specific N bits?
190         How are IPv6 Bridges actually distinguished?
192           A new type of BridgeSplitter (sort of like a BridgeHolder)
193           is devised; the function of which is to split bridges into different
194           rings determined by a filter function.
196           The filtering mechanism here is similar to BridgeDB's ipCategories
197           implementation, the difference is that both the filters and ring
198           names are specified at instance construction.
200           The construction of a BridgeSplitter instance should be done by
201           passing lists of tuples (ringName,filterFunction) to the constructor.
202           This feature allows for dynamically creating filtered BridgeRings, 
203           which would prove useful for constructing more complex filters, for
204           example, filtering by both address class and reachability from
205           specific countries.
207           This implementation could increase the rate at which bridges are
208           detected and blocked, although the rate could be controlled by the
209           frequency that BridgeDB updates its knowledge of blocked bridges.
210           
211           #XXX: I have some concern about the performance of
212           # filtering bridges dynamically for each response. BridgeDB should
213           # learn to cache recently used dynamic filters so that the impact of
214           # popular requests will be reduced, and BridgeDB does not have to
215           # pre-compute or identify which types of requests will be popular.
217           The implementation could look similar to the current 'subring'
218           implementation; or the current 'ipCategories' implementation. Both of
219           the features are implemented using subrings that hold a subset of
220           the parent ring's bridges; the subset being defined by a filtering
221           function.
223           An accompanying Distributor based on the existing IPBasedDistributor
224           shall be designed to use the above BridgeSplitter so that sorted
225           Bridges are selectable by address type. Because a bridge
226           may now have both IPv6 and IPv4 addresses, BridgeDB needs to take
227           one of the following approaches when only a single address class is
228           requested:
230             a. filter addresses of the other address class from the response
231             b. include the other addresses in the response
233       2. Email Distributor
235         The Email Distributor must accept additional new commands parsed from
236         the subject or a single line in the body of an email message.
238           ipv4  - request IPv4 bridges.
239           ipv6  - request IPv6 bridges.
241         The default action may be set in bridgedb.conf with the option
242         EMAIL_DEFAULT_ADDRESS_CLASS, which must be one of 'ipv6' or 'ipv4'.  If
243         the option is not given in the config, EMAIL_DEFAULT_ADDRESS_CLASS shall
244         default to 'ipv4'.
246         Similar to the IPBasedDistributor, BridgeDB must determine how the
247         response should accommodate bridges with both address classes.
249       3. Unassigned Distributor and Buckets
251         BridgeDB must provide a selector to choose between exporting
252         IPv4, IPv6, or both types of bridges.
254         BridgeDB currently provides a way to export bucket files with
255         unallocated bridges. The existing syntax provides no mechanism to
256         differentiate by address class.
258         Proposed new FILE_BUCKET syntax:
260           A dictionary of dictionaries with the following acceptable keys and
261           values.
263           'filename_prefix' shall be a unique string used as the output filename
264           prefix. This is string is also the key to a dictionary that contains
265           the following key/values:
267           'address-class' : one of either 'ipv6' or 'ipv4'
268           'number'        : an integer > 0
270         Users may wish to provide descriptive names,
271         e.g.
272         
273           FILE_BUCKETS = {
274                   'filename_prefix': {'address-class': 'ipv6', 'number': 10},
275                   'descriptive_name': {'address-class': 'ipv6', 'number': 10},
276           }
278         Future BridgeDB enhancements may expand these options to include other
279         filters.
280         #XXX: e.g. buckets of bridges 'not-blocked-in'