add more ruleset examples
This commit is contained in:
1
doc/ref/ruleset-1.json
Normal file
1
doc/ref/ruleset-1.json
Normal file
File diff suppressed because one or more lines are too long
163
doc/ref/ruleset-1.nft
Normal file
163
doc/ref/ruleset-1.nft
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
#!/usr/sbin/nft -f
|
||||||
|
# Compiled from examples/router.fwl
|
||||||
|
# Single inet table: fwl
|
||||||
|
|
||||||
|
flush ruleset
|
||||||
|
|
||||||
|
table inet fwl {
|
||||||
|
|
||||||
|
# ── Data: let rfc1918 ────────────────────────────────────────────────────
|
||||||
|
set rfc1918 {
|
||||||
|
type ipv4_addr
|
||||||
|
flags interval
|
||||||
|
elements = {
|
||||||
|
10.0.0.0/8,
|
||||||
|
172.16.0.0/12,
|
||||||
|
192.168.0.0/16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Data: let forwards ──────────────────────────────────────────────────
|
||||||
|
map forwards {
|
||||||
|
type inet_proto . inet_service : ipv4_addr . inet_service
|
||||||
|
elements = {
|
||||||
|
tcp . 8080 : 10.17.1.10 . 80,
|
||||||
|
tcp . 2222 : 10.17.1.11 . 22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── WireGuard ct mark state machine ─────────────────────────────────────
|
||||||
|
# Compiles: flow WireGuardHandshake = WGInitiation . WGResponse within 5s
|
||||||
|
# State: ct mark 0 = Idle, 1 = SawInitiation, 2 = Confirmed
|
||||||
|
#
|
||||||
|
# WGInitiation: UDP, udp length == 156 (8 hdr + 148 payload), payload[0] == 0x01
|
||||||
|
# WGResponse: UDP, udp length == 100 (8 hdr + 92 payload), payload[0] == 0x02
|
||||||
|
# @th,64,8 = first byte of UDP payload (offset 64 bits past transport header start)
|
||||||
|
|
||||||
|
chain wg_flow {
|
||||||
|
# Packet 1: Idle → SawInitiation
|
||||||
|
ct state new ct mark 0 \
|
||||||
|
meta l4proto udp udp length 156 \
|
||||||
|
@th,64,8 0x01 \
|
||||||
|
ct mark set 1 \
|
||||||
|
return
|
||||||
|
|
||||||
|
# Packet 2: SawInitiation → Confirmed
|
||||||
|
ct mark 1 \
|
||||||
|
meta l4proto udp udp length 100 \
|
||||||
|
@th,64,8 0x02 \
|
||||||
|
ct mark set 2 \
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── rule blockOutboundWG ─────────────────────────────────────────────────
|
||||||
|
# Compiles: rule blockOutboundWG : Frame -> <FlowMatch, Log> Action
|
||||||
|
# Called via jump from forward. Drops confirmed WG handshakes, returns otherwise.
|
||||||
|
|
||||||
|
chain blockOutboundWG {
|
||||||
|
# Feed matching UDP into the WG state machine
|
||||||
|
meta nfproto ipv4 meta l4proto udp \
|
||||||
|
udp length 156 \
|
||||||
|
@th,64,8 0x01 \
|
||||||
|
jump wg_flow
|
||||||
|
|
||||||
|
# If handshake is now Confirmed (ct mark 2): log + drop
|
||||||
|
ct mark 2 \
|
||||||
|
log prefix "WG blocked: " level warn \
|
||||||
|
drop
|
||||||
|
|
||||||
|
# Continue: return to forward chain (no verdict)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy input ─────────────────────────────────────────────────────────
|
||||||
|
# hook = Input, table = Filter, priority = filter (0), default = drop
|
||||||
|
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority filter; policy drop;
|
||||||
|
|
||||||
|
# | _ if ct.state in { Established, Related } -> Allow
|
||||||
|
ct state { established, related } accept
|
||||||
|
|
||||||
|
# | Frame(lo, _) -> Allow
|
||||||
|
iifname "lo" accept
|
||||||
|
|
||||||
|
# | Frame(_, IPv6(ip6, ICMPv6(_, _))) if ip6.src in fe80::/10 -> Allow
|
||||||
|
meta nfproto ipv6 ip6 nexthdr ipv6-icmp ip6 saddr fe80::/10 accept
|
||||||
|
|
||||||
|
# | Frame(_, IPv4(_, TCP(tcp, _))) if tcp.dport == :22 -> Allow
|
||||||
|
meta nfproto ipv4 meta l4proto tcp tcp dport 22 accept
|
||||||
|
|
||||||
|
# | Frame(_, IPv4(_, UDP(udp, _))) if udp.dport == :51944 -> Allow
|
||||||
|
meta nfproto ipv4 meta l4proto udp udp dport 51944 accept
|
||||||
|
|
||||||
|
# | _ -> Drop (chain policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy forward ───────────────────────────────────────────────────────
|
||||||
|
# hook = Forward, table = Filter, priority = filter (0), default = drop
|
||||||
|
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority filter; policy drop;
|
||||||
|
|
||||||
|
# | _ if ct.state in { Established, Related } -> Allow
|
||||||
|
ct state { established, related } accept
|
||||||
|
|
||||||
|
# | frame if iif in lan_zone && oif == wan -> blockOutboundWG(frame)
|
||||||
|
meta iifname { "lan", "wg0" } meta oifname "wan" jump blockOutboundWG
|
||||||
|
|
||||||
|
# | _ if ct.status == DNAT -> Allow
|
||||||
|
ct status dnat accept
|
||||||
|
|
||||||
|
# | Frame(iif in lan_zone -> wan, _) -> Allow
|
||||||
|
meta iifname { "lan", "wg0" } meta oifname "wan" accept
|
||||||
|
|
||||||
|
# | Frame(iif in lan_zone -> lan_zone, _) -> Allow
|
||||||
|
meta iifname { "lan", "wg0" } meta oifname { "lan", "wg0" } accept
|
||||||
|
|
||||||
|
# | Frame(wan -> lan_zone, IPv4(ip, TCP|UDP)) if (proto, dport) in forwards -> Allow
|
||||||
|
# Membership test only — the actual DNAT is done in nat_prerouting.
|
||||||
|
meta iifname "wan" meta oifname { "lan", "wg0" } \
|
||||||
|
meta nfproto ipv4 \
|
||||||
|
meta l4proto { tcp, udp } \
|
||||||
|
meta l4proto . th dport @forwards \
|
||||||
|
accept
|
||||||
|
|
||||||
|
# | _ -> Drop (chain policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy output ────────────────────────────────────────────────────────
|
||||||
|
# hook = Output, table = Filter, priority = filter (0), default = accept
|
||||||
|
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority filter; policy accept;
|
||||||
|
# | _ -> Allow (chain policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy nat_prerouting ────────────────────────────────────────────────
|
||||||
|
# hook = Prerouting, table = NAT, priority = dstnat (-100), default = accept
|
||||||
|
|
||||||
|
chain nat_prerouting {
|
||||||
|
type nat hook prerouting priority dstnat; policy accept;
|
||||||
|
|
||||||
|
# | Frame(_, IPv4(ip, TCP|UDP)) ->
|
||||||
|
# if FIB.daddrLocal(ip.dst) then DNATMap((proto, dport), forwards) else Allow
|
||||||
|
meta nfproto ipv4 meta l4proto { tcp, udp } \
|
||||||
|
fib daddr type local \
|
||||||
|
dnat ip to meta l4proto . th dport map @forwards
|
||||||
|
|
||||||
|
# | _ -> Allow (chain policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy nat_postrouting ───────────────────────────────────────────────
|
||||||
|
# hook = Postrouting, table = NAT, priority = srcnat (100), default = accept
|
||||||
|
|
||||||
|
chain nat_postrouting {
|
||||||
|
type nat hook postrouting priority srcnat; policy accept;
|
||||||
|
|
||||||
|
# | Frame(_ -> wan, IPv4(ip, _)) if ip.src in rfc1918 -> Masquerade
|
||||||
|
meta oifname "wan" meta nfproto ipv4 ip saddr @rfc1918 masquerade
|
||||||
|
|
||||||
|
# | _ -> Allow (chain policy)
|
||||||
|
}
|
||||||
|
}
|
||||||
69
examples/simple-router.fwl
Normal file
69
examples/simple-router.fwl
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
interface wan : WAN { dynamic; };
|
||||||
|
interface lan : LAN { cidr4 = { 10.0.0.0/24 }; };
|
||||||
|
|
||||||
|
zone lan_zone = { lan };
|
||||||
|
|
||||||
|
let rfc1918 : Set<IPv4> = { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 };
|
||||||
|
|
||||||
|
-- Single IPv4 port forward: tcp:8080 -> 10.0.0.10:80
|
||||||
|
let forwards : Map<(Protocol, Port), (IP, Port)> = {
|
||||||
|
(tcp, :8080) -> (10.0.0.10, :80)
|
||||||
|
};
|
||||||
|
|
||||||
|
-- Open inbound ports on the router itself
|
||||||
|
let open_ports : Set<Port> = { :22 };
|
||||||
|
|
||||||
|
-- IPv6 forwarded destination: tcp . 2001:db8::1 . 22000
|
||||||
|
let forwards_v6 : Set<(Protocol, IP, Port)> = {
|
||||||
|
(tcp, 2001:db8::1, :22000)
|
||||||
|
};
|
||||||
|
|
||||||
|
policy input : Frame
|
||||||
|
on { hook = Input, table = Filter, priority = Filter }
|
||||||
|
= {
|
||||||
|
| _ if ct.state in { Established, Related } -> Allow;
|
||||||
|
| Frame(lo, _) -> Allow;
|
||||||
|
| Frame(_, IPv6(ip6, ICMPv6(_, _)))
|
||||||
|
if ip6.src in fe80::/10 -> Allow;
|
||||||
|
| Frame(_, IPv4(_, TCP(tcp, _)))
|
||||||
|
if tcp.dport in open_ports -> Allow;
|
||||||
|
| Frame(_, IPv4(_, UDP(udp, _)))
|
||||||
|
if udp.dport == :51944 -> Allow;
|
||||||
|
| _ -> Drop;
|
||||||
|
};
|
||||||
|
|
||||||
|
policy forward : Frame
|
||||||
|
on { hook = Forward, table = Filter, priority = Filter }
|
||||||
|
= {
|
||||||
|
| _ if ct.state in { Established, Related } -> Allow;
|
||||||
|
| _ if ct.status == DNAT -> Allow;
|
||||||
|
| Frame(iif in lan_zone -> wan, _) -> Allow;
|
||||||
|
| Frame(wan -> iif in lan_zone, IPv4(ip, TCP(th, _) | UDP(th, _)))
|
||||||
|
if (ip.protocol, th.dport) in forwards -> Allow;
|
||||||
|
| Frame(wan -> iif in lan_zone, IPv6(ip6, TCP(th, _) | UDP(th, _)))
|
||||||
|
if (ip6.protocol, ip6.dst, th.dport) in forwards_v6 -> Allow;
|
||||||
|
| _ -> Drop;
|
||||||
|
};
|
||||||
|
|
||||||
|
policy output : Frame
|
||||||
|
on { hook = Output, table = Filter, priority = Filter }
|
||||||
|
= {
|
||||||
|
| _ -> Allow;
|
||||||
|
};
|
||||||
|
|
||||||
|
policy nat_prerouting : Frame
|
||||||
|
on { hook = Prerouting, table = NAT, priority = DstNat }
|
||||||
|
= {
|
||||||
|
| Frame(_, IPv4(ip, TCP(th, _) | UDP(th, _))) ->
|
||||||
|
if perform FIB.daddrLocal(ip.dst)
|
||||||
|
then DNATMap((ip.protocol, th.dport), forwards)
|
||||||
|
else Allow;
|
||||||
|
| _ -> Allow;
|
||||||
|
};
|
||||||
|
|
||||||
|
policy nat_postrouting : Frame
|
||||||
|
on { hook = Postrouting, table = NAT, priority = SrcNat }
|
||||||
|
= {
|
||||||
|
| Frame(_ -> wan, IPv4(ip, _)) if ip.src in rfc1918 -> Masquerade;
|
||||||
|
| _ -> Allow;
|
||||||
|
};
|
||||||
955
examples/simple-router.fwl.json
Normal file
955
examples/simple-router.fwl.json
Normal file
@@ -0,0 +1,955 @@
|
|||||||
|
{
|
||||||
|
"nftables": [
|
||||||
|
{
|
||||||
|
"metainfo": {
|
||||||
|
"json_schema_version": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table": {
|
||||||
|
"family": "inet",
|
||||||
|
"name": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"hook": "input",
|
||||||
|
"name": "input",
|
||||||
|
"policy": "drop",
|
||||||
|
"prio": 0,
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "filter"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"hook": "forward",
|
||||||
|
"name": "forward",
|
||||||
|
"policy": "drop",
|
||||||
|
"prio": 0,
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "filter"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"hook": "output",
|
||||||
|
"name": "output",
|
||||||
|
"policy": "accept",
|
||||||
|
"prio": 0,
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "filter"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"hook": "prerouting",
|
||||||
|
"name": "nat_prerouting",
|
||||||
|
"policy": "accept",
|
||||||
|
"prio": -100,
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "nat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"hook": "postrouting",
|
||||||
|
"name": "nat_postrouting",
|
||||||
|
"policy": "accept",
|
||||||
|
"prio": 100,
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "nat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"elem": [
|
||||||
|
{
|
||||||
|
"prefix": {
|
||||||
|
"addr": "10.0.0.0",
|
||||||
|
"len": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prefix": {
|
||||||
|
"addr": "172.16.0.0",
|
||||||
|
"len": 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prefix": {
|
||||||
|
"addr": "192.168.0.0",
|
||||||
|
"len": 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"name": "rfc1918",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "ipv4_addr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map": {
|
||||||
|
"elem": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"concat": [
|
||||||
|
"tcp",
|
||||||
|
8080
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"concat": [
|
||||||
|
"10.0.0.10",
|
||||||
|
80
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"map": [
|
||||||
|
"ipv4_addr",
|
||||||
|
"inet_service"
|
||||||
|
],
|
||||||
|
"name": "forwards",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": [
|
||||||
|
"inet_proto",
|
||||||
|
"inet_service"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"elem": [
|
||||||
|
22
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"name": "open_ports",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "inet_service"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"elem": [
|
||||||
|
{
|
||||||
|
"concat": [
|
||||||
|
"tcp",
|
||||||
|
"2001:db8:0:0:0:0:0:1",
|
||||||
|
22000
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"name": "forwards_v6",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": [
|
||||||
|
"inet_proto",
|
||||||
|
"ipv4_addr",
|
||||||
|
"inet_service"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"ct": {
|
||||||
|
"key": "state"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "in",
|
||||||
|
"right": [
|
||||||
|
"established",
|
||||||
|
"related"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "lo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"field": "nexthdr",
|
||||||
|
"protocol": "ip6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv6-icmp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"field": "saddr",
|
||||||
|
"protocol": "ip6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": {
|
||||||
|
"prefix": {
|
||||||
|
"addr": "fe80:0:0:0:0:0:0:0",
|
||||||
|
"len": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "tcp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"field": "dport",
|
||||||
|
"protocol": "tcp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "@open_ports"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "udp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"field": "dport",
|
||||||
|
"protocol": "udp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "51944"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"drop": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"ct": {
|
||||||
|
"key": "state"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "in",
|
||||||
|
"right": [
|
||||||
|
"established",
|
||||||
|
"related"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"ct": {
|
||||||
|
"key": "status"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "dnat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "in",
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"lan"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "in",
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"lan"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "tcp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"concat": [
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "protocol",
|
||||||
|
"protocol": "ip"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "dport",
|
||||||
|
"protocol": "th"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "@forwards"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "in",
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"lan"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "udp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"concat": [
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "protocol",
|
||||||
|
"protocol": "ip"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "dport",
|
||||||
|
"protocol": "th"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "@forwards"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "in",
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"lan"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "tcp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"concat": [
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "protocol",
|
||||||
|
"protocol": "ip6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "daddr",
|
||||||
|
"protocol": "ip6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "dport",
|
||||||
|
"protocol": "th"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "@forwards_v6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "in",
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"lan"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "udp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"concat": [
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "protocol",
|
||||||
|
"protocol": "ip6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "daddr",
|
||||||
|
"protocol": "ip6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"field": "dport",
|
||||||
|
"protocol": "th"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "@forwards_v6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"drop": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "output",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "nat_prerouting",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "tcp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "nat_prerouting",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "udp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "nat_prerouting",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "nat_postrouting",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"field": "saddr",
|
||||||
|
"protocol": "ip"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"op": "==",
|
||||||
|
"right": "@rfc1918"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"masquerade": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"chain": "nat_postrouting",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
98
examples/simple-router.nft
Normal file
98
examples/simple-router.nft
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
table inet fwl {
|
||||||
|
|
||||||
|
# ── let rfc1918 ──────────────────────────────────────────────────────────
|
||||||
|
set rfc1918 {
|
||||||
|
type ipv4_addr
|
||||||
|
flags interval
|
||||||
|
elements = {
|
||||||
|
10.0.0.0/8,
|
||||||
|
172.16.0.0/12,
|
||||||
|
192.168.0.0/16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── let open_ports : Set<Port> ───────────────────────────────────────────
|
||||||
|
set open_ports {
|
||||||
|
type inet_service
|
||||||
|
elements = { 22 }
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── let forwards_v6 : Set<(Protocol, IP, Port)> ──────────────────────────
|
||||||
|
set forwards_v6 {
|
||||||
|
type inet_proto . ipv6_addr . inet_service
|
||||||
|
elements = {
|
||||||
|
tcp . 2001:db8::1 . 22000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── let forwards : Map<(Protocol, Port), (IP, Port)> ────────────────────
|
||||||
|
map forwards {
|
||||||
|
type inet_proto . inet_service : ipv4_addr . inet_service
|
||||||
|
elements = {
|
||||||
|
tcp . 8080 : 10.0.0.10 . 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── zone lan_zone = { lan } ──────────────────────────────────────────────
|
||||||
|
# Zones compile to anonymous sets wherever referenced in iifname/oifname.
|
||||||
|
# With a single member the set degenerates to a plain string match,
|
||||||
|
# but we keep the set form so the compiler output is uniform regardless
|
||||||
|
# of zone size.
|
||||||
|
set lan_zone {
|
||||||
|
type ifname
|
||||||
|
elements = { "lan" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy input ─────────────────────────────────────────────────────────
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority filter; policy drop;
|
||||||
|
|
||||||
|
ct state { established, related } accept
|
||||||
|
iifname "lo" accept
|
||||||
|
meta nfproto ipv6 ip6 nexthdr ipv6-icmp ip6 saddr fe80::/10 accept
|
||||||
|
meta nfproto ipv4 meta l4proto tcp tcp dport @open_ports accept
|
||||||
|
meta nfproto ipv4 meta l4proto udp udp dport 51944 accept
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy forward ───────────────────────────────────────────────────────
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority filter; policy drop;
|
||||||
|
|
||||||
|
ct state { established, related } accept
|
||||||
|
ct status dnat accept
|
||||||
|
|
||||||
|
# | Frame(iif in lan_zone -> wan, _) -> Allow
|
||||||
|
meta iifname @lan_zone meta oifname "wan" accept
|
||||||
|
|
||||||
|
# | Frame(wan -> iif in lan_zone, IPv4 TCP|UDP) if (proto,dport) in forwards
|
||||||
|
meta iifname "wan" meta oifname @lan_zone \
|
||||||
|
meta nfproto ipv4 meta l4proto { tcp, udp } \
|
||||||
|
meta l4proto . th dport @forwards accept
|
||||||
|
|
||||||
|
# | Frame(wan -> iif in lan_zone, IPv6 TCP|UDP) if (proto,dst,dport) in forwards_v6
|
||||||
|
meta iifname "wan" meta oifname @lan_zone \
|
||||||
|
meta nfproto ipv6 meta l4proto { tcp, udp } \
|
||||||
|
meta l4proto . ip6 daddr . th dport @forwards_v6 accept
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy output ────────────────────────────────────────────────────────
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority filter; policy accept;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy nat_prerouting ────────────────────────────────────────────────
|
||||||
|
chain nat_prerouting {
|
||||||
|
type nat hook prerouting priority dstnat; policy accept;
|
||||||
|
|
||||||
|
meta nfproto ipv4 meta l4proto { tcp, udp } \
|
||||||
|
fib daddr type local \
|
||||||
|
dnat ip to meta l4proto . th dport map @forwards
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── policy nat_postrouting ───────────────────────────────────────────────
|
||||||
|
chain nat_postrouting {
|
||||||
|
type nat hook postrouting priority srcnat; policy accept;
|
||||||
|
|
||||||
|
meta oifname "wan" meta nfproto ipv4 ip saddr @rfc1918 masquerade
|
||||||
|
}
|
||||||
|
}
|
||||||
693
examples/simple-router.nft.json
Normal file
693
examples/simple-router.nft.json
Normal file
@@ -0,0 +1,693 @@
|
|||||||
|
{
|
||||||
|
"nftables": [
|
||||||
|
{
|
||||||
|
"metainfo": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"release_name": "Commodore Bullmoose #7",
|
||||||
|
"json_schema_version": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table": {
|
||||||
|
"family": "inet",
|
||||||
|
"name": "fwl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"name": "input",
|
||||||
|
"type": "filter",
|
||||||
|
"hook": "input",
|
||||||
|
"prio": 0,
|
||||||
|
"policy": "drop"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"name": "forward",
|
||||||
|
"type": "filter",
|
||||||
|
"hook": "forward",
|
||||||
|
"prio": 0,
|
||||||
|
"policy": "drop"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"name": "output",
|
||||||
|
"type": "filter",
|
||||||
|
"hook": "output",
|
||||||
|
"prio": 0,
|
||||||
|
"policy": "accept"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"name": "nat_prerouting",
|
||||||
|
"type": "nat",
|
||||||
|
"hook": "prerouting",
|
||||||
|
"prio": -100,
|
||||||
|
"policy": "accept"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"name": "nat_postrouting",
|
||||||
|
"type": "nat",
|
||||||
|
"hook": "postrouting",
|
||||||
|
"prio": 100,
|
||||||
|
"policy": "accept"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"family": "inet",
|
||||||
|
"name": "rfc1918",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "ipv4_addr",
|
||||||
|
"flags": [
|
||||||
|
"interval"
|
||||||
|
],
|
||||||
|
"elem": [
|
||||||
|
{
|
||||||
|
"prefix": {
|
||||||
|
"addr": "10.0.0.0",
|
||||||
|
"len": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prefix": {
|
||||||
|
"addr": "172.16.0.0",
|
||||||
|
"len": 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prefix": {
|
||||||
|
"addr": "192.168.0.0",
|
||||||
|
"len": 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"family": "inet",
|
||||||
|
"name": "open_ports",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "inet_service",
|
||||||
|
"elem": [
|
||||||
|
22
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"family": "inet",
|
||||||
|
"name": "forwards_v6",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": [
|
||||||
|
"inet_proto",
|
||||||
|
"ipv6_addr",
|
||||||
|
"inet_service"
|
||||||
|
],
|
||||||
|
"elem": [
|
||||||
|
{
|
||||||
|
"concat": [
|
||||||
|
"tcp",
|
||||||
|
"2001:db8::1",
|
||||||
|
22000
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map": {
|
||||||
|
"family": "inet",
|
||||||
|
"name": "forwards",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": [
|
||||||
|
"inet_proto",
|
||||||
|
"inet_service"
|
||||||
|
],
|
||||||
|
"map": [
|
||||||
|
"ipv4_addr",
|
||||||
|
"inet_service"
|
||||||
|
],
|
||||||
|
"elem": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"concat": [
|
||||||
|
"tcp",
|
||||||
|
8080
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"concat": [
|
||||||
|
"10.0.0.10",
|
||||||
|
80
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"family": "inet",
|
||||||
|
"name": "lan_zone",
|
||||||
|
"table": "fwl",
|
||||||
|
"type": "ifname",
|
||||||
|
"elem": [
|
||||||
|
"lan"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"ct": {
|
||||||
|
"key": "state"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"established",
|
||||||
|
"related"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "lo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"protocol": "ip6",
|
||||||
|
"field": "nexthdr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "ipv6-icmp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"protocol": "ip6",
|
||||||
|
"field": "saddr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"prefix": {
|
||||||
|
"addr": "fe80::",
|
||||||
|
"len": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"protocol": "tcp",
|
||||||
|
"field": "dport"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "@open_ports"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "input",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"protocol": "udp",
|
||||||
|
"field": "dport"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": 51944
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"ct": {
|
||||||
|
"key": "state"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"established",
|
||||||
|
"related"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "in",
|
||||||
|
"left": {
|
||||||
|
"ct": {
|
||||||
|
"key": "status"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "dnat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "@lan_zone"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "@lan_zone"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"tcp",
|
||||||
|
"udp"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"concat": [
|
||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"protocol": "th",
|
||||||
|
"field": "dport"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"right": "@forwards"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "forward",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "iifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "@lan_zone"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"tcp",
|
||||||
|
"udp"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"concat": [
|
||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"protocol": "ip6",
|
||||||
|
"field": "daddr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"protocol": "th",
|
||||||
|
"field": "dport"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"right": "@forwards_v6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accept": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "nat_prerouting",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "nfproto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "ipv4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"set": [
|
||||||
|
"tcp",
|
||||||
|
"udp"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"fib": {
|
||||||
|
"result": "type",
|
||||||
|
"flags": [
|
||||||
|
"daddr"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "local"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"dnat": {
|
||||||
|
"family": "ip",
|
||||||
|
"addr": {
|
||||||
|
"map": {
|
||||||
|
"key": {
|
||||||
|
"concat": [
|
||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"key": "l4proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"payload": {
|
||||||
|
"protocol": "th",
|
||||||
|
"field": "dport"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"data": "@forwards"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule": {
|
||||||
|
"family": "inet",
|
||||||
|
"table": "fwl",
|
||||||
|
"chain": "nat_postrouting",
|
||||||
|
"expr": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"meta": {
|
||||||
|
"key": "oifname"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "wan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"op": "==",
|
||||||
|
"left": {
|
||||||
|
"payload": {
|
||||||
|
"protocol": "ip",
|
||||||
|
"field": "saddr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": "@rfc1918"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"masquerade": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user