Wrap any TCP-based service with multiplexed mutual TLS tunnels.
Status: Stable
- Multiplexed: All traffic goes over one TCP connection.
- Mutual Forwarded: Each peer can listen from and connect to the other peer simultaneously over the same underlying connection.
- Secured: All traffic is optionally protected by mutual authenticated TLS.
- Incompatible: Always enforce the latest TLS version.
In terms of performance, creating multiplexed TCP tunnels is generally not a good idea, see Head-of-line blocking. Make sure you have a good reason to do so.
Trusted | Untrusted | Trusted
+--------+ +------------+ +------------+ +--------+
| Client |-n->| | | |-n->| Server |
+--------+ | | | | +--------+
| tlswrapper |-1->| tlswrapper |
+--------+ | | | | +--------+
| Server |<-n-| | | |<-n-| Client |
+--------+ +------------+ +------------+ +--------+
+-------------------------------+
| TCP traffic |
+-------------------------------+
| yamux stream multiplexing |
+-------------------------------+
| mutual TLS 1.3 (optional) |
+-------------------------------+
| TCP/IP (untrusted network) |
+-------------------------------+
Like SSH, each peer should have a key pair (certificate + private key) and an authorized list. Only certificates in the authorized list can communicate with the peer.
This behavior is based on TLS 1.3 implemented by "crypto/tls" library in Go.
By default, all certificates are self-signed. This will not reduce security.
See gencerts.sh.
./gencerts.sh client server
{
"tunnel": [
{
"muxlisten": "0.0.0.0:12345",
"dial": "127.0.0.1:8080"
}
],
"cert": "server-cert.pem",
"key": "server-key.pem",
"authcerts": [
"client-cert.pem"
]
}
{
"tunnel": [
{
"listen": "127.0.0.1:8080",
"muxdial": "example.com:12345"
}
],
"cert": "client-cert.pem",
"key": "client-key.pem",
"authcerts": [
"server-cert.pem"
]
}
- "tunnel": TLS tunnel configs
- "tunnel[*].muxlisten": Server bind address for TLS connections
- "tunnel[*].muxdial": Client dial address for TLS connections
- "tunnel[*].listen": Listen for port forwarding
- "tunnel[*].dial": The address we forward incoming connections to
- "cert": peer certificate
- "key": peer private key
- "authcerts": peer authorized certificates list, bundles are supported
See source code for a complete list of all available options.
See config.json for example config file.
./tlswrapper -c config.json
You may also found the systemd user unit tlswrapper.service is useful.
# get source code
git clone https://github.com/hexian000/tlswrapper.git
cd tlswrapper
# build an executable for local system
./make.sh r