True end-to-end encryption where the stunl server never sees your plaintext
$ stunl -port 3000 -e2e
$ stunl -port 3000 -e2e -e2e-cert ./cert.pem -e2e-key ./key.pem
$ stunl -port 3000 -e2e -autocert -domain tunnel.example.com
With E2E encryption enabled, TLS is terminated on your machine rather than on the stunl server. Traffic passes through the server fully encrypted -- it acts as a blind relay.
┌─────────┐ TLS encrypted ┌──────────────┐ encrypted (gRPC) ┌──────────────┐ ┌───────────┐
│ Browser │ ────────────────► │ stunl server │ ───────────────────► │ stunl client │ ────► │ Local app │
│ │ ◄──────────────── │ (blind relay)│ ◄─────────────────── │ (TLS termination)│ ◄──── │ :3000 │
└─────────┘ └──────────────┘ └──────────────┘ └───────────┘
│
Server NEVER sees
plaintext traffic
| Flag | Description |
|---|---|
| -e2e | Enable end-to-end encryption. Without -e2e-cert/-e2e-key, generates a self-signed certificate. |
| -e2e-cert | Path to your TLS certificate (PEM). Must be used with -e2e-key. |
| -e2e-key | Path to your TLS private key (PEM). Must be used with -e2e-cert. |
| -autocert | Use Let's Encrypt to obtain a trusted certificate. Requires a custom domain with a CNAME to stunl. |
When you pass -e2e without specifying certificate paths, stunl generates a self-signed ECDSA P-256 certificate with 1-year validity. The certificate is saved to ~/.stunl/ and reused on subsequent runs.
$ stunl -port 8080 -e2e
● E2E encryption enabled (self-signed)
Certificate: ~/.stunl/e2e-cert.pem
Bring your own certificate and key. Both flags must be specified together. The key file must have 0600 permissions.
$ stunl -port 443 -e2e \
-e2e-cert /etc/ssl/cert.pem \
-e2e-key /etc/ssl/key.pem
Obtains a trusted certificate from Let's Encrypt. The private key is generated locally on your machine and never transmitted. The client sends a CSR (Certificate Signing Request) to the stunl server, which completes the ACME HTTP-01 challenge and returns the signed certificate.
Requires a custom domain with a CNAME record pointing to stunl.
# 1. Add CNAME record: tunnel.example.com → stunl.io
# 2. Run with autocert:
$ stunl -port 3000 -e2e -autocert -domain tunnel.example.com
-e2e-cert and -e2e-key must be specified together
.. in paths)
0600 permissions (owner read/write only)
With -autocert, the private key is generated locally using ECDSA P-256 and never leaves your machine. Only the CSR is sent to the stunl server, which uses it to complete the ACME challenge with Let's Encrypt. The signed certificate is returned to the client.
$ stunl -port 3000 -e2e -id my-dev-app
$ stunl -port 8080 -e2e -autocert \
-domain api.example.com -id production
$ stunl -port 443 -e2e \
-e2e-cert /etc/pki/tls/certs/company.pem \
-e2e-key /etc/pki/tls/private/company-key.pem