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

WireGuard VPS Tunnel — Docker Edition

Автоматическая настройка WireGuard-туннеля в Docker-контейнерах между VPS (с публичным IP) и домашним сервером за NAT (Raspberry Pi, Orange Pi, Starlink и т.д.).

Поддерживаемые архитектуры: linux/amd64 (Intel/AMD VPS) и linux/arm64 (Raspberry Pi 4/5, Orange Pi).

Архитектура

                          Интернет
                             │
                    ┌────────┴────────┐
                    │   VPS (сервер)   │
                    │  Публичный IP    │
                    │  например:       │
                    │  2.59.219.234    │
                    │                  │
                    │ ┌──────────────┐ │
                    │ │   Docker     │ │
                    │ │ wireguard-   │ │
                    │ │ server       │ │
                    │ │              │ │
                    │ │ wg0:10.0.0.1 │ │
                    │ │ :51820 (UDP) │ │
                    │ │              │ │
                    │ │ iptables     │ │
                    │ │ DNAT:        │ │
                    │ │ :80→10.0.0.2 │ │
                    │ │ :443→10.0.0.2│ │
                    │ └──────┬───────┘ │
                    └────────┼────────┘
                             │
              ╔══════════════╧══════════════╗
              ║  WireGuard UDP :51820       ║
              ║  (PersistentKeepalive=21)   ║
              ╚══════════════╤══════════════╝
                             │
                    ┌────────┴────────┐
                    │  Домашний сервер │
                    │  (за NAT/CGNAT) │
                    │  Raspberry Pi   │
                    │  Starlink       │
                    │                 │
                    │ ┌──────────────┐│
                    │ │   Docker     ││
                    │ │ wireguard-   ││
                    │ │ client       ││
                    │ │              ││
                    │ │ wg0:10.0.0.2 ││
                    │ │              ││
                    │ │ Watchdog     ││
                    │ │ (встроенный) ││
                    │ └──────┬───────┘│
                    └────────┼────────┘
                             │
                    ┌────────┴────────┐
                    │  Nginx Proxy    │
                    │  Manager :80,443│
                    │  → backend      │
                    └─────────────────┘

Как это работает:

  1. VPS принимает входящие соединения на порты 80 и 443
  2. iptables (внутри Docker-контейнера) перенаправляет трафик через WireGuard-туннель на домашний сервер (10.0.0.2)
  3. Домашний сервер (RPi) инициирует соединение с VPS — работает через любой NAT
  4. PersistentKeepalive = 21 секунда поддерживает туннель активным даже при отсутствии трафика
  5. Встроенный Watchdog на клиенте мониторит состояние туннеля и перезапускает при обрыве
  6. Всё изолировано в Docker-контейнерах — не затрагивает хост-систему

Быстрый старт (1 команда)

На VPS:

git clone http://192.168.2.28:3000/OpenDoor/wireguard-vps-tunnel.git
cd wireguard-vps-tunnel
sudo ./install.sh --vps --ports 80,443

На домашнем сервере (Raspberry Pi / Orange Pi):

git clone http://192.168.2.28:3000/OpenDoor/wireguard-vps-tunnel.git
cd wireguard-vps-tunnel
sudo ./install.sh --client --vps-ip 2.59.219.234

Примечание: Docker-образы автоматически выбираются под архитектуру вашего устройства (amd64 для VPS, arm64 для Raspberry Pi). Сборка не требуется — образы загружаются из Gitea Container Registry. Для локальной сборки добавьте флаг --build.

Ручная установка через Docker Compose

1. Клонирование репозитория

git clone http://192.168.2.28:3000/OpenDoor/wireguard-vps-tunnel.git
cd wireguard-vps-tunnel

2. Генерация ключей

# Установите wireguard-tools если ещё нет
sudo apt-get install -y wireguard-tools

