From f28b665afda6c68693af88dc8f556f34d07ebe70 Mon Sep 17 00:00:00 2001 From: Phill Kelley <34226495+Paraphraser@users.noreply.github.com> Date: Tue, 19 Jul 2022 18:41:38 +1000 Subject: [PATCH] Extend router launch script: 1. Support `ZEROTIER_ONE_USE_IPTABLES_NFT` environment variable. If omitted or has any value other than `true`, `iptables` is used (maintains backwards compatibility). If `true`, substitutes `iptables-nft`. This definitely seems to be necessary on Raspberry Pi running Bullseye. 2. Support `ZEROTIER_ONE_LOCAL_PHYS` environment variable. Defaults to `eth0` if omitted (maintains backwards compatibility). Allows for overriding to `wlan0` (eg Raspberry Pi Zero 2W), or both `eth0 wlan0` to support multiple subnets or failover modes, or similar situations (eg extra network interface cards). 3. Support `ZEROTIER_ONE_NETWORK_ID` as an alternative to the `join` command. Means container will always fail safe if its persistent storage is erased - will look like a new identity but can be authorised and will then be reachable for additional configuration. 4. Support `PUID` + `PGID` environment variables. Default to 999 and 994, respectively, mimicking what happens on a "native" install of ZeroTier-One (on a Raspberry Pi). 5. Perform unconditional reset of ownership (PUID:PGID) throughout persistent store on each launch. This avoids many permission problems that can sometimes occur in docker environments. 6. Add launch message with date. Assists in assessing recency of "sendto: Network unreachable" messages that can occur after a reboot where the container resumes before networking is available. Signed-off-by: Phill Kelley <34226495+Paraphraser@users.noreply.github.com> --- scripts/entrypoint-router.sh | 49 ++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/scripts/entrypoint-router.sh b/scripts/entrypoint-router.sh index 1d89214..f8fdbdc 100755 --- a/scripts/entrypoint-router.sh +++ b/scripts/entrypoint-router.sh @@ -1,14 +1,53 @@ #!/usr/bin/env sh set -Eeo pipefail +echo "$(date) - launching ZeroTier-One in routing mode" + if [ "${1:0:1}" = '-' ]; then set -- zerotier-one "$@" fi -PHY_IFACE=eth0 -ZT_IFACE="zt+" -iptables -t nat -A POSTROUTING -o $PHY_IFACE -j MASQUERADE -iptables -A FORWARD -i $PHY_IFACE -o $ZT_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT -iptables -A FORWARD -i $ZT_IFACE -o $PHY_IFACE -j ACCEPT +# useful paths +CONFIG_DIR="/var/lib/zerotier-one" +NETWORKS_DIR="$CONFIG_DIR/networks.d" +# set up network auto-join if (a) the networks directory does not exist +# and (b) the ZEROTIER_ONE_NETWORK_ID environment variable is non-null. +if [ ! -d "$NETWORKS_DIR" -a -n "$ZEROTIER_ONE_NETWORK_ID" ] ; then + echo "Assuming container first run. Configuring auto-join of network ID:" + echo " $ZEROTIER_ONE_NETWORK_ID" + echo "You will need to authorize this host at:" + echo " https://my.zerotier.com/network/$ZEROTIER_ONE_NETWORK_ID" + mkdir -p "$NETWORKS_DIR" + touch "$NETWORKS_DIR/$ZEROTIER_ONE_NETWORK_ID.conf" +fi + +# make sure permissions are correct +PUID="${PUID:-"999"}" +PGID="${PGID:-"994"}" +if [ "$(id -u)" = '0' -a -d "$CONFIG_DIR" ]; then + chown -Rc "$PUID:$PGID" "$CONFIG_DIR" +fi + +# use an appropriate default for a local physical interface +PHY_IFACES="${ZEROTIER_ONE_LOCAL_PHYS:-"eth0"}" + +# default to iptables (maintain compatibility for existing systems) +IPTABLES_CMD=iptables +# but support override to use iptables-nft +[ "$ZEROTIER_ONE_USE_IPTABLES_NFT" = "true" ] && IPTABLES_CMD=iptables-nft + +# the wildcard for the local zerotier interface is +ZT_IFACE="zt+" + +# iterate the local interface(s) and enable NAT services +for PHY_IFACE in $PHY_IFACES ; do + echo "Using $IPTABLES_CMD to enable NAT services on $PHY_IFACE" + $IPTABLES_CMD -t nat -A POSTROUTING -o $PHY_IFACE -j MASQUERADE + $IPTABLES_CMD -A FORWARD -i $PHY_IFACE -o $ZT_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT + $IPTABLES_CMD -A FORWARD -i $ZT_IFACE -o $PHY_IFACE -j ACCEPT +done + +# launch zerotier-one exec "$@" +