Am 29.03.22 um 17:31 schrieb Frank Wunderlich: > Hi, > > got portknocking basicly working, currently only for ssh (of course changed ports in my config ;) ) > > define pkport1=123 > define pkport2=234 > define pkport3=345 > define pkport4=456 > > chain PortKnock { > tcp dport $pkport1 add @candidates_ipv4 {ip saddr . $pkport2 timeout 1s} > tcp dport $pkport2 ip saddr . tcp dport @candidates_ipv4 add @candidates_ipv4 {ip saddr . $pkport3 timeout 1s} > tcp dport $pkport3 ip saddr . tcp dport @candidates_ipv4 add @candidates_ipv4 {ip saddr . $pkport4 timeout 1s} > tcp dport $pkport4 ip saddr . tcp dport @candidates_ipv4 add @clients_ipv4 {ip saddr timeout 10s} log prefix "Successful v4 portknock: " > > > tcp dport ssh ip saddr @clients_ipv4 ct count 5 counter accept comment "ratelimited ssh" > > tcp dport $guarded_ports ct state established,related counter accept > > iifname $ifexternal tcp dport $guarded_ports counter reject with tcp reset > } > > as far as i tested it, it opens the port (ssh) only for a short period (~5s) then closes it. so connection needs to be establishes in this short time. after closing connection port gets closed too...so far so good. imho i can increase the time with the timeout-setting, right? > This first strategy seems to work by adjusting the rules over time. When knocking the first port @candidates_ipv4 is changed so it matches the next port (and source ip). The rule with $pkport1 still works but would re-add the source ip to the candidates with the next port in the sequence. I assume for multiple ports and different sequences it is necessary to have unique names per candidates and client variable. The other rule from the examples does not mutate the rule but selects different entry points and records state in contrack table as well as independent sets per knock port. Initial jump entry is PortKnock which tries the states in reverse. Clients (=ip) which already knocked correctly are handled first with a refresh. All others move through the sets. Either they proceed in time or they get evicted after 10s (timeout) which is checked every 4s (gc-interval). I'd say this is a matter of taste along the lines of Shannon: gc-interval below half the timeout. Also for the second case sets need to be named unique per guarded port. That is why the original author seems to prefer scripts to generate the rules. Final question remains: which strategy is more performant? I assume the first changes the same condition again and again which saves memory but requires more CPU. The second throws memory at the problem and saves CPU.