SSHD Under Daemontools and UCSPI-TCP

Text and color conventions used in this document:

This text provides notes and instructions.

This text gives terminal commands.
This text provides config file and shell script contents.


This page will briefly show how I install DJB's daemontools and ucspi-tcp. The FAQ for daemontools provides an explanation of why it may be a superior way to run service daemons. I have come to like using it and am slowly converting many of the critical services on my servers to be run under it. As an example, I will show how I run the ssh daemon under daemontools instead of init.d. Since I prefer to use Debian Linux for my servers, I will use the Debian ssh package and show how to convert the default install into a version which runs under daemontools.

Download and Install Daemontools

You can download daemontools at DJB's page here.

wget -c

All DJB software has an issue with the definition of errno in the error.h file. You can fix this by making the following change to the file /package/admin/daemontools-0.76/src/error.h. Note that the first line places comments around the expression which means the compiler will ignore it. The second line includes the errno.h header file where errno will be defined.

/* extern int errno;  */
#include <errno.h>

Another way to deal with this is to add the following to the cc line in the file conf-cc which is also in the src dir:

-include /usr/include/errno.h

Now you can continue with the normal build:

cd /package/admin/daemontools-0.76

Downlad and Install UCSPI-TCP

The ucspi-tcp (pronounced ooks-pie tee see pee) provides the tcpserver program and associated utilities. I also use the patches suggested by John Simpson. Here's how to download, patch and build it.

cd /usr/local/src
wget -c
tar xzvf ./ucspi-tcp-0.88.tar.gz
cd ucspi-tcp-0.88/

Add -include /usr/include/errno.h to conf-cc. Download the patches and continue with a normal build:

cd /usr/local/src
wget -c
wget -c
cd ucspi-tcp-0.88/
patch < ../ucspi-rss.diff
patch < ../tcpserver-limits-2007-12-22.patch
make setup check

Ucspi-tcp should now be installed and ready to use.

Man Pages

You should now have Daemon Tools and UCSP-TCP installed and functional. But these installs did not include documentation. It is important as you get more familiar with these tools to have the documentation readily available. Because of this, I will show how to install the man pages for all the programs included with both of these applications.

William Baxter has created man pages for both applications. Download them and unpack them. Then copy them as the README file directs to your man page directory:

cd /usr/local/src
wget -c
wget -c
tar xzvf ucspi-tcp-0.88-man.tar.gz
tar xzvf daemontools-0.76-man.tar.gz
cd daemontools-man/
gzip *.8 ; cp *.8.gz /usr/share/man/man8/
cd ../ucspi-tcp-0.88-man
gzip *.1 ; cp *.1.gz /usr/share/man/man1/

Now all the man pages for these applications should be available to browse and look at.

Convert SSHD Package

You very likely have ssh already installed on your system. If you do not have it installed, then here's how to do it:

apt-get update
apt-get install openssh-server

The Debian package will install a script in /etc/init.d/ssh which is used by init.d to start and stop the daemon. Just change the name of this to /etc/init.d/ so that it will not be supervised by init.d. The Debian package will also put configuration files in /etc/ssh/. The sshd config file will be used by daemontools: /etc/ssh/sshd_config.

The basic form of daemontools is to have a run directory and a service directory. The service directory is located in the system root and was created already when we installed daemontools. In the service directory are links to the run scripts of the various daemons which are being run by daemontools.

Create Directories

I like to have all my run directories under /var/supervise. So the first step is to create the directories and files for sshd:

mkdir -p /var/supervise/sshd/log
chmod 1755 /var/supervise/sshd
chmod 755 /var/supervise/sshd/log

System D

If you are using a Linux which uses systemd there are some modifications necessary for service scan to work. You must create a systemd unit file. Here is what I use:

Description=Daemontools service supervision

ExecStart=/usr/local/bin/svscanboot /service/


Install this file at:


Now disable the existing sshd service (which will be run by daemontools) and enable the new service by running these commands:

systemctl stop sshd
systemctl disable sshd
systemctl enable daemontools.service
systemctl start daemontools.service

Run the following to check if the service is running:

systemctl status daemontools.service

Run Scripts

Now we need to create a run script which will start the sshd daemon. We can use the configuration file from the Debian package. However, some things will now be controlled by tcpserver so if there are any overlaps, be sure to change them.


if [ ! -d /var/run/sshd ]; then
   mkdir /var/run/sshd
   chmod 0755 /var/run/sshd

exec 2>&1
exec tcpserver -vR \
    -c ${CONLIMIT} \
    -x /etc/tcp.ssh.cdb \
    0 22 \
    sshd -i \
    -e -f /etc/ssh/sshd_config

Be sure to read the man page (which we just installed) to understand all the options used here. One thing you will notice is the file /etc/tcp.ssh.cdb is being referenced. This works in a way similar to the files hosts.deny and hosts.allow. Read the man page for tcprules to understand what you might want to put in this file in order to enhance security and limit who can connect to your server. Actually, you will create the file /etc/tcp.ssh and then compile the /etc/tcp.ssh/cdb file by doing this, followed by changing permissions:

tcprules /etc/tcp.ssh.cdb /etc/tcp.ssh.tmp < /etc/tcp.ssh
chmod 644 /etc/tcp.ssh.cdb

Another common configuration decision is what interface to use. Many servers have more than one network card and associated interface for that card. You may want to restrict access to the server so that only one particular network (associated with one of the interfaces) is used. This can be done in a couple of different ways. The host option to tcpserver can have a specific IP address which would restrict it to one interface. My run file uses the number 0 which allows any interface. You can also restrict the network allowed in the cdb file as was described above. For example, if you want to restrict access to your server so that only systems on the network are allowed, put this in your /etc/tcp.ssh file:


Multilog Run File

Now we must create the run file for multilog: /var/supervise/sshd/log/run:


exec multilog t n20 s1256000 /var/log/sshd

Be sure to set the permissions:

chmod 755 /var/log/sshd/log/run

Notice that the log output will go to /var/log/sshd. It is somewhat more common to put the log output to the relative path ./main. I just like to have the log files in the traditional Debian location.

Start it up!

Everything should be ready now. In order to start up the service you just link the run script into the /service/ directory. Be sure to stop the daemon if it is currently running under init.d.

/etc/init.d/ssh stop
ln -s /var/supervise/sshd /service/

You can check the service by using svstat (read the man page):

svstat /service/sshd

The output should be a number greater than 1. If it's not, something is wrong and you should retrace your steps. A good way to troubleshoot a problem with tcpserver is to execute the run file right at your terminal and see what it does:

cd /var/supervise/sshd

And of course it's a good idea to look at the log file or use the tail command to watch what's going on in real time. When you read the log file, you must use the tai64nlocal (see it's man page) program to translate the times stamps used by multilog. Read the man page of tai64n for more information on this. Here is an example of how to read the sshd log file using less:

cat /var/log/sshd/current | tai64nlocal | less

All material on is copyright © Bob Wooldridge
Contact: bobber @