forked from dndx/phantun
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(docker): add Docker image build. Thanks @pexcn for the contribu…
…tions! Co-authored-by: Datong Sun <[email protected]>
- Loading branch information
Showing
6 changed files
with
319 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: Docker image build | ||
|
||
on: | ||
push: | ||
paths-ignore: | ||
- '**.md' | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-22.04 | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
|
||
- name: Setup QEMU | ||
uses: docker/setup-qemu-action@v2 | ||
with: | ||
platforms: linux/amd64 | ||
|
||
- name: Setup Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
|
||
- name: Build Docker Image | ||
uses: docker/build-push-action@v3 | ||
with: | ||
context: . | ||
file: docker/Dockerfile | ||
tags: phantun | ||
platforms: linux/amd64 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
README.md | ||
docker-compose.yml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# | ||
# Dockerfile for phantun | ||
# | ||
|
||
# | ||
# Build stage | ||
# | ||
FROM rust:alpine AS builder | ||
|
||
COPY . /phantun | ||
|
||
RUN apk update \ | ||
&& apk add --no-cache --virtual .build-deps musl-dev \ | ||
&& cd phantun \ | ||
&& cargo build --release \ | ||
&& strip target/release/server target/release/client \ | ||
&& install target/release/server /usr/local/bin/phantun-server \ | ||
&& install target/release/client /usr/local/bin/phantun-client \ | ||
&& cd - \ | ||
&& rm -r phantun \ | ||
&& apk del .build-deps \ | ||
&& rm -rf /var/cache/apk/* | ||
|
||
# | ||
# Runtime stage | ||
# | ||
FROM alpine:3.16 | ||
|
||
RUN apk update \ | ||
&& apk add --no-cache iptables ip6tables tzdata \ | ||
&& rm -rf /var/cache/apk/* | ||
|
||
COPY --from=builder /usr/local/bin/phantun-server /usr/local/bin/ | ||
COPY --from=builder /usr/local/bin/phantun-client /usr/local/bin/ | ||
COPY docker/phantun.sh /usr/local/bin/ | ||
|
||
ENV USE_IPTABLES_NFT_BACKEND=0 | ||
ENV RUST_LOG=INFO | ||
|
||
ENTRYPOINT ["phantun.sh"] | ||
CMD ["phantun-server", "--help"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# phantun (docker) | ||
|
||
## Build | ||
|
||
```sh | ||
docker build -t phantun -f docker/Dockerfile . | ||
``` | ||
|
||
## Usage | ||
|
||
It is recommended to use docker-compose, see [docker-compose.yml](docker-compose.yml) for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
version: '3.9' | ||
|
||
services: | ||
phantun-server: | ||
image: phantun | ||
container_name: phantun-server | ||
restart: unless-stopped | ||
network_mode: host | ||
privileged: true | ||
environment: | ||
USE_IPTABLES_NFT_BACKEND: 0 | ||
RUST_LOG: INFO | ||
command: > | ||
phantun-server --local 1985 --remote 127.0.0.1:1984 --ipv4-only | ||
phantun-client: | ||
image: phantun | ||
container_name: phantun-client | ||
restart: unless-stopped | ||
network_mode: host | ||
privileged: true | ||
environment: | ||
USE_IPTABLES_NFT_BACKEND: 0 | ||
RUST_LOG: INFO | ||
command: > | ||
phantun-client --local 127.0.0.1:1984 --remote 11.22.33.44:1985 --ipv4-only |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
#!/bin/sh | ||
|
||
# alias settings must be global, and must be defined before the function being called with the alias | ||
if [ "$USE_IPTABLES_NFT_BACKEND" = 1 ]; then | ||
alias iptables=iptables-nft | ||
alias iptables-save=iptables-nft-save | ||
alias ip6tables=ip6tables-nft | ||
alias ip6tables-save=ip6tables-nft-save | ||
fi | ||
|
||
info() { | ||
local green='\e[0;32m' | ||
local clear='\e[0m' | ||
local time=$(date '+%Y-%m-%d %T') | ||
printf "${green}[${time}] [INFO]: ${clear}%s\n" "$*" | ||
} | ||
|
||
warn() { | ||
local yellow='\e[1;33m' | ||
local clear='\e[0m' | ||
local time=$(date '+%Y-%m-%d %T') | ||
printf "${yellow}[${time}] [WARN]: ${clear}%s\n" "$*" >&2 | ||
} | ||
|
||
error() { | ||
local red='\e[0;31m' | ||
local clear='\e[0m' | ||
local time=$(date '+%Y-%m-%d %T') | ||
printf "${red}[${time}] [ERROR]: ${clear}%s\n" "$*" >&2 | ||
} | ||
|
||
_get_default_iface() { | ||
ip -4 route show default | awk -F 'dev' '{print $2}' | awk '{print $1}' | ||
} | ||
|
||
_get_default6_iface() { | ||
ip -6 route show default | awk -F 'dev' '{print $2}' | awk '{print $1}' | ||
} | ||
|
||
_get_addr_by_iface() { | ||
ip -4 addr show dev "$1" | grep -w "inet" | awk '{print $2}' | awk -F '/' '{print $1}' | head -1 | ||
} | ||
|
||
_get_addr6_by_iface() { | ||
ip -6 addr show dev "$1" | grep -w "inet6" | awk '{print $2}' | awk -F '/' '{print $1}' | head -1 | ||
} | ||
|
||
_check_rule_by_comment() { | ||
iptables-save | grep -q "$1" | ||
} | ||
|
||
_check_rule6_by_comment() { | ||
ip6tables-save | grep -q "$1" | ||
} | ||
|
||
_is_server_mode() { | ||
[ "$1" = "phantun-server" ] | ||
} | ||
|
||
_is_ipv4_only() { | ||
case "$@" in | ||
*-4*|*--ipv4-only*) | ||
return 0 | ||
;; | ||
*\ -4*|*\ --ipv4-only*) | ||
return 0 | ||
;; | ||
esac | ||
return 1 | ||
} | ||
|
||
_get_tun_from_args() { | ||
local tun=$(echo "$@" | awk -F '--tun' '{print $2}' | awk '{print $1}') | ||
echo ${tun:=tun0} | ||
} | ||
|
||
_get_peer_from_args() { | ||
local peer=$(echo "$@" | awk -F '--tun-peer' '{print $2}' | awk '{print $1}') | ||
_is_server_mode "$1" && echo ${peer:=192.168.201.2} || echo ${peer:=192.168.200.2} | ||
} | ||
|
||
_get_peer6_from_args() { | ||
local peer=$(echo "$@" | awk -F '--tun-peer6' '{print $2}' | awk '{print $1}') | ||
_is_server_mode "$1" && echo ${peer:=fcc9::2} || echo ${peer:=fcc8::2} | ||
} | ||
|
||
_get_port_from_args() { | ||
local value=$(echo "$@" | awk -F '-l|--local' '{print $2}' | awk '{print $1}') | ||
_is_server_mode "$1" && echo $value || echo $value | awk -F ':' '{print $2}' | ||
} | ||
|
||
_iptables() { | ||
iptables -w 10 "$@" | ||
} | ||
|
||
_ip6tables() { | ||
ip6tables -w 10 "$@" | ||
} | ||
|
||
apply_sysctl() { | ||
info "apply sysctl: $(sysctl -w net.ipv4.ip_forward=1)" | ||
! _is_ipv4_only "$@" || return | ||
info "apply sysctl: $(sysctl -w net.ipv6.conf.all.forwarding=1)" | ||
} | ||
|
||
apply_iptables() { | ||
local interface=$(_get_default_iface) | ||
local address=$(_get_addr_by_iface "${interface}") | ||
local tun=$(_get_tun_from_args "$@") | ||
local peer=$(_get_peer_from_args "$@") | ||
local port=$(_get_port_from_args "$@") | ||
local comment="phantun_${tun}_${port}" | ||
|
||
if _check_rule_by_comment "${comment}"; then | ||
warn "iptables rules already exist, maybe needs to check." | ||
else | ||
_iptables -A FORWARD -i $tun -j ACCEPT -m comment --comment "${comment}" || error "iptables filter rule add failed." | ||
_iptables -A FORWARD -o $tun -j ACCEPT -m comment --comment "${comment}" || error "iptables filter rule add failed." | ||
if _is_server_mode "$1"; then | ||
info "iptables DNAT rule added: [${comment}]: ${interface} -> ${tun}, ${address} -> ${peer}" | ||
_iptables -t nat -A PREROUTING -p tcp -i $interface --dport $port -j DNAT --to-destination $peer \ | ||
-m comment --comment "${comment}" || error "iptables DNAT rule add failed." | ||
else | ||
info "iptables SNAT rule added: [${comment}]: ${tun} -> ${interface}, ${peer} -> ${address}" | ||
_iptables -t nat -A POSTROUTING -s $peer -o $interface -j SNAT --to-source $address \ | ||
-m comment --comment "${comment}" || error "iptables SNAT rule add failed." | ||
fi | ||
fi | ||
} | ||
|
||
apply_ip6tables() { | ||
! _is_ipv4_only "$@" || return | ||
|
||
local interface=$(_get_default6_iface) | ||
local address=$(_get_addr6_by_iface "${interface}") | ||
local tun=$(_get_tun_from_args "$@") | ||
local peer=$(_get_peer6_from_args "$@") | ||
local port=$(_get_port_from_args "$@") | ||
local comment="phantun_${tun}_${port}" | ||
|
||
if _check_rule6_by_comment "${comment}"; then | ||
warn "ip6tables rules already exist, maybe needs to check." | ||
else | ||
_ip6tables -A FORWARD -i $tun -j ACCEPT -m comment --comment "${comment}" || error "ip6tables filter rule add failed." | ||
_ip6tables -A FORWARD -o $tun -j ACCEPT -m comment --comment "${comment}" || error "ip6tables filter rule add failed." | ||
if _is_server_mode "$1"; then | ||
info "ip6tables DNAT rule added: [${comment}]: ${interface} -> ${tun}, ${address} -> ${peer}" | ||
_ip6tables -t nat -A PREROUTING -p tcp -i $interface --dport $port -j DNAT --to-destination $peer \ | ||
-m comment --comment "${comment}" || error "ip6tables DNAT rule add failed." | ||
else | ||
info "ip6tables SNAT rule added: [${comment}]: ${tun} -> ${interface}, ${peer} -> ${address}" | ||
_ip6tables -t nat -A POSTROUTING -s $peer -o $interface -j SNAT --to-source $address \ | ||
-m comment --comment "${comment}" || error "ip6tables SNAT rule add failed." | ||
fi | ||
fi | ||
} | ||
|
||
stop_process() { | ||
kill $(pidof phantun-server phantun-client) | ||
info "terminate phantun process." | ||
} | ||
|
||
revoke_iptables() { | ||
local tun=$(_get_tun_from_args "$@") | ||
local port=$(_get_port_from_args "$@") | ||
local comment="phantun_${tun}_${port}" | ||
|
||
iptables-save -t filter | grep "${comment}" | while read rule; do | ||
_iptables -t filter ${rule/-A/-D} || error "iptables filter rule remove failed." | ||
done | ||
iptables-save -t nat | grep "${comment}" | while read rule; do | ||
_iptables -t nat ${rule/-A/-D} || error "iptables nat rule remove failed." | ||
done | ||
info "iptables rule: [${comment}] removed." | ||
} | ||
|
||
revoke_ip6tables() { | ||
! _is_ipv4_only "$@" || return | ||
|
||
local tun=$(_get_tun_from_args "$@") | ||
local port=$(_get_port_from_args "$@") | ||
local comment="phantun_${tun}_${port}" | ||
|
||
ip6tables-save -t filter | grep "${comment}" | while read rule; do | ||
_ip6tables -t filter ${rule/-A/-D} || error "ip6tables filter rule remove failed." | ||
done | ||
ip6tables-save -t nat | grep "${comment}" | while read rule; do | ||
_ip6tables -t nat ${rule/-A/-D} || error "ip6tables nat rule remove failed." | ||
done | ||
info "ip6tables rule: [${comment}] removed." | ||
} | ||
|
||
graceful_stop() { | ||
warn "caught SIGTERM or SIGINT signal, graceful stopping..." | ||
stop_process | ||
revoke_iptables "$@" | ||
revoke_ip6tables "$@" | ||
} | ||
|
||
start_phantun() { | ||
trap 'graceful_stop "$@"' SIGTERM SIGINT | ||
apply_sysctl "$@" | ||
apply_iptables "$@" | ||
apply_ip6tables "$@" | ||
"$@" & | ||
wait | ||
} | ||
|
||
start_phantun "$@" |