Installation

The folllowing command will install stunnel, stunnel3 and stunnel4. stunnel is a symlink to stunnel3

apt-get install stunnel

stunnel -v

Creating a certificate

In order for stunnel to work, you'll need a keypair. Use the following commands to create one:

openssl genrsa -out stunnel.key 2048
openssl req -new -x509 -key stunnel.key -out stunnel.pem -days 1095
cat stunnel.key stunnel.pem >> /etc/stunnel/stunnel.pem
chmod 600 /etc/stunnel/stunnel.pem
rm stunnel.key stunnel.pem

Configuration

You can edit /etc/stunnel/stunnel.conf to setup stunnel.

[google]
accept = 8888
connect = www.google.com:443
cert = /etc/stunnel/stunnel.pem
client = yes

The name between brackets is simply an identifier for the service. It needs to be unique within your config, but is not used otherwise.

The accept line tells stunnel on which (local)port to listen to incoming connections The connect line tells stunnel to which host+port to forward the connection. The client (options yes or no) tells stunnel which mode to run in:

  • yes: incoming connections on accept port are un-encrypted and forwarded to the encrypted service defined by the connect tag.
  • no: incoming connections on accept port are encrypted (using cert), and forwarded to the unencrypted service defined by the connect tag.

Enabling stunnel

Edit /etc/default/stunnel4 and set ENABLED=1

(Re)start Stunnel

/etc/init.d/stunnel4 restart

Debugging and logging

You can add foreground = yes to your stunnel.conf to keep stunnel in the foreground.

For log messages, add debug = 7 to get low level debug output in syslog. debug = 5 should give you enough information about which services are called from/to which ips.

tail -f /var/log/stunnel4/stunnel.log
tail -f /var/log/syslog

You can now connect to your unencrypted port 8888, and set a test request:

telnet localhost 8888
GET /

HTTP/1.0 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: https://www.google.co.uk/?gfe_rd=cr&ei=PPoNV4HAE6eI8Qf5gZSgDQ
Content-Length: 262
Date: Wed, 13 Apr 2016 07:50:20 GMT
Alternate-Protocol: 443:quic
Alt-Svc: quic=":443"; ma=2592000; v="32,31,30,29,28,27,26,25"

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="https://www.google.co.uk/?gfe_rd=cr&amp;ei=PPoNV4HAE6eI8Qf5gZSgDQ">here</A>.
</BODY></HTML>

You can also use curl to send http requests to an https server:

curl --header 'Host: www.google.com' "http://localhost:8888"

This will give you the same output. Note that the Host header is important, as you'd otherwise be sending an incorrect hostname, which could trip up SNI-enabled servers.

Troubleshooting

"sslVersion = TLSv1.2": Incorrect version of SSL protocol

If you're trying to force a TLSv1.2 connection, you'll need to have an stunnel version > 4.53 Sadly, Ubuntu 14.04 comes with stunnel 4.53. At the time of this writing (April 2016), I could not find any apt-sources offering a more recent stunnel version. Alternatively you could compile it manually. I did not try that.

Ubuntu 15 comes with 5.06. In order to get this to work we simply got a very minimal Ubuntu 15 server to proxy traffic that requires TLSv1.2 specifically.

Alternatively, you could setup a minimal Docker container, or find one on the Docker Hub.

curl: (56) Recv failure: Connection reset by peer

You can enable debuging in your stunnel.conf, and tail the logfile, to get details.

Stunnel doesn't start

See "Enabling stunnel" above.