HTTP URL knocking

2015-08-26

I recently needed to knock open a port on my server, but the usual port knocking based methods did not work as many of the outgoing knock ports were blocked. e.g. So using knockd wasn't practical in this instance.

The following script shows how you can use a web based port knock to open up ports. In my particular case this opens up port 443 and redirects it to 22, because 22 is blocked by the outbound firewall.

I've not made the script intelligent enough to open the ports only to the knocking client, but it is possible since the IP address of the client is in the Apache web log, but remember that web accesses often go though proxy servers, so that may not open up access to the right IP address though

It assumes that you have an instance of Apache running. The script can be tailored to use other web servers easily. The script is nice and short and it requires no special tools nor libraries. There are of coarse specially made http port knocking systems available, which will offer better performance and so on.

The script is fairly straight forward, change the grep line to add your own knocking secret, and the open_port and close_port functions to perform the firewall action you require.

#!/bin/sh

open_port() {
    /sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 22  
    /sbin/iptables -I INPUT -p tcp --dport 22 -j ACCEPT
}

close_port() {
    /sbin/iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 22 
    /sbin/iptables -D INPUT -p tcp --dport 22 -j ACCEPT 
}

tail -n0 --follow=name /var/log/apache2/access.log | 
(while read line; do 
    if echo $line | grep "/SOME SECRET THING/"; then
        echo OPEN
        open_port
        sleep 60
        echo CLOSE    
        close_port
    fi
done)