Files
wireguard-vps-tunnel/server/entrypoint.sh
Deploy Bot dcebf21e03
Some checks failed
Build and Push Docker Images / Сборка сервера (multi-arch) (push) Has been cancelled
Build and Push Docker Images / Сборка клиента (multi-arch) (push) Has been cancelled
fix: restart-safe entrypoints, remove obsolete compose version
- Add wg0 interface cleanup before startup (prevents 'already exists' crash)
- Always regenerate wg0.conf to pick up key changes
- Remove obsolete 'version' from docker-compose files
- Fix read-only /proc/sys writes (host-level ip_forward already set)
2026-07-30 00:30:18 +01:00

145 lines
7.2 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# =============================================================================
# WireGuard VPS Tunnel — точка входа сервера (VPS)
# Генерирует конфигурацию wg0.conf из переменных окружения и поднимает туннель.
# =============================================================================
set -euo pipefail
# ── Значения по умолчанию ───────────────────────────────────────────────────
SERVER_WG_IP="${SERVER_WG_IP:-10.0.0.1}"
SERVER_WG_PORT="${SERVER_WG_PORT:-51820}"
FORWARD_PORTS="${FORWARD_PORTS:-80,443}"
WG_CONF="/etc/wireguard/wg0.conf"
# ── Логирование ─────────────────────────────────────────────────────────────
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$1] $*"; }
# ── Автоопределение внешнего интерфейса и IP ────────────────────────────────
detect_network() {
if [[ -z "${SERVER_PUBLIC_IFACE:-}" ]]; then
SERVER_PUBLIC_IFACE=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $5; exit}')
if [[ -z "$SERVER_PUBLIC_IFACE" ]]; then
log "ERROR" "Не удалось определить внешний сетевой интерфейс"
exit 1
fi
log "INFO" "Автоопределён внешний интерфейс: ${SERVER_PUBLIC_IFACE}"
fi
if [[ -z "${SERVER_PUBLIC_IP:-}" ]]; then
SERVER_PUBLIC_IP=$(curl -4 -s ifconfig.me 2>/dev/null || curl -4 -s icanhazip.com 2>/dev/null || echo "")
if [[ -z "$SERVER_PUBLIC_IP" ]]; then
log "ERROR" "Не удалось определить публичный IP. Укажите SERVER_PUBLIC_IP"
exit 1
fi
log "INFO" "Автоопределён публичный IP: ${SERVER_PUBLIC_IP}"
fi
}
# ── Генерация ключей ───────────────────────────────────────────────────────
generate_keys() {
local private_key_file="/etc/wireguard/server_private.key"
local public_key_file="/etc/wireguard/server_public.key"
if [[ -f "$private_key_file" ]] && [[ -f "$public_key_file" ]]; then
log "INFO" "Ключи сервера уже существуют"
else
log "INFO" "Генерация ключей сервера..."
wg genkey | tee "$private_key_file" | wg pubkey > "$public_key_file"
chmod 600 "$private_key_file"
log "INFO" "Ключи сервера сгенерированы"
fi
SERVER_PRIVATE_KEY=$(cat "$private_key_file")
SERVER_PUBLIC_KEY=$(cat "$public_key_file")
}
# ── Создание конфигурации WireGuard ────────────────────────────────────────
create_wg_config() {
# Всегда пересоздаём конфиг — ключи или порты могли измениться
if [[ -f "$WG_CONF" ]]; then
log "INFO" "Обновление конфигурации ${WG_CONF}..."
rm -f "$WG_CONF"
fi
if [[ -z "${CLIENT_PUBLIC_KEY:-}" ]]; then
log "ERROR" "CLIENT_PUBLIC_KEY не задан. Укажите публичный ключ клиента."
exit 1
fi
local client_wg_ip="${CLIENT_WG_IP:-10.0.0.2}"
# Формируем правила DNAT для каждого порта
local dnat_rules=""
local dnat_down_rules=""
IFS=',' read -ra PORT_ARRAY <<< "$FORWARD_PORTS"
for port in "${PORT_ARRAY[@]}"; do
port=$(echo "$port" | xargs)
dnat_rules+="iptables -t nat -A PREROUTING -d ${SERVER_PUBLIC_IP} -p tcp --dport ${port} -j DNAT --to-destination ${client_wg_ip}:${port}; "
dnat_down_rules+="iptables -t nat -D PREROUTING -d ${SERVER_PUBLIC_IP} -p tcp --dport ${port} -j DNAT --to-destination ${client_wg_ip}:${port}; "
done
mkdir -p "$(dirname "$WG_CONF")"
cat > "$WG_CONF" <<WGCONF
# WireGuard VPS Tunnel — конфигурация сервера (VPS)
# Создано: $(date '+%Y-%m-%d %H:%M:%S')
[Interface]
PrivateKey = ${SERVER_PRIVATE_KEY}
Address = ${SERVER_WG_IP}/24
ListenPort = ${SERVER_WG_PORT}
PostUp = ${dnat_rules} iptables -t nat -A POSTROUTING -d ${client_wg_ip} -j MASQUERADE; iptables -I FORWARD 1 -i ${SERVER_PUBLIC_IFACE} -o wg0 -p tcp -m multiport --dports ${FORWARD_PORTS} -j ACCEPT; iptables -I FORWARD 2 -i wg0 -o ${SERVER_PUBLIC_IFACE} -m state --state ESTABLISHED,RELATED -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = ${dnat_down_rules} iptables -t nat -D POSTROUTING -d ${client_wg_ip} -j MASQUERADE; iptables -D FORWARD -i ${SERVER_PUBLIC_IFACE} -o wg0 -p tcp -m multiport --dports ${FORWARD_PORTS} -j ACCEPT; iptables -D FORWARD -i wg0 -o ${SERVER_PUBLIC_IFACE} -m state --state ESTABLISHED,RELATED -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT
[Peer]
# Клиент (домашний сервер / Raspberry Pi)
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = ${client_wg_ip}/32
WGCONF
chmod 600 "$WG_CONF"
log "INFO" "Конфигурация WireGuard создана: ${WG_CONF}"
}
# ── Запуск WireGuard ───────────────────────────────────────────────────────
start_wireguard() {
log "INFO" "Запуск WireGuard интерфейса wg0..."
# Включаем IP-форвардинг (может быть read-only в Docker, хост уже настроен)
echo 1 > /proc/sys/net/ipv4/ip_forward 2>/dev/null || true
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding 2>/dev/null || true
# Удаляем старый интерфейс если остался от предыдущего запуска
if ip link show wg0 &>/dev/null; then
log "INFO" "Удаление старого интерфейса wg0..."
ip link del wg0 2>/dev/null || true
sleep 1
fi
wg-quick up wg0
log "INFO" "WireGuard интерфейс wg0 запущен"
log "INFO" "Публичный ключ сервера: ${SERVER_PUBLIC_KEY}"
log "INFO" "Скопируйте его на клиент: SERVER_PUBLIC_KEY=${SERVER_PUBLIC_KEY}"
}
# ── Главная функция ────────────────────────────────────────────────────────
main() {
log "INFO" "=== Запуск WireGuard VPS Tunnel (сервер) ==="
log "INFO" "SERVER_WG_IP=${SERVER_WG_IP}"
log "INFO" "SERVER_WG_PORT=${SERVER_WG_PORT}"
log "INFO" "FORWARD_PORTS=${FORWARD_PORTS}"
detect_network
generate_keys
create_wg_config
start_wireguard
log "INFO" "Сервер запущен. Ожидание..."
exec sleep infinity
}
main