mirror of
https://github.com/dndx/phantun.git
synced 2025-01-18 13:59:30 +08:00
chore(docker): add Docker image build. Thanks @pexcn for the contributions!
Co-authored-by: Datong Sun <dndx@idndx.com>
This commit is contained in:
parent
ee7ee5d5f9
commit
d7913c1407
30
.github/workflows/docker.yml
vendored
Normal file
30
.github/workflows/docker.yml
vendored
Normal file
@ -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
|
2
docker/.dockerignore
Normal file
2
docker/.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
README.md
|
||||||
|
docker-compose.yml
|
41
docker/Dockerfile
Normal file
41
docker/Dockerfile
Normal file
@ -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"]
|
11
docker/README.md
Normal file
11
docker/README.md
Normal file
@ -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.
|
26
docker/docker-compose.yml
Normal file
26
docker/docker-compose.yml
Normal file
@ -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
|
209
docker/phantun.sh
Executable file
209
docker/phantun.sh
Executable file
@ -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 "$@"
|
Loading…
x
Reference in New Issue
Block a user