#!/bin/bash # Manual NAT for Docker with daemon.json "iptables": false. # Docker does not install MASQUERADE; fixed IPs on docbr0 stay untouched. # # Install: /usr/local/sbin/docker-nat-rules.sh (chmod +x) # Service: vm101-docker-nat-rules.service → /etc/systemd/system/docker-nat-rules.service set -euo pipefail OUT_IF=$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1); exit}}') [[ -n "${OUT_IF:-}" ]] || { echo "Could not detect outbound interface" >&2; exit 1; } # Remove legacy per-bridge rules from earlier tests (idempotent cleanup) for net in 10.2.2.0/24 172.16.0.0/12 \ 172.17.0.0/16 172.18.0.0/16 172.19.0.0/16 172.20.0.0/16 \ 172.21.0.0/16 172.22.0.0/16 172.23.0.0/16; do while iptables -t nat -C POSTROUTING -s "$net" -o "$OUT_IF" -j MASQUERADE 2>/dev/null; do iptables -t nat -D POSTROUTING -s "$net" -o "$OUT_IF" -j MASQUERADE done done add_masq() { local src=$1 iptables -t nat -C POSTROUTING -s "$src" -o "$OUT_IF" -j MASQUERADE 2>/dev/null \ || iptables -t nat -A POSTROUTING -s "$src" -o "$OUT_IF" -j MASQUERADE } add_masq "10.2.2.0/24" # docbr0 — static container IPs add_masq "172.16.0.0/12" # Docker bridge networks echo "docker-nat-rules: MASQUERADE via $OUT_IF for 10.2.2.0/24 and 172.16.0.0/12"