migrate to one service
This commit is contained in:
+5
-17
@@ -2,29 +2,17 @@ FROM golang:1.24-bookworm AS builder
|
|||||||
|
|
||||||
RUN apt-get update && apt-get install -y git
|
RUN apt-get update && apt-get install -y git
|
||||||
|
|
||||||
# Клонируем репозиторий и собираем приложение
|
|
||||||
WORKDIR /outline-sdk
|
WORKDIR /outline-sdk
|
||||||
RUN git clone https://github.com/OutlineFoundation/outline-sdk.git .
|
RUN git clone https://github.com/OutlineFoundation/outline-sdk.git .
|
||||||
WORKDIR /outline-sdk/x/examples/outline-cli
|
WORKDIR /outline-sdk/x/examples/outline-cli
|
||||||
|
|
||||||
RUN CGO_ENABLED=1 go build -o /outline-cli -ldflags="-extldflags=-static" .
|
RUN CGO_ENABLED=1 go build -o /outline-cli -ldflags="-extldflags=-static" .
|
||||||
|
|
||||||
FROM debian:bookworm
|
FROM lscr.io/linuxserver/wireguard:latest
|
||||||
RUN apt-get update && apt-get install -y curl wget
|
|
||||||
# Устанавливаем необходимые утилиты для работы сети и создаем пустой resolv.conf.head
|
|
||||||
RUN apt-get update && apt-get install -y iproute2 iptables && \
|
|
||||||
rm -rf /var/lib/apt/lists/* && \
|
|
||||||
touch /etc/resolv.conf.head
|
|
||||||
|
|
||||||
# Копируем собранный бинарный файл из этапа сборки
|
|
||||||
COPY --from=builder /outline-cli /usr/local/bin/outline-cli
|
COPY --from=builder /outline-cli /usr/local/bin/outline-cli
|
||||||
|
COPY root/ /
|
||||||
|
|
||||||
# Обертка-энтрипоинт: готовит DNS и запускает outline-cli
|
RUN chmod +x /usr/local/bin/outline-cli \
|
||||||
COPY entrypoint.sh /usr/local/bin/outline-entrypoint.sh
|
/custom-cont-init.d/* \
|
||||||
|
/etc/s6-overlay/s6-rc.d/svc-outline/run
|
||||||
# Делаем бинарный файл исполняемым
|
|
||||||
RUN chmod +x /usr/local/bin/outline-cli /usr/local/bin/outline-entrypoint.sh
|
|
||||||
|
|
||||||
# Точка входа
|
|
||||||
ENTRYPOINT ["/usr/local/bin/outline-entrypoint.sh"]
|
|
||||||
|
|
||||||
|
|||||||
+13
-41
@@ -1,19 +1,27 @@
|
|||||||
services:
|
services:
|
||||||
outline-client:
|
wg2outline:
|
||||||
build: .
|
build: .
|
||||||
container_name: outline-client
|
container_name: wg2outline
|
||||||
privileged: true
|
privileged: true
|
||||||
# WireGuard UDP port is published from this service because
|
|
||||||
# the wireguard container shares this network namespace.
|
|
||||||
ports:
|
ports:
|
||||||
- "51821:51820/udp"
|
- "51821:51820/udp"
|
||||||
environment:
|
environment:
|
||||||
# Replace with your Outline access key.
|
|
||||||
OUTLINE_TRANSPORT: "${OUTLINE_TRANSPORT}"
|
OUTLINE_TRANSPORT: "${OUTLINE_TRANSPORT}"
|
||||||
INTERNAL_SUBNET: "${INTERNAL_SUBNET}"
|
INTERNAL_SUBNET: "${INTERNAL_SUBNET}"
|
||||||
|
PUID: 1000
|
||||||
|
PGID: 1000
|
||||||
|
TZ: Etc/UTC
|
||||||
|
SERVERURL: ${SERVERURL}
|
||||||
|
SERVERPORT: 51821
|
||||||
|
PEERS: ${PEERS:-1}
|
||||||
|
PEERDNS: 1.1.1.1
|
||||||
|
PERSISTENTKEEPALIVE_PEERS: 25
|
||||||
|
MTU: 1280
|
||||||
|
LOG_CONFS: true
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
- SYS_ADMIN
|
- SYS_ADMIN
|
||||||
|
- SYS_MODULE
|
||||||
devices:
|
devices:
|
||||||
- /dev/net/tun:/dev/net/tun
|
- /dev/net/tun:/dev/net/tun
|
||||||
security_opt:
|
security_opt:
|
||||||
@@ -26,45 +34,9 @@ services:
|
|||||||
- net.ipv6.conf.all.forwarding=0
|
- net.ipv6.conf.all.forwarding=0
|
||||||
- net.ipv6.conf.all.disable_ipv6=1
|
- net.ipv6.conf.all.disable_ipv6=1
|
||||||
- net.ipv6.conf.default.disable_ipv6=1
|
- net.ipv6.conf.default.disable_ipv6=1
|
||||||
restart: unless-stopped
|
|
||||||
logging:
|
|
||||||
driver: json-file
|
|
||||||
options:
|
|
||||||
max-size: "50m"
|
|
||||||
max-file: "5"
|
|
||||||
|
|
||||||
wireguard:
|
|
||||||
image: lscr.io/linuxserver/wireguard:latest
|
|
||||||
container_name: wg2outline
|
|
||||||
depends_on:
|
|
||||||
- outline-client
|
|
||||||
# Important: share network stack with outline-client so all
|
|
||||||
# traffic from WG peers leaves through Outline routing/policy.
|
|
||||||
network_mode: "service:outline-client"
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
- SYS_MODULE
|
|
||||||
environment:
|
|
||||||
- PUID=1000
|
|
||||||
- PGID=1000
|
|
||||||
- TZ=Etc/UTC
|
|
||||||
# Public IP or domain of this server for peers.
|
|
||||||
- SERVERURL=${SERVERURL}
|
|
||||||
- SERVERPORT=51821
|
|
||||||
- PEERS=${PEERS:-1}
|
|
||||||
- PEERDNS=1.1.1.1
|
|
||||||
- INTERNAL_SUBNET=${INTERNAL_SUBNET}
|
|
||||||
# Keepalive helps on NAT/mobile networks.
|
|
||||||
- PERSISTENTKEEPALIVE_PEERS=25
|
|
||||||
# Optional for enterprise networks that block MTU/fragmentation.
|
|
||||||
- MTU=1280
|
|
||||||
# Firewall/NAT is handled by the host/namespace setup.
|
|
||||||
- LOG_CONFS=true
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./wireguard-config:/config
|
- ./wireguard-config:/config
|
||||||
- /lib/modules:/lib/modules:ro
|
- /lib/modules:/lib/modules:ro
|
||||||
sysctls:
|
|
||||||
- net.ipv4.conf.all.src_valid_mark=1
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
logging:
|
logging:
|
||||||
driver: json-file
|
driver: json-file
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
|
||||||
|
# Some distros mount /etc/resolv.conf as a file from the host.
|
||||||
|
# Ensure DNS works reliably inside the VPN network namespace.
|
||||||
|
umount /etc/resolv.conf 2>/dev/null || true
|
||||||
|
[ -f /etc/resolv.conf ] || printf 'nameserver 1.1.1.1\n' > /etc/resolv.conf
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
if [ -z "${OUTLINE_TRANSPORT:-}" ]; then
|
||||||
|
echo "ERROR: OUTLINE_TRANSPORT is required (ss://...)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${INTERNAL_SUBNET:-}" ]; then
|
||||||
|
echo "ERROR: INTERNAL_SUBNET is required (e.g. 10.13.13.0)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
WG_FWMARK=0x51820
|
||||||
|
WG_SUBNET="${INTERNAL_SUBNET}/24"
|
||||||
|
|
||||||
|
apply_bypass_rules() {
|
||||||
|
# WireGuard UDP replies go to the peer's public IP, not the WG subnet.
|
||||||
|
# Mark and bypass Outline policy routing for those packets.
|
||||||
|
ip rule add pref 50 fwmark "${WG_FWMARK}" lookup main 2>/dev/null || true
|
||||||
|
|
||||||
|
# Inner IP traffic to WG peers must use the main table (replies via wg0).
|
||||||
|
ip rule add pref 100 to "${WG_SUBNET}" lookup main 2>/dev/null || true
|
||||||
|
|
||||||
|
# Docker/custom bridge subnets differ per host (e.g. 172.17.0.0/16, 10.200.0.0/16).
|
||||||
|
local pref=101
|
||||||
|
local cidr
|
||||||
|
for cidr in $(ip -4 route show proto kernel scope link 2>/dev/null | awk '$2 == "dev" { print $1 }'); do
|
||||||
|
ip rule add pref "${pref}" to "${cidr}" lookup main 2>/dev/null || true
|
||||||
|
pref=$((pref + 1))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_wg_mangle() {
|
||||||
|
local wg_port="$1"
|
||||||
|
if iptables -t mangle -C OUTPUT -p udp --sport "${wg_port}" -j MARK --set-mark "${WG_FWMARK}" 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
iptables -t mangle -A OUTPUT -p udp --sport "${wg_port}" -j MARK --set-mark "${WG_FWMARK}"
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_outline_routing() {
|
||||||
|
local i
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
if ip link show outline233 >/dev/null 2>&1 && ip rule show | grep -q 'lookup 233'; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "WARN: Outline routing not ready after 30s, applying bypass rules anyway" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/usr/local/bin/outline-cli -transport "${OUTLINE_TRANSPORT}" &
|
||||||
|
OUTLINE_PID=$!
|
||||||
|
|
||||||
|
wait_for_outline_routing || true
|
||||||
|
apply_bypass_rules
|
||||||
|
setup_wg_mangle "${SERVERPORT:-51820}"
|
||||||
|
|
||||||
|
# wg0 starts after this service; refresh rules once the interface and listen port are known.
|
||||||
|
(
|
||||||
|
for _ in $(seq 1 60); do
|
||||||
|
if ip link show wg0 >/dev/null 2>&1; then
|
||||||
|
wg_port="$(wg show wg0 listen-port 2>/dev/null || echo "${SERVERPORT:-51820}")"
|
||||||
|
setup_wg_mangle "${wg_port}"
|
||||||
|
apply_bypass_rules
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
) &
|
||||||
|
|
||||||
|
# Ensure exactly one NAT rule for traffic leaving via Outline interface.
|
||||||
|
if iptables -t nat -C POSTROUTING -o outline+ -j MASQUERADE 2>/dev/null; then
|
||||||
|
while iptables -t nat -C POSTROUTING -o outline+ -j MASQUERADE 2>/dev/null; do
|
||||||
|
iptables -t nat -D POSTROUTING -o outline+ -j MASQUERADE || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
iptables -t nat -A POSTROUTING -o outline+ -j MASQUERADE
|
||||||
|
|
||||||
|
wait "$OUTLINE_PID"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
longrun
|
||||||
Reference in New Issue
Block a user