diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 19ff23571..ab6da34e8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,7 +4,6 @@ name: Lint env: HADOLINT_VERSION: v1.17.2 - SHELLCHECK_OPTS: -e SC1008 -s bash on: pull_request: @@ -50,6 +49,8 @@ jobs: - name: Run linter uses: ludeeus/action-shellcheck@2.0.0 + env: + SHELLCHECK_OPTS: -e SC1008 -s bash -x with: # Names of scripts with custom shebangs that the action would not # discover on its own: diff --git a/openthread_border_router/CHANGELOG.md b/openthread_border_router/CHANGELOG.md index 745b10773..8381cf6b7 100644 --- a/openthread_border_router/CHANGELOG.md +++ b/openthread_border_router/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2.16.6 + +- Fix and improve NAT64 firewall rules +- Enable recovery mechanism from "radio tx timeout" errors for beta +- Narrow non-firewall forwarding rules to Thread interface + ## 2.16.5 - Add `backbone_interface` option to override the network interface used for IPv6 routing. diff --git a/openthread_border_router/Dockerfile b/openthread_border_router/Dockerfile index 6564f3118..93822eba5 100644 --- a/openthread_border_router/Dockerfile +++ b/openthread_border_router/Dockerfile @@ -62,6 +62,7 @@ RUN \ -DOT_COAPS=OFF \ -DOT_THREAD_VERSION=1.4 \ -DOT_PROJECT_CONFIG="/usr/src/ot-br-posix/third_party/openthread/repo/openthread-core-ha-config-posix.h" \ + -DOT_RCP_RESTORATION_MAX_COUNT=2 \ && cd /usr/src/ot-br-posix/build/otbr \ && ninja install diff --git a/openthread_border_router/config.yaml b/openthread_border_router/config.yaml index 99c8ae103..33f950694 100644 --- a/openthread_border_router/config.yaml +++ b/openthread_border_router/config.yaml @@ -1,5 +1,5 @@ --- -version: 2.16.5 +version: 2.16.6 slug: openthread_border_router name: OpenThread Border Router description: OpenThread Border Router add-on diff --git a/openthread_border_router/rootfs/etc/s6-overlay/s6-rc.d/otbr-agent/finish b/openthread_border_router/rootfs/etc/s6-overlay/s6-rc.d/otbr-agent/finish index 7ece6a29d..5c1039bee 100755 --- a/openthread_border_router/rootfs/etc/s6-overlay/s6-rc.d/otbr-agent/finish +++ b/openthread_border_router/rootfs/etc/s6-overlay/s6-rc.d/otbr-agent/finish @@ -16,7 +16,7 @@ else bashio::log.info "otbr-agent exited with code $e (by signal $2)." fi -# shellcheck disable=SC1091 +# shellcheck source=./openthread_border_router/rootfs/etc/s6-overlay/scripts/otbr-agent-common . /etc/s6-overlay/scripts/otbr-agent-common ipset_destroy_if_exist() @@ -28,16 +28,13 @@ ipset_destroy_if_exist() done } -# shellcheck disable=SC2154,SC2086 -while ip6tables -C FORWARD -o $thread_if -j $otbr_forward_ingress_chain 2> /dev/null; do - # shellcheck disable=SC2086 - ip6tables -D FORWARD -o $thread_if -j $otbr_forward_ingress_chain +while ip6tables -C FORWARD -o "${thread_if}" -j "${otbr_forward_ingress_chain}" 2> /dev/null; do + ip6tables -D FORWARD -o "${thread_if}" -j "${otbr_forward_ingress_chain}" done -# shellcheck disable=SC2086 -if ip6tables -L $otbr_forward_ingress_chain 2> /dev/null; then - ip6tables -w -F $otbr_forward_ingress_chain - ip6tables -w -X $otbr_forward_ingress_chain +if ip6tables -L "${otbr_forward_ingress_chain}" 2> /dev/null; then + ip6tables -w -F "${otbr_forward_ingress_chain}" + ip6tables -w -X "${otbr_forward_ingress_chain}" fi ipset_destroy_if_exist otbr-ingress-deny-src @@ -45,17 +42,35 @@ ipset_destroy_if_exist otbr-ingress-deny-src-swap ipset_destroy_if_exist otbr-ingress-allow-dst ipset_destroy_if_exist otbr-ingress-allow-dst-swap -# shellcheck disable=SC2154,SC2086 -while ip6tables -C FORWARD -i $thread_if -j $otbr_forward_egress_chain 2> /dev/null; do - ip6tables -D FORWARD -i $thread_if -j $otbr_forward_egress_chain +while ip6tables -C FORWARD -i "${thread_if}" -j "${otbr_forward_egress_chain}" 2> /dev/null; do + ip6tables -D FORWARD -i "${thread_if}" -j "${otbr_forward_egress_chain}" done -# shellcheck disable=SC2086 -if ip6tables -L $otbr_forward_egress_chain 2> /dev/null; then - ip6tables -w -F $otbr_forward_egress_chain - ip6tables -w -X $otbr_forward_egress_chain +if ip6tables -L "${otbr_forward_egress_chain}" 2> /dev/null; then + ip6tables -w -F "${otbr_forward_egress_chain}" + ip6tables -w -X "${otbr_forward_egress_chain}" fi -bashio::log.info "OTBR firewall teardown completed." + +# Remove FORWARD jump(s) +while iptables -C FORWARD -j "${otbr_forward_nat64_chain}" 2>/dev/null; do + iptables -D FORWARD -j "${otbr_forward_nat64_chain}" +done + +# Flush and delete chain +if iptables -L "${otbr_forward_nat64_chain}" -n 2>/dev/null; then + iptables -w -F "${otbr_forward_nat64_chain}" + iptables -w -X "${otbr_forward_nat64_chain}" +fi + +# Clean mangle and nat rules +while iptables -t mangle -C PREROUTING -i "${thread_if}" -j MARK --set-mark "${otbr_fw_mark}" 2>/dev/null; do + iptables -t mangle -D PREROUTING -i "${thread_if}" -j MARK --set-mark "${otbr_fw_mark}" +done + +while iptables -t nat -C POSTROUTING -m mark --mark "${otbr_fw_mark}" -j MASQUERADE 2>/dev/null; do + iptables -t nat -D POSTROUTING -m mark --mark "${otbr_fw_mark}" -j MASQUERADE +done +bashio::log.info "OTBR firewall/NAT64 rules teardown completed." if test "$e" -ne 0; then echo "$e" > /run/s6-linux-init-container-results/exitcode diff --git a/openthread_border_router/rootfs/etc/s6-overlay/s6-rc.d/otbr-agent/run b/openthread_border_router/rootfs/etc/s6-overlay/s6-rc.d/otbr-agent/run index 26d1bf9b4..ead6314fc 100755 --- a/openthread_border_router/rootfs/etc/s6-overlay/s6-rc.d/otbr-agent/run +++ b/openthread_border_router/rootfs/etc/s6-overlay/s6-rc.d/otbr-agent/run @@ -5,7 +5,7 @@ # OpenThread BorderRouter start script # ============================================================================== -# shellcheck disable=SC1091 +# shellcheck source=./openthread_border_router/rootfs/etc/s6-overlay/scripts/otbr-agent-common . /etc/s6-overlay/scripts/otbr-agent-common declare backbone_if @@ -96,45 +96,43 @@ ipset create -exist otbr-ingress-deny-src-swap hash:net family inet6 ipset create -exist otbr-ingress-allow-dst hash:net family inet6 ipset create -exist otbr-ingress-allow-dst-swap hash:net family inet6 +ip6tables -N "${otbr_forward_ingress_chain}" +ip6tables -I FORWARD 1 -o "${thread_if}" -j "${otbr_forward_ingress_chain}" + +ip6tables -N "${otbr_forward_egress_chain}" +ip6tables -I FORWARD 2 -i "${thread_if}" -j "${otbr_forward_egress_chain}" + if bashio::config.true 'firewall'; then bashio::log.info "Setup OTBR firewall..." -# shellcheck disable=SC2086,SC2154 - ip6tables -N $otbr_forward_ingress_chain -# shellcheck disable=SC2086,SC2154 - ip6tables -I FORWARD 1 -o $thread_if -j $otbr_forward_ingress_chain - - # shellcheck disable=SC2086 - ip6tables -A $otbr_forward_ingress_chain -m pkttype --pkt-type unicast -i ${thread_if} -j DROP - # shellcheck disable=SC2086 - ip6tables -A $otbr_forward_ingress_chain -m set --match-set otbr-ingress-deny-src src -j DROP - # shellcheck disable=SC2086 - ip6tables -A $otbr_forward_ingress_chain -m set --match-set otbr-ingress-allow-dst dst -j ACCEPT - # shellcheck disable=SC2086 - ip6tables -A $otbr_forward_ingress_chain -m pkttype --pkt-type unicast -j DROP - # shellcheck disable=SC2086 - ip6tables -A $otbr_forward_ingress_chain -j ACCEPT - - # shellcheck disable=SC2086,SC2154 - ip6tables -N $otbr_forward_egress_chain - # shellcheck disable=SC2086 - ip6tables -I FORWARD 2 -i $thread_if -j $otbr_forward_egress_chain - # shellcheck disable=SC2086 - ip6tables -A $otbr_forward_egress_chain -j ACCEPT + + ip6tables -A "${otbr_forward_ingress_chain}" -m pkttype --pkt-type unicast -i "${thread_if}" -j DROP + ip6tables -A "${otbr_forward_ingress_chain}" -m set --match-set otbr-ingress-deny-src src -j DROP + ip6tables -A "${otbr_forward_ingress_chain}" -m set --match-set otbr-ingress-allow-dst dst -j ACCEPT + ip6tables -A "${otbr_forward_ingress_chain}" -m pkttype --pkt-type unicast -j DROP + ip6tables -A "${otbr_forward_ingress_chain}" -j ACCEPT + + ip6tables -A "${otbr_forward_egress_chain}" -j ACCEPT else - # Make sure ip6tables (as used by Docker) allow IP forwarding - ip6tables -P FORWARD ACCEPT - # HAOS 9.3 and earlier (for 9.4 accept is the default so this won't do anything) - ip6tables-legacy -P FORWARD ACCEPT + ip6tables -A "${otbr_forward_ingress_chain}" -j ACCEPT + + ip6tables -A "${otbr_forward_egress_chain}" -j ACCEPT fi if bashio::config.true 'nat64'; then - # shellcheck disable=SC2086 - iptables -t mangle -A PREROUTING -i ${thread_if} -j MARK --set-mark 0x1001 - iptables -t nat -A POSTROUTING -m mark --mark 0x1001 -j MASQUERADE - # shellcheck disable=SC2086 - iptables -t filter -A FORWARD -o ${backbone_if} -j ACCEPT - # shellcheck disable=SC2086 - iptables -t filter -A FORWARD -i ${backbone_if} -j ACCEPT + # Mark Thread traffic in mangle + iptables -t mangle -A PREROUTING -i "${thread_if}" -j MARK --set-mark "${otbr_fw_mark}" + + # MASQUERADE marked traffic + iptables -t nat -A POSTROUTING -m mark --mark "${otbr_fw_mark}" -j MASQUERADE + + # NAT64 forward chain — jump unconditionally, filter inside + iptables -N "${otbr_forward_nat64_chain}" + iptables -I FORWARD 1 -j "${otbr_forward_nat64_chain}" + + # Forward marked traffic + iptables -A "${otbr_forward_nat64_chain}" -m mark --mark "${otbr_fw_mark}" -o "${backbone_if}" -j ACCEPT + # Use conntrack to identify return traffic + iptables -A "${otbr_forward_nat64_chain}" -m conntrack --ctstate ESTABLISHED,RELATED -i "${backbone_if}" -o "${thread_if}" -j ACCEPT fi otbr_rest_listen="::" diff --git a/openthread_border_router/rootfs/etc/s6-overlay/scripts/otbr-agent-common b/openthread_border_router/rootfs/etc/s6-overlay/scripts/otbr-agent-common index e4d4669a9..54b17c140 100644 --- a/openthread_border_router/rootfs/etc/s6-overlay/scripts/otbr-agent-common +++ b/openthread_border_router/rootfs/etc/s6-overlay/scripts/otbr-agent-common @@ -1,9 +1,14 @@ -#!/bin/sh +# shellcheck shell=bash +# shellcheck disable=SC2034 declare thread_if declare otbr_forward_ingress_chain declare otbr_forward_egress_chain +declare otbr_forward_nat64_chain +declare otbr_fw_mark thread_if="wpan0" otbr_forward_ingress_chain="OTBR_FORWARD_INGRESS" otbr_forward_egress_chain="OTBR_FORWARD_EGRESS" +otbr_forward_nat64_chain="OTBR_FORWARD_NAT64" +otbr_fw_mark="0x1001"