11# go-tunnel - Robust Quic/TLS Tunnel (Stunnel replacement)
22
33## What is it?
4- A supercharged [ Stunnel] ( https://www.stunnel.org ) replacement written in golang. It is
4+ A supercharged [ Stunnel] ( https://www.stunnel.org ) replacement written in golang.
55is in a sense a proxy enabling addition of network-encryption to existing
66clients without any source code changes.
77
8- go-tunnel uses golang's TLS stack and built-in certification verification.
9-
108## Features
119
1210- TLS 1.3 for client and server mode (TLS Connect or TLS Listen)
1311- Quic client and server mode (Quic listen or Quic connect)
12+ - Optional SOCKS for connecting endpoint (SOCKS server)
1413- Optional TLS client certificate (for Quic/TLS Connect)
1514- SNI on the listening Quic/TLS server
1615- Ratelimits - global and per-IP
@@ -19,50 +18,66 @@ go-tunnel uses golang's TLS stack and built-in certification verification.
1918- YAML Configuration file
2019- Access Control on per IP or subnet basis (allow/deny combination)
2120- Strong ciphers and curves preferred on both client & server
21+ - Comes with end-to-end tests covering variety of scenarios
2222
2323Note that TLS private keys need to be * unencrypted* ; we don't support password protected
2424private keys yet. The main reason for this is that when ` gotun ` is daemonized, it may not be
2525possible to obtain the password in an interactive manner. Additionally, for SNI support, it may be
2626impossible to ask for interactive password in the middle of a client connection setup.
2727
28- ### Motivating Example
29- Let us suppose that you have a SOCKS5 server on host ` 192.168.55.3 ` and this
30- is accessible via a "gateway" node ` 172.16.55.3 ` . Furthermore, let us say that
31- clients/browsers wishing to use the SOCKS5 proxy are in the ` 10.0.0.0/24 ` subnet.
32- And to keep things simple, let us assume that one host in the ` 10.0.0.0 ` network
33- can access the gateway node: ` 10.0.0.5 ` .
28+ ## Motivating Example
29+ Lets assume you have a public server on ` proxy.example.com `
30+ listening on Quic/UDP supporting SOCKS protocol for connecting to
31+ outbound destinations. For security reasons, you want to limit
32+ access to only clients that are TLS authenticated (TLS client
33+ certs).
34+
35+ Lets also assume that you have a laptop that wants to connect to the
36+ SOCKS server efficiently.
37+
38+ Using two instances of ` gotun ` , you can accomplish this:
39+
40+ 1 . Local gotun instance on your laptop configured to accept TCP and
41+ connect using Quic to the external server ` proxy.example.com `
3442
35- Ordinarily, we'd create a IP routing rule on ` 10.0.0.5 ` to make the hosts on its network
36- access the ` 192.168.55.0/24 ` via ` 172.16.55.3 ` . But, we desire the communication
37- between ` 10.0.0.0/24 ` and ` 172.16.55.0/24 ` to be encrypted.
43+ 2 . Server gotun instance on the external host configured to accept
44+ authenticated Quic connections and proxy via SOCKS.
3845
39- Thus, with go-tunnel, one can setup a "bridge" between the two networks - and the bridge
40- is encrypted with TLS. The picture below explains the connectivity:
46+ 3 . Configure your laptop browser to use the "local" SOCKS server.
4147
42- ![ example diagram] ( /docs/example-diagram.png )
48+ Using Quic to connect the two ` gotun ` instances reduces the TCP/TLS
49+ overhead of every socks connection. And, TLS client certs enables
50+ strong authentication on the external server.
4351
44- In the setup above, hosts will treat ` 10.0.0.5:1080 ` as their "real" SOCKS server. Behind the
45- scenes, go-tunnel is relaying the packets from ` 10.0.0.5 ` to ` 172.16.55.3 ` via TLS. And, in turn
46- ` 172.16.55.3 ` relays the decrypted packets to the actual SOCKS server on ` 192.168.55.3 ` .
52+ The picture below explains the connectivity:
4753
48- The config file shown above actually demonstrates a really secure tunnel - where the server and
49- client both use certificates to authenticate each other.
54+ ![ example diagram] ( /docs/socks-example.png )
5055
51- Assuming the config on "Gotunnel-A" is in file ` a.conf ` , and the config on "Gotunnel-B" is in
52- ` b.conf ` , to run the above example, on host "Gotunnel-A":
56+ In the setup above, the laptop browser clients will treat
57+ ` 127.0.0.1:1080 ` as their "real" SOCKS server. Behind the scenes,
58+ ` gotun ` will tunnel the packets via Quic to a remote endpoint where
59+ a second ` gotun ` instance will unbundle the SOCKS protocol and
60+ connect to the final destination.
5361
54- gotun -d a.conf
62+ The config file shown above actually demonstrates a really secure tunnel
63+ - where the server and client both use certificates to authenticate each other.
5564
56- And, on host "Gotunnel-B":
65+ Assuming the config on "Gotunnel Laptop" is in file ` client.conf ` , and the
66+ config on "Gotunnel Server" is in ` server.conf ` , to run the above example,
67+ on host "Gotunnel-A":
5768
58- gotun -d b .conf
69+ gotun client .conf
5970
71+ And, on the public server:
6072
61- The ` -d ` flag runs ` gotun ` in debug mode - where the logs are sent
62- to STDOUT.
73+ gotun server.conf
6374
64- ### Building go-tunnel
65- You need a reasonably new Golang toolchain (1.8+). And the ` go `
75+ The ` -d ` flag for ` gotun ` runs it in debug mode - where the logs are sent
76+ to STDOUT. It's not recommended to run a production server in debug
77+ mode (too many log messages).
78+
79+ ## Building go-tunnel
80+ You need a reasonably new Golang toolchain (1.14+). And the ` go `
6681executable needs to be in your path. Then run:
6782
6883 make
@@ -105,8 +120,8 @@ In debug mode, the logs are sent to STDOUT and the debug level is set to DEBUG
105120In the absence of the ` -d ` flag, the default log level is INFO or
106121whatever is set in the config file.
107122
108- ### Config File
109- The config file is a YAML v2 document. A self-explanatory example is below:
123+ ## Config File
124+ The config file is a YAML v2 document. A complete, self-explanatory example is below:
110125
111126``` yaml
112127
@@ -121,6 +136,10 @@ log: STDOUT
121136# Logging level - "DEBUG", "INFO", "WARN", "ERROR"
122137loglevel : DEBUG
123138
139+ # config dir - where all non-absolute file references below will
140+ # apply.
141+ config-dir : /etc/gotun
142+
124143# Listeners
125144listen :
126145 # Listen plain text
@@ -129,25 +148,26 @@ listen:
129148 deny : []
130149
131150 timeout :
132- connect : 10
133- read : 10
134- write : 30
151+ connect : 5
152+ read : 2
153+ write : 2
135154
136155 # limit to N reqs/sec globally
137156 ratelimit :
138157 global : 2000
139- perhost : 30
158+ per-host : 30
159+ cache-size : 10000
140160
141161 # Connect via TLS
142162 connect :
143163 address : host.name:443
144164 bind : my.ip.address
145165 tls :
146- cert : /path/to/crt
147- key : /path/to/key
148- # path to CA bundle that can verify the server certificate.
149- # This can be a file or a directory.
150- ca : /path/to/ca.crt
166+ cert : /path/to/crt
167+ key : /path/to/key
168+ # path to CA bundle that can verify the server certificate.
169+ # This can be a file or a directory.
170+ ca : /path/to/ca.crt
151171
152172 # if address is a name, then servername is populated from it.
153173 # else, if it is an IP address, it must be set below.
@@ -159,29 +179,48 @@ listen:
159179 allow : [127.0.0.1/8, 11.0.1.0/24, 11.0.2.0/24]
160180 deny : []
161181 timeout :
162- connect : 8
163- read : 9
164- write : 27
182+ connect : 5
183+ read : 2
184+ write : 2
165185
166186 tls :
167- sni : true
168- certdir : /path/to/cert/dir
187+ sni : /path/to/cert/dir
169188
170189 # clientcert can be "required" or "optional" or "blank" or absent.
171190 # if it is required/optional, then clientca must be set to the list of
172191 # CAs that can verify a presented client cert.
173- clientcert : required
174- clientca : /path/to/clientca.crt
192+ client-cert : required
193+ client-ca : /path/to/clientca.crt
175194
176195 # plain connect but use proxy-protocol v1 when speaking
177196 # downstream
178197 connect :
179198 address : 55.66.77.88:80
180199 proxyprotocol : v1
181200
201+
202+ # Listen on Quic + client auth and connect to SOCKS
203+ - address : 127.0.0.1:8443
204+ tls :
205+ quic : true
206+ cert : /path/to/crt
207+ key : /path/to/key
208+ # path to CA bundle that can verify the server certificate.
209+ # This can be a file or a directory.
210+ ca : /path/to/ca.crt
211+
212+ client-cert : required
213+ client-ca : /path/to/clientca.crt
214+
215+ connect :
216+ address : SOCKS
217+
182218```
183219
184- ### Using SNI
220+ The ` etc/ ` directory has example configurations for running
221+ Quic+SOCKS on a public server and a local laptop.
222+
223+ ## Using SNI
185224SNI is exposed via domain specific certs & keys in the ` tls.certdir ` config block. SNI is
186225enabled by setting ` tls.sni ` config element to ` true ` ; and each hostname that is requested via
187226SNI needs a cert and key file with the file prefix of hostname. e.g., if the client is looking
@@ -190,7 +229,15 @@ for hostname "blog.mydomain.com" via SNI, then `gotun` will look for `blog.mydom
190229an example for SNI configured on listen address ` 127.0.0.1:9443 ` .
191230
192231
193- ### Performance Test
232+ ## Security
233+ ` gotun ` tries to be safe by default:
234+
235+ - Opinionated TLS 1.3 configuration
236+ - All config file references are checked for safety: e.g., any TLS
237+ certs/keys are verified to have sane permissions (NOT group/world
238+ writable)
239+
240+ ## Performance Test
194241Using iperf3 on two debian-linux (amd64) hosts connected via Gigabit Ethernet and ` gotun ` running on either end,
195242the performance looks like so:
196243
@@ -224,7 +271,7 @@ CPU Utilization: local/sender 1.8% (0.0%u/1.7%s), remote/receiver 9.0% (0.6%u/8.
224271
225272```
226273
227- ### Access Control Rules
274+ ## Access Control Rules
228275Go-tunnel implements a flexible ACL by combination of
229276allow/deny rules. The rules are evaluated in the following order:
230277
@@ -234,7 +281,7 @@ allow/deny rules. The rules are evaluated in the following order:
234281- Explicit denial takes precedence over explicit allow
235282- Default (fall through) policy is to deny
236283
237- #### Example of allow/deny combinations
284+ ### Example of allow/deny combinations
238285
2392861 . Allow all:
240287
@@ -273,7 +320,24 @@ If you are a developer, the notes here will be useful for you:
273320
274321- The code uses go modules; so, you'll need a reasonably new go toolchain (1.10+)
275322
276- - The go-tunnel code is in ` ./gotun`.
323+ - The go-tunnel code is in ` ./gotun`:
324+
325+ * main.go: `main()` for `gotun`
326+ * server.go: Implements TCP/TLS and Quic servers; also
327+ implements the SOCKS server protocol
328+ * conf.go: YAML configuration file parser
329+ * quicdial.go: Dial outbound connections via Quic + streams
330+ * tcpdial.go: Dial outbound connections via TCP
331+ * safety.go: Safely open files/dirs referenced in config file
332+
333+ - Tests : running tests: `go test -v ./gotun`
334+ Some of the tests/helpers :
335+ * mocked_test.go: Mock servers and clients
336+ * tcp_test.go: Tests for TCP/TLS to TCP/TLS
337+ * quic_test.go: Tests for TCP/TLS to Quic and vice versa
338+ * socks_test.go: Tests for socks (includes a test for the
339+ example configuration above)
340+ * utils_test.go: test helpers (e.g., `assert()`)
277341
278342- We build `build` - a a master shell script to build the daemons;
279343 it does two very important things :
0 commit comments