Skip to content

Commit

Permalink
docker networking: avoid address blocks used by local networks
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
dirkhh committed Jan 21, 2025
1 parent c87cea2 commit e018819
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit e018819

Please sign in to comment.