141 lines
4.7 KiB
Bash
Executable File
141 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
APP_COMPONENT="${APP_COMPONENT:-combined}"
|
|
TPROXY_PORT="${TPROXY_PORT:-7895}"
|
|
TPROXY_MARK="${TPROXY_MARK:-1}"
|
|
TPROXY_TABLE="${TPROXY_TABLE:-100}"
|
|
TPROXY_CHAIN="${TPROXY_CHAIN:-VPN_PROXY_TPROXY}"
|
|
GATEWAY_FORWARD_CHAIN="${GATEWAY_FORWARD_CHAIN:-VPN_PROXY_FORWARD}"
|
|
GATEWAY_NAT_CHAIN="${GATEWAY_NAT_CHAIN:-VPN_PROXY_NAT}"
|
|
GATEWAY_CLIENT_CIDRS="${GATEWAY_CLIENT_CIDRS:-10.0.0.0/8 172.16.0.0/12 192.168.0.0/16}"
|
|
PROXY_PORT="${PROXY_PORT:-8080}"
|
|
PROXY_BIND_IP="${PROXY_BIND_IP:-0.0.0.0}"
|
|
PROXY_INPUT_CHAIN="${PROXY_INPUT_CHAIN:-VPN_PROXY_INPUT}"
|
|
PROXY_FIREWALL="${PROXY_FIREWALL:-true}"
|
|
PROXY_ALLOWED_CIDRS="${PROXY_ALLOWED_CIDRS:-10.0.0.0/8 172.16.0.0/12 192.168.0.0/16}"
|
|
BYPASS_CIDRS="${BYPASS_CIDRS:-0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4}"
|
|
|
|
log() {
|
|
printf '[gateway-entrypoint] %s\n' "$*"
|
|
}
|
|
|
|
if [[ "$APP_COMPONENT" == "control" ]]; then
|
|
exec node /app/src/server/index.js
|
|
fi
|
|
|
|
ipt() {
|
|
iptables -w "$@"
|
|
}
|
|
|
|
cleanup_proxy_firewall() {
|
|
ipt -D INPUT -p tcp --dport "$PROXY_PORT" -j "$PROXY_INPUT_CHAIN" 2>/dev/null || true
|
|
ipt -D INPUT -p udp --dport "$PROXY_PORT" -j "$PROXY_INPUT_CHAIN" 2>/dev/null || true
|
|
ipt -F "$PROXY_INPUT_CHAIN" 2>/dev/null || true
|
|
ipt -X "$PROXY_INPUT_CHAIN" 2>/dev/null || true
|
|
}
|
|
|
|
cleanup_tproxy() {
|
|
ipt -t mangle -D PREROUTING -j "$TPROXY_CHAIN" 2>/dev/null || true
|
|
ipt -t mangle -F "$TPROXY_CHAIN" 2>/dev/null || true
|
|
ipt -t mangle -X "$TPROXY_CHAIN" 2>/dev/null || true
|
|
ip rule del fwmark "$TPROXY_MARK" table "$TPROXY_TABLE" 2>/dev/null || true
|
|
ip route flush table "$TPROXY_TABLE" 2>/dev/null || true
|
|
}
|
|
|
|
cleanup_gateway_forwarding() {
|
|
ipt -D FORWARD -j "$GATEWAY_FORWARD_CHAIN" 2>/dev/null || true
|
|
ipt -t nat -D POSTROUTING -j "$GATEWAY_NAT_CHAIN" 2>/dev/null || true
|
|
ipt -F "$GATEWAY_FORWARD_CHAIN" 2>/dev/null || true
|
|
ipt -X "$GATEWAY_FORWARD_CHAIN" 2>/dev/null || true
|
|
ipt -t nat -F "$GATEWAY_NAT_CHAIN" 2>/dev/null || true
|
|
ipt -t nat -X "$GATEWAY_NAT_CHAIN" 2>/dev/null || true
|
|
}
|
|
|
|
enable_ip_forwarding() {
|
|
if [[ -w /proc/sys/net/ipv4/ip_forward ]]; then
|
|
printf '1' > /proc/sys/net/ipv4/ip_forward || true
|
|
elif command -v sysctl >/dev/null 2>&1; then
|
|
sysctl -w net.ipv4.ip_forward=1 >/dev/null 2>&1 || true
|
|
fi
|
|
}
|
|
|
|
setup_proxy_firewall() {
|
|
if [[ "$PROXY_FIREWALL" != "true" || "$PROXY_BIND_IP" == "127.0.0.1" || "$PROXY_BIND_IP" == "::1" ]]; then
|
|
return
|
|
fi
|
|
|
|
cleanup_proxy_firewall
|
|
ipt -N "$PROXY_INPUT_CHAIN"
|
|
for cidr in $PROXY_ALLOWED_CIDRS; do
|
|
ipt -A "$PROXY_INPUT_CHAIN" -s "$cidr" -j RETURN
|
|
done
|
|
ipt -A "$PROXY_INPUT_CHAIN" -j DROP
|
|
ipt -I INPUT -p tcp --dport "$PROXY_PORT" -j "$PROXY_INPUT_CHAIN"
|
|
ipt -I INPUT -p udp --dport "$PROXY_PORT" -j "$PROXY_INPUT_CHAIN"
|
|
}
|
|
|
|
setup_gateway_forwarding() {
|
|
log "setup direct gateway forwarding"
|
|
cleanup_gateway_forwarding
|
|
enable_ip_forwarding
|
|
|
|
ipt -N "$GATEWAY_FORWARD_CHAIN"
|
|
ipt -t nat -N "$GATEWAY_NAT_CHAIN"
|
|
for cidr in $GATEWAY_CLIENT_CIDRS; do
|
|
ipt -A "$GATEWAY_FORWARD_CHAIN" -s "$cidr" -j ACCEPT
|
|
ipt -A "$GATEWAY_FORWARD_CHAIN" -d "$cidr" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
|
ipt -t nat -A "$GATEWAY_NAT_CHAIN" -s "$cidr" -m addrtype ! --dst-type LOCAL -j MASQUERADE
|
|
done
|
|
ipt -I FORWARD 1 -j "$GATEWAY_FORWARD_CHAIN"
|
|
ipt -t nat -I POSTROUTING 1 -j "$GATEWAY_NAT_CHAIN"
|
|
}
|
|
|
|
setup_tproxy() {
|
|
log "setup tproxy on port ${TPROXY_PORT}"
|
|
cleanup_tproxy
|
|
enable_ip_forwarding
|
|
|
|
ip rule add fwmark "$TPROXY_MARK" table "$TPROXY_TABLE" 2>/dev/null || true
|
|
ip route replace local 0.0.0.0/0 dev lo table "$TPROXY_TABLE"
|
|
ipt -t mangle -N "$TPROXY_CHAIN"
|
|
ipt -t mangle -A "$TPROXY_CHAIN" -m addrtype --dst-type LOCAL -j RETURN
|
|
ipt -t mangle -A "$TPROXY_CHAIN" -m mark --mark "$TPROXY_MARK" -j RETURN
|
|
ipt -t mangle -A "$TPROXY_CHAIN" -i 'br-+' -j RETURN
|
|
|
|
# Private/local destinations stay reachable; every intercepted public packet goes to VPN.
|
|
for cidr in $BYPASS_CIDRS; do
|
|
ipt -t mangle -A "$TPROXY_CHAIN" -d "$cidr" -j RETURN
|
|
done
|
|
|
|
ipt -t mangle -A "$TPROXY_CHAIN" -p tcp -j TPROXY --on-port "$TPROXY_PORT" --tproxy-mark "$TPROXY_MARK/$TPROXY_MARK"
|
|
ipt -t mangle -A "$TPROXY_CHAIN" -p udp -j TPROXY --on-port "$TPROXY_PORT" --tproxy-mark "$TPROXY_MARK/$TPROXY_MARK"
|
|
}
|
|
|
|
setup_gateway_forwarding
|
|
setup_tproxy
|
|
setup_proxy_firewall
|
|
|
|
if [[ "$APP_COMPONENT" == "dataplane" ]]; then
|
|
node /app/src/server/dataplane.js &
|
|
else
|
|
node /app/src/server/index.js &
|
|
fi
|
|
APP_PID=$!
|
|
|
|
shutdown() {
|
|
kill "$APP_PID" 2>/dev/null || true
|
|
wait "$APP_PID" 2>/dev/null || true
|
|
cleanup_proxy_firewall
|
|
cleanup_tproxy
|
|
cleanup_gateway_forwarding
|
|
}
|
|
|
|
trap 'shutdown; exit 0' SIGTERM SIGINT
|
|
wait "$APP_PID"
|
|
STATUS=$?
|
|
cleanup_proxy_firewall
|
|
cleanup_tproxy
|
|
cleanup_gateway_forwarding
|
|
exit "$STATUS"
|