Skip to content

Wrap your TCP-based service with multiplexing mTLS tunnels.

License

Notifications You must be signed in to change notification settings

hexian000/tlswrapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tlswrapper

MIT License Build Go Report Card Downloads Release

Wrap any TCP-based service with multiplexed mutual TLS tunnels.

Status: Stable

Features

  • 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 |
+--------+    +------------+    +------------+    +--------+

Protocol Stack

+-------------------------------+
|          TCP traffic          |
+-------------------------------+
|   yamux stream multiplexing   |
+-------------------------------+
|   mutual TLS 1.3 (optional)   |
+-------------------------------+
|  TCP/IP (untrusted network)   |
+-------------------------------+

Authentication Model

Like SSH, each peer should have a key pair (X.509 certificate + PKCS #8 private key) and an authorized list. Only certificates in the authorized list (or signed by any authorized certificate) can communicate with the peer.

TLS behavior is based on "crypto/tls" library in Go.

Quick Start

Generating Key Pair

# generate private root certificate
./tlswrapper -gencerts ca
# ca-cert.pem, ca-key.pem

# generate peer certificates
./tlswrapper -gencerts peer0,peer1,peer2 -sign ca
# peerN-cert.pem, peerN-key.pem

Adding a certificate to "authcerts" will allow all certificates signed by it (including itself).

Creating Config Files

Example:

client -> peer1 -> peer0 <- peer2 -> server

For simpler cases, just remove the unused fragments.

peer0.json: If peer name is peer2, ask for myhttp service.

{
  "peername": "peer0",
  "muxlisten": "0.0.0.0:38000",
  "services": {
    "myhttp-peer2": "127.0.0.1:8080"
  },
  "peers": {
    "peer2": {
      "listen": "127.0.0.1:8080",
      "service": "myhttp"
    }
  },
  "certs": [
    {
      "cert": "@peer0-cert.pem",
      "key": "@peer0-key.pem"
    }
  ],
  "authcerts": [
    "@ca-cert.pem"
  ]
}

peer1.json: Ask peer0 for myhttp-peer2 service.

{
  "peername": "peer1",
  "peers": {
    "peer0": {
      "addr": "example.com:38000",
      "listen": "127.0.0.1:8080",
      "service": "myhttp-peer2"
    }
  },
  "certs": [
    {
      "cert": "@peer1-cert.pem",
      "key": "@peer1-key.pem"
    }
  ],
  "authcerts": [
    "@ca-cert.pem"
  ]
}

peer2.json: Connect to peer0.

{
  "peername": "peer2",
  "services": {
    "myhttp": "127.0.0.1:8080"
  },
  "peers": {
    "peer0": {
      "addr": "example.com:38000"
    }
  },
  "certs": [
    {
      "cert": "@peer2-cert.pem",
      "key": "@peer2-key.pem"
    }
  ],
  "authcerts": [
    "@ca-cert.pem"
  ]
}

Notes

Feel free to add more services/peers, or bring up forwards/reverses between the same instances.

  • "peername": local peer name
  • "muxlisten": listener bind address
  • "services": local service forwards
  • "services[*]": local service dial address
  • "peers": named peers to that need to keep connected
  • "peers[*].addr": dial address
  • "peers[*].listen": listen for port forwarding
  • "peers[*].service": the service name we ask the peer for
  • "certs": local certificates
  • "certs[*].cert": PEM encoded certificate (use "@filename" to read external file, same below)
  • "certs[*].key": PEM encoded private key
  • "authcerts": peer authorized certificates list, bundles are supported
  • "authcerts[*].cert": PEM encoded certificate

See source code for a complete list of all available options.

See config.json for example config file.

Start

./tlswrapper -c server.json

./tlswrapper -c client.json

Building/Installing from Source

# get source code
git clone https://github.com/hexian000/tlswrapper.git
cd tlswrapper
# checkout tagged version
git checkout v2.0.4
# build release executable
./make.sh r

# or install the latest development version
go install github.com/hexian000/tlswrapper/v3/cmd/tlswrapper@latest

Credits