And that’s why we hate fucking GNU/Linux.
iproute2
$ man brctl
[…]
NOTES
brctl(8) is obsolete. Some features such as STP guard, hairpin mode,
fast leave and root block are intentionally not implemented in this
command. Instead use bridge command from iproute2 package for a more
full set of features.
But:
$ man ip | fgrep -i bridge
tifier can be one of inet, inet6, bridge, mpls or link. If this
-B shortcut for -family bridge.
$ man ip | fgrep -- -B
link } | -4 | -6 | -I | -D | -B | -0 | -l[oops] { maximum-addr-
-B shortcut for -family bridge.
$ man ip-bridge
No manual entry for ip-bridge
$ l /usr/share/doc/iproute2/
README.Debian changelog.Debian.gz copyright
Because fuck the user, that’s why. Who needs documentation when he can have the latest bling-bling tool?
(You’ll also pry netstat from my cold dead fingers, though GNU/Linux route was always so bad I very quickly used ip r, and almost all ifconfig calls did get changed to ip a…)
STP vs. IPv6
$ man bridge-utils-interfaces
[…]
bridge_stp state
turn spanning tree protocol on/off, state values are on or yes
to turn stp on and any other thing to set it off, default has
changed to off for security reasons in latest kernels, so you
should specify if you want stp on or off with this option, and
not rely on your kernel's default behaviour. Setting stp to on
will cause IPv6 address to be lost, see: http://bugs.de‐
bian.org/736336
[…]
Mentioned bugreport has: CLOSED WONTFIX because:
STP requires that device goes into listen only mode when it starts up (forwarding delay).
IPv6 requires Duplicate Address Detection when the device starts up.
Therefore DAD interacts badly with STP.
I mean, it’s not as if the DAD couldn’t be delayed until STP releases its hold…
nftables
nftables was promised as the new thing to rule them all (just as ipfwadm, ipchains, iptables and netfilter were, of course). But for the first time, people said they knew of OpenBSD pf(4) and had learnt a bit from it.
missing init script
The first disillusionment comes quickly, there is no init script. Apparently, it’s only for #systemdsucks users. But either prop an /etc/nftables.conf into /etc/rc.local (the former is executable, with shebang, by default) or:
$ cat /etc/init.d/nft
#!/bin/sh
### BEGIN INIT INFO
# Provides: nftables-loaded
# Required-Start: $local_fs $time
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Load nftables
# Description: Loads nftables config.
### END INIT INFO
# absolute basics
LC_ALL=C PATH=/sbin:/usr/sbin:/bin:/usr/bin
export LC_ALL PATH
unset LANGUAGE
DESC='Load nftables'
NAME=nftables-load
. /lib/init/vars.sh
test -t 0 && VERBOSE=yes
. /lib/lsb/init-functions
case $1 in
(start)
/etc/nftables.conf
exit 0
;;
(stop)
nft flush ruleset
exit 0
;;
(restart|try-restart|reload|force-reload)
exit 0
;;
(status)
exit 4
;;
(*)
echo >&2 "Usage: $0 {start|stop|restart|try-restart|force-reload|status}"
exit 3
;;
esac
the configuration file and the documentation
The file can apparently be restored from the running state, like pfctl -sn, pfctl -sq, pfctl -sr, etc. (or pfctl -sa and some removing). But the exact command is hard to find in the manpage.
{ printf '%s\n' '#!/usr/sbin/nft -f' '' 'flush ruleset' ''; sudo nft list ruleset; } >/etc/nftables.conf
If you run fail2ban, you’ll also want to remove the f2b-table afterwards.
Actually writing the rules, however, is an exercise in disappointment. They tried the syntax thing like OpenBSD did but lost themselves in it and forgot to actually explain how these things work.
adding to tables
Suppose someone spammed us (say SSH attack) and we want to block their Legacy IP address.
The command syntax for this is awful, it’s as if you write the configuration file anew:
$ sudo nft add element inet filter fu4 \{ 139.19.117.130, \}
(Some shells may need the backslash escapes, some may allow you to get by without them.) Compare with:
$ sudo pfctl -t theo -T add 139.19.117.130
1/1 addresses added.
Do also note I need two tables (fu4 and fu6) for nftables because a table cannot hold addresses of multiple types unless you’re OpenBSD or a derivative thereof where one single table (here affectionately named theo) suffices.
A bit later, you review the list of most recently added “IP address nukes” and find out that the offender has contacted you from multiple addresses of their allocated range, and you find out the range. Blessed be BSD:
$ sudo pfctl -t theo -T add 139.19.117.130/25
1/1 addresses added.
Not so much nftables:
$ sudo nft add element inet filter fu4 \{ 139.19.117.130/25, \}
Error: interval overlaps with an existing one
add element inet filter fu4 { 139.19.117.130/25, }
^^^^^^^^^^^^^^^^^
Error: Could not process rule: File exists
add element inet filter fu4 { 139.19.117.130/25, }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
$ sudo nft del element inet filter fu4 \{ 139.19.117.130, \}
Error: syntax error, unexpected element, expecting string
del element inet filter fu4 { 139.19.117.130, }
^^^^^^^
$ sudo nft remove element inet filter fu4 \{ 139.19.117.130, \}
Error: syntax error, unexpected element, expecting string
remove element inet filter fu4 { 139.19.117.130, }
^^^^^^^
$ sudo nft delete element inet filter fu4 \{ 139.19.117.130, \}
$ sudo nft add element inet filter fu4 \{ 139.19.117.130/25, \}
I mean, why would I want to widen a range in a table? (BSD actually saves both entries; I wouldn’t mind for the more specific entries to go away when adding the one with a smaller CIDR præfix length.)
The error message itself is also supremely unhelpful, instead of complaining about del or remove it complains about element; thankfully, your reporter has had sufficient exposure (and I mean this in the radioactive sense) to nftables already to not fall for that.
As you can see, even remembering the one to use is awkward… and incidentally different from even aforementioned iproute2 which uses del!
Because fuck consistency, that’s why.
Gotta love GNU/Linux, because if you don’t love it you’ll go crazy trying to use it.
At some point in my life (not right now as I’m between jobs) I was ready to take money to someone who manages to port OpenBSD pf(4) to the Linux kernel to replace its inferiour packet filters. I wouldn’t mind if to use the pf port one would have to lose all concepts of their input/forward/output chains and the things like marking, if it just worked the same as on OpenBSD (altq, nat/rdr, pass/block).