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>
This commit is contained in:
Phill Kelley 2022-07-19 18:41:38 +10:00
parent bf15adc4ce
commit f28b665afd
No known key found for this signature in database
GPG Key ID: 73D35B58592A2E98

View File

@ -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 "$@"