mirror of
https://github.com/zyclonite/zerotier-docker.git
synced 2025-02-13 15:09:17 +01:00
allow switching gateway modes without recreating/restarting the container
This commit is contained in:
parent
d18dfe3b09
commit
ef5ea76415
@ -11,7 +11,7 @@ LABEL org.opencontainers.image.title="zerotier" \
|
||||
|
||||
ENV LOG_PATH=/var/log/supervisor
|
||||
|
||||
COPY scripts/entrypoint-router.sh /usr/sbin/
|
||||
COPY scripts/entrypoint-router.sh scripts/gatewaymode /usr/sbin/
|
||||
|
||||
RUN apk add --no-cache --purge --clean-protected iptables iptables-legacy tzdata \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
@ -42,61 +42,11 @@ fi
|
||||
|
||||
echo "$(date) - launching ZeroTier-One in routing mode"
|
||||
|
||||
# use an appropriate default for a local physical interface
|
||||
# (using eth0 maintains backwards compatibility)
|
||||
PHY_IFACES="${ZEROTIER_ONE_LOCAL_PHYS:-"eth0"}"
|
||||
|
||||
# default to iptables (maintains backwards compatibility)
|
||||
IPTABLES_CMD=iptables-legacy
|
||||
# but support an override to use iptables-nft
|
||||
[ "${ZEROTIER_ONE_USE_IPTABLES_NFT}" = "true" ] && IPTABLES_CMD=iptables-nft
|
||||
|
||||
# the default forwarding mode is inbound (backwards compatible)
|
||||
GATEWAY_MODE="${ZEROTIER_ONE_GATEWAY_MODE:-"inbound"}"
|
||||
|
||||
# the wildcard for the local zerotier interface is
|
||||
ZT_IFACE="zt+"
|
||||
|
||||
# function to add and remove the requisite rules
|
||||
# - $1 is either "A" (add) or "D" (delete)
|
||||
# - $2 is comment
|
||||
update_iptables() {
|
||||
case "${GATEWAY_MODE}" in
|
||||
"inbound" )
|
||||
echo "$2 ${IPTABLES_CMD} rules for inbound traffic (ZeroTier to local interfaces ${PHY_IFACES})"
|
||||
for PHY_IFACE in ${PHY_IFACES} ; do
|
||||
${IPTABLES_CMD} -t nat -${1} POSTROUTING -o ${PHY_IFACE} -j MASQUERADE
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -j ACCEPT
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -j DROP
|
||||
done
|
||||
;;
|
||||
"outbound" )
|
||||
echo "$2 ${IPTABLES_CMD} rules for outbound traffic (local interfaces ${PHY_IFACES} to ZeroTier)"
|
||||
${IPTABLES_CMD} -t nat -${1} POSTROUTING -o ${ZT_IFACE} -j MASQUERADE
|
||||
for PHY_IFACE in ${PHY_IFACES} ; do
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -j ACCEPT
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -j DROP
|
||||
done
|
||||
;;
|
||||
"both" )
|
||||
echo "$2 ${IPTABLES_CMD} rules for bi-directional traffic (local interfaces ${PHY_IFACES} to/from ZeroTier)"
|
||||
${IPTABLES_CMD} -t nat -${1} POSTROUTING -o ${ZT_IFACE} -j MASQUERADE
|
||||
for PHY_IFACE in ${PHY_IFACES} ; do
|
||||
${IPTABLES_CMD} -t nat -${1} POSTROUTING -o ${PHY_IFACE} -j MASQUERADE
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -j ACCEPT
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -j ACCEPT
|
||||
done
|
||||
;;
|
||||
* )
|
||||
echo "Warning: ZEROTIER_ONE_GATEWAY_MODE=${GATEWAY_MODE} is not supported - ignored"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# add rules to set up NAT-routing
|
||||
update_iptables "A" "adding"
|
||||
gatewaymode "${GATEWAY_MODE}"
|
||||
|
||||
# define where the ZeroTier daemon will write its output (if any)
|
||||
TAIL_PIPE="/tmp/zerotier-ipc-log"
|
||||
@ -123,7 +73,7 @@ termination_handler() {
|
||||
echo "$(date) - terminating ZeroTier-One"
|
||||
|
||||
# remove rules
|
||||
update_iptables "D" "removing"
|
||||
gatewaymode disable
|
||||
|
||||
# relay the termination message to the daemon
|
||||
# (the pipe listener is cleaned up automatically)
|
||||
|
176
scripts/gatewaymode
Normal file
176
scripts/gatewaymode
Normal file
@ -0,0 +1,176 @@
|
||||
#!/bin/sh
|
||||
|
||||
# use an appropriate default for a local physical interface
|
||||
# (using eth0 maintains backwards compatibility)
|
||||
PHY_IFACES="${ZEROTIER_ONE_LOCAL_PHYS:-"eth0"}"
|
||||
|
||||
# default to iptables (maintains backwards compatibility)
|
||||
IPTABLES_CMD=iptables-legacy
|
||||
# but support an 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+"
|
||||
|
||||
# function to add and remove the requisite rules
|
||||
# - $1 is either "A" (add) or "D" (delete)
|
||||
# - $2 is requested mode
|
||||
_update_iptables() {
|
||||
local action
|
||||
case "${1}" in
|
||||
"I" )
|
||||
action="Inserting"
|
||||
;;
|
||||
"A" )
|
||||
action="Adding"
|
||||
;;
|
||||
"D" )
|
||||
action="Deleting"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${2}" in
|
||||
"inbound" )
|
||||
echo "${action} ${IPTABLES_CMD} rules for inbound traffic (ZeroTier to local interfaces ${PHY_IFACES})"
|
||||
for PHY_IFACE in ${PHY_IFACES} ; do
|
||||
${IPTABLES_CMD} -t nat -${1} POSTROUTING -o ${PHY_IFACE} -j MASQUERADE
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -j DROP
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -j ACCEPT
|
||||
done
|
||||
;;
|
||||
"outbound" )
|
||||
echo "${action} ${IPTABLES_CMD} rules for outbound traffic (local interfaces ${PHY_IFACES} to ZeroTier)"
|
||||
${IPTABLES_CMD} -t nat -${1} POSTROUTING -o ${ZT_IFACE} -j MASQUERADE
|
||||
for PHY_IFACE in ${PHY_IFACES} ; do
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -j DROP
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -j ACCEPT
|
||||
done
|
||||
;;
|
||||
"both" )
|
||||
echo "${action} ${IPTABLES_CMD} rules for bi-directional traffic (local interfaces ${PHY_IFACES} to/from ZeroTier)"
|
||||
${IPTABLES_CMD} -t nat -${1} POSTROUTING -o ${ZT_IFACE} -j MASQUERADE
|
||||
for PHY_IFACE in ${PHY_IFACES} ; do
|
||||
${IPTABLES_CMD} -t nat -${1} POSTROUTING -o ${PHY_IFACE} -j MASQUERADE
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -j ACCEPT
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -j ACCEPT
|
||||
done
|
||||
;;
|
||||
"none" )
|
||||
echo "${action} ${IPTABLES_CMD} rules for _no_ traffic (local interfaces ${PHY_IFACES} to/from ZeroTier)"
|
||||
for PHY_IFACE in ${PHY_IFACES} ; do
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${ZT_IFACE} -o ${PHY_IFACE} -j DROP
|
||||
${IPTABLES_CMD} -${1} FORWARD -i ${PHY_IFACE} -o ${ZT_IFACE} -j DROP
|
||||
done
|
||||
esac
|
||||
}
|
||||
|
||||
# Get current gateway mode by looking up what iptable rules are in place
|
||||
_get_current_mode() {
|
||||
|
||||
if [ -n "$( ${IPTABLES_CMD} -S -t nat 2> /dev/null | grep "\-o ${ZT_IFACE}" )" ]; then
|
||||
#either outbound or both
|
||||
if [ -n "$( ${IPTABLES_CMD} -S | grep "\-i ${ZT_IFACE}.*RELATED" )" ]; then
|
||||
echo "outbound"
|
||||
else
|
||||
echo "both"
|
||||
fi
|
||||
elif [ -n "$( ${IPTABLES_CMD} -S | grep "\-i ${ZT_IFACE}.*ACCEPT" )" ]; then
|
||||
echo "inbound"
|
||||
elif [ -n "$( ${IPTABLES_CMD} -S | grep "\-i ${ZT_IFACE}.*DROP" )" ]; then
|
||||
echo "none"
|
||||
else
|
||||
echo "disabled"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
_usage() {
|
||||
echo "Usage: $0 inbound | outbound | both | none | disable | status"
|
||||
echo "Set, query or disable gateway mode."
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " inbound Only permit traffic from the ZeroTier cloud to the local physical interfaces."
|
||||
echo " outbound Only permit traffic from the local physical interfaces to the ZeroTier cloud."
|
||||
echo " both Permit bi-directional traffic between the local physical interfaces and the ZeroTier cloud."
|
||||
echo " none Block all traffic between the local physical interfaces and the ZeroTier cloud."
|
||||
echo " disable Remove iptable rules. NOTE: because default forward rule is accept, this behaves like \"both\"."
|
||||
echo " status Show current gateway mode (e.g. inbound, outbound, etc)"
|
||||
echo ""
|
||||
exit $1
|
||||
}
|
||||
|
||||
main() {
|
||||
local i
|
||||
|
||||
local opt
|
||||
local mode=$( _get_current_mode )
|
||||
case "${1}" in
|
||||
"inbound" )
|
||||
if [ ${mode} == "inbound" ]; then
|
||||
echo "Already in mode inbound."
|
||||
break
|
||||
fi
|
||||
if [ ! ${mode} == "disabled" ]; then
|
||||
_update_iptables D ${mode}
|
||||
fi
|
||||
_update_iptables I inbound
|
||||
;;
|
||||
"outbound" )
|
||||
if [ ${mode} == "outbound" ] ; then
|
||||
echo "Already in mode outbound."
|
||||
break
|
||||
fi
|
||||
if [ ! ${mode} == "disabled" ]; then
|
||||
_update_iptables D ${mode}
|
||||
fi
|
||||
_update_iptables I outbound
|
||||
;;
|
||||
"both" )
|
||||
if [ ${mode} == "both" ]; then
|
||||
echo "Already in mode both."
|
||||
break
|
||||
fi
|
||||
if [ ! ${mode} == "disabled" ]; then
|
||||
_update_iptables D ${mode}
|
||||
fi
|
||||
_update_iptables I both
|
||||
;;
|
||||
"none" )
|
||||
if [ ${mode} == "none" ]; then
|
||||
echo "Already in mode none."
|
||||
break
|
||||
fi
|
||||
if [ ! ${mode} == "disabled" ]; then
|
||||
_update_iptables D ${mode}
|
||||
fi
|
||||
_update_iptables I none
|
||||
;;
|
||||
"disable" )
|
||||
if [ ${mode} == "disabled" ]; then
|
||||
echo "Already disabled."
|
||||
break
|
||||
fi
|
||||
if [ ! ${mode} == "disabled" ]; then
|
||||
_update_iptables D ${mode}
|
||||
fi
|
||||
;;
|
||||
"status" )
|
||||
echo ${mode}
|
||||
;;
|
||||
"" )
|
||||
echo "Please specify a valid argument."
|
||||
_usage 0
|
||||
;;
|
||||
* )
|
||||
echo "Warning: Gateway mode (${1}) is not supported - ignored"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
exit ${?}
|
||||
|
Loading…
Reference in New Issue
Block a user