Table of Contents
New America Foundation - Contractor Agreement #33-OTIUSAID2013 “NAF6”
Section 1: Work to be Performed (Scope of Work)
Milestone 1: Implement MSP
- R1. Implement Mesh Stream Protocol (MSP), a byte-stream protocol that mimics the semantics of TCP. (See N1.)
Milestone 2: Implement authenticated TCP→MSP & MSP→TCP port forwarding
- R8. Update serval and commotion wikis to document the use of the port forwarding functions. (See N4.)
Milestone 3: Integrated SOCKS proxy with auto-discovery of proxy servers on mesh
- R9. Implement a service probe extension for DNA that asks if any nodes on the network are offering SOCKS proxy services, caches the result, and updates the port forwarding rules using the TCP to MSP port forwarding library. The service discovery probe will be made general purpose to allow mesh nodes to announce arbitrary services. (See N5.)
- R11. Add an “Offer SOCKS proxy access to the internet (can cost you money)” option to the “Connect” Activity of the Serval Mesh application that is enabled only when cellular data is enabled or equivalent functionality. When selected, this launches the “Select peers to allow to use your SOCKS proxy” activity that allows manipulation of a list of SIDs who are allowed to use the SOCKS proxy, or an equivalent mechanism. (See N6.)
- R14. Commit an updated version of the Serval Mesh app that includes the above functionality. (See N7.)
Technical notes
- N2. The new MDP packet filtering rules only match SID and MDP port number because the IP addresses of forwarded TCP connections are unknown to the Serval DNA daemon. The only suitable point in the connection chain for IP black/whitelisting would be the run-time configuration of the SOCKS proxy server implemented for R11, to only allow certain devices to access the SOCKS proxy.
- N3. The new MDP packet filtering rules are specified in an ASCII text file whose path is set in the Serval DNA configuration option
mdp.filter_rules_path
. Typically this text file would be in the same directory as theservald.conf
file, in which case the path can be relative. The syntax is shown by the following example:allow <>*:7 drop <*:8 allow <>0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF drop all
- The effect of this file is:
- the first line allows all packets to and from the PING port of all remote nodes, effectively allowing this node to ping other nodes
- the second line blocks all packets from any remote node sent to the local TRACE port, preventing this node from participating in route tracing
- the third line allows all packets received from and sent to the given SID
- the last line disallows all other packets
- The rules are tried in order from first to last on each incoming and outgoing packet until a rule is found that matches. If that rule is
drop
then the packet is blocked. If no rule matches then the packet is allowed. So in the example above, TRACE packets will not be received from the node with the given SID because rule 2 matches before rule 3. - The filter rules only affect incoming packets which are addressed to the local node and outgoing packets generated by the local node. They do not apply to packets for other nodes that are forwarded. This is because, in general, packets for other nodes are encrypted, so the port numbers are unknown.
- Even if a rule prevents a broadcast packet from being processed by this node, that packet will still be forwarded to other nodes.
- The Mesh-Packet-Filtering.md technical document contains a more comprehensive (and up to date) description of the packet rules file.
- N4. The Tunnelling.md technical document describes the TCP-over-MSP tunnelling commands in detail.
- N5. Instead of attempting to overload DNS, which suffers from security issues and a strict hierarchical delegation model unsuited to a dynamically changing network topology with no infrastructure, the opportunity was taken to invent a new service discovery protocol completly native to the Serval Mesh, taking advantage of the inherent security provided by Serval Identity (SID) addressing and Mesh Datagram Protocol (MDP) packet encryption. The new protocol was later named Cooee. The Cooee.md technical document describes the new protocol, which will be extended as needed in future to encompass more kinds of service.
- N6. As well as a SOCKS proxy, an HTTP proxy was implemented to assist with testing, since most Android browsers do not support SOCKS but do support HTTP proxies. This makes the grant much more practical, since most uses of the TCP-over-Mesh tunnelling would have the objective of providing Web access.
- N7. In practical terms, the SOCKS/HTTP proxy feature that this grant adds to the Serval Mesh app for Android is of very limited use, and is suitable mainly for demonstration and proof-of-concept, because:
- an Android device can only act as a useful proxy service if it has Internet access via either Wi-Fi or a Mobile Data Plan
- if an Android device is connected to the internet via Wi-Fi, then it cannot put Wi-Fi in Ad Hoc mode or run as a Personal Hotspot, so it can only connect with other Android devices that are associated to the same Access Point, in which case they also have Internet access, and have no need of the Serval Mesh proxy
- if a Mobile Data Plan is available on a proxy Android device, then it can easily share this with nearby devices using Android's Personal Hotspot function, so the Serval Mesh proxy is superfluous
PROGRESS REPORT
Milestone 1
All development, testing and documentation work for Milestone 1 was carried out by modifying the Serval DNA software component. The results of the work are freely available as source code from Serval DNA GitHub repository, so most links below refer to this repository.
Example usage, server side:
1$ servald msp listen 512 - Listening on port 512 - New connection from SID2:268 ^D - Sending EOF to SID2:512 - Received EOF from SID2:512 - Connection with SID2:512 closed
Example usage, corresponding client side:
2$ servald msp connect SID1 512 - Connecting to SID1:512 - Connected to SID1:512 - Received EOF from SID1:512 ^D - Sending EOF to SID1:512 - Connection with SID1:512 closed
R1 – Implement MSP
- commit 3a53318 improved MSP failure handling
- commit df6af96 implemented MSP connection timeouts and keep-alive packets, to ensure that an MSP connection fails if the other end ceases responding
- commit 12a0ca4 revamped the MSP API to make it more usable and extensible
R2 – Test MSP
- commit 3a53318 improved the first test case to assert that transmitted data arrives intact
- commit 741442c added two more test cases, for one-way transfers of large (64 KiB) data
- commit df6af96 added two more test cases, one for keep-alive of a quiescent connection, and one for connection failure when no end-point is listening
R3 – Document MSP
- the Mesh Stream Protocol (MSP) wiki page was created and inserted into the Technology Roadmap
- commit 938d645 added the Mesh-Stream-Protocol.md MSP API technical document skeleton
- commit 1dc09f5 added incomplete documentation for the MSP API
- this wiki page was updated with more links to GitHub commits
- commit 5463fee improved the Mesh-Stream-Protocol.md MSP API technical document to describe the revamped API
Milestone 2
As with Milestone 1, all development, testing and documentation work for Milestone 2 was carried out by modifying the Serval DNA software component. The results of the work are freely available as source code from Serval DNA GitHub repository, so most links below refer to this repository.
Example usage, assuming telnetd is listening on localhost:23:
1$ servald msp listen --forward=23 512 - Forwarding from port 512 to AF_INET:127.0.0.1:23
2$ servald msp connect --forward=4096 SID1 512 - Forwarding from AF_INET:127.0.0.1:4096 to SID1:512
2$ telnet localhost 4096 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Ubuntu Saucy Salamander (development branch) hostname login: ... $ cat /dev/urandom | hexdump -C ... ^C $ exit Connection closed by foreign host.
R4 – Implement TCP → MSP forwarding (client side)
- commit e09387b refactored how MSP handles i/o on its TCP sockets
- commit 99e08d1 added the
--forward=PORT
option to the MDP connect command, that accepts TCP connections to a given PORT (from the local host only) and forwards the data over MSP to the given Serval Identity (SID) and MDP port number - if the
--once
option is given, only a single TCP connection will be accepted, and once it closes the command exits
R5 – Implement MSP → TCP forwarding (server side)
- commit 48dce9a added the
--forward=PORT
option to the MDP listen command, that upon receiving an MDP connection, connects to the given TCP PORT (on the local host) and forwards the data to that TCP connection if successful - if the
--once
option is given, only a single MDP connection will be accepted, and once it closes the command exits
R6 – Implement MDP black/whitelist
- commit ea9de73 implemented a new configuration option
mdp.filter_rules_path
which names an ASCII text file that contains a list of filter rules for all incoming and outgoing MDP packets - the same commit created a new test suite tests/mdp, containing two test cases for packet filtering rules
- commit df18143 improved the filter rules syntax to make it possible to write a single rule matching inbound and outbound packets from a single SID
R7 – Test MSP-TCP forwarding and MDP black/whitelist
- commit 99e08d1 added another test case, for forwarding a TCP connection via MSP connection (client end)
- commit 48dce9a added another test case, for forwarding an MSP connection to a TCP port (server end), thereby creating a TCP tunnel through MSP
- commit 68421db improved diagnostic logging for the test cases
R8 – Document MSP-TCP forwarding and MDP black/whitelist
- commit 1e6caa0 created the Tunnelling.md technical document to describe the new TCP forwarding commands
- commit be4f7ad created the Mesh-Packet-Filtering.md technical document to describe the new MDP packet filter configuration
Milestone 3
All development, testing and documentation work for Milestone 3 was carried out by modifying the Serval DNA software component and the Serval Mesh app for Android (a.k.a. Batphone). The results of the work are freely available as source code from Serval DNA GitHub repository and Batphone GitHub repository, so most links below refer to this repository.
R9 – Service discovery
R10 – SOCKS proxy client in Batphone
- Batphone commit b3d8735 added a new Android service to Batphone to start the Serval DNA MSP connect process, and added a new Android activity (screen) to discover a SOCKS server using Cooee and allow the user to select one
- Batphone commit 017cefe replaced the Serval Mesh home-screen “Maps” icon with a blank icon (awaiting an icon design) labelled “Proxy” that opens the new activity
R11 – SOCKS proxy server in Batphone
- The Srelay SOCKS proxy server by Tomo. M., publicly licensed under a conventional three-clause BSD license, was chosen for its simplicity, good coverage of the standard, recent activity, and compatible license
- Batphone commit 65bb8cf imported the Srelay source code as a Git submodule and added it to the Batphone build
- Batphone commit b3d8735 added a new Android service to Batphone to start the SOCKS server process and the Serval DNA MSP listen process, and added a new Android activity (screen) to start and stop the SOCKS server
R12 – Testing
- The following automated Serval DNA tests were added:
- the new tests/msp script tests Mesh Stream Protocol (MSP) via the msp connect and msp listen commands
- An HTTP proxy server was added to Batphone in addition to the SOCKS proxy (see N6) to facilitate testing:
- Micro Proxy by Jeff Poskanzer, publicly licensed under a conventional two-clause BSD license was chosen for its simplicity, small size and compatible license
- Micro Proxy relies on an Internet service daemon to listen on a TCP socket and start it when required, so:
- Tiny Inetd by Dave Vandervies, publicly licensed under the ISC License, was chosen for its simplicity, small size and compatible license
- Batphone commit b3d8735 included code to start Tiny Inetd and Micro Proxy as well as the SOCKS proxy server
- The tunnelling proxy function was manually tested using the HTTP proxy, since the stock Android browser supports HTTP proxies but not SOCKS
- Serval senior developers were able to browse to almost all web pages, including content-rich pages like Google Image search
- Some web pages, such as Youtube videos, fetched content directly via the Wi-Fi Access Point instead of the HTTP Proxy, because their JavaScript content fetching code did not respect the system HTTP Proxy setting
- The new HTTP Proxy manual test case was added to the Batphone Release Testing plan, and executed by development staff
R13 – Update wikis
- The following Serval Developer Wiki pages were created and/or updated:
- The following new technical documents were added:
R14 – Commit Batphone with SOCKS
- The Batphone httpproxy branch was created to be the latest release of Batphone with the SOCKS/HTTP proxy functionality included
- The SOCKS/HTTP proxy functionality was not added to the Batphone Git development branch – see N7