knockd server

Knockd is a port knocking daemon, a program that listens for specific packets on specific ports, and will run a command when it hears the correct sequence. It is used to hide ports from public view for better privacy/security.

Preparation

Read http://www.portknocking.org/ for background on the process of port forwarding.

Required Packages

Server (OpenWrt)

  • knockd

Client (your PC)

Choice of port knocking is left to the reader, it can be a full application or even as simple as a few netcat commands in a shell script.

Installation

opkg

opkg install knockd

Configuration

knockd is configured in /etc/knockd.conf

Server configuration

Here is the default knockd configuration.

[options]
	logfile = /var/log/knockd.log

[openSSH]
	sequence    = 7000,8000,9000
	seq_timeout = 5
	command     = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
	tcpflags    = syn

[closeSSH]
	sequence    = 9000,8000,7000
	seq_timeout = 5
	command     = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
	tcpflags    = syn
knockd automatically replaces %IP% with the IP address of the client that sent the knock, so you can open the port only to the authorized client.

This controls access to port 22 on the router, but it's not compatible with OpenWRT's iptables setup, and I don't want to SSH into the router, I want to use it to enable port forwarding to an SSH server inside my network.

Using it to manage port forwards is a bit more complicated. It requires several iptables rules to be enabled. I made a script that puts all the necessary commands together:

#!/bin/sh

PORT=$1
SRC_IP=$2
DST_IP=$3
ACTION=$4
. /lib/functions/network.sh; network_get_ipaddr WAN_IP wan

iptables $ACTION nat_reflection_in -s 192.168.1.0/24 -d $WAN_IP/32 -p tcp -m tcp --dport $PORT -m comment --comment "wan" -j DNAT --to-destination $DST_IP:$PORT -t nat
iptables $ACTION nat_reflection_out -s 192.168.1.0/24 -d $DST_IP/32 -p tcp -m tcp --dport $PORT -m comment --comment "wan" -j SNAT --to-source 192.168.1.1 -t nat
iptables $ACTION zone_wan_prerouting -p tcp -m tcp -s $SRC_IP --dport $PORT -j DNAT --to-destination $DST_IP:$PORT -t nat
iptables $ACTION nat_reflection_fwd -s 192.168.1.0/24 -d $DST_IP/32 -p tcp -m tcp --dport $PORT -m comment --comment "wan" -j ACCEPT 
iptables $ACTION zone_wan_forward -d $DST_IP/32 -p tcp -m tcp --dport $PORT -j ACCEPT

The command can be used as follows, where xxx.xxx.xxx.xxx is the IP address of your ssh server you want to forward to and %IP% is the IP of the client you want to allow:

./forward.sh 22 %IP% xxx.xxx.xxx.xxx -I
to create a port forward
./forward.sh 22 %IP% xxx.xxx.xxx.xxx -D
to disable a port forward.

This script was developed for OpenWRT Attitude Adjustment. The iptables commands may be different in other versions due to changes in structure. To figure out the necessary commands I created a port forward using the web GUI and used the iptables-save command to list the iptables rules that each forward generates. I had to add -t nat to the end of some of them. Also, I can't guarantee that this is the preferred or most elegant solution, but it works for me.

Client configuration

There are plenty of different port knocking clients available for all platforms, including Windows, Linux, OSX, and even Android.

Examples

Here's an example knockd.conf using the forward.sh script:

[options]
	logfile = /var/log/knockd.log
	interface = eth1

[OpenPort]
	sequence    = 123,456,789
	seq_timeout = 5
	command     = /path/to/forward.sh 22 %IP% 192.168.1.99 -I
	cmd_timeout = 3600
	stop_command= /path/to/forward.sh 22 %IP% 192.168.1.99 -D
	tcpflags    = syn
	
[ClosePort]
	sequence    = 789,456,123
	seq_timeout = 5
	command     = /path/to/forward.sh 22 %IP% 192.168.1.99 -D
	tcpflags    = syn

Start on boot

You should be able to put the command knockd -d into /etc/rc.local using the webGUI (System tab → Startup tab → rc.local section).

Administration

TODO

Troubleshooting

Check the knockd log at /var/log/knockd.log to see if you are knocking successfully, and to see what the command returns.

If you get something like this when running forward.sh:

Try `iptables -h' or 'iptables --help' for more information.
then you probably don't have the right commands in the script. Try creating a forward in the WebGUI with a distinctive port number (say 5555) and run
iptables-save | grep 5555
to find the right commands.

Notes

Back to top

doc/howto/portknock.server.txt · Last modified: 2014/05/10 05:06 by texasdex