snowflake/server
David Fifield 0790954020 USERADDR support for turbotunnel sessions.
The difficulty here is that the whole point of turbotunnel sessions is
that they are not necessarily tied to a single WebSocket connection, nor
even a single client IP address. We use a heuristic: whenever a
WebSocket connection starts that has a new ClientID, we store a mapping
from that ClientID to the IP address attached to the WebSocket
connection in a lookup table. Later, when enough packets have arrived to
establish a turbotunnel session, we recover the ClientID associated with
the session (which kcp-go has stored in the RemoteAddr field), and look
it up in the table to get an IP address. We introduce a new data type,
clientIDMap, to store the clientID-to-IP mapping during the short time
between when a WebSocket connection starts and handleSession receives a
fully fledged KCP session.
2020-04-23 16:03:02 -06:00
..
README.md Use Manager.HTTPHandler for automatic TLS support in the server. 2018-03-05 21:16:51 -08:00
server.go USERADDR support for turbotunnel sessions. 2020-04-23 16:03:02 -06:00
server_test.go In server, treat a client IP address of 0.0.0.0 as missing. 2020-02-22 16:13:17 -07:00
stats.go Bring code into line with Golangci-lint linters 2019-10-08 10:25:44 -04:00
torrc README and documentation for server. 2017-01-21 14:53:51 -08:00
turbotunnel.go USERADDR support for turbotunnel sessions. 2020-04-23 16:03:02 -06:00
turbotunnel_test.go USERADDR support for turbotunnel sessions. 2020-04-23 16:03:02 -06:00

This is the server transport plugin for Snowflake. The actual transport protocol it uses is WebSocket. In Snowflake, the client connects to the proxy using WebRTC, and the proxy connects to the server (this program) using WebSocket.

Setup

The server needs to be able to listen on port 80 in order to generate its TLS certificates. On Linux, use the setcap program to enable the server to listen on port 80 without running as root:

setcap 'cap_net_bind_service=+ep' /usr/local/bin/snowflake-server

Here is a short example of configuring your torrc file to run the Snowflake server under Tor:

SocksPort 0
ORPort 9001
ExtORPort auto
BridgeRelay 1

ServerTransportListenAddr snowflake 0.0.0.0:443
ServerTransportPlugin snowflake exec ./server --acme-hostnames snowflake.example --acme-email admin@snowflake.example --log /var/log/tor/snowflake-server.log

The domain names given to the --acme-hostnames option should resolve to the IP address of the server. You can give more than one, separated by commas.

TLS

The server uses TLS WebSockets by default: wss:// not ws://. There is a --disable-tls option for testing purposes, but you should use TLS in production.

The server automatically fetches certificates from Let's Encrypt as needed. Use the --acme-hostnames option to tell the server what hostnames it may request certificates for. You can optionally provide a contact email address, using the --acme-email option, so that Let's Encrypt can inform you of any problems. The server will cache TLS certificate data in the directory pt_state/snowflake-certificate-cache inside the tor state directory.

In order to fetch certificates automatically, the server needs to listen on port 80, in addition to whatever ports it is listening on for WebSocket connections. This is a requirement of the ACME protocol used by Let's Encrypt. The program will exit if it can't bind to port 80. On Linux, you can use the setcap program, part of libcap2, to enable the server to bind to low-numbered ports without having to run as root:

setcap 'cap_net_bind_service=+ep' /usr/local/bin/snowflake-server