From e0188190a0d5892cf97f2f7d0112ab25184b650e Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 19 Jan 2025 20:22:10 -0800 Subject: [PATCH] docker networking: avoid address blocks used by local networks Grab the networks of all physical interfaces and check a large set of candidate cidrs in order to find one to use that won't conflict with an address range that's already in use. Add a pre execution script to adsb-docker that sets that available cidr as the base for Docker's network bridge creation. Signed-off-by: Dirk Hohndel --- release-notes.md | 1 + .../adsb-setup/find-safe-docker-network.py | 31 ++++++++++++++++++ .../root/opt/adsb/scripts/fix-docker-network | 32 +++++++++++++++++++ .../lib/systemd/system/adsb-docker.service | 1 + 4 files changed, 65 insertions(+) create mode 100644 src/modules/adsb-feeder/filesystem/root/opt/adsb/adsb-setup/find-safe-docker-network.py create mode 100755 src/modules/adsb-feeder/filesystem/root/opt/adsb/scripts/fix-docker-network diff --git a/release-notes.md b/release-notes.md index 28cda641..e360a5a7 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,4 +1,5 @@ Changes since v2.2.5 include: +- ensure that the Docker network doesn't conflict with any network that the user is already connected to - update Dozzle container to current version - don't show the 'upgrade to stable' button on the home page when this is actually a downgrade. Still offer that ability on the system management page. - stage2: avoid potential data consistency issues when manipulating micro feeders diff --git a/src/modules/adsb-feeder/filesystem/root/opt/adsb/adsb-setup/find-safe-docker-network.py b/src/modules/adsb-feeder/filesystem/root/opt/adsb/adsb-setup/find-safe-docker-network.py new file mode 100644 index 00000000..016e2a8f --- /dev/null +++ b/src/modules/adsb-feeder/filesystem/root/opt/adsb/adsb-setup/find-safe-docker-network.py @@ -0,0 +1,31 @@ +# call with cidr notation of the physical networks that the host is connected to +# e.g.: python3 find-safe-docker-network.py 192.168.2.178/24 10.84.2.18/16 + +import ipaddress +import sys + +in_use = [] +for arg in sys.argv[1:]: + try: + cidr = ipaddress.ip_network(arg, strict=False) + in_use.append(cidr) + except: + print(f"skipping {cidr}") + pass + +# start with three of the usual suspects and then for good measure add a few more dozen in the 10.x.x.x range +cidr_choices = ["172.17.0.0/16", "172.18.0.0/16", "172.19.0.0/16"] +for b in range(172, 240): + cidr_choices.append(f"10.{b}.0.0/16") +for block in cidr_choices: + cidr = ipaddress.ip_network(block) + useable = True + for lcidr in in_use: + if lcidr.overlaps(cidr): + useable = False + break + + if useable: + print(block) + exit(0) +exit(1) diff --git a/src/modules/adsb-feeder/filesystem/root/opt/adsb/scripts/fix-docker-network b/src/modules/adsb-feeder/filesystem/root/opt/adsb/scripts/fix-docker-network new file mode 100755 index 00000000..25b80234 --- /dev/null +++ b/src/modules/adsb-feeder/filesystem/root/opt/adsb/scripts/fix-docker-network @@ -0,0 +1,32 @@ +#!/bin/bash +# in the hopefully unlikely case that the network the user is connected to +# conflicts with the docker network, let's avoid that + +# we only want this if we are running as an image +[ ! -f /opt/adsb/os.adsb.feeder.image ] && exit 0 + +if [ ! -f /opt/adsb/scripts/common.sh ] +then + echo "missing /opt/adsb/scripts/common.sh -- that's generally a bad sign" +else + . /opt/adsb/scripts/common.sh + rootcheck + logparent +fi + +# find all physical network interfaces and create a space separated list of their local CIDRs +phys_if=$(find /sys/class/net -type l -not -lname '*virtual*' -printf '%f\n') +phys_cidrs=$(for i in $phys_if; do ip ad li "$i" | grep -oP '(?<=inet\s)\d+(\.\d+){3}/\d+'; done | sed -e "s/[[:space:]]\+/ /g") + +# check all those CIDRs against a few private network ranges - done in python to avoid complexity of doing thing by hand +# shellcheck disable=SC2086 # we WANT you to word split... +cidr=$(python3 adsb-setup/find-safe-docker-network.py ${phys_cidrs}) + +# now set this up in the Docker config file (which we create if necessary) +[ ! -f /etc/docker/daemon.json ] && echo "{}" > /etc/docker/daemon.json +tmp=$(mktemp) +jq --arg cidr "$cidr" '."default-address-pools" = {"base": $cidr, "size": 24}' /etc/docker/daemon.json > "$tmp" +mv "$tmp" /etc/docker/daemon.json +echo "Docker setup with available network pool:" +cat /etc/docker/daemon.json + diff --git a/src/modules/adsb-feeder/filesystem/root/usr/lib/systemd/system/adsb-docker.service b/src/modules/adsb-feeder/filesystem/root/usr/lib/systemd/system/adsb-docker.service index fc2162fa..106e04b8 100644 --- a/src/modules/adsb-feeder/filesystem/root/usr/lib/systemd/system/adsb-docker.service +++ b/src/modules/adsb-feeder/filesystem/root/usr/lib/systemd/system/adsb-docker.service @@ -7,6 +7,7 @@ PartOf=docker.service SyslogIdentifier=adsb-docker WorkingDirectory=/opt/adsb ExecStartPre=-/usr/bin/bash -c "mount -o remount,exec,size=$(( $(cat /proc/meminfo | grep -i 'memtotal' | grep -o '[[:digit:]]*') / 2 ))k /run" +ExecStartPre=/opt/adsb/scripts/fix-docker-network ExecStart=/opt/adsb/docker-compose-start RemainAfterExit=yes ExecStop=/opt/adsb/docker-compose-adsb stop -t 30