Stunnel is a SSL wrapper for those web services which could not deploy SSL directly. I am using Ratchet for websocket, and it does not support SSL. So I found this wonderful tool!
Stunnel listened SSL connection on the accept
ports, then strip the SSL, and forward it to the connect
ports.
accept
and connect
are defined in the stunnel.conf
.
stunnel package download from Rudix, or use homebrew, or mac-port. Very convinient to install!
If you use Rudix pacakge to install, the binaries of stunnel and stunnel3 will be installed in /usr/local/bin/.
However, it is not easy to find its installed place. You can’t find it by using ‘whereis’ or ‘which’!
But luckily, you can just run:
$ stunnel
and the prompt will give you enough information. Such as where is the location of the stunnel.conf is /usr/local/etc/stunnel/stunnel.conf.
Specify the group priviledge. Add the group ‘stunnel’ and a user ‘stunnel’ in this group. Then change the stunnel.conf.
; A copy of some devices and system files is needed within the chroot jail
; Chroot conflicts with configuration file reload and many other features
chroot = /usr/local/var/lib/stunnel/
; Chroot jail can be escaped if setuid option is not used
setuid = stunnel
setgid = stunnel
$ sudo chown -R stunnel /usr/local/var/lib/stunnel/
$ sudo chgrp -R stunnel /usr/local/var/lib/stunnel/
Specify the location of the certificate and key. We will generate the certificate later.
; Certificate/key is needed in server mode and optional in client mode
cert = /usr/local/etc/stunnel/stunnel.pem
Stunnel is default to run in a daemon mode (which means in the background.) However, for the sake of developers, we can make it run at the foreground and to see the log.
foreground=yes
After all the deployment, we can now test the 443 to 80.
[https]
accept = 443
connect = 80
If you want to use web socket, you can listen to the 8443 port for imcoming “wss”, and run websocket service at the 8081 which only accept connection from localhost.
client=no
[websockets]
accept = 127.0.0.1:8443
connect = 127.0.0.1:8081
By reference to this blog, I generated the certificate for my localhost websocket server
openssl genrsa -out key.pem 2048
openssl req -new -x509 -key key.pem -out cert.pem -days 1095
cat key.pem cert.pem >> /usr/local/etc/stunnel/stunnel.pem
Note that the Common Name for the certificate is exactly the same as your host address. If you are develop your localhost server, your can specify ‘localhost’.
Now you can try to connect to the port 8081 in the javascript console of a browser such as Chrome and Safari.
var conn = new WebSocket('wss://localhost:8443');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
Unfortunately, the connection will not be able to establish at this moment. It is simply because the browser does not trust the certificate. To solved it, let’s add the certificate to the keychain access.
Now that the browsers (Chrome and Safari) will acknowledge the certificate, and the connection will establish. Enjoy. :)