Skip to content

Instantly share code, notes, and snippets.

@inkblot
Created July 4, 2024 01:34
Show Gist options
  • Select an option

  • Save inkblot/22e685e9f633e5e065c6c89db022ef48 to your computer and use it in GitHub Desktop.

Select an option

Save inkblot/22e685e9f633e5e065c6c89db022ef48 to your computer and use it in GitHub Desktop.
*filter
:INPUT DROP
:FORWARD DROP
:OUTPUT ACCEPT
:newconn -
:compliance -
:knocks -
:knock1 -
:knock2 -
:knock3 -
:Continue -
# Open ports on the services chain are always open
:services -
# Open ports on the locked chain are only open after knocking
:locked -
-A locked -p tcp --dport 22 -j ACCEPT
-A locked -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -j compliance
-A INPUT -m conntrack --ctstate NEW -j newconn
-A newconn -j knocks
-A newconn -m set --match-set blacklist src -j DROP
-A newconn -j services
-A newconn -j SET --add-set blacklist src
-A compliance -p icmp --icmp-type 3 -j ACCEPT
-A compliance -p icmp --icmp-type 4 -j ACCEPT
-A knocks -m recent --rcheck --seconds 30 --name K3 -j SET --add-set whitelist src
-A knocks -m recent --remove --name K3 -j Continue
-A knocks -m set --match-set whitelist src -j locked
-A knocks -m recent --rcheck --seconds 30 --name K2 -p tcp --dport {{ knock_3 }} -j knock3
-A knocks -m recent --remove --name K2 -j DROP
-A knocks -m recent --rcheck --seconds 30 --name K1 -p tcp --dport {{ knock_2 }} -j knock2
-A knocks -m recent --remove --name K1 -j DROP
-A knocks -p tcp --dport {{ knock_1 }} -j knock1
-A knock1 -m recent --set --name K1 -j DROP
-A knock2 -m recent --set --name K2 -j Continue
-A knock3 -m recent --set --name K3 -j Continue
COMMIT
@inkblot
Copy link
Author

inkblot commented Jul 4, 2024

This is a template for an iptables-only port knocking firewall configuration, to be realized at startup using netfilter-persistent. It takes three arguments: knock_1, knock_2, and knock_3. These are the three TCP ports which make up the knock sequence. This configuration requires the existence of two ipsets: blacklist and whitelist. Here are the rules:

  • Any port which is opened on the services chain is open to all source IP addresses, unless it is on blacklist, unless this is overridden by an entry on whitelist.
  • Any port which is opened on the locked chain is open only to clients on whitelist.
  • Any source IP that sends a packet to a port which is closed is added to blacklist.
  • Any source IP that sends the correct knocking sequence is added to whitelist.

To knock on this firewall and get added to whitelist, a client must send a SYN to the knock_1 port, then within 30 seconds send a SYN to the knock_2 port, and then within 30 more seconds send a SYN to the knock_3 port. Clients that begin the knock sequence will be added to blacklist and lose all access until completing the sequence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment