From charlesreid1

Stunnel Client

Running an stunnel client requires installing stunnel and setting up a configuration file just like if you were setting up an Stunnel/Server, except swapping the accept and connect ports, since we want the client to accept local traffic (on port 8443) and send it on to the server that it connects to with SSL (on port 443).

Ports/Arrangement

The stunnel server will be listening on port 443. We want to connect to the external server on 443, and forward the traffic to a local port 8443.

Stunnel Config File

If we want to establish a connection on port 443 (externally) to forward on to port 8443 (locally), we can use the following config file:

output  = /var/log/stunnel4/stunnel.log
cert    = /usr/local/etc/stunnel/stunnel.pem
key     = /usr/local/etc/stunnel/stunnel.pem
pid     = /var/run/stunnel4/stunnel.pid
client  = yes
[https]
accept  = 127.0.0.1:8443
connect = 10.11.12.13:443

A couple of things to note:

  • Server certificate must be the same certificate as is on the stunnel server.
  • /var/log/stunnel4 and /var/run/stunnel4 must both exist.
$ sudo mkdir -p /var/{run,log}/stunnel4

Why does the certificate on the client need to be the same one as is on the server? That's how you verify the identity of the server - if you can receive their public key over a trusted, published, public channel, then you can exchange encrypted communications with them. Use a trusted, encrypted channel like SSH or a USB key if you have physical access to the server.

If you can't establish a trusted connection with the server, there's no way to verify its identity.

On Linux you can put your certificates and your config file in /etc/stunnel.

For Homebrew users it is /usr/local/etc/homebrew.

Starting Stunnel Client

To start stunnel, you'll run the stunnel binary. This will attempt to silently establish a connection in the background to the specified stunnel server.

if the connection is successful, the command will be totally silent. Otherwise, it will print out whatever error results from running the command. Here's what an unsuccessful command looks like:

$ sudo stunnel
[ ] Clients allowed=2375
[ ] Cron thread initialized
[.] stunnel 5.30 on x86_64-apple-darwin14.5.0 platform
[.] Compiled with OpenSSL 0.9.8zc 19 Mar 2015
[.] Running  with OpenSSL 0.9.8zh 14 Jan 2016
[.] Update OpenSSL shared libraries or rebuild stunnel
[.] Threading:PTHREAD Sockets:POLL,IPv6 TLS:ENGINE,OCSP
[ ] errno: (*__error())
[.] Reading configuration from file /usr/local/etc/stunnel/stunnel.conf
[.] UTF-8 byte order mark not detected
[ ] Compression disabled
[ ] Snagged 64 random bytes from /Volumes/noospace/Users/charles/.rnd
[ ] Wrote 1024 new random bytes to /Volumes/noospace/Users/charles/.rnd
[ ] PRNG seeded successfully
[ ] Initializing service [https]
[ ] Loading certificate from file: /usr/local/etc/stunnel/stunnel.fullchain.pem
[ ] Certificate loaded from file: /usr/local/etc/stunnel/stunnel.fullchain.pem
[ ] Loading private key from file: /usr/local/etc/stunnel/stunnel.key.pem
[ ] Private key loaded from file: /usr/local/etc/stunnel/stunnel.key.pem
[ ] Private key check succeeded
[:] Service [https] needs authentication to prevent MITM attacks
[ ] SSL options: 0x03000004 (+0x03000000, -0x00000000)
[.] Configuration successful
[ ] Listening file descriptor created (FD=6)
[ ] Service [https] (FD=6) bound to 127.0.0.1:2200
[!] Cannot open log file: /var/log/stunnel4/stunnel.log
[ ] Closing service [https]
[ ] Service [https] closed (FD=6)
[ ] Service [https] closed


Testing Stunnel Client

To test out the stunnel client, first run stunnel on the server:

[remote] $ stunnel

run a Python web server on the remote machine on port 8443:

[remote] $ echo "<h2>Hallo wkerld!</h2>" > index.html
[remote] $ python -m SimpleHTTPServer 8443

Now on the client machine, run stunnel:

[client] $ stunnel

now you should be able to access the web server on localhost:8443, without having to specify the address of the server.

Flags