What is difference between Port Knocking and URL Knocking?

URL Knocking continuously reading apache's (or other web server ) log and if it see some URL (such as https://example.com/TheSecretStringHere/) that bypass matched with preset on the server side "TheSecretStringHere" string with requested URL then it simply manipulate firewall rules by opening access to specified on server side port. This solution could be used without any 3rd party software by utilizing only commonly installed by OS utilities.

Advantage of this method is, - if you use https protocol, then it eliminate man-in-a-middle watchers since actual URL is invisible because it's encrypted. Other one - it easy to implement your own solution based on your workflow.

Disadvantage - it all based on implementation.

In the link I provided, script continuously reading web server's log using effective feature of
tail -f (that utilize inotify kernel notification on file changes) and filter URL with grep. If URL matched with secret string then script trigger some action.

There is additional extra utilities that can be used in user space such as inotifywait that can effectively watch for web server log and if there is any changes - fire up some action (that could be not just opening port).

Port Knocking in contrast is usually dedicated 3rd party programs and isn't protected from man-in-a-middle, but do the same as URL Knocking.

As a conclusion, if you setup any web server that can create log files and support https then IMO URL Knocking is more secure way to open ports on demand.


Example of URL Knocking (from the link above):

#!/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)

Credit for script is going to: Jason Spashett