mirror of
https://github.com/zyclonite/zerotier-docker.git
synced 2025-01-25 06:18:34 +01:00
177 lines
5.3 KiB
Bash
177 lines
5.3 KiB
Bash
#!/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 ${?}
|
|
|