commit 7418f65d0ebc7d982b080ecde93b276062f2f3d5 Author: George Kadianakis desnacked@riseup.net Date: Wed Mar 29 13:02:00 2017 +0200
Introduce prop279: "A Name System API for Tor Onion Services" --- proposals/279-naming-layer-api.txt | 521 +++++++++++++++++++++++++++++++++++++ proposals/proposal-status.txt | 6 + 2 files changed, 527 insertions(+)
diff --git a/proposals/279-naming-layer-api.txt b/proposals/279-naming-layer-api.txt new file mode 100644 index 0000000..73616aa --- /dev/null +++ b/proposals/279-naming-layer-api.txt @@ -0,0 +1,521 @@ +Filename: 279-naming-layer-api.txt +Title: A Name System API for Tor Onion Services +Author: George Kadianakis, Yawning Angel, David Goulet +Created: 04-Oct-2016 +Status: Draft + + Table Of Contents: + + 1. Introduction + 1.1. Motivation + 1.2. Design overview and rationale + 2. System Specification + 2.1. System overview [SYSTEMOVERVIEW] + 2.2. System Illustration + 2.3. System configuration [TORRC] + 2.3.1. Tor name resolution logic + 2.4. Name system initialization [INITPROTOCOL] + 2.5. Name resolution using NS API + 2.5.1. Message format + 2.5.2. RESOLVED status codes + 2.5.3. Further name resolution behavior + 2.6. Cancelling a name resolution request + 2.7. Launching name plugins [INITENVVARS] + 2.8. Name plugin workflow [NSBEHAVIOR] + 2.8.1. Name plugin shutdown [NSSHUTDOWN] + 2.9. Further details of stdin/stdout communication + 2.9.1. Message Format + 3. Discussion + 3.1. Using second-level domains instead of tld + 3.2. Name plugins handling all tlds '*' + 3.3. Deployment strategy + 3.4. Miscellaneous discussion topics + 4. Acknowledgements + A.1: Example communication Tor <-> name plugin [PROTOEXAMPLE] + A.2: Example plugins [PLUGINEXAMPLES] + +1. Introduction + + This proposal specifies a modular API for integrating name systems with Tor. + +1.1. Motivation + + Tor onion service addresses are decentralized and self-authenticated but + they are not human-memorable (e.g. 3g2upl4pq6kufc4m.onion). This is a source + of poor usability, since Internet users are familiar with the convenient + naming of DNS and are not used to addresses being random text. + + In particular, onion addresses are currently composed of 16 random base32 + characters, and they look like this: + + 3g2upl4pq6kufc4m.onion + vwakviie2ienjx7t.onion + idnxcnkne4qt76tg.onion + vwakviie2ienjx6t.onion + + When Proposal 224 get deployed, onion addresses will become even + bigger: 53 base32 characters. That's: + + llamanymityx4fi3l6x2gyzmtmgxjyqyorj9qsb5r543izcwymle.onion + lfels7g3rbceenuuqmpsz45z3lswakqf56n5i3bvqhc22d5rrsza.onion + odmmeotgcfx65l5hn6ejkaruvai222vs7o7tmtllszqk5xbysola.onion + qw3yvgovok3dsarhqephpu2pkiwzjdk2fgdfwwf3tb3vgzxr5kba.onion + + Over the years Tor users have come up with various ad-hoc ways of handling + onion addresses. For example people memorize them, or use third-party + centralized directories, or just google them everytime. + + We believe that the UX problem of non-human-memorable addresses is not + actually solved with the above ad-hoc solutions and remains a critical + usability barrier that prevents onion services from being used by a wider + audience. + +1.2. Design overview and rationale + + During the past years there has been lots of research on secure naming and + various such systems have been proposed (e.g. GNS, Namecoin, etc.). + + Turns out securely naming things is a very hard research problem, and hence + none of the proposed systems is a clear winner: all of them carry various + trade-offs. Furthermore, none of the proposed systems has seen widespread use + so far, which makes it even harder to pick a single project. + + Given the plenitude of options, one approach to decide which system + is best is to make various decent name systems available and let the + Tor community and the sands of time pick the winner. Also, it might + be that there is no single winner, and perhaps different specialized + name system should be used in different situations. We believe that + by getting secure name systems actually get utilized by real users, + the whole field will mature and existing systems will get battle-hardened. + + Hence, the contribution of this proposal is a modular Name System API + (NSA) that allows developers to integrate their own name systems in + Tor. The interface design is name-system-agnostic, and it's heavily + based on the pluggable transports API (proposal 180). It should be + flexible enough to accommodate all sorts of name systems (see [PLUGINEXAMPLES]). + +2. System Specification + + A developer that wants to integrate a name system with Tor needs to first + write a wrapper that understands the Tor Name System API (NS API). Using the + Name System API, Tor asks the name system to perform name queries, and + receives the query results. The NS API works using environment variables and + stdin/stdout communication. It aims to be portable and easy to implement. + +2.1. System overview [SYSTEMOVERVIEW] + + Here is an overview of the Tor name system: + + Alice, a Tor user, can activate various name systems by editing her + torrc file and specifying which tld each name system is responsible + for. For this section, let's consider a simple fictional name system, + unicorn, which magically maps domains with the .corn tld to the + correct onion address. Here it is: + + OnionNamePlugin 0 .corn /usr/local/bin/unicorn + + After Alice enables the unicorn plugin, she attempts connecting to + elephantforum.corn. Tor will intercept the SOCKS request, and use the + executable at /usr/local/bin/unicorn to query the unicorn name system + for elephantforum.corn. Tor communicates with the unicorn plugin + using the Tor NS API through which name queries and their results can + be transported using stdin/stdout. + + If elephantforum.corn corresponds to an onion address in the unicorn + name system, unicorn should return the onion address to Tor using the + Tor NS API. Tor must then internally rewrite the elephantforum.corn + address to the actual onion address, and initiate a connection to it. + +2.2. System Illustration + + Here is a diagram illustrating how the Tor Name System API works. The name + system used in this example is GNS, but there is nothing GNS-specific here + and GNS could be swapped for any other name system (like hosts files, or + Namecoin). + + The example below illustrates how a user who types debian.zkey in their Tor + browser gets redirected to sejnfjrq6szgca7v.onion after Tor consults the GNS + network. + + Please revisit this illustration after reading the rest of the proposal. + + | $~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$ + | 1. $ 4. GNS magic!! $ + | User: SOCKS CONNECT to $ debian.zkey -> sejnfjrq6szgca7v.onion$ + | http://debian.zkey/ $~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$~~~~~~~$ + | $ + +-----|-----------------------------------------+ $ + |+----v-----+ 2. +---------+| 3. $ + ||Tor | debian.zkey |Tor || debian.zkey +-$-------+ + ||Networking------------------------->Naming -------------------------> | + ||Submodule | |Submodule|| Tor Name System API | GNS | + || <------------------------- <------------------------- wrapper| + || | 6. | ||5. | | + |+----|-----+ sejnfjrq6szgca7v.onion +---------+|sejnfjrq6szgca7v.onion +---------+ + +-----|-----------------------------------------+ + | 7. + | Tor: Connect to + | http://sejnfjrq6szgca7v.onion/ + v + + +2.3. System configuration [TORRC] + + As demonstrated in [SYSTEMOVERVIEW], a Tor user who wants to use a name + system has to edit their configuration file appropriately. Here is the torrc + line format: + + OnionNamePlugin <priority> <tld> <path> + + where <priority> is a positive integer denoting the priority with which this + name plugin should be consulted. <tld> is a string which restricts the scope + of this plugin to a particular tld. Finally, <path> is a filesystem path to + an executable that speaks the Tor Name System API and can act as an + intermediary between Tor and the name system. + + For example here is a snippet from a torrc file: + OnionNamePlugin 0 .hosts /usr/local/bin/local-hosts-file + OnionNamePlugin 1 .zkey /usr/local/bin/gns-tor-wrapper + OnionNamePlugin 2 .bit /usr/local/bin/namecoin-tor-wrapper + OnionNamePlugin 3 .scallion /usr/local/bin/community-hosts-file + +2.3.1. Tor name resolution logic + + When Tor receives a SOCKS request to an address that has a name + plugin assigned to it, it needs to perform a query for that address + using that name plugin. + + If there are multiple name plugins that correspond to the requested + address, Tor queries all relevant plugins sorted by their priority + value, until one of them returns a successful result. If two plugins + have the same priority value, Tor MUST abort. + + If all plugins fail to successfuly perform the name resolution, Tor SHOULD + default to using the exit node for name resolution. + XXX or not? because of leaks? + +2.4. Name system initialization [INITPROTOCOL] + + When Tor finds OnionNamePlugin lines in torrc, it launches and initializes + their respective executables. + + When launching name plugins, Tor sets various environment variables to pass + data to the name plugin (e.g. NS API version, state directory, etc.). More + information on the environment variables at [INITENVVARS]. + + After a name plugin initializes and parses all needed environment + variables, it communicates with Tor using its stdin/stdout. + + The first line that a name plugin sends to stdout signifies that it's ready + to receive name queries. This line looks like this: + + INIT <VERSION> <STATUS_CODE> [<STATUS_MSG>] + + where VERSION is the Tor NS API protocol version that the plugin supports, + STATUS_CODE is an integer status code, and STATUS_MSG is an optional string + error message. STATUS_CODE value 0 is reserved for "success", and all other + integers are error codes. + + See [PROTOEXAMPLE] for an example of this protocol. + +2.5. Name resolution using NS API + + Here is how actual name resolution requests are performed in NS API. + +2.5.1. Message format + + When Tor receives a SOCKS request to an address with a tld that has a name + plugin assigned to it, Tor performs an NS API name query for that address. + + Tor does this by printing lines on the name plugin stdout as follows: + + RESOLVE <QUERY_ID> <NAME_STRING> + + where QUERY_ID is a unique integer corresponding to this query, and + NAME_STRING is the name to be queried. + + When the name plugin completes the name resolution, it prints the following + line in its stdout: + + RESOLVED <QUERY_ID> <STATUS_CODE> <RESULT> + + where QUERY_ID is the corresponding query ID and STATUS_CODE is an integer + status code. RESULT is the resolution result (an onion address) or an error + message if the resolution was not succesful. + + See [PROTOEXAMPLE] for an example of this protocol. + + XXX Should <RESULT> be optional in the case of failure? + +2.5.2. RESOLVED status codes + + Name plugins can deliver the following status codes: + + 0 -- The name resolution was successful. + + 1 -- Name resolution generic failure. + + 2 -- Name tld not recognized. + + 3 -- Name not registered. + + 4 -- Name resolution timeout exceeded. + + XXX add more status codes here as needed + +2.5.3. Further name resolution behavior + + Tor and name plugins MAY cache name resolution results in memory as + needed. Caching results on disk should be avoided. + + Tor SHOULD abort (or cancel) an ongoing name resolution request, if it takes + more than NAME_RESOLUTION_TIMEOUT seconds. + XXX NAME_RESOLUTION_TIMEOUT = ??? + + Tor MUST validate that the resolution result is a valid .onion name. + XXX should we also accept IPs and regular domain results??? + XXX perhaps we should make sure that results are not names that need + additional name resolution to avoid endless loops. e.g. imagine + some sort of loop like this: + debian.zkey -> debian-bla.zkey -> debian.zkey -> etc. + +2.6. Cancelling a name resolution request + + Tor might need to cancel an ongoing name resolution request + (e.g. because a timeout passed, or the client is not interested in + that address anymore). In this case, Tor sends the following line to + the plugin stdout as follows: + + CANCEL <QUERY_ID> + + to which the name plugin, after performing the cancellation, SHOULD + answer with: + + CANCELED <QUERY_ID> + +2.7. Launching name plugins [INITENVVARS] + + As described in [INITPROTOCOL], when Tor launches a name plugin, it sets + certain environment variables. At a minimum, it sets (in addition to the + normal environment variables inherited from Tor): + + "TOR_NS_STATE_LOCATION" -- A filesystem directory path where the + plugin should store state if it wants to. This directory is not + required to exist, but the plugin SHOULD be able to create it if + it doesn't. The plugin MUST NOT store state elsewhere. + Example: TOR_NS_STATE_LOCATION=/var/lib/tor/ns_state/ + + "TOR_NS_PROTO_VERSION" -- To tell the plugin which versions of this + configuration protocol Tor supports. Future versions will give a + comma-separated list. Plugins MUST accept comma-separated lists + containing any version that they recognize, and MUST work correctly even + if some of the versions they don't recognize are non-numeric. Valid + version characters are non-space, non-comma printing ASCII characters. + Example: TOR_NS_PROTO_VERSION=1,1a,2,4B + + "TOR_NS_PLUGIN_OPTIONS" -- Specifies configuration options for this + name plugin as a semicolon-separated list of k=v strings with + options that are to be passed to the plugin. + + Colons, semicolons, equal signs and backslashes MUST be escaped with a + backslash. + + If there are no arguments that need to be passed to any of the + plugins, "TOR_NS_PLUGIN_OPTIONS" MAY be omitted. + + For example consider the following options for the "banana" name plugin: + + TOR_NS_PLUGIN_OPTIONS=timeout=5;url=https://bananacake.com + + Will pass to banana the parameters 'timeout=5' and + 'url=https://bananacake.com'. + + XXX Do we like this option-passing interface? Do we have any lessons + from our PT experiences? + + XXX Add ControlPort/SocksPort environment variables. + + See [PROTOEXAMPLE] for an example of this environment + +2.8. Name plugin workflow [NSBEHAVIOR] + + Name plugins follow the following workflow: + + 1) Tor sets the required environment values and launches the name plugin + as a sub-process (fork()/exec()). See [INITENVVARS]. + + 2) The name plugin checks its environment, and determines the supported NS + API versions using the env variable TOR_NS_PROTO_VERSION. + + 2.1) If there are no compatible versions, the name plugin writes + an INIT message with a failure status code as in + [INITPROTOCOL], and then shuts down. + + 3) The name plugin parses and handles the rest of the environment values. + + 3.1) If the environment variables are malformed, or otherwise + invalid, the name plugin writes an INIT message with a + failure status code as in [INITPROTOCOL], and then shuts + down. + + 4) After the name plugin completely initializes, it sends a successful + INIT message to stdout as in [INITPROTOCOL]. Then it continues + monitoring its stdin for incoming RESOLVE messages. + + 6) When the name plugin receives a RESOLVE message, it performs the name + resolution and replies with the appropriate RESOLVED message. + + 7) Upon being signaled to terminate by the parent process [NSSHUTDOWN], the + name plugin gracefully shuts down. + +2.8.1. Name plugin shutdown [NSSHUTDOWN] + + To ensure clean shutdown of all name plugins when Tor shuts down, the + following rules apply for name plugins: + + Name plugins MUST handle OS specific mechanisms to gracefully terminate + (e.g. SIGTERM). + + Name plugins SHOULD monitor their stdin and exit gracefully when it is + closed. + +2.9. Further details of stdin/stdout communication + +2.9.1. Message Format + + Tor communicates with its name plugins by writing NL-terminated lines to + stdout. The line metaformat is + + <Line> ::= <Keyword> <OptArgs> <NL> + <Keyword> ::= <KeywordChar> | <Keyword> <KeywordChar> + <KeyWordChar> ::= <any US-ASCII alphanumeric, dash, and underscore> + <OptArgs> ::= <Args>* + <Args> ::= <SP> <ArgChar> | <Args> <ArgChar> + <ArgChar> ::= <any US-ASCII character but NUL or NL> + <SP> ::= <US-ASCII whitespace symbol (32)> + <NL> ::= <US-ASCII newline (line feed) character (10)> + + Tor MUST ignore lines with keywords that it doesn't recognize. + +3. Discussion + +3.1. Using second-level domains instead of tld + + People have suggested that users should try to connect to reddit.zkey.onion + instead of reddit.zkey. That is, we should always preserve .onion as the + tld, and only utilize second-level domains for naming. + + The argument for this is that this way users cannot accidentally leak + addresses to DNS, as the .onion domain is reserved by RFC 7686. + + The counter-argument here is that this might be confusing to users since + they are not used to the second-level domain being special (e.g. co.uk). + Also, what happens when someone registers a 16-character name, that matches + the length of a vanilla onion address? + + We should consider the concerns here and take the right decision. + +3.2. Name plugins handling all tlds '*' + + In [TORRC], we assigned a single tld to each name plugin. Should we also + accept catch-all tlds using '*'? I'm afraid that this way a name system + could try to resolve even normal domains like reddit.com . + + Perhaps we trust the name plugin itself, but maybe the name system + network could exploit this? Also, the catch-all tld will probably + cause some engineering complications in this proposal (as it did for PTs). + +3.3. Deployment strategy + + We need to devise a deployment strategy that will allow us to improve + the UX of our users as soon as possible, but without taking hasty, + sloppy or uneducated decisions. + + For starters, we should make it easy for developers to write wrappers around + their secure name systems. We should develop libraries that speak the NS API + protocol and can be used to quickly write wrappers. Similar libraries were quite + successful during pluggable transport deployment; see pyptlib and goptlib. + + In the beginning, name plugins should be third-party applications that can + be installed by interested users manually or through package managers. Users + will also have to add the appropriate OnionNamePlugin line to their torrc. + This will be a testing phase, and also a community-growing phase. + + After some time, and when we get a better idea of how name plugins + work for the community, we can start considering how to make them + more easily usable. For example, we can start by including some name + plugins into TBB in an optional opt-in fashion. We should be careful + here, as people have real incentives for attacking name systems and + we should not put our users unwillingly in danger. + +3.4. Miscellaneous discussion topics + + 1. The PT spec tries hard so that a single executable can expose multiple + PTs. In this spec, it's clear that each executable is a single name + plugin. Is this OK or a bad idea? Should we change interfaces so that + each name plugin has an identifier, and then use that identifier for + things? + + 2. Should we make our initialization protocol _identical_ to the PT API + initialization protocol? That is, use ENV-ERROR etc. instead of INT? + + 3. Does it make sense to support reverse queries, from .onion to names? So + that people auto-learn the names of the onions they use? + +4. Acknowledgements + + Proposal details discussed during Tor hackfest in Seattle between + Yawning, David and me. Thanks to Lunar and indolering for more + discussion and feedback. + +Appendix A.1: Example communication Tor <-> name plugin [PROTOEXAMPLE] + + Environemnt variables: + + TOR_NS_STATE_LOCATION=/var/lib/tor/ns_state + TOR_NS_PROTO_VERSION=1 + TOR_NS_PLUGIN_OPTIONS=timeout=5;cache=/home/user/name_cache + + Messages between Tor and the banana name plugin: + + Name plugin (banana) -> Tor: + INIT 1 0 + + Tor -> Name plugin (banana): + RESOLVE 1 daewonskate.banana + + Name plugin (banana) -> Tor: + RESOLVED 1 0 jqkscnkne4qt91iq.onion + + Tor -> Name plugin (banana): + RESOLVE 1 architecturedirect.zkey + + Name plugin (banana) -> Tor (banana): + RESOLVE 1 2 "zkey not recognized tld" + + Tor -> Name plugin (banana): + RESOLVE 1 origamihub.banana + + Name plugin (banana) -> Tor (banana): + RESOLVE 1 2 wdxfpaxar4dg12vd.onion + +Appendix A.2: Example plugins [PLUGINEXAMPLES] + + Here are a few examples of name plugins for brainstorming: + + a) Simplest plugin: A local hosts file. Basically a local petname system + that maps names to onion addresses. + + b) A remote hosts file. A centralized community hosts file that people trust. + + c) Multiple remote hosts files. People can add their own favorite community + hosts file. + + d) Multiple remote hosts files with notaries and reputation + trust. Like moxie's convergence tool but for names. + + e) GNS + + f) OnioNS + + g) Namecoin/Blockstart diff --git a/proposals/proposal-status.txt b/proposals/proposal-status.txt index 105dca4..f9cf218 100644 --- a/proposals/proposal-status.txt +++ b/proposals/proposal-status.txt @@ -541,3 +541,9 @@ again to remind me! security against malicious exit nodes, by specifying their own set of exit nodes.
+279 A Name System API for Tor Onion Services [DRAFT] + + The proposal specifies a modular system for integrating naming systems + (GNS, Namecoin, etc.) with Tor onion services. + +