Files
wireguard-vps-tunnel/server/entrypoint.sh
Deploy Bot 5d618a04b5
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
feat: multi-arch Docker образы (amd64+arm64), CI/CD, registry
- Dockerfile с multi-stage сборкой для linux/amd64 и linux/arm64
- Gitea Actions CI/CD для автоматической сборки и пуша в registry
- docker-compose с поддержкой multi-arch образов
- install.sh с автоопределением архитектуры и выбором: pull vs build
- uninstall.sh обновлён для Docker-деинсталляции
- README.md обновлён: multi-arch, CI/CD, Gitea registry
2026-07-29 20:38:47 +01:00

137 lines
6.7 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} уже существует, пропускаем создание"
return 0
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-форвардинг
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
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