add more ruleset examples
This commit is contained in:
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