Files
Maks Kukarin b2da6daf33 Add Docker image and compose for local client / exit-node runs
One multi-stage image (golang:1.26-alpine -> alpine:3.22, CGO off) serving
both roles via an env-driven entrypoint:

- client: SOCKS5 proxy, no special privileges, published on 127.0.0.1:1080
- exit-node: raw sockets + the kernel-RST drop, confined to the container's
  network namespace (NET_RAW/NET_ADMIN via compose), so the iptables rule
  can never touch the host — the containerized variant of the scoped rule
  the README already recommends

docker-compose.yml runs the two ends behind separate profiles; .env.example
documents TRANSPORT (yandex|vyandex|oneme), DOC_URL, MAX_TOKEN/MAX_UID, etc.
2026-09-12 14:22:08 +05:00

66 lines
1.8 KiB
Bash
Executable File

#!/bin/sh
# Maps environment variables to openflux flags and, for the exit node,
# installs the kernel-RST-drop rule *inside this container's netns*.
#
# Why the rule: the exit node's TCP connections live in a userspace (gVisor)
# stack, so the kernel has no socket for them and answers every inbound
# SYN-ACK with an RST, tearing the tunnel down. Confining the DROP to the
# container netns is the scoped variant of upstream's host-wide rule — it
# cannot affect the host or other containers.
set -eu
role="${ROLE:-client}"
transport="${TRANSPORT:-yandex}"
listen="${SOCKS5_LISTEN:-:1080}"
case "$role" in
client|exit-node) ;;
*)
echo "ROLE must be 'client' or 'exit-node' (got '$role')" >&2
exit 2
;;
esac
case "$transport" in
yandex|vyandex|oneme) ;;
*)
echo "TRANSPORT must be one of yandex, vyandex, oneme (got '$transport')" >&2
exit 2
;;
esac
set -- "--$role" --transport "$transport"
if [ "$role" = client ]; then
set -- "$@" --socks5 "$listen"
fi
if [ -n "${URL:-}" ]; then
set -- "$@" --url "$URL"
fi
if [ -n "${MAX_TOKEN:-}" ]; then
set -- "$@" --maxToken "$MAX_TOKEN"
fi
if [ -n "${MAX_UID:-}" ]; then
set -- "$@" --maxUid "$MAX_UID"
fi
if [ -n "${LOCAL_IP:-}" ]; then
# Optional: pin the egress IP (alias IP) so the RST drop could be scoped
# with `-s <ip>` too; inside a dedicated container netns it's usually
# unnecessary.
set -- "$@" --local-ip "$LOCAL_IP"
fi
case "${DEBUG:-0}" in
1|true|yes) set -- "$@" --debug ;;
esac
if [ "$role" = exit-node ]; then
echo "[entrypoint] dropping outbound TCP RSTs inside the container netns"
if ! iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP; then
echo "[entrypoint] WARNING: iptables failed (missing NET_ADMIN?); kernel RSTs will kill tunnel connections" >&2
fi
fi
echo "[entrypoint] exec: openflux $*"
exec openflux "$@"