Skip to content

Instantly share code, notes, and snippets.

@tomty89
Last active February 1, 2022 11:23
Show Gist options
  • Save tomty89/90e8075dcf8304ac46e67c34225938ab to your computer and use it in GitHub Desktop.
Save tomty89/90e8075dcf8304ac46e67c34225938ab to your computer and use it in GitHub Desktop.
nftables rules for a bridge that enslaves a passthru macvlan created on top of a wlan interface
port=0
dhcp-relay=192.168.1.150,192.168.1.1,bridge1
#!/usr/bin/nft -f
table bridge bridge1_fwd
delete table bridge bridge1_fwd
table bridge bridge1_fwd {
define no_lan = # mac address of the default gateway
define no_lan_ip = # ip address of the default gateway
chain eg_drop_ip {
ether daddr != $no_lan drop
ip daddr { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 } drop
udp dport 67 drop
}
chain eg_drop {
# iifname "macvl0" drop
ip daddr != $no_lan_ip goto eg_drop_ip
arp daddr ip != $no_lan_ip drop
meta protocol ip6 drop
}
chain ig_drop_ip {
ether saddr != $no_lan drop
ip saddr { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 } drop
udp dport 67 drop
}
chain ig_drop {
ip saddr != $no_lan_ip goto ig_drop_ip
arp saddr ip != $no_lan_ip drop
meta protocol ip6 drop
}
chain forward {
type filter hook forward priority filter; policy accept;
meta ibrname != "bridge1" return
oifname "macvl0" goto eg_drop
iifname "macvl0" goto ig_drop
iifname != "macvl0" drop
}
}
#!/usr/bin/nft -f
table bridge bridge1_io
delete table bridge bridge1_io
table bridge bridge1_io {
chain drop_v6 {
meta protocol ip6 drop
}
chain io_eps {
icmp type { echo-reply, echo-request } accept
meta protocol arp accept
jump drop_v6
}
chain input_eps {
jump io_eps
udp dport 67 accept
drop
}
chain input {
type filter hook input priority filter; policy accept;
meta ibrname != "bridge1" return
iifname != "macvl0" goto input_eps
jump drop_v6
}
chain output_eps {
jump io_eps
udp sport 67 accept
drop
}
chain output {
type filter hook output priority filter; policy accept;
meta obrname != "bridge1" return
oifname != "macvl0" goto output_eps
jump drop_v6
}
}
#!/usr/bin/nft -f
table bridge bridge1_nat
delete table bridge bridge1_nat
table bridge bridge1_nat {
define eg_mac = # mac address of bridge1, which should have been set to that of macvl0 (macvlan in passthru mode)
map eps {
type ipv4_addr : ether_addr
elements = # add the ip and mac address(es) of the vm(s) as map element(s)
}
chain prerouting {
type filter hook prerouting priority dstnat; policy accept;
meta ibrname != "bridge1" return
iifname != "macvl0" return
ether daddr set ip daddr map @eps
ether daddr set arp daddr ip map @eps arp daddr ether set ether daddr
}
chain postrouting {
type filter hook postrouting priority srcnat; policy accept;
meta obrname != "bridge1" return
oifname != "macvl0" return
ether saddr $eg_mac return
meta protocol { ip, arp } ether saddr set $eg_mac
arp saddr ether set ether saddr
}
}
#!/usr/bin/nft -f
table ip dhcp_filter
delete table ip dhcp_filter
table ip dhcp_filter {
chain input_drop {
udp sport != 67 drop
iifname != "bridge1" drop
}
chain input {
type filter hook input priority filter; policy accept;
udp dport 67 jump input_drop
}
}
[Unit]
Description=dnsmasq - A lightweight DHCP and caching DNS server
Documentation=man:dnsmasq(8)
After=network.target
Before=network-online.target nss-lookup.target
Wants=nss-lookup.target
[Service]
ExecStartPre=/usr/bin/dnsmasq --test
ExecStart=/usr/bin/dnsmasq -k --user=dnsmasq --pid-file -C /etc/dnsmasq/%i.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
PrivateDevices=true
ProtectSystem=full
[Install]
WantedBy=multi-user.target
@tomty89
Copy link
Author

tomty89 commented Aug 11, 2021

bridge1 does not need to have the same mac address as macvl0 if dhcp is not necessary? (with corresponding mapping added to eps, of course)

@tomty89
Copy link
Author

tomty89 commented Aug 13, 2021

with the help of dhcp reservation in the router (and relaying dhcp with dnsmasq), static configuration is now optional

@tomty89
Copy link
Author

tomty89 commented Aug 24, 2021

apparently dnsmasq does not bind to an interface for the dhcp relay agent, even with bind-interfaces. it does not do that for the dhcp server either if binding was actually delayed with bind-dynamic

@tomty89
Copy link
Author

tomty89 commented Aug 24, 2021

use an inet table for bridge_io?

@tomty89
Copy link
Author

tomty89 commented Sep 6, 2021

there seems to be "leakage" of dhcp traffics from the wlan interface; use a separate (ip) table instead to filter out all undesired traffics

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment