Sprint 0 / #18: multi-stage Dockerfile и супервизор entrypoint #49
@@ -0,0 +1,32 @@
|
|||||||
|
# Пример клиентского конфига AmneziaWG для awg-dash.
|
||||||
|
#
|
||||||
|
# Скопируйте в том /config как awg0.conf (имя файла = имя интерфейса) или
|
||||||
|
# загрузите через Web UI (задача #38). Значения ниже — заглушки, замените своими.
|
||||||
|
# Файл в репозитории не является рабочим конфигом и не содержит реальных ключей.
|
||||||
|
|
||||||
|
[Interface]
|
||||||
|
# Адрес внутри туннеля (из панели провайдера AmneziaWG)
|
||||||
|
Address = 10.8.1.2/32
|
||||||
|
|
||||||
|
# DNS: адрес должен указывать на этот шлюз, иначе не сработает DNS-split (ADR-005)
|
||||||
|
DNS = 10.8.1.1
|
||||||
|
|
||||||
|
PrivateKey = <PRIVATE_KEY>
|
||||||
|
|
||||||
|
# Обфускация AmneziaWG (Amnezia VPN: экспорт -> AmneziaWG)
|
||||||
|
Jc = 4
|
||||||
|
Jmin = 40
|
||||||
|
Jmax = 70
|
||||||
|
S1 = 0
|
||||||
|
S2 = 0
|
||||||
|
H1 = 1
|
||||||
|
H2 = 2
|
||||||
|
H3 = 3
|
||||||
|
H4 = 4
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = <SERVER_PUBLIC_KEY>
|
||||||
|
PresharedKey = <PRESHARED_KEY>
|
||||||
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
|
Endpoint = <SERVER_HOST>:<SERVER_PORT>
|
||||||
|
PersistentKeepalive = 25
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Супервизор контейнера awg-dash (задача #18, ADR-002).
|
||||||
|
# Последовательность: preflight -> подготовка -> запуск awg-api под awg.
|
||||||
|
# Привилегированный агент awg-agent стартует отсюда же после реализации (#22).
|
||||||
|
#
|
||||||
|
# Роль процесса: все сетевые операции выполняет агент под root; здесь только
|
||||||
|
# проверяем, что нужные возможности и устройства проброшены, и падаем явной
|
||||||
|
# ошибкой, если контейнер запущен без них (а не тихо деградируем).
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
CONFIG_DIR="${AWG_CONFIG_DIR:-/config}"
|
||||||
|
DATA_DIR="${AWG_DATA_DIR:-/data}"
|
||||||
|
RUN_DIR="${AWG_RUN_DIR:-/run/awg}"
|
||||||
|
API_HOST="${AWG_API_HOST:-0.0.0.0}"
|
||||||
|
API_PORT="${AWG_API_PORT:-8080}"
|
||||||
|
ROUTING_TABLE_ID=100
|
||||||
|
ROUTING_TABLE_NAME=awg-vpn
|
||||||
|
|
||||||
|
log() { printf '[entrypoint] %s\n' "$*"; }
|
||||||
|
fail() { printf '[entrypoint] FATAL: %s\n' "$*" >&2; exit 1; }
|
||||||
|
|
||||||
|
log 'preflight'
|
||||||
|
[ -e /dev/net/tun ] || fail '/dev/net/tun не проброшен: добавьте --device=/dev/net/tun:/dev/net/tun'
|
||||||
|
iptables -t mangle -L -n >/dev/null 2>&1 || fail 'iptables недоступен: нужен --cap-add=NET_ADMIN (и/или --privileged)'
|
||||||
|
command -v awg >/dev/null 2>&1 || fail 'бинарь awg не найден в образе'
|
||||||
|
command -v amneziawg-go >/dev/null 2>&1 || log 'WARN: amneziawg-go не найден — остаётся только kernel-модуль'
|
||||||
|
command -v ipset >/dev/null 2>&1 || fail 'ipset не найден в образе'
|
||||||
|
|
||||||
|
log 'подготовка каталогов состояния'
|
||||||
|
mkdir -p "$CONFIG_DIR" "$DATA_DIR" "$RUN_DIR"
|
||||||
|
chown -R awg:awg "$CONFIG_DIR" "$DATA_DIR" "$RUN_DIR" 2>/dev/null || true
|
||||||
|
chmod 700 "$CONFIG_DIR" "$DATA_DIR" 2>/dev/null || true
|
||||||
|
|
||||||
|
if ! grep -q "^${ROUTING_TABLE_ID} ${ROUTING_TABLE_NAME}" /etc/iproute2/rt_tables 2>/dev/null; then
|
||||||
|
printf '%s %s\n' "$ROUTING_TABLE_ID" "$ROUTING_TABLE_NAME" >> /etc/iproute2/rt_tables \
|
||||||
|
|| log 'WARN: не удалось записать таблицу маршрутизации в /etc/iproute2/rt_tables'
|
||||||
|
fi
|
||||||
|
|
||||||
|
sysctl -w net.ipv4.ip_forward=1 >/dev/null 2>&1 \
|
||||||
|
|| log 'WARN: не удалось включить net.ipv4.ip_forward (нужен SYS_MODULE или --privileged)'
|
||||||
|
|
||||||
|
log "awg: $(awg --version 2>/dev/null | head -n 1 || echo 'version unknown')"
|
||||||
|
|
||||||
|
api_pid=''
|
||||||
|
if [ -f /app/backend/awg_api/app.py ]; then
|
||||||
|
log "запуск awg-api на ${API_HOST}:${API_PORT}"
|
||||||
|
su-exec awg /opt/venv/bin/uvicorn awg_api.app:app --host "$API_HOST" --port "$API_PORT" &
|
||||||
|
api_pid=$!
|
||||||
|
else
|
||||||
|
log 'WARN: awg_api/app.py ещё не реализован (задача #31) — API не запущен, контейнер работает только как агент'
|
||||||
|
fi
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if [ -n "$api_pid" ] && kill -0 "$api_pid" 2>/dev/null; then
|
||||||
|
log 'остановка awg-api'
|
||||||
|
kill -TERM "$api_pid" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
trap stop INT TERM
|
||||||
|
|
||||||
|
if [ -n "$api_pid" ]; then
|
||||||
|
# ждём завершения API и прокидываем его код возврата в Docker
|
||||||
|
set +e
|
||||||
|
wait "$api_pid"
|
||||||
|
rc=$?
|
||||||
|
set -e
|
||||||
|
log "awg-api завершился с кодом $rc"
|
||||||
|
exit "$rc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log 'активных процессов нет (agent #22 и api #31 ещё не реализованы) — ожидание сигнала'
|
||||||
|
while :; do
|
||||||
|
sleep 3600 &
|
||||||
|
wait $!
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user