mirror of
				https://github.com/dndx/phantun.git
				synced 2025-11-04 11:55:34 +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:
		
							
								
								
									
										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 "$@"
 | 
			
		||||
		Reference in New Issue
	
	Block a user