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 following is a sample output during the install:
Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: stunnel4 Suggested packages: logcheck-database The following NEW packages will be installed: stunnel stunnel4 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 151kB of archives. After this operation, 434kB of additional disk space will be used. Do you want to continue [Y/n]? y Get:1 http://ftp.debian.org lenny/main stunnel4 3:4.22-2 [141kB] Get:2 http://ftp.debian.org lenny/main stunnel 3:4.22-2 [10.2kB] Fetched 151kB in 3s (45.6kB/s) Selecting previously deselected package stunnel4. (Reading database ... 19375 files and directories currently installed.) Unpacking stunnel4 (from .../stunnel4_3%3a4.22-2_i386.deb) ... Selecting previously deselected package stunnel. Unpacking stunnel (from .../stunnel_3%3a4.22-2_all.deb) ... Processing triggers for man-db ... Setting up stunnel4 (3:4.22-2) ... Warning: The home dir /var/run/stunnel4 you specified can't be accessed: No such file or directory Adding system user `stunnel4' (UID 104) ... Adding new group `stunnel4' (GID 109) ... Adding new user `stunnel4' (UID 104) with group `stunnel4' ... Not creating home directory `/var/run/stunnel4'. Setting up stunnel (3:4.22-2) ...
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 following 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.key
or the equivalent default:
cd /etc/stunnel openssl req -new -x509 -days 365 -nodes -out stunnel.pem -keyout stunnel.key
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 like:
ln -s /etc/stunnel/stunnel.pem /etc/ssl/certs/e56d2502.0
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/ssl/certs/stunnel.pem ;cert = /etc/stunnel/stunnel.pem key = /etc/stunnel/stunnel.key 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/stunnel4 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. We then restart the container.
Updated Autostart for "insserv" based containers
With the use of LSB tags in insserv instead of update-rc startup scripting, the above 101.start and 101.stop type files are not necessary and stunnel will not autostart anymore using this method. The error (# dmesg | tail) states that /proc is not mounted as yet.
The following procedure will enable stunnel to autostart:
- Create /etc/init.d/autostart having:
#!/bin/sh /etc/init.d/stunnel4 start
- Make it executable:
chmod +x /etc/init.d/autostart
- Place a SymLink in the Auto Startup folder
cd /etc/rcS.d ln -s ../init.d/autostart /etc/rcS.d/S98autostart