Search:  
Gentoo Wiki

HOWTO_Port_Knocking


This article is part of the HOWTO series.
Installation Kernel & Hardware Networks Portage Software System X Server Gaming Non-x86 Emulators Misc

Contents

Why Port Knocking?

Port knocking is a great method to allow remote access without the security risks associated with keeping ports constantly open on the internet side of your networked host. This was intended to be used as an extra line of defense and is not an excuse for weak passwords.

With port knocking, the firewalled server machine runs the knock-daemon. This daemon listens for a specific sequence of tcp or udp "knocks" and associates them with an action. The knock daemon listens at a very low level in the TCP/IP stack and does not require any open ports to operate. The program is also completely stealth from outside the system. This stealth also adds a layer of security because attackers can not see any signs of the knock-daemon running, nor will they be likely to attempt random knocks to try to gain access.

On the client side, we have a program called knock which then issues these "knocks" to the host machine in order to perform a desired action, usually to open a port for remote access. This usually restricts the port to only the IP that issues the knock which also increases security over a simple open port.

Setting up the server

Installing the knock daemon is easy enough, you should have a working firewall prior to setting knock up. And yes, you must be root for this section!

# emerge knock

After that, we set up the config file using your favorite editor. The file should look like this:

File: /etc/knockd.conf
[options]
       logfile = /var/log/knockd.log
[openSSH]
       sequence    = 7000,8000,9000
       seq_timeout = 5
       command     = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
       tcpflags    = syn
[closeSSH]
       sequence    = 9000,8000,7000
       seq_timeout = 5
       command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
       tcpflags    = syn

Using that format, you should be able to add or modify your own entries.

If you already have a terminating target in the end of your chain which drops incoming connections, then adding a rule (iptables -A) after the terminating rule will not have the intended results. In such a case, use "iptables -I" instead of "iptables -A" to insert the rule above the terminating target.

%IP% is the IP address of the knocking machine. So a port will be opened or closed only for the person issuing the knock.

The command is not restricted to just iptables. You can use any command you like. Personally, I have one that issues a command to turn on a machine on my network so I can access it even if someone turned it off on me.

By following the port number in the sequence listing with :type, we can switch between tcp and udp pings like this: 9000:tcp,8000:udp,7000:tcp When no type is given, tcp is assumed.

Another useful example is:

File: /etc/knockd.conf
[opencloseSSH]
       sequence    = 7000,8000,9000
       seq_timeout = 5
       tcpflags    = syn
       start_command = /usr/sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
       cmd_timeout   = 10
       stop_command  = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

In this example, when the 7000,8000,9000 knock is recieved it will issue the start_command. It will then wait 10 seconds and then issue the stop_command. This will give you 10 seconds to initiate your connection. After the connection is started, most firewalls will allow the connection to continue after the port is closed to new connections.

I would recommend this format for most applications for the reason that people usually forget to close the port using the first example. Otherwise it will result in a big list of open ports in iptables that you will later need to clear.

Additional note on 2nd example

This second example is certainly the more preferable configuration for the reasons mentioned above, but I found that I had to add one more rule to iptables to allow this approach to work correctly. My iptables configuration is based on the one that you'll find in Oskar Andreasson classic tutorial. To allow the connection to continue after knockd has added the iptables rule and then removed it, you'll need a line similar to this:

iptables -I INPUT -p tcp -s 0/0 --dport ssh -m state --state ESTABLISHED -j ACCEPT

The key is the '-m state --state ESTABLISHED' parameters which allow established connections to continue. Once I added this to my (permanent) iptables rules, the approach worked for me. Of course as the original author stated, many iptables setups may have this in place by default.

Adding knock to startup

Add knock to startup using the usual format, and then start it up:

# rc-update add knock default
# /etc/init.d/knock start

If you need knock to run on an interface other than eth0, change /etc/conf.d/knock to fit your needs by adding -i <interface>:

File: /etc/conf.d/knock
OPTS="-d -i ppp0"

Other Tasks

Make sure to close all the ports on your firewall that are now controlled with portknock. If you don't, then this whole thing was kind of useless, wasn't it?

Using a Knock Client

The other side of the program is called knock and is included with the daemon. If you need to download the program separately for use on a Win32 machine, go to the projects homepage. If you need to use it on another linux machine you will need to either grab the whole thing, or simply copy /usr/bin/knock to removable media.

We issue the command in this format:

# knock hostname portnumber portnumber portnumber

Packet types can be changed between tcp and udp in the same manner as previously mentioned.

Tip: To make your life easier, you can make a shell script for carrying out knocks that can be used frequently.
However, there is always a possibility that other people may read your shell script, thus compromising your knock sequence

Example: Using netcat to knock on the target machine

You can also use netcat to knock if the type of packets required are same, i.e. either tcp or udp but not a combination, and only the SYN tcp flags is being considered.

 # nc -z <target-ip> <port1> <port2> <port3>...

This works on netcat v1.10. The one made by the hobbit.

Conclusion

Congratulations, you made it! If you followed everything and you started with a working firewall, you should now have port knocking implemented on your server. For more information on this program, go to the project's homepage .

Ryan Bair --Pyroboy101 01:06, 15 Mar 2005 (GMT)


Last modified: Fri, 19 Sep 2008 12:36:00 +0000 Hits: 34,769