Pknock match implements so-called "port knocking", a stealthy system for network authentication: a client sends packets to selected ports in a specific sequence (= simple mode, see example 1 below), or a HMAC payload to a single port (= complex mode, see example 2 below), to a target machine that has pknock rule(s) installed. The target machine then decides whether to unblock or block (again) the pknock-protected port(s). This can be used, for instance, to avoid brute force attacks on ssh or ftp services.

Example prerequisites:

    modprobe cn

    modprobe xt_pknock

Example 1 (TCP mode, manual closing of opened port not possible):

    iptables -P INPUT DROP

    iptables -A INPUT -p tcp -m pknock --knockports 4002,4001,4004 --strict --name SSH --time 10 --autoclose 60 --dport 22 -j ACCEPT

The rule will allow tcp port 22 for the attempting IP address after the successful reception of TCP SYN packets to ports 4002, 4001 and 4004, in this order (a.k.a. port-knocking). Port numbers in the connect sequence must follow the exact specification, no other ports may be "knocked" inbetween. The rule is named 'SSH' — a file of the same name for tracking port knocking states will be created in /proc/net/xt_pknock . Successive port knocks must occur with delay of at most 10 seconds. Port 22 (from the example) will be automatiaclly dropped after 60 minutes after it was previously allowed.

Example 2 (UDP mode — non-replayable and non-spoofable, manual closing of opened port possible, secure, also called "SPA" = Secure Port Authorization):

    iptables -A INPUT -p udp -m pknock --knockports 4000 --name FTP --opensecret foo --closesecret bar --autoclose 240 -j DROP

    iptables -A INPUT -p tcp -m pknock --checkip --name FTP --dport 21 -j ACCEPT

The first rule will create an "ALLOWED" record in /proc/net/xt_pknock/FTP after the successful reception of an UDP packet to port 4000. The packet payload must be constructed as a HMAC256 using "foo" as a key. The HMAC content is the particular client's IP address as a 32-bit network byteorder quantity, plus the number of minutes since the Unix epoch, also as a 32-bit value. (This is known as Simple Packet Authorization, also called "SPA".) In such case, any subsequent attempt to connect to port 21 from the client's IP address will cause such packets to be accepted in the second rule.

Similarly, upon reception of an UDP packet constructed the same way, but with the key "bar", the first rule will remove a previously installed "ALLOWED" state record from /proc/net/xt_pknock/FTP, which means that the second rule will stop matching for subsequent connection attempts to port 21. In case no close-secret packet is received within 4 hours, the first rule will remove "ALLOWED" record from /proc/net/xt_pknock/FTP itself.

Things worth noting:

General:

Specifying --autoclose 0 means that no automatic close will be performed at all.

xt_pknock is capable of sending information about successful matches via a netlink socket to userspace, should you need to implement your own way of receiving and handling portknock notifications. Be sure to read the documentation in the doc/pknock/ directory, or visit the original site — http://portknocko.berlios.de/ .

TCP mode:

This mode is not immune against eavesdropping, spoofing and replaying of the port knock sequence by someone else (but its use may still be sufficient for scenarios where these factors are not necessarily this important, such as bare shielding of the SSH port from brute-force attacks). However, if you need these features, you should use UDP mode.

It is always wise to specify three or more ports that are not monotonically increasing or decreasing with a small stepsize (e.g. 1024,1025,1026) to avoid accidentally triggering the rule by a portscan.

Specifying the inter-knock timeout with --time is mandatory in TCP mode, to avoid permanent denial of services by clogging up the peer knock-state tracking table that xt_pknock internally keeps, should there be a DDoS on the first-in-row knock port from more hostile IP addresses than what the actual size of this table is (defaults to 16, can be changed via the "peer_hasht_ents" module parameter). It is also wise to use as short a time as possible (1 second) for --time for this very reason. You may also consider increasing the size of the peer knock-state tracking table. Using --strict also helps, as it requires the knock sequence to be exact. This means that if the hostile client sends more knocks to the same port, xt_pknock will mark such attempt as failed knock sequence and will forget it immediately. To completely thwart this kind of DDoS, knock-ports would need to have an additional rate-limit protection. Or you may consider using UDP mode.

UDP mode:

This mode is immune against eavesdropping, replaying and spoofing attacks. It is also immune against DDoS attack on the knockport.

For this mode to work, the clock difference on the client and on the server must be below 1 minute. Synchronizing time on both ends by means of NTP or rdate is strongly suggested.

There is a rate limiter built into xt_pknock which blocks any subsequent open attempt in UDP mode should the request arrive within less than one minute since the first successful open. This is intentional; it thwarts eventual spoofing attacks.

Because the payload value of an UDP knock packet is influenced by client's IP address, UDP mode cannot be used across NAT.

For sending UDP "SPA" packets, you may use either knock.sh or knock-orig.sh. These may be found in doc/pknock/util.