xinet is an enhanced inetd. It comes with
access controls, resource controls, possibilities to pass environment settings
over to a server, and so on. Unfortunately courier-imap and qmail depend on their own "internet
super servers". So you have the same code three times (xinetd, tcpserver,
couriertcpd). tcpserver and couriertcpd do not support udp, couriertcpd also
performs very badly (I tried to spwan qmail-smtp from couriertcp and opened
one hundred connections: couriertcpd did not kill about 80 connections after
smtp conversation was done). So I was looking for how to use qmail-smtp and
courier-imap with xinetd.
Both servers expect that information about the client like the ip address or
the port number is available in environment variables like
$TCPREMOTEIP or $TCPREMOTEPORT. You could use tcp-env from the
qmail package to do that.
courier-imap reads its configuration from several environment settings which
are defined in /etc/imap/imapd (or whereever you put those
configuration files). You can source them in your xinetd startup script and
pass them to courier-imap by using xinetd's passenv-feature.
qmail-smtp acts as a smtprelay if there is an environment variable called
$RELAYHOST. Normally this is set up by tcpserver if the ip address of
the remote client matches a predefined address range which is allowed to relay
mails. xinetd lacks this feature. So I wrote a small programm called
relaycheck, which is meant to be started from tcp-env. If $TCPREMOTEIP
matches any ip addresses you specified as first argument for relaycheck, then
the program you specified as second argument will be called with the desired
environment variable $RELAYHOST.
Let's have a look at my configuration files and startup scripts. I am running qmail and courier-imap on a dual-homed machine. Access to the imapd should be granted only to the 192.168.0.0/24 subnet. qmail-smtp should be accessible by any host, but should act as a mailrelay for localhost (127.0.0.1) and the 192.168.0.0/24 subnet.
xinetd startup script:
#!/bin/sh # /sbin/rc.d/init.d/xinetd PATH=/bin:/sbin:/usr/bin:/usr/sbin PROG=/usr/sbin/xinetd MYPIDFILE=/var/run/xinetd.pid if [ ! -x $PROG ]; then exit 0 fi case "$1" in start) set -a . /etc/imap/imapd $PROG -filelog /var/log/xinetd.log -pidfile $MYPIDFILE ;; stop) if [ -f $MYPIDFILE ]; then if kill -0 `cat $MYPIDFILE`; then kill `cat $MYPIDFILE` fi rm -f $MYPIDFILE fi ;; reload) if [ -f $MYPIDFILE ]; then if kill -0 `cat $MYPIDFILE`; then kill -HUP `cat $MYPIDFILE` else rm -f $MYPIDFILE $0 start fi else $0 start fi ;; restart) $0 stop && $0 start ;; *) echo "usage: $0 (start|stop|reload|restart)" esac
xinetd configuration file:
# /etc/xinetd.conf service smtp { flags = NODELAY socket_type = stream wait = no user = qmaild server = /var/qmail/bin/tcp-env server_args = -R /usr/bin/relaycheck 127.0.0.1,192.168.0. /var/qmail/bin/qmail-smtpd log_type = FILE /var/log/smtpd.log log_on_success = PID HOST EXIT DURATION log_on_failure = HOST ATTEMPT passenv = } service imap { flags = NODELAY socket_type = stream wait = no user = root server = /var/qmail/bin/tcp-env server_args = -R /usr/sbin/imaplogin /usr/libexec/authlib/authshadow /usr/bin/imapd Maildir only_from = 192.168.0.0/24 bind = 192.168.0.1 log_type = FILE /var/log/imapd.log log_on_success = PID HOST EXIT DURATION log_on_failure = HOST ATTEMPT }
relaycheck.c (compile with diet -Os gcc -W -Wall -s -nostdinc -o relaycheck relaycheck.c)