moat docs ยท language 1
GitHub

Language Actions

Actions what a rule does with the packets it matches.

ActionMeaning
pass, dropFinal verdict. Must be the last action of its list.
add ip.src to SET [ttl D]Insert the source (or ip.dst) into an addresses set.
limit RATE [per ip.src[/N]] burst B [on exceed ACTIONS]Token bucket. Without per, one bucket is shared by all packets.

per ip.src/N (N from 1 to 32) groups IPv4 sources by their /N; IPv6 sources are then grouped by /64. on exceed must end with pass or drop and cannot contain limit. The burst is counted in packets for packet rates and in bytes for bit rates.

Packet rates go up to 1000000000/s. Each packet costs a whole number of nanoseconds, so rates above about 100000000/s are approximate: 400000000/s costs 3 ns a packet and lets about 333000000/s through.

rule udp_flood {
    when udp
    then limit 5000/s per ip.src burst 10000
        on exceed add ip.src to banned, drop
}

How limits work

Limits follow the generic cell rate algorithm: each key keeps the time at which its next packet is due. A burst of B packets can arrive at once; after that packets fit at the rate. The state is shared by all CPUs, so the rate holds for the whole machine, and it lives in one map of 65536 keys that forgets the least recently seen ones.

A per ip.src limit puts packets that have no IP header in one shared bucket of the rule; guard the rule with ip to keep them out. Rate limit state starts afresh when the rules are loaded or reloaded.

Adding to sets

add never shortens an entry: an address already in the set without an expiry, or with a later one, keeps it. In audit mode add does nothing, so turning audit off never starts with sets filled by traffic that was only being observed.

moat decides whether a packet goes on into the host; it never sends one anywhere. There is no action to answer, bounce or redirect a packet.