From 8f0041f7a40feae537caaf7ae02d578ee2915b76 Mon Sep 17 00:00:00 2001 From: Laszlo Magyar Date: Mon, 16 Oct 2023 21:43:51 +0200 Subject: [PATCH] protect local subnets (not the configurable advertised subnets) from collision no DOCS change is required --- .../etc/s6-overlay/s6-rc.d/mss-clamping/run | 2 +- .../etc/s6-overlay/s6-rc.d/post-tailscaled/run | 4 ++-- tailscale/rootfs/usr/bin/protect-subnet-routes | 6 +++--- tailscale/rootfs/usr/bin/subnet-routes | 17 +++++++++++------ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/tailscale/rootfs/etc/s6-overlay/s6-rc.d/mss-clamping/run b/tailscale/rootfs/etc/s6-overlay/s6-rc.d/mss-clamping/run index 5cf464d0..360c9c06 100755 --- a/tailscale/rootfs/etc/s6-overlay/s6-rc.d/mss-clamping/run +++ b/tailscale/rootfs/etc/s6-overlay/s6-rc.d/mss-clamping/run @@ -9,7 +9,7 @@ declare -a routes=() declare -a interfaces=() declare route family interface -readarray -t routes < <(subnet-routes) +readarray -t routes < <(subnet-routes advertised) # In case of non userspace networking, clamp the MSS to the MTU for all advertised subnet's interface # If user later enables subnet routing for site-to-site networking, these settings are already there diff --git a/tailscale/rootfs/etc/s6-overlay/s6-rc.d/post-tailscaled/run b/tailscale/rootfs/etc/s6-overlay/s6-rc.d/post-tailscaled/run index 3e3b2416..864c63df 100755 --- a/tailscale/rootfs/etc/s6-overlay/s6-rc.d/post-tailscaled/run +++ b/tailscale/rootfs/etc/s6-overlay/s6-rc.d/post-tailscaled/run @@ -63,7 +63,7 @@ tags=$(bashio::config "tags//[] | join(\",\")" "") options+=(--advertise-tags="${tags}") # Advertise subnet routes -readarray -t routes < <(subnet-routes) +readarray -t routes < <(subnet-routes advertised) IFS="," options+=(--advertise-routes="${routes[*]}") unset IFS @@ -102,7 +102,7 @@ bashio::log.info "Tailscale is running" if bashio::config.false "userspace_networking"; then readarray -t colliding_routes < <( \ comm -1 -2 \ - <(printf "%s" "${routes[@]/%/$'\n'}") \ + <(subnet-routes local) \ <(/opt/tailscale status --json --peers=true --self=false \ | jq -rc '.Peer[] | select(has("PrimaryRoutes")) | .PrimaryRoutes[]' \ | sort -u)) diff --git a/tailscale/rootfs/usr/bin/protect-subnet-routes b/tailscale/rootfs/usr/bin/protect-subnet-routes index 859bdf1f..8040910e 100755 --- a/tailscale/rootfs/usr/bin/protect-subnet-routes +++ b/tailscale/rootfs/usr/bin/protect-subnet-routes @@ -33,10 +33,10 @@ if bashio::config.false "userspace_networking"; then bashio::log.info "Supervisor is ready" fi - readarray -t routes < <(subnet-routes) + readarray -t routes < <(subnet-routes local) if (( 0 < ${#routes[@]} )); then - bashio::log.info "Adding advertised local subnets to ip rules with higher priority than Tailscale's routing," - bashio::log.info "to prevent routing advertised local subnets if the same subnet is routed within your tailnet." + bashio::log.info "Adding local subnets to ip rules with higher priority than Tailscale's routing," + bashio::log.info "to prevent routing local subnets if the same subnet is routed within your tailnet." fi for route in "${routes[@]}"; do if [[ "${route}" =~ .*:.* ]]; then diff --git a/tailscale/rootfs/usr/bin/subnet-routes b/tailscale/rootfs/usr/bin/subnet-routes index 792792a8..ad2c72b8 100755 --- a/tailscale/rootfs/usr/bin/subnet-routes +++ b/tailscale/rootfs/usr/bin/subnet-routes @@ -15,24 +15,29 @@ function appendarray() { readarray -t -O "${#array[@]}" array } -if bashio::cache.exists 'subnet-routes'; then - readarray -t routes < <(bashio::cache.get 'subnet-routes') +if ! [[ $1 =~ ^(local|advertised)$ ]]; then + echo "Usage: subnet-routes local|advertised" 1>&2 + exit 1 +fi + +if bashio::cache.exists "subnet-routes-$1"; then + readarray -t routes < <(bashio::cache.get "subnet-routes-$1") printf -v response "%s" "${routes[@]/%/$'\n'}" else - if bashio::config.exists "advertise_routes"; then + if [[ "$1" == "advertised" ]] && bashio::config.exists "advertise_routes"; then # Configuration exists, use configured values for address in $(bashio::config "advertise_routes"); do addresses+=("${address}") done else - # Find interfaces and matching addresses from which we can extract routes to be advertised + # Find interfaces and matching addresses from which we can extract routes for interface in $(bashio::network.interfaces); do appendarray addresses < <(bashio::network.ipv4_address "${interface}") appendarray addresses < <(bashio::network.ipv6_address "${interface}") done fi - # Extract routes to be advertised + # Extract routes for address in "${addresses[@]}"; do if bashio::var.has_value "${address}"; then # Skip local link addresses @@ -58,7 +63,7 @@ else readarray -t routes < <(printf "%s" "${routes[@]/%/$'\n'}" | sort -u) printf -v response "%s" "${routes[@]/%/$'\n'}" - bashio::cache.set 'subnet-routes' "${response}" + bashio::cache.set "subnet-routes-$1" "${response}" fi printf "%s" "${response}"