I’ve modified your script for my own purposes and thought I’d share it here as well, if someone has the same use-case (forwarding simple broadcast packets).
The modifications include:
- Fixing the default value for
TYPE(not important) - Adding support for forwarding simple broadcast packets using the
-bflag. I’m not sure if it will work for something more complex that e.g. requires two-way communication, but it’s completely enough for Syncthing’s local discovery protocol to actually start working.
DISCLAIMER: I am not well-versed in nft/iptables, and as such, I have used an LLM to help me write those rules. If there’s any security vulnerabilities introduced because of that, please let me know. I tried to keep the amount of lines changed to the minimum.
I attach the script below:
#!/bin/sh
END_QUBE="$1"
PORT="$2"
TYPE="${3:-tcp}"
BFLAG="$4"
usage() {
echo "usage: $0 qube_name port_number [tcp|udp] [-b]"
exit 0
}
find_netvm() {
QUBE="$1"
NET_VM="$(qvm-ls -n | awk -v qube="${QUBE}" '$1 == qube { print $3 }')"
DESTINATION="$(qvm-ls -n | awk -v qube="${QUBE}" '$1 == qube { print $4 }')"
echo "Qube $QUBE has $NET_VM for netvm"
if [ "$NET_VM" != "-" ]
then
# new: only the netvm holding the uplink sees a real L2 broadcast
if [ "$BFLAG" = "-b" ] && \
[ "$(qvm-ls -n | awk -v qube="${NET_VM}" '$1 == qube { print $3 }')" = "-" ]
then BCAST=yes ; else BCAST=no ; fi
cat <<EOF | qvm-run --no-gui -u root --pass-io "$NET_VM" "/bin/sh"
if ! nft -nn list table ip qubes | grep "chain nat {" >/dev/null ; then
nft add chain qubes nat { type nat hook prerouting priority dstnat\; }
fi
if [ "${BCAST}" = "yes" ] ; then
nft add chain qubes bcast { type filter hook prerouting priority mangle\; }
nft insert rule qubes bcast iifname != \"vif*\" meta pkttype broadcast "${TYPE}" dport "${PORT}" counter meta pkttype set host
fi
nft insert rule qubes custom-input "${TYPE}" dport "${PORT}" accept
nft insert rule qubes custom-forward "${TYPE}" dport "${PORT}" accept
nft insert rule qubes nat iifname != \"vif*\" "${TYPE}" dport "${PORT}" dnat "${DESTINATION}"
EOF
if [ $? -eq 0 ] ; then echo "$NET_VM -> $QUBE: [OK]" ; else echo "$NET_VM -> $QUBE: [KO]" ; exit 1 ; fi
find_netvm "$NET_VM"
fi
}
if [ -z "$1" ] || [ -z "$2" ]
then
usage
fi
if qvm-ls --running | grep ^"${END_QUBE} " >/dev/null
then
echo "qube is running"
find_netvm "$END_QUBE"
cat <<EOF | qvm-run --no-gui -u root --pass-io "$END_QUBE" "/bin/sh"
nft add rule qubes custom-input "${TYPE}" dport "${PORT}" accept
EOF
else
echo "qube ${END_QUBE} is not running"
fi