Add docker-tailscale-route: fix Docker losing internet under Tailscale exit-node
Tailscale's exit-node "route all traffic" mode captures Docker's forwarded container traffic into its tunnel and drops it as an unrecognized flow, causing every outbound request from inside a container to hang until timeout. This installs a systemd timer that keeps an ip rule in place routing Docker's bridge subnet around Tailscale's catch-all route instead. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
63
install.sh
Executable file
63
install.sh
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Written by an LLM (Claude Code) — review before trusting on a machine
|
||||
# other than the one this was diagnosed on. See README.md.
|
||||
#
|
||||
# Installs the docker-tailscale-route fix: a systemd timer that keeps an
|
||||
# ip rule in place routing Docker's bridge traffic around Tailscale's
|
||||
# exit-node catch-all route. See docker-tailscale-route.sh for the full
|
||||
# explanation of the underlying problem.
|
||||
#
|
||||
# Usage:
|
||||
# sudo ./install.sh [--subnet CIDR] [--priority N] [--table NAME]
|
||||
#
|
||||
# The optional flags only need to be passed if Docker's default address
|
||||
# pool doesn't apply on this machine (see the comment in
|
||||
# docker-tailscale-route.sh); they're written to
|
||||
# /etc/default/docker-tailscale-route and sourced by the script at
|
||||
# runtime.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Must be run as root (sudo ./install.sh)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
SUBNET=""
|
||||
PRIORITY=""
|
||||
TABLE=""
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--subnet) SUBNET="$2"; shift 2 ;;
|
||||
--priority) PRIORITY="$2"; shift 2 ;;
|
||||
--table) TABLE="$2"; shift 2 ;;
|
||||
*) echo "Unknown argument: $1" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
install -o root -g root -m 0755 "$SCRIPT_DIR/docker-tailscale-route.sh" /usr/local/sbin/docker-tailscale-route.sh
|
||||
install -o root -g root -m 0644 "$SCRIPT_DIR/docker-tailscale-route.service" /etc/systemd/system/docker-tailscale-route.service
|
||||
install -o root -g root -m 0644 "$SCRIPT_DIR/docker-tailscale-route.timer" /etc/systemd/system/docker-tailscale-route.timer
|
||||
|
||||
if [ -n "$SUBNET" ] || [ -n "$PRIORITY" ] || [ -n "$TABLE" ]; then
|
||||
{
|
||||
[ -n "$SUBNET" ] && echo "DOCKER_SUBNET=\"$SUBNET\""
|
||||
[ -n "$PRIORITY" ] && echo "RULE_PRIORITY=\"$PRIORITY\""
|
||||
[ -n "$TABLE" ] && echo "TARGET_TABLE=\"$TABLE\""
|
||||
} > /etc/default/docker-tailscale-route
|
||||
chown root:root /etc/default/docker-tailscale-route
|
||||
chmod 0644 /etc/default/docker-tailscale-route
|
||||
fi
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now docker-tailscale-route.timer
|
||||
|
||||
echo "Installed. Current status:"
|
||||
systemctl status docker-tailscale-route.timer --no-pager
|
||||
echo
|
||||
echo "ip rule list:"
|
||||
ip rule list
|
||||
Reference in New Issue
Block a user