Port Knocking

Port knocking is a fun tactic for exposing otherwise hidden services to a client that can present a shared secret in the form of a correct series of particular packets. Since the server end of the scheme is typically implemented with Netfilter the number of ways the authentication can be complicated is limited only by Netfilter's capacity to filter packets. For example you could choose to implement a scheme that requires packets of various sizes, header configurations or payloads. In its simplest and most common form the client sends a tcp SYN packet to a series of ports at the destination address in a specific sequence known only to the client and server. This allows an authorized user to gain access from virtually any machine equipped with any number of TCP based, port-configurable clients including telnet, avoiding the inherent problems of requiring specialty software or custom scripts.

#!/bin/sh # # http://foxpa.ws/port-knocking/ # # Uncomment LOG rules to monitor client activity via syslog. PORT1=1111 PORT2=2222 PORT3=3333 PORT4=4444 PROTECTED=22 TIMEOUT=60 iptables -N KNOCKP1 iptables -A KNOCKP1 -m recent --name KNOCKP1 --set #iptables -A KNOCKP1 -j LOG --log-prefix "KNOCK PHASE1: " iptables -N KNOCKP2 iptables -A KNOCKP2 -m recent --name KNOCKP1 --remove iptables -A KNOCKP2 -m recent --name KNOCKP2 --set #iptables -A KNOCKP2 -j LOG --log-prefix "KNOCK PHASE2: " iptables -N KNOCKP3 iptables -A KNOCKP3 -m recent --name KNOCKP2 --remove iptables -A KNOCKP3 -m recent --name KNOCKP3 --set #iptables -A KNOCKP3 -j LOG --log-prefix "KNOCK PHASE3: " iptables -N KNOCKP4 iptables -A KNOCKP4 -m recent --name KNOCKP3 --remove iptables -A KNOCKP4 -m recent --name KNOCKP --set #iptables -A KNOCKP4 -j LOG --log-prefix "KNOCK PHASE4: " iptables -N KNOCK iptables -A KNOCK -p tcp -m tcp --dport $PORT1 -m conntrack --ctstate NEW -j KNOCKP1 iptables -A KNOCK -p tcp -m tcp --dport $PORT2 -m conntrack --ctstate NEW -m recent --rcheck --seconds $TIMEOUT --reap --name KNOCKP1 -j KNOCKP2 iptables -A KNOCK -p tcp -m tcp --dport $PORT3 -m conntrack --ctstate NEW -m recent --rcheck --seconds $TIMEOUT --reap --name KNOCKP2 -j KNOCKP3 iptables -A KNOCK -p tcp -m tcp --dport $PORT4 -m conntrack --ctstate NEW -m recent --rcheck --seconds $TIMEOUT --reap --name KNOCKP3 -j KNOCKP4 iptables -A INPUT ! -s -j KNOCK iptables -A INPUT -p tcp -m tcp -dport $PROTECTED -m conntrack --ctstate NEW -m recent --rcheck --seconds $TIMEOUT --name KNOCK --reap -j ACCEPT iptables -A INPUT -p tcp -m tcp -dport $PROTECTED -m conntrack --ctstate NEW -j REJECT

We can use netcat or nmap to send our knocks:
$ nc -z -w1 hostname port $ nmap -Pn --host_timeout 1 --max-retries 0 -p port hostname

It's easy to create a one-liner using shell loops:
$ for x in 1111 2222 3333 4444; do nc -z -w1 hostname $x && sleep 1; done && ssh hostname

You can add this to your OpenSSH client configuration at ~/.ssh/config (create the file if it does not exist) so that it runs every time you attempt to connect to host.alias:
Host host.alias HostName hostname ProxyCommand sh -c "for x in 1111 2222 3333 4444; do nc -z -w1 %h $x; done && nc %h %p"


There are no comments for this item.