# Сгенерируйте ключи
mkdir -p config
wg genkey | tee config/server_private.key | wg pubkey > config/server_public.key
wg genkey | tee config/client_private.key | wg pubkey > config/client_public.key
chmod 600 config/*.key

3. Настройка VPS (сервер)

Создайте .env файл:

CLIENT_PUBLIC_KEY=<ключ из config/client_public.key>
SERVER_PUBLIC_IP=2.59.219.234
FORWARD_PORTS=80,443

Запустите:

sudo docker compose -f docker-compose.server.yml up -d

4. Настройка клиента (домашний сервер)

Создайте .env файл:

VPS_PUBLIC_IP=2.59.219.234
SERVER_PUBLIC_KEY=<ключ из config/server_public.key>
PERSISTENT_KEEPALIVE=21

Запустите:

sudo docker compose -f docker-compose.client.yml up -d

5. Проверка

# На VPS
docker exec wireguard-server wg show
docker exec wireguard-server ping 10.0.0.2

# На домашнем сервере
docker exec wireguard-client wg show
docker exec wireguard-client ping 10.0.0.1

Обмен ключами (пошагово)

Шаг 1: На VPS — генерация ключей и запуск

sudo ./install.sh --vps --ports 80,443

Скрипт выведет публичный ключ сервера. Скопируйте его.

Шаг 2: На клиенте — запуск с ключом сервера

# Отредактируйте .env, вставив SERVER_PUBLIC_KEY из шага 1
sudo ./install.sh --client --vps-ip 2.59.219.234

Скрипт выведет публичный ключ клиента. Скопируйте его.

Шаг 3: На VPS — добавление ключа клиента

# Отредактируйте .env, вставив CLIENT_PUBLIC_KEY из шага 2
# Перезапустите контейнер:
sudo docker compose -f docker-compose.server.yml up -d --force-recreate

Переменные окружения

Сервер (VPS)

Переменная По умолчанию Описание
CLIENT_PUBLIC_KEY обязательно Публичный ключ клиента
SERVER_WG_IP 10.0.0.1 WireGuard IP сервера
SERVER_WG_PORT 51820 Порт WireGuard
FORWARD_PORTS 80,443 Порты для проброса (через запятую)
SERVER_PUBLIC_IP авто Публичный IP VPS
SERVER_PUBLIC_IFACE авто Внешний сетевой интерфейс

Клиент (домашний сервер)

Переменная По умолчанию Описание
VPS_PUBLIC_IP обязательно Публичный IP VPS
SERVER_PUBLIC_KEY обязательно Публичный ключ сервера
CLIENT_WG_IP 10.0.0.2 WireGuard IP клиента
VPS_WG_PORT 51820 Порт WireGuard на VPS
PERSISTENT_KEEPALIVE 21 Интервал keepalive (сек)

Опции командной строки (install.sh)

Опция Описание По умолчанию
--vps Режим VPS (сервер)
--client Режим клиента (домашний сервер)
--vps-ip IP Публичный IP VPS автоопределение
--ports PORT,... Порты для проброса (VPS) 80,443
--wg-port PORT Порт WireGuard 51820
--keepalive SEC PersistentKeepalive (сек) 21
--build Локальная сборка образа (вместо загрузки из registry) pull

Watchdog (мониторинг туннеля)

Watchdog встроен в клиентский контейнер и выполняет:

  1. Проверяет, что интерфейс wg0 поднят
  2. Проверяет доступность VPS через туннель (ping 10.0.0.1)
  3. Проверяет доступность VPS через интернет (ping VPS_IP)
  4. Если туннель не работает, но VPS доступен — перезапускает WireGuard
  5. Использует экспоненциальную отсрочку при повторных сбоях:
    • 10с → 20с → 40с → 80с → 120с (максимум)
  6. После 3 успешных проверок подряд сбрасывает отсрочку

Просмотр логов:

docker compose -f docker-compose.client.yml logs -f

Starlink использует CGNAT (Carrier-Grade NAT), что означает:

  • Нет публичного IPv4 — домашний сервер недоступен из интернета напрямую
  • Высокая задержка — 25-60 мс (спутниковая связь)
  • Кратковременные обрывы — при переключении между спутниками
  • UDP работает лучше TCP — меньше проблем с TCP congestion control

Рекомендации для Starlink:

  1. PERSISTENT_KEEPALIVE=21 — оптимальное значение (каждые 21 сек отправляет keepalive-пакет)
  2. Watchdog обязателен — автоматически восстанавливает туннель после обрывов
  3. Не используйте SSH reverse tunnel — TCP-over-TCP на спутниковом канале работает плохо
  4. MTU = 1420 (стандартный для WireGuard) — не меняйте без необходимости

Multi-Arch (Поддержка архитектур)

Docker-образы собираются автоматически для двух архитектур:

Архитектура Устройства Образ
linux/amd64 VPS (Intel/AMD), десктопы git.softuniq.eu/opendoor/wireguard-vps-tunnel-server:latest
linux/arm64 Raspberry Pi 4/5, Orange Pi, Mac M1/M2 git.softuniq.eu/opendoor/wireguard-vps-tunnel-client:latest

Установщик автоматически определяет архитектуру хоста и загружает соответствующий образ. Принудительная локальная сборка:

# Собрать образ локально (для текущей архитектуры)
sudo ./install.sh --vps --build

# Или через docker compose
docker compose -f docker-compose.server.yml build
docker compose -f docker-compose.client.yml build

CI/CD

При пуше в ветку main или создании тега v* Gitea Actions автоматически собирает и пушит multi-arch образы:

  • git.softuniq.eu/opendoor/wireguard-vps-tunnel-server:latest
  • git.softuniq.eu/opendoor/wireguard-vps-tunnel-client:latest

Сборка использует QEMU для кросс-компиляции и Docker Buildx для multi-arch образов.

Сравнение: Docker vs Host-Based

Критерий Docker Host-Based
Изоляция Полная (контейнер) Нет (хост-система)
Зависимости Только Docker wireguard-tools, iptables, systemd
Multi-arch amd64 + arm64 Ручная установка под каждую ОС
Обновление docker compose pull && up -d Ручная замена скриптов
Откат docker compose down && up (предыдущий образ) Ручной откат конфигов
Переносимость Любой Linux с Docker Debian/Ubuntu/Armbian
Безопасность Минимальная поверхность атаки (Alpine) Полный доступ к хосту
Watchdog Встроен в контейнер Отдельный systemd-сервис
Логи docker logs journald + файлы
Ресурсы ~15 МБ образ, ~20 МБ RAM ~5 МБ RAM (без контейнера)

Сравнение: WireGuard vs SSH Reverse Tunnel

Критерий WireGuard SSH Reverse Tunnel
Протокол UDP (kernel) TCP (userspace)
Производительность ~1 Gbps ~100 Mbps
Задержка Минимальная TCP-over-TCP проблема
Starlink Оптимально (UDP) Плохо (TCP через TCP)
Переподключение Мгновенное Заметная задержка
NAT traversal PersistentKeepalive Autossh + мониторинг
Проброс портов iptables DNAT ssh -R
Отказоустойчивость Встроенная Требует autossh
Нагрузка на CPU Минимальная (kernel) Заметная (шифрование в userspace)

Устранение неполадок

Контейнер не запускается

# Проверить логи
docker compose -f docker-compose.server.yml logs
docker compose -f docker-compose.client.yml logs

# Проверить статус
docker compose -f docker-compose.server.yml ps
docker compose -f docker-compose.client.yml ps

Туннель не поднимается

# Проверить статус WireGuard внутри контейнера
docker exec wireguard-server wg show
docker exec wireguard-client wg show

# Проверить, что порт открыт на VPS
nc -zvu <VPS_IP> 51820

Порты не пробрасываются

# Проверить правила iptables внутри контейнера
docker exec wireguard-server iptables -t nat -L PREROUTING -n
docker exec wireguard-server iptables -L FORWARD -n

# Проверить IP-форвардинг
docker exec wireguard-server sysctl net.ipv4.ip_forward

Пинг не проходит

# Проверить что интерфейс поднят
docker exec wireguard-server ip link show wg0
docker exec wireguard-client ip link show wg0

# Проверить IP-адреса
docker exec wireguard-server ip addr show wg0
docker exec wireguard-client ip addr show wg0

Полный сброс и переустановка

# Деинсталляция
sudo ./uninstall.sh --remove-images --remove-config

# Переустановка
sudo ./install.sh --vps --ports 80,443

Деинсталляция

sudo ./uninstall.sh

Опции:

  • --remove-images — также удалить Docker-образы
  • --remove-config — также удалить директорию config/ с ключами и .env

Деинсталлятор:

  • Останавливает и удаляет Docker-контейнеры
  • Опционально удаляет образы и конфигурацию
  • НЕ трогает SSH-сервер, Docker и другие сервисы
  • НЕ изменяет sshd_config (PasswordAuthentication остаётся без изменений)

Безопасность

  • Ключи: приватные ключи хранятся с правами 600 (только root)
  • Изоляция: контейнеры работают в изолированном окружении (Alpine Linux)
  • Фаервол: iptables правила применяются атомарно через PostUp/PostDown
  • SSH: парольная аутентификация НЕ отключается — скрипт не трогает sshd_config
  • Порты: открываются только указанные порты (по умолчанию 80 и 443)
  • WireGuard: использует современную криптографию (Curve25519, ChaCha20, BLAKE2s)
  • Docker: --cap-add=NET_ADMIN --cap-add=SYS_MODULE — минимально необходимые capabilities
  • Read-only: /lib/modules монтируется в режиме ro (только чтение)

Структура проекта

wireguard-vps-tunnel/
├── server/
│   ├── Dockerfile           # Docker-образ сервера (Alpine 3.20)
│   ├── entrypoint.sh        # Точка входа: генерация конфига, запуск WG
│   └── healthcheck.sh       # Healthcheck: wg show wg0
├── client/
│   ├── Dockerfile           # Docker-образ клиента (Alpine 3.20)
│   ├── entrypoint.sh        # Точка входа: генерация конфига, запуск WG + watchdog
│   ├── watchdog.sh          # Watchdog: мониторинг и автовосстановление туннеля
│   └── healthcheck.sh       # Healthcheck: ping VPS WG IP
├── docker-compose.server.yml # Docker Compose для VPS
├── docker-compose.client.yml # Docker Compose для клиента
├── .env.example             # Шаблон переменных окружения
├── install.sh               # 1-Click установщик (Docker)
├── uninstall.sh             # Деинсталлятор (Docker)
├── .dockerignore            # Исключения для сборочного контекста
├── .gitea/
│   └── workflows/
│       └── build.yml        # CI/CD: сборка Docker-образов
└── README.md                # Документация

Поддерживаемые ОС

  • Любой Linux с Docker 20.10+
  • Debian 11+ (Bullseye, Bookworm)
  • Ubuntu 20.04+ (Focal, Jammy, Noble)
  • Armbian (Orange Pi, Banana Pi, etc.)
  • Raspberry Pi OS (Raspbian)

Лицензия

MIT

Description
WireGuard VPN туннель между VPS и домашним сервером (Starlink-оптимизированный). Установка в 1 клик.
Readme 115 KiB
2026-07-29 19:39:08 +00:00
Languages
Shell 97.4%
Dockerfile 2.6%