Stunnel in DAB appliances
Why stunnel
Sometimes it is necessary to use a SSH Wrapper - stunnel4 / stunnel3 - for example if we have a server with a MySQL daemon on it that needs to have some databases accessed from another server's MySQL client.
Pre-requisites and Asumptions
For the sake of simplicity, I assume that both are OpenVZ DAB generated appliances having host names Remote-DB-Host (SERVER) and Data-Accessing-Host (CLIENT). We further assume that each host has it's own MySQL daemon running on the normal port 3306. We need to enable a MySQL client on the Data-Accessing-Host to access a MySQL DB in the Remote-DB-Host in a secure manner (SSH Wrapped). Let us assume the following for reference:
Remote-DB-Host - SERVER
IP: 192.168.5.15 MySQL Server Port: 3306 To be configured Incoming SSH MySQL Port: 3320
Data-Accessing-Host - CLIENT
IP: 192.168.5.45 MySQL Server Port: 3306 To be configured MySQL Client Access Port: 3310 To be configured MySQL Client SSH Outgoing Port: 3320 (same as Remote-DB-Host's Incoming SSH Port)
Installation
On both hosts' (SERVER and CLIENT) console, execute:
apt-get install stunnel
If all goes well, you will get stunnel v4 installed.
The installed version of stunnel can be obtained from: # dpkg -l 'stunnel*'
Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad) ||/ Name Version Description +++-==============-==============-============================================ ii stunnel 3:4.22-2 dummy upgrade package ii stunnel4 3:4.22-2 Universal SSL tunnel for network daemons
PEM Cerificate generation
The PEM certificate should by default exist as /etc/stunnel/stunnel.pem It must be generated on the SERVER and is optional on the CLIENT. The default certificate generation template (edit as needed) is at:
/usr/share/doc/stunnel4/examples/stunnel.cnf
The folowing normal method of certificate generation hangs (Ctrl-C to exit) on DAB appliances:
make-ssl-cert /usr/share/doc/stunnel4/examples/stunnel.cnf /etc/stunnel/stunnel.pem
Hence we will have to revert to it's equivalent:
openssl req -new -x509 -days 365 -nodes -config /usr/share/doc/stunnel4/examples/stunnel.cnf -out
stunnel.pem -keyout /etc/stunnel/stunnel.pem In order to prevent hacking, the name of the stunnel.pem file is hashed using:
/usr/lib/ssl/misc/c_hash /etc/stunnel/stunnel.pem
This will result in some output like (yours will be different):
e56d2502.0 => /etc/stunnel/stunnel.pem
This should be the file name given to the link stored in /etc/ssl/certs/ folder or better still, if the /etc/stunnel/stunnel.pem file itself is renamed so.
On attempting to use stunnel, you will get the following error:
Wrong permissions on /etc/stunnel/stunnel.pem
This remedied by fixing the permission thus:
chmod 600 /etc/stunnel/stunnel.pem
A file named /etc/stunnel/stunnel.rnd will now have been created. This is the seed for the random number generator.
Server Configuration
We edit the /etc/stunnel/stunnel.conf file in the SERVER and comment out or delete every line leaving only the following in it:
; Certificate/key is needed in server mode and optional in client mode cert = /etc/stunnel/stunnel.pem
sslVersion = SSLv3 chroot = /var/lib/stunnel4/ setuid = stunnel4 setgid = stunnel4 ; PID is created inside chroot jail pid = /stunnel4.pid ; Some performance tunings socket = l:TCP_NODELAY=1 socket = r:TCP_NODELAY=1 ; Service-level configuration [mysqld] accept = 3320 connect = 3306
Client Configuration
We edit the /etc/stunnel/stunnel.conf file in the SERVER and comment out or delete every line leaving only the following in it:
; Certificate/key is needed in server mode and optional in client mode cert = /etc/stunnel/stunnel.pem sslVersion = SSLv3 chroot = /var/lib/stunnel4/ setuid = stunnel4 setgid = stunnel4 ; PID is created inside chroot jail pid = /stunnel4.pid ; Some performance tunings socket = l:TCP_NODELAY=1 socket = r:TCP_NODELAY=1 ; Use it for client mode client = yes ; Service-level configuration [mysqld] accept = 3310 connect = 192.168.5.15:3320
Note the presence of the client = yes line in the client config above.
SERVER and CLIENT stunnel Usage
We now edit /etc/default/stunnel making:
ENABLED=1
so that we may run stunnel as a service with default parameters set in the /etc/stunnel/stunnel.conf file.
We now start the stunnel with:
/etc/init.d/stunnel4 start
To stop it:
/etc/init.d/stunnel4 stop
The generic syntax is:
Usage: /etc/init.d/stunnel4 {start|stop|force-reload|restart}
We check the status with:
ps aux | grep stunnel
We should get something like this:
root 25454 0.0 0.0 3860 436 pts/0 S 08:13 0:00 stunnel4 stunnel.conf root 25455 0.0 0.0 3860 436 pts/0 S 08:13 0:00 stunnel4 stunnel.conf root 25456 0.0 0.0 3860 436 pts/0 S 08:13 0:00 stunnel4 stunnel.conf root 25457 0.0 0.0 3860 436 pts/0 S 08:13 0:00 stunnel4 stunnel.conf root 25458 0.0 0.0 3860 436 pts/0 S 08:13 0:00 stunnel4 stunnel.conf stunnel4 25460 0.0 0.0 3936 988 ? Ss 08:13 0:00 stunnel4 stunnel.conf root 25464 0.0 0.0 1724 548 pts/0 S+ 08:13 0:00 grep stunnel
SSH MySQL Client Access
Create a MySQL user (say remoteuser) in the SERVER machine with localhost access and a password and permissions to the databases needed.
On the CLIENT machine we can connect to the MySQL daemon on the SERVER, using:
mysql -h 192.168.5.45 --port=3310 -u remoteuser -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1005 Server version: 5.0.51a-24+lenny3 (Debian) Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
and disconnect with:
mysql> exit Bye
If we use localhost instead of the IP (192.168.5.45) in the above mysql connect string, we will get an error like:
inetd mode must define a remote host or an executable
This is peculiar to the OpenVZ Debian template since the localhost is mapped to 127.0.0.1 and not the LAN IP of 192.168.5.45 in the /etc/hosts file as the current LAN IP comes from the OpenVZ template config file at boot time only.
AutoRun At Startup
When stunnel4 is installed, it gets into the startup runlevel X scripts in /etc/rcX.d folders. This was automatically done by the install scripts using:
update-rc.d stunnel4 defaults 20
This does not work well atleast in OpenVZ containers. Hence we remove these runlevel symlinks and run them from the container's action scripts.
update-rc.d -f stunnel4 remove
On the Hardware Node where the container's (eg., assume VEID as 101) config files are stored, viz., /etc/vz/conf/ folder, we create two files as below:
- /etc/vz/conf/101.start
#!/bin/bash /etc/init.d/stunnel4 restart
- /etc/vz/conf/101.stop
#!/bin/bash /etc/init.d/stunnel4 stop
We use restart instead of start in 101.start file as it may already have been started.