2

I want to launch lighttpd when someone tries to connect to port 80. I started with a simple test script to see if anything was working:

/etc/xinetd.d/www

service www
{
    disable         = no
    socket_type     = stream
    protocol        = tcp
    port              = 80
    log_on_success += USERID 
    log_on_failure += USERID
    server          = /usr/server_test.sh
    user            = root
    instances       = UNLIMITED
    wait            = no
    log_type        = SYSLOG daemon debug
}

where /usr/server_test.sh:

#!/bin/sh
echo "www connection"
lighttpd -D -f /usr/lighttpd.conf &
webconfig -c /usr/cppcms.js &

service xinetd restart

When I try:

nc localhost 80

I get:

www connection 2013-11-25 16:37:13: (network.c.345) can't bind to port:  80 Address already in use

How do I get xinetd and lighttpd to work together, not fight over same port?

2
  • lighttpd is not meant to work that way, you should just run it as a daemon. This bug was closed as wontfix by the developer team: redmine.lighttpd.net/issues/1584 Commented Nov 29, 2013 at 10:57
  • Ahh, nice spotted. But is there any way to do this, then without xinetd ? Commented Nov 29, 2013 at 11:16

1 Answer 1

5

Do not do it this way, run lighttpd strictly as a daemon. The daemon xinetd is mean to start services that are not actually running all the time. When xinetd sees traffic it "spins up" a particular service to meet the need, but otherwise the processes are not running.

By the way, you cannot share a TCP port between 2 daemons/services. Only one service can bind to a particular TCP port, essentially owning it for the duration of the time that it's running.

Doing it anyway

If you're absolutely sure you want to run it like this then take a look at this tutorial that shows exactly this scenario on a Raspberry Pi. The tutorial is titled: Starting mysqld and httpd on demand with xinetd.

This script was created, /etc/xinetd.init.d/lighttpd:

#!/bin/bash
# inspired on this article
# https://www.linuxnet.ch/automatic-tunnels-with-xinetd-and-netcat/
# script is called from xinetd
# script starts and stops service using /etc/init.d scripts

SERVICE=/etc/init.d/lighttpd  # script used to start/stop service
PORT=81 # port where end service should listen
PID_FILE=/var/run/lighttpd.pid # pid file generated by init script
REAPER_PID_FILE="/var/run/lighttpd_reaper.pid" # pid file generated by this script
REAPER_SLEEP=180 # The reaper sleeps in seconds and checks for idle conns
LOG=/var/log/syslog # where to log messages

# this function checks if we already have reaper
check_reaper(){
        if  [ -s $REAPER_PID_FILE ]
        then
                reaper_pid=`cat $REAPER_PID_FILE 2>/dev/null`
                ps -p $reaper_pid &> /dev/null
                if [ $? -ne 0 ]
                then
                        start_reaper &    # If we don't have a reaper we start one
                        echo $! > $REAPER_PID_FILE
                fi
        else
                start_reaper &
                echo $! > $REAPER_PID_FILE
        fi

}

# this function starts a reaper, which is a background process that will kill the end service if its inactive
start_reaper(){
        while [ -f $PID_FILE ]
        do
                sleep $REAPER_SLEEP                                      # We wait
                touched=`stat --printf %W $REAPER_PID_FILE 2>/dev/null`  # We check when the reaper PID was last touched
                now=`date +%s 2>/dev/null`
                let idle=$now-$touched
                if [ $idle -gt $REAPER_SLEEP ]              # If reaper pid has not been touched in more than a sleep cycle we stop the service
                then
                        echo `date`" REAPER STOPPING SERVICE AFTER BEING $idle" >> $LOG   
                        $SERVICE stop >> $LOG               # This is the stop service instruction
                        rm $REAPER_PID_FILE 
                        exit 0
                fi
        done
}


# This is where we start our service
start_service(){
        sleep 1                    # Added a delay to trouble shoot as browsers kickstart several connections, we need to allow the PID file to be created this can be improved.
        if [ -s $PID_FILE ]        # We check if the PID file for the end service exist to avoid calling the start script when the service has already been started
        then
                return
        else
                echo `date`" STARTING $SERVICE" >> $LOG
                $SERVICE start &>> $LOG                  #this is the start service instruction
                return
        fi
}

# We probe and wait for the service to come on line
wait_for_service(){
        nc -w30 -z 127.0.0.1 $PORT &>/dev/null          # probe end port with a timeout of 30 seconds
        if [[ $? -ne 0 ]]
        then
                echo `date`" XINET SERVICE START ON $PORT TIMED OUT" >> $LOG
        fi
}

# This is were all the magic happens netcat passes traffic back and forth
transmit(){
        nc -w30 127.0.0.1 $PORT 2>/dev/null  # netcat is awesome, timeout flag of 30 seconds can be adjusted
}

# this is the main program that is called every time
main()
{
        nc -z 127.0.0.1 $PORT &>/dev/null  # We probe the end service
        if [[ $? -ne 0 ]]                  # If its not responding
        then
                start_service              # We start service
                wait_for_service           # We wait for service to became online
        fi
        check_reaper                       # We always check we have a reaper
        touch $REAPER_PID_FILE             # We log activity by touching the reaper PID file
        transmit                           # We transmit data 
        exit 0                             
}

main

And the following xinetd service was created:

service http
{
        disable         = no
        socket_type     = stream
        protocol        = tcp
        port              = 80
        server = /etc/xinetd.init.d/lighttpd
        user            = root
        wait            = no
}
2
  • We have a small embedded system, so we would, if possible, only launch programs when needed. Commented Nov 29, 2013 at 11:07
  • @JakobJ - see updates. Commented Nov 29, 2013 at 11:15

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.