mirror of
https://github.com/zyclonite/zerotier-docker.git
synced 2024-12-12 09:20:55 +01:00
Merge pull request #12 from Paraphraser/20220718-router-master
20220718 router master
This commit is contained in:
commit
030632aada
4
.github/workflows/multiarch.yml
vendored
4
.github/workflows/multiarch.yml
vendored
@ -103,8 +103,8 @@ jobs:
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.GITHUB_TOKEN }} ${{ env.IMAGE_NAME }}:latest docker://ghcr.io/zyclonite/${{ env.IMAGE_NAME }}:latest
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.GITHUB_TOKEN }} ${{ env.IMAGE_NAME }}:latest docker://ghcr.io/zyclonite/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
|
||||
|
||||
bridge:
|
||||
uses: ./.github/workflows/bridge.yml
|
||||
router:
|
||||
uses: ./.github/workflows/router.yml
|
||||
needs: push
|
||||
with:
|
||||
tag: ${{ github.event.release.tag_name }}
|
||||
|
@ -1,4 +1,4 @@
|
||||
name: Bridge Mode build
|
||||
name: Router Mode build
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
@ -43,11 +43,11 @@ jobs:
|
||||
|
||||
- name: Build unstable image
|
||||
if: ${{ inputs.event == 'push' }}
|
||||
run: buildah bud --platform ${{ matrix.platform.name }} --build-arg FROM_IMAGE=${{ format('ghcr.io/zyclonite/{0}', env.IMAGE_NAME) }} --build-arg FROM_VERSION=main -f ./Dockerfile.bridge -t ${{ env.IMAGE_NAME }}:${{ matrix.platform.tag }} .
|
||||
run: buildah bud --platform ${{ matrix.platform.name }} --build-arg FROM_IMAGE=${{ format('ghcr.io/zyclonite/{0}', env.IMAGE_NAME) }} --build-arg FROM_VERSION=main -f ./Dockerfile.router -t ${{ env.IMAGE_NAME }}:${{ matrix.platform.tag }} .
|
||||
|
||||
- name: Build stable image
|
||||
if: ${{ inputs.event == 'release' }}
|
||||
run: buildah bud --platform ${{ matrix.platform.name }} --build-arg FROM_IMAGE=${{ format('ghcr.io/zyclonite/{0}', env.IMAGE_NAME) }} --build-arg FROM_VERSION=${{ inputs.tag }} -f ./Dockerfile.bridge -t ${{ env.IMAGE_NAME }}:${{ matrix.platform.tag }} .
|
||||
run: buildah bud --platform ${{ matrix.platform.name }} --build-arg FROM_IMAGE=${{ format('ghcr.io/zyclonite/{0}', env.IMAGE_NAME) }} --build-arg FROM_VERSION=${{ inputs.tag }} -f ./Dockerfile.router -t ${{ env.IMAGE_NAME }}:${{ matrix.platform.tag }} .
|
||||
|
||||
- name: Check images created
|
||||
run: buildah images | grep '${{ env.IMAGE_NAME }}'
|
||||
@ -98,16 +98,16 @@ jobs:
|
||||
- name: Push unstable images
|
||||
if: ${{ inputs.event == 'push' }}
|
||||
run: |
|
||||
buildah manifest push --all --format v2s2 --creds zyclonite:${{ secrets.REGISTRY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://docker.io/zyclonite/${{ env.IMAGE_NAME }}:bridge-main
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.QUAY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://quay.io/zyclonite/${{ env.IMAGE_NAME }}:bridge-main
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.GITHUB_TOKEN }} ${{ env.IMAGE_NAME }}:latest docker://ghcr.io/zyclonite/${{ env.IMAGE_NAME }}:bridge-main
|
||||
buildah manifest push --all --format v2s2 --creds zyclonite:${{ secrets.REGISTRY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://docker.io/zyclonite/${{ env.IMAGE_NAME }}:router-main
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.QUAY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://quay.io/zyclonite/${{ env.IMAGE_NAME }}:router-main
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.GITHUB_TOKEN }} ${{ env.IMAGE_NAME }}:latest docker://ghcr.io/zyclonite/${{ env.IMAGE_NAME }}:router-main
|
||||
|
||||
- name: Push stable images
|
||||
if: ${{ inputs.event == 'release' }}
|
||||
run: |
|
||||
buildah manifest push --all --format v2s2 --creds zyclonite:${{ secrets.REGISTRY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://docker.io/zyclonite/${{ env.IMAGE_NAME }}:bridge
|
||||
buildah manifest push --all --format v2s2 --creds zyclonite:${{ secrets.REGISTRY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://docker.io/zyclonite/${{ env.IMAGE_NAME }}:bridge-${{ github.event.release.tag_name }}
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.QUAY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://quay.io/zyclonite/${{ env.IMAGE_NAME }}:bridge
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.QUAY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://quay.io/zyclonite/${{ env.IMAGE_NAME }}:bridge-${{ github.event.release.tag_name }}
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.GITHUB_TOKEN }} ${{ env.IMAGE_NAME }}:latest docker://ghcr.io/zyclonite/${{ env.IMAGE_NAME }}:bridge
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.GITHUB_TOKEN }} ${{ env.IMAGE_NAME }}:latest docker://ghcr.io/zyclonite/${{ env.IMAGE_NAME }}:bridge-${{ github.event.release.tag_name }}
|
||||
buildah manifest push --all --format v2s2 --creds zyclonite:${{ secrets.REGISTRY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://docker.io/zyclonite/${{ env.IMAGE_NAME }}:router
|
||||
buildah manifest push --all --format v2s2 --creds zyclonite:${{ secrets.REGISTRY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://docker.io/zyclonite/${{ env.IMAGE_NAME }}:router-${{ github.event.release.tag_name }}
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.QUAY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://quay.io/zyclonite/${{ env.IMAGE_NAME }}:router
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.QUAY_PASSWORD }} ${{ env.IMAGE_NAME }}:latest docker://quay.io/zyclonite/${{ env.IMAGE_NAME }}:router-${{ github.event.release.tag_name }}
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.GITHUB_TOKEN }} ${{ env.IMAGE_NAME }}:latest docker://ghcr.io/zyclonite/${{ env.IMAGE_NAME }}:router
|
||||
buildah manifest push --all --creds zyclonite:${{ secrets.GITHUB_TOKEN }} ${{ env.IMAGE_NAME }}:latest docker://ghcr.io/zyclonite/${{ env.IMAGE_NAME }}:router-${{ github.event.release.tag_name }}
|
@ -4,20 +4,20 @@ ARG FROM_VERSION=latest
|
||||
FROM ${FROM_IMAGE}:${FROM_VERSION}
|
||||
|
||||
LABEL org.opencontainers.image.title="zerotier" \
|
||||
org.opencontainers.image.version="bridge-${ZT_VERSION}" \
|
||||
org.opencontainers.image.description="ZeroTier One as Docker Image" \
|
||||
org.opencontainers.image.version="router-${ZT_VERSION}" \
|
||||
org.opencontainers.image.description="ZeroTier One router as Docker Image" \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.source="https://github.com/zyclonite/zerotier-docker"
|
||||
|
||||
ENV LOG_PATH=/var/log/supervisor
|
||||
|
||||
COPY scripts/entrypoint-bridge.sh /usr/sbin/
|
||||
COPY scripts/entrypoint-router.sh /usr/sbin/
|
||||
|
||||
RUN apk add --no-cache --purge --clean-protected iptables \
|
||||
RUN apk add --no-cache --purge --clean-protected iptables tzdata \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
EXPOSE 9993/udp
|
||||
|
||||
ENTRYPOINT ["entrypoint-bridge.sh"]
|
||||
ENTRYPOINT ["entrypoint-router.sh"]
|
||||
|
||||
CMD ["-U"]
|
199
README-router.md
Normal file
199
README-router.md
Normal file
@ -0,0 +1,199 @@
|
||||
## zerotier router
|
||||
|
||||
### Description
|
||||
|
||||
This is a variation built on top of the zyclonite/zerotier container which implements a local network router. It is based upon the ZeroTier Knowledge Base article:
|
||||
|
||||
* [Route between ZeroTier and Physical Networks](https://zerotier.atlassian.net/wiki/spaces/SD/pages/224395274/Route+between+ZeroTier+and+Physical+Networks)
|
||||
|
||||
Technically, this could be described as a *half-router*:
|
||||
|
||||
* You can initiate connections *from* a remote client *to* devices on the LAN; but
|
||||
* You can't initiate connections *to* the remote client *from* devices on the LAN.
|
||||
|
||||
### Command line example
|
||||
|
||||
``` console
|
||||
$ docker run --name zerotier-one --device=/dev/net/tun \
|
||||
--cap-add=NET_ADMIN --cap-add=NET_RAW --cap-add=SYS_ADMIN \
|
||||
--env TZ=Etc/UTC --env PUID=999 -env PGID=994 \
|
||||
--env ZEROTIER_ONE_LOCAL_PHYS=eth0 \
|
||||
--env ZEROTIER_ONE_USE_IPTABLES_NFT=false \
|
||||
--env ZEROTIER_ONE_GATEWAY_MODE=inbound \
|
||||
--env ZEROTIER_ONE_NETWORK_IDS=«yourDefaultNetworkID(s)» \
|
||||
-v /var/lib/zerotier-one:/var/lib/zerotier-one zyclonite/zerotier:router
|
||||
```
|
||||
|
||||
Note:
|
||||
|
||||
* Environment variables that can contain multiple values should be enclosed in quotes with the components separated by spaces. Example:
|
||||
|
||||
``` console
|
||||
--env ZEROTIER_ONE_LOCAL_PHYS="eth0 wlan0"
|
||||
```
|
||||
|
||||
### Compose file example
|
||||
|
||||
``` yaml
|
||||
version: '3'
|
||||
services:
|
||||
zerotier:
|
||||
image: "zyclonite/zerotier:router"
|
||||
container_name: zerotier-one
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
network_mode: host
|
||||
volumes:
|
||||
- '/var/lib/zerotier-one:/var/lib/zerotier-one'
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
- NET_RAW
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- TZ=Etc/UTC
|
||||
- PUID=999
|
||||
- PGID=994
|
||||
- ZEROTIER_ONE_LOCAL_PHYS=eth0
|
||||
- ZEROTIER_ONE_USE_IPTABLES_NFT=false
|
||||
- ZEROTIER_ONE_GATEWAY_MODE=inbound
|
||||
# - ZEROTIER_ONE_NETWORK_IDS=«yourDefaultNetworkID(s)»
|
||||
```
|
||||
|
||||
Note:
|
||||
|
||||
* The right hand sides of environment variables should *never* be enclosed in quotes. If you need to pass multiple values, separate them with spaces. Example:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_LOCAL_PHYS=eth0 wlan0
|
||||
```
|
||||
|
||||
### Environment variables
|
||||
|
||||
* `TZ` – timezone support. Example:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- TZ=Australia/Sydney
|
||||
```
|
||||
|
||||
Defaults to `Etc/UTC` if omitted.
|
||||
|
||||
* `PUID` + `PGID` – user and group IDs for ownership of persistent store. Example:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
```
|
||||
|
||||
If omitted, `PUID` defaults to user ID 999, while `PGID` defaults to group ID 994.
|
||||
|
||||
These variables are only used to ensure consistent ownership of persistent storage on each launch. They do not affect how the container *runs.* Absent a `user:` directive, the container runs as root and does not downgrade its privileges.
|
||||
|
||||
* `ZEROTIER_ONE_LOCAL_PHYS` - a space-separated list of physical interfaces that should be configured to participate in NAT-based routing. Examples:
|
||||
|
||||
- Use only the physical Ethernet interface (this is also the default of the variable is omitted):
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_LOCAL_PHYS=eth0
|
||||
```
|
||||
|
||||
- If your computer only has WiFi active (eg Raspberry Pi Zero W2):
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_LOCAL_PHYS=wlan0
|
||||
```
|
||||
|
||||
- If your computer has both Ethernet and WiFi interfaces active and you wish to be able to route through each interface:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_LOCAL_PHYS=eth0 wlan0
|
||||
```
|
||||
|
||||
This scheme could be appropriate where the physical interfaces were:
|
||||
|
||||
1. In the same broadcast domain (subnet). Disconnecting Ethernet would fail-over to WiFi.
|
||||
2. In different broadcast domains, such as if you allocated different subnets for Ethernet and WiFi.
|
||||
|
||||
* `ZEROTIER_ONE_USE_IPTABLES_NFT` - controls the command the container uses to set up NAT forwarding. Example:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_USE_IPTABLES_NFT=true
|
||||
```
|
||||
|
||||
- `false` means the container uses `iptables`. This is the default.
|
||||
- `true` means the container uses `iptables-nft`.
|
||||
|
||||
Try `true` if NAT does not seem to be working. This is needed on Raspberry Pi Bullseye.
|
||||
|
||||
* `ZEROTIER_ONE_GATEWAY_MODE` - controls the traffic direction. Examples:
|
||||
|
||||
- Only permit traffic *from* the ZeroTier cloud *to* the local physical interfaces:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_GATEWAY_MODE=inbound
|
||||
```
|
||||
|
||||
- Only permit traffic *from* the local physical interfaces *to* the ZeroTier cloud:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_GATEWAY_MODE=outbound
|
||||
```
|
||||
|
||||
- Permit bi-directional traffic between the local physical interfaces and the ZeroTier cloud:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_GATEWAY_MODE=both
|
||||
```
|
||||
|
||||
Defaults to `inbound` if omitted. Note that you will probably need one or more static routes configured in your local LAN router so that traffic originating in a local host which is not running the ZeroTier client can be directed to the gateway host.
|
||||
|
||||
* `ZEROTIER_ONE_NETWORK_IDS` – a space-separated list of ZeroTier network IDs.
|
||||
|
||||
This variable is *only* effective on first launch. There is no default if it is omitted. Examples:
|
||||
|
||||
- to join a single network:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_NETWORK_IDS=aaaaaaaaaaaaaaaa
|
||||
```
|
||||
|
||||
Equivalent of running the following command after the container first starts:
|
||||
|
||||
```
|
||||
$ docker exec zerotier zerotier-cli join aaaaaaaaaaaaaaaa
|
||||
```
|
||||
|
||||
- to join a multiple networks:
|
||||
|
||||
``` yaml
|
||||
environment:
|
||||
- ZEROTIER_ONE_NETWORK_IDS=aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbb
|
||||
```
|
||||
|
||||
Equivalent of running the following commands after the container first starts:
|
||||
|
||||
```
|
||||
$ docker exec zerotier zerotier-cli join aaaaaaaaaaaaaaaa
|
||||
$ docker exec zerotier zerotier-cli join bbbbbbbbbbbbbbbb
|
||||
```
|
||||
|
||||
It does not matter whether you use this environment variable or the `join` command, you still need to use ZeroTier Central to approve the computer for each network it joins.
|
||||
|
||||
### Managed route(s)
|
||||
|
||||
For each ZeroTier container that is configured as a router, ZeroTier needs at least one *Managed Route*.
|
||||
|
||||
The [ZeroTier Wiki](https://zerotier.atlassian.net/wiki/spaces/SD/pages/224395274/Route+between+ZeroTier+and+Physical+Networks#Configure-the-ZeroTier-managed-route) explains how to design managed routes.
|
||||
|
||||
You configure Managed Routes in ZeroTier Central.
|
@ -32,14 +32,11 @@ or create an empty file with the network as name
|
||||
|
||||
/var/lib/zerotier-one/networks.d/8056c2e21c000001.conf
|
||||
|
||||
#### Bridge mode
|
||||
It is the implementation of the local network bridge [paper](https://zerotier.atlassian.net/wiki/spaces/SD/pages/193134593/Bridge+your+ZeroTier+and+local+network+with+a+RaspberryPi)
|
||||
#### Router mode
|
||||
|
||||
docker run --name zerotier-one --device=/dev/net/tun \
|
||||
--cap-add=NET_ADMIN --cap-add=NET_RAW --cap-add=SYS_ADMIN \
|
||||
-v /var/lib/zerotier-one:/var/lib/zerotier-one zyclonite/zerotier:bridge
|
||||
A variation on the container which implements a local network router. See:
|
||||
|
||||
That will start the zero-one, establish connection and build the bridge once the `zt` interface is up.
|
||||
* [router README](./README-router.md)
|
||||
|
||||
#### Source
|
||||
|
||||
|
23
docker-compose-router.yml
Normal file
23
docker-compose-router.yml
Normal file
@ -0,0 +1,23 @@
|
||||
version: '3'
|
||||
services:
|
||||
zerotier:
|
||||
image: "zyclonite/zerotier:router"
|
||||
container_name: zerotier-one
|
||||
devices:
|
||||
- /dev/net/tun
|
||||
network_mode: host
|
||||
volumes:
|
||||
- '/var/lib/zerotier-one:/var/lib/zerotier-one'
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN
|
||||
- NET_RAW
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- TZ=Etc/UTC
|
||||
- PUID=999
|
||||
- PGID=994
|
||||
- ZEROTIER_ONE_LOCAL_PHYS=eth0
|
||||
- ZEROTIER_ONE_USE_IPTABLES_NFT=false
|
||||
- ZEROTIER_ONE_GATEWAY_MODE=inbound
|
||||
# - ZEROTIER_ONE_NETWORK_IDS=yourNetworkID
|
@ -25,7 +25,7 @@ spec:
|
||||
|
||||
containers:
|
||||
- name: zerotier
|
||||
image: zyclonite/zerotier:bridge
|
||||
image: zyclonite/zerotier:router
|
||||
resources:
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
|
@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
set -Eeo pipefail
|
||||
|
||||
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
|
||||
|
||||
exec "$@"
|
154
scripts/entrypoint-router.sh
Executable file
154
scripts/entrypoint-router.sh
Executable file
@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env sh
|
||||
set -Eeo pipefail
|
||||
|
||||
if [ "${1:0:1}" = '-' ]; then
|
||||
set -- zerotier-one "$@"
|
||||
fi
|
||||
|
||||
# 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_IDS environment variable is non-null.
|
||||
if [ ! -d "${NETWORKS_DIR}" -a -n "${ZEROTIER_ONE_NETWORK_IDS}" ] ; then
|
||||
echo "Assuming container first run."
|
||||
mkdir -p "${NETWORKS_DIR}"
|
||||
for NETWORK_ID in ${ZEROTIER_ONE_NETWORK_IDS} ; do
|
||||
echo "Configuring auto-join of network ID: ${NETWORK_ID}"
|
||||
touch "${NETWORKS_DIR}/${NETWORK_ID}.conf"
|
||||
echo "You will need to authorize this host at:"
|
||||
echo " https://my.zerotier.com/network/${NETWORK_ID}"
|
||||
done
|
||||
fi
|
||||
|
||||
# make sure permissions are always as expected (self-repair)
|
||||
PUID="${PUID:-"999"}"
|
||||
PGID="${PGID:-"994"}"
|
||||
if [ "$(id -u)" = '0' -a -d "${CONFIG_DIR}" ]; then
|
||||
chown -Rc "${PUID}:${PGID}" "${CONFIG_DIR}"
|
||||
fi
|
||||
|
||||
# is routing enabled?
|
||||
if [ $(sysctl -n net.ipv4.ip_forward) -ne 1 ] ; then
|
||||
|
||||
# no! there is no point in setting up rules or termination handler
|
||||
echo "$(date) - IPv4 forwarding not enabled - launching ZeroTier-One in non-routing mode"
|
||||
|
||||
# just exec the client (this script ends here)
|
||||
exec "$@"
|
||||
|
||||
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
|
||||
# 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
|
||||
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
|
||||
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"
|
||||
|
||||
# define where the ZeroTier daemon will write its output (if any)
|
||||
TAIL_PIPE=$(mktemp /tmp/zerotier-ipc-XXXXXX)
|
||||
|
||||
# start listening and echoing anything that appears there into this process
|
||||
tail -f "${TAIL_PIPE}" &
|
||||
|
||||
# make a note of the process ID for tail
|
||||
TAIL_PIPE_PID=${!}
|
||||
|
||||
# start the ZeroTier daemon in detached state
|
||||
nohup "$@" </dev/null >"${TAIL_PIPE}" 2>&1 &
|
||||
|
||||
# make a note of the process ID
|
||||
ZEROTIER_DAEMON_PID=${!}
|
||||
|
||||
# report
|
||||
echo "$(date) - ZeroTier daemon is running as process ${ZEROTIER_DAEMON_PID}"
|
||||
|
||||
# function to handle cleanup
|
||||
termination_handler() {
|
||||
|
||||
echo "$(date) - terminating ZeroTier-One"
|
||||
|
||||
# remove rules
|
||||
update_iptables "D" "removing"
|
||||
|
||||
# relay the termination message to the daemon
|
||||
if [ -d "/proc/${ZEROTIER_DAEMON_PID}" ] ; then
|
||||
kill -TERM ${ZEROTIER_DAEMON_PID}
|
||||
wait ${ZEROTIER_DAEMON_PID}
|
||||
fi
|
||||
|
||||
# tell the pipe listener to go away too
|
||||
if [ -d "/proc/${TAIL_PIPE_PID}" ] ; then
|
||||
kill -TERM ${TAIL_PIPE_PID}
|
||||
wait ${TAIL_PIPE_PID}
|
||||
fi
|
||||
|
||||
# clean up the pipe file
|
||||
rm "${TAIL_PIPE}"
|
||||
|
||||
}
|
||||
|
||||
# set up termination handler (usually catches TERM)
|
||||
trap termination_handler INT TERM HUP
|
||||
|
||||
# suspend this script while the zerotier daemon is running
|
||||
wait ${ZEROTIER_DAEMON_PID}
|
||||
|
||||
# would not usually expect to arrive here inside a Docker container but
|
||||
# it can happen if the user does a "sudo killall zerotier-one" rather
|
||||
# that use Docker commands
|
||||
echo "$(date) - the ZeroTier daemon has quit unexpectedly - cleaning up"
|
||||
|
||||
# run the termination handler
|
||||
termination_handler
|
Loading…
Reference in New Issue
Block a user