Assignment #4: Port Knocking Netfilter
Due Date: May 3, 2006
Total Points: 100

Introduction

Port knocking is a method of establishing communications with a server that has no open ports. The knock is a series of packets sent to unused port numbers on the remote machine. When the server receives the correct knock, it opens a port for a set period of time so that the client can connect to whatever service is using the port. Port knocking allows servers to keep ports securely closed until the services on those ports (such as ssh for remote logins) are requested by a valid user.

While port knocking can be implemented as a userspace daemon that watches firewall log entries, it's most effectively implemented as a netfilter module. Your port knocking module will need to maintain information about incoming packets (port number, timestamp, open or closed state) in a hash table whose key is the source IP address. Whenever a UDP packet arrives for the port, check the hash table for a matching entry for that source IP address. If no entry is found, add a new entry. If it is found, check the timestamp of the entry to be sure that it hasn't expired and check if the new packet matches the next port in the knocking sequence. If the correct knocking sequence is received from a host, change the state of the entry to open and allow incoming packets to that port. The port will remain open for a set period of time, after which it will be closed again.

Assignment

You'll need to create a Netfilter module for the kernel, including:

  1. A header file ipt_knock.h under include/linux/netfilter_ipv4 which defineds ipt_knock_info.
  2. A C file ipt_knock.c under net/ipv4/netfilter directory.
  3. Modifications to Config.in and Makefile in net/ipv4/netfilter so that the knock module can be configured and compiled.

Do not modify any pre-existing kernel files other than Config.in and Makefile.

In the module initialization function of ipt_knock.c, create an informational procsfs file, /proc/net/ip_knock as we did in lab #4. This file will display the current state of your hash table. The output should be of the format:

[age] src=[src_ip_addr] match=[match_count] state=[state]
where age is the age since the last matching knock packet was received (if the port is closed) or since the port was opened, src is the source IP address of the packets, match is a count of the number of matched packets in the sequence, and state is either open or closed.

Modify iptables to support your Netfilter module. You may find it helpful to start with an existing iptables extension like libipt_sctp.c. Base your changes on the version of iptables used in lab #11. You'll need to make the following changes to iptables:

  1. Create a new iptables extension module, extensions/libipt_knock.c. Your struct iptables_match data structure needs to contain function pointers to the following functions:
  2. Add libipt_knock to the PF_EXT_SLIB target in extensions/Makefile.

Your module must support the following command line options:

--knock-secured-port port           Specify the port protected by knocking.
--knock-delay-threshold ms          Maximum delay in ms between knock packets.
--knock-open-duration ms            Length of time (in ms) port remains open.
--knock-port-seq p1,...,pN          Sequence of port numbers of knock.

Submission

Submit a gzipped tar file (.tar.gz suffix) containing the files listed above. The kernel files should be in a subdirectory called linux, while the iptables files should be in a subdirectory named iptables. The kernel files should be stored in appropriate subdirectories, i.e. ipt_knock.c should be stored under linux/net/ipv4/netfilter. Include a README file that summarizes your design decisions and the modifications you made to implement them. Submit the file by e-mail to me. You'll also need to schedule a time to demo your code for me.

References

  1. PortKnocking.org (many references available on the Documentation page)
  2. iptables HOWTO
  3. iptables Tutorial
  4. Netfilter Hacking HOWTO
  5. Jennifer Hou's CS498 Lectures
 

©2006 James Walden, Ph.D.