Documentation at

Firewall Knock Operator - fwknop implements an authorization scheme known as Single Packet Authorization (SPA) for strong service concealment. SPA requires only a single packet which is encrypted, non-replayable, and authenticated via an HMAC in order to communicate desired access to a service that is hidden behind a firewall in a default-drop filtering stance. The main application of SPA is to use a firewall to drop all attempts to connect to services such as SSH in order to make the exploitation of vulnerabilities (both 0-day and unpatched code) more difficult. Any service that is concealed by SPA naturally cannot be scanned for with Nmap. It's like next generation Port Knocking...

Replace the default SSH port 22 with your SSH port, if different. Be sure, you have another method, of getting to the server if locked out! Try this out on a NON-PRODUCTION system only.

[spaclient]# apt-get install fwknop-client

[spaserver]# apt-get install fwknop-server

Let's initialize/setup the fwknoprc file:

[spaclient]$ fwknop --key-gen --use-hmac --save-rc-stanza -A tcp/22 -D ServerIP

Backup your keys on the spaclient ~/.fwknoprc to a safe place as without them, you will be locked out of any system that is SPA protected.

[spaclient]$ nano ~/.fwknoprc


ACCESS           tcp/22
# ACCESS           tcp/443,tcp/80
KEY_BASE64       CopyME
USE_HMAC         Y

[spaserver]# nano /etc/fwknop/access.conf

SOURCE               ANY
OPEN_PORTS           tcp/22
# OPEN_PORTS           tcp/443,tcp/80
MAX_FW_TIMEOUT       300
KEY_BASE64           PasteMe
HMAC_KEY_BASE64      PasteMe

[spaserver]# nano /etc/fwknop/fwknopd.conf

#PCAP_INTF eth0;
FIREWALL_EXE /sbin/iptables;

[spaclient]$ nmap -P0 -n -p 22 spaserver

22/tcp open ssh

[spaserver]# nano /usr/local/bin/

$IPTABLES -I INPUT 1 -i $LAN -p tcp --dport 22 -j DROP
# $IPTABLES -I INPUT 1 -i $LAN -p tcp --dport 80 -j DROP
# $IPTABLES -I INPUT 1 -i $LAN -p tcp --dport 443 -j DROP
$IPTABLES -I INPUT 1 -i $LAN -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -t filter -A FWKNOP_INPUT -i $LAN -p tcp --dport 22 -j ACCEPT
# $IPTABLES -t filter -A FWKNOP_INPUT -i $LAN -p tcp -m multiport --dports 80,443 -j ACCEPT

[spaserver]# chmod +x /usr/local/bin/

[spaserver]# nano /lib/systemd/system/fwknop-server.service

Description=Firewall Knock Operator Daemon

ExecReload=/bin/kill -HUP $MAINPID


[spaserver]# systemctl daemon-reload

[spaserver]# systemctl enable fwknop-server.service

[spaserver]# systemctl start fwknop-server.service

[spaserver]# systemctl status fwknop-server.service

[spaclient]$ nmap -P0 -n -p 22 spaserver

22/tcp filtered ssh

Note: Make sure your date/time, and timezones EX New_York are the same on the client and server by doing:
$ timedatectl set-timezone America/New_York . Beware: that changing from UTC to EDT, etc... on a server might break timestamps on the server [which is a big deal if its a logging or database server]!! Otherwise, if the time does not match, the next command for SPA knock will fail. Test both systems to make sure date and time are correct by:
$ date

Let's send a SPA packet to allow access for the default of 30 seconds:

[spaclient]$ fwknop -n mypie -a MYIP -U bob -v

[spaclient]$ nmap -P0 -n -p 22 spaserver

22/tcp open ssh

Let's send a SPA packet to allow access for the 300 seconds:

[spaclient]$ fwknop -n mypie -a MYIP -U bob -v --fw-timeout 300