Port knocking example
Jump to navigation
Jump to search
This page shows some examples on how to use portknocking in nftables.
Example 1
Link to original nftables script is here.
Knocking sequence, in this example below, are TCP ports: 123, 234, 345 and 456.
define guarded_ports = {ssh}
table inet portknock {
set clients_ipv4 {
type ipv4_addr
flags timeout
}
set clients_ipv6 {
type ipv6_addr
flags timeout
}
set candidates_ipv4 {
type ipv4_addr . inet_service
flags timeout
}
set candidates_ipv6 {
type ipv6_addr . inet_service
flags timeout
}
chain input {
type filter hook input priority -10; policy accept;
iifname "lo" return
tcp dport 123 add @candidates_ipv4 {ip saddr . 234 timeout 1s}
tcp dport 123 add @candidates_ipv6 {ip6 saddr . 234 timeout 1s}
tcp dport 234 ip saddr . tcp dport @candidates_ipv4 add @candidates_ipv4 {ip saddr . 345 timeout 1s}
tcp dport 234 ip6 saddr . tcp dport @candidates_ipv6 add @candidates_ipv6 {ip6 saddr . 345 timeout 1s}
tcp dport 345 ip saddr . tcp dport @candidates_ipv4 add @candidates_ipv4 {ip saddr . 456 timeout 1s}
tcp dport 345 ip6 saddr . tcp dport @candidates_ipv6 add @candidates_ipv6 {ip6 saddr . 456 timeout 1s}
tcp dport 456 ip saddr . tcp dport @candidates_ipv4 add @clients_ipv4 {ip saddr timeout 10s} log prefix "Successful portknock: "
tcp dport 456 ip6 saddr . tcp dport @candidates_ipv6 add @clients_ipv6 {ip6 saddr timeout 10s} log prefix "Successful portknock: "
tcp dport $guarded_ports ip saddr @clients_ipv4 counter accept
tcp dport $guarded_ports ip6 saddr @clients_ipv6 counter accept
tcp dport $guarded_ports ct state established,related counter accept
tcp dport $guarded_ports counter reject with tcp reset
}
}
Example 2
Link to original nftables script is here.
Knocking sequence, in this example below, are TCP ports: 123, 234, 345 and 456.
#!/usr/bin/env nft -f
flush ruleset
table ip Inet4 {
set Knocked_1 {
type ipv4_addr
flags timeout
timeout 10s
gc-interval 4s
}
set Knocked_2 {
type ipv4_addr
flags timeout
timeout 10s
gc-interval 4s
}
set Knocked_3 {
type ipv4_addr
flags timeout
timeout 10s
gc-interval 4s
}
set Knocked_4 {
type ipv4_addr
flags timeout
timeout 2m
gc-interval 4s
}
chain Knock_1 {
set add ip saddr @Knocked_1
}
chain Unknock_1 {
set update ip saddr timeout 0s @Knocked_1
}
chain Knock_2 {
set update ip saddr timeout 0s @Knocked_1
set add ip saddr @Knocked_2
}
chain Unknock_2 {
set update ip saddr timeout 0s @Knocked_2
}
chain Knock_3 {
set update ip saddr timeout 0s @Knocked_2
set add ip saddr @Knocked_3
}
chain Unknock_3 {
set update ip saddr timeout 0s @Knocked_3
}
chain Knock_4 {
set update ip saddr timeout 0s @Knocked_3
set add ip saddr @Knocked_4 log prefix "Port-Knock accepted: "
}
chain RefreshKnock {
set update ip saddr timeout 2m @Knocked_4
}
chain PortKnock {
ct state new ip saddr @Knocked_4 goto RefreshKnock
tcp dport 456 ct state new ip saddr @Knocked_3 goto Knock_4
tcp dport 345 ct state new ip saddr @Knocked_3 return
ip saddr @Knocked_3 ct state new goto Unknock_3
tcp dport 345 ct state new ip saddr @Knocked_2 goto Knock_3
tcp dport 234 ct state new ip saddr @Knocked_2 return
ip saddr @Knocked_2 ct state new goto Unknock_2
tcp dport 234 ct state new ip saddr @Knocked_1 goto Knock_2
tcp dport 123 ct state new ip saddr @Knocked_1 return
ip saddr @Knocked_1 ct state new goto Unknock_1
tcp dport 123 ct state new goto Knock_1
}
chain FilterIn {
type filter hook input priority 0
policy drop
# allow established/related connections
ct state established,related accept
# early drop of invalid connections
ct state invalid drop
# allow from loopback
meta iif lo accept
# allow icmp
ip protocol icmp accept
# port-knocking
jump PortKnock
# misc. filtering
# ...
}
chain FilterOut {
type filter hook output priority 0
policy accept
}
}