Port knocking example
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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
}
}