WireGuard Server + Client Automation
Проект автоматизирует установку и настройку WireGuard-сервера и WireGuard-клиента на Debian/Ubuntu.
Основная идея: один репозиторий с понятными Bash-скриптами для быстрого разворачивания и переустановки WireGuard-стека.
Назначение проекта
- Быстро развернуть WireGuard-сервер (
wg-quick@wg0) с автозапуском черезsystemd. - Включить IP forwarding и NAT для выхода клиентов в интернет через сервер.
- Установить легкий GUI для управления (
wireguard-uiв Docker). - Автоматизировать добавление клиента с клиентской машины через SSH на сервер.
- Поддержать 2 режима маршрутизации клиента:
- полный туннель (весь трафик через VPN)
- выборочный туннель (только заданные сети)
Поддерживаемые ОС
- Debian 11/12
- Ubuntu 22.04/24.04
Скрипты ориентированы на Debian-family (APT, systemd).
Структура проекта
README.md.gitignorelib/common.sh— общие функцииbootstrap/install_wg_install.sh— установка короткой командыwg-installtemplates/wg0.conf.template— шаблон базовогоwg0.confserver/install_server.sh— установка сервера + GUIserver/wg-peerctl.sh— helper для регистрации peer на сервереclient/install_client.sh— установка и автонастройка клиента
Архитектура решения
- Сервер разворачивается нативно на
wg-quick+systemd(стабильность после reboot). - GUI (
wireguard-ui) запускается в Docker, но работает с тем же/etc/wireguard, где лежит серверный конфиг. - На сервере ставится
wg-syncconf@wg0.path: при изменении/etc/wireguard/wg0.conf(в том числе послеApplyв GUI) конфиг автоматически применяется в живой интерфейсwg0. - Клиентский скрипт:
- генерирует ключи локально,
- подключается к серверу по SSH,
- вызывает
/usr/local/sbin/wg-peerctl add ..., - получает параметры подключения,
- пишет локальный
/etc/wireguard/wg0.conf, - запускает и включает
wg-quick@wg0. Каждый запуск клиентского установщика сначала очищает старые клиентские ключи/конфиг выбранного интерфейса и поднимает клиента заново.
Почему выбран GUI wireguard-ui
- Легкий для VPS (один контейнер).
- Понятный веб-интерфейс.
- Не требует переносить основной WireGuard в Docker: VPN остается в нативном
systemd. - Проще обслуживание: серверная сеть и NAT остаются под полным контролем Bash-скрипта.
- GUI не разрабатывается в этом проекте с нуля: используется готовый
wireguard-ui, а проект автоматизирует его установку и настройку.
Какие пакеты устанавливаются
Сервер
wireguard,wireguard-toolsiproute2,iptablescurl,ca-certificates,openssl,qrencodedocker.ioи один из пакетов:docker-compose-pluginилиdocker-compose(в зависимости от версии ОС/репозиториев)
Клиент
wireguard,wireguard-toolsiproute2openssh-client,sshpassca-certificates
Установка сервера
- Клонировать/открыть репозиторий.
- Запустить:
sudo bash server/install_server.sh
Важно: серверный установщик теперь всегда выполняет полный reset прошлого состояния (/etc/wireguard + wireguard-ui data/db) и поднимает всё заново.
Запуск сервера одной командой (без git clone)
tmp="$(mktemp -d)" && curl -fL "https://git.ruslan.xyz/ruslan/Wireguard_server/archive/main.tar.gz" -o "$tmp/repo.tar.gz" && tar -xzf "$tmp/repo.tar.gz" -C "$tmp" && bash "$tmp/wireguard_server/server/install_server.sh"
Короткая команда wg-install (установить один раз)
Из локального репозитория:
sudo bash bootstrap/install_wg_install.sh
После этого запуск сервера:
sudo wg-install
С аргументами тоже работает:
sudo wg-install --non-interactive --server-public-ip 203.0.113.10 --default-iface eth0
Установка wg-install без git clone:
tmp="$(mktemp -d)" && curl -fL "https://git.ruslan.xyz/ruslan/Wireguard_server/archive/main.tar.gz" -o "$tmp/repo.tar.gz" && tar -xzf "$tmp/repo.tar.gz" -C "$tmp" && sudo bash "$tmp/wireguard_server/bootstrap/install_wg_install.sh"
Скрипт интерактивно спросит недостающие данные:
- публичный IP (если не определился автоматически)
- порт WireGuard
- параметры GUI (логин/пароль)
Если пароль GUI не передан аргументом, скрипт генерирует случайный пароль из 8 символов. В интерактивном режиме можно ответить y и ввести новый пароль отдельным шагом или сразу ввести пароль в том же вопросе.
Non-interactive пример
sudo bash server/install_server.sh \
--non-interactive \
--wg-interface wg0 \
--wg-port 51820 \
--wg-network 10.66.66.0/24 \
--wg-address 10.66.66.1/24 \
--server-public-ip 203.0.113.10 \
--default-iface eth0 \
--gui-enable yes \
--gui-host vpn.example.com \
--gui-port 5000 \
--gui-user admin \
--gui-password 'StrongPass123!'
Установка клиента
Запускать на клиентской машине:
sudo bash client/install_client.sh
Важно: клиентский установщик теперь всегда выполняет reset старой конфигурации для выбранного интерфейса (wg0 по умолчанию): удаляет клиентские ключи/конфиг и создает их заново.
Запуск клиента одной командой (без git clone)
tmp="$(mktemp -d)" && curl -fL "https://git.ruslan.xyz/ruslan/Wireguard_server/archive/main.tar.gz" -o "$tmp/repo.tar.gz" && tar -xzf "$tmp/repo.tar.gz" -C "$tmp" && sudo bash "$tmp/wireguard_server/client/install_client.sh"
Скрипт попросит:
- адрес сервера
- SSH-учетные данные
- режим маршрутизации (full/split)
- список сетей (если
split)
Non-interactive пример (SSH-ключ)
sudo bash client/install_client.sh \
--non-interactive \
--server-host 203.0.113.10 \
--server-user root \
--ssh-auth key \
--mode full \
--client-name laptop-01
Non-interactive пример (SSH-пароль)
sudo bash client/install_client.sh \
--non-interactive \
--server-host 203.0.113.10 \
--server-user root \
--ssh-auth password \
--ssh-password 'your_password' \
--mode split \
--allowed-ips 10.0.0.0/8,192.168.0.0/16 \
--client-name laptop-02
Как создаются ключи
- Сервер:
/etc/wireguard/server_private.keyи/etc/wireguard/server_public.key. - Клиент:
/etc/wireguard/wg0_client_private.key,..._public.key,..._psk.key. - При каждом запуске серверного установщика серверные ключи создаются заново (так как выполняется полный reset).
Как задаются маршруты
Клиентский скрипт поддерживает режимы:
full—AllowedIPs = 0.0.0.0/0,::/0split—AllowedIPsзадается списком сетей
Для full добавляется route-exception до IP WireGuard-сервера, чтобы не потерять SSH/доступ при переключении default route.
Как включается автозапуск
Используется systemd:
- Сервер:
wg-quick@wg0.service - Клиент:
wg-quick@wg0.service
Скрипты выполняют systemctl enable --now ....
Как открыть GUI
После установки сервера GUI доступен по адресу:
http://<GUI_HOST>:<GUI_PORT>
Пример:
http://203.0.113.10:5000
Логин/пароль задаются во время установки сервера.
Как получить QR для iPhone в GUI
- Откройте GUI по ссылке из итоговой сводки установки.
- Перейдите в раздел клиентов (
Clients). - Создайте клиента (
New Client) или выберите существующего. - Нажмите кнопку показа QR (или
Show QR) у клиента. - На iPhone: WireGuard →
Add Tunnel→Create from QR codeи отсканируйте код.
В установщике уже задаются дефолты GUI для корректной генерации клиентских конфигов: endpoint, DNS, порт и путь к wg0.conf.
Взаимодействие клиента с сервером
- Клиент генерирует локальные ключи.
- Клиент по SSH вызывает на сервере
wg-peerctl add. - Серверный helper:
- выделяет IP клиенту внутри VPN-сети,
- добавляет peer идемпотентно,
- применяет конфиг,
- возвращает параметры подключения.
- Клиент собирает локальный
wg0.conf, запускает интерфейс и автозапуск.
Примеры использования
Проверка статуса на сервере
sudo systemctl status wg-quick@wg0
sudo wg show
Ручное добавление peer через helper
sudo /usr/local/sbin/wg-peerctl add \
--client-name test-client \
--client-public-key '<client_pub_key>'
Проверка клиента
sudo wg show
ip route
curl -4 ifconfig.me
Безопасность и ограничения
- Приватные ключи не пишутся в лог.
- Конфиги и ключи сохраняются с ограниченными правами (
600). - Перед перезаписью конфигов делаются backup-файлы.
- SSH по паролю поддержан, но менее безопасен, чем SSH-ключи.
- В non-interactive режиме пароль в командной строке может попасть в shell history — лучше использовать SSH-ключ.
- Скрипты предполагают root-доступ на сервере для изменения
/etc/wireguardиsystemd. - GUI запускается без TLS по умолчанию (HTTP). Для production рекомендуется ставить reverse proxy (Nginx/Caddy) с HTTPS и ограничением доступа.
Диагностика и устранение проблем
- WireGuard не поднялся:
sudo systemctl status wg-quick@wg0
sudo journalctl -u wg-quick@wg0 -n 100 --no-pager
sudo wg show
- Не работает интернет у клиента:
ip route
sudo wg show
Проверьте AllowedIPs, ip_forward, NAT и внешний интерфейс сервера.
- Клиент не добавляется по SSH:
- Проверьте доступность SSH (
ssh user@server). - Проверьте, что на сервере установлен helper:
ls -l /usr/local/sbin/wg-peerctl
- GUI недоступен:
sudo docker ps
sudo docker logs wireguard-ui --tail=100
sudo ss -tulpn | grep 5000
Если при запуске встречается ошибка KeyError: 'ContainerConfig' (обычно на legacy docker-compose v1), перезапустите установщик из актуальной версии репозитория: в нем добавлена автоматическая очистка старого контейнера wireguard-ui перед запуском.
Для уже сломанного состояния можно вручную очистить старые контейнеры и запустить установщик снова:
docker ps -aq --filter 'label=com.docker.compose.service=wireguard-ui' | xargs -r docker rm -f
docker ps -a --format '{{.Names}}' | grep -E '(^|[_-])wireguard-ui($|[_-])' | xargs -r docker rm -f
Если клиенты из GUI создаются в неправильной подсети, просто перезапустите серверный установщик: теперь он автоматически очищает БД GUI и поднимает всё с нуля.
Важные пути
- Серверный конфиг:
/etc/wireguard/wg0.conf - Метаданные сервера:
/etc/wireguard/wg-meta.env - Клиентский конфиг:
/etc/wireguard/wg0.conf - Server install log:
/var/log/wireguard-server-install.log - Client install log:
/var/log/wireguard-client-install.log - Peer helper log:
/var/log/wireguard-peerctl.log
Справка по ключам
bash server/install_server.sh --help
bash client/install_client.sh --help
bash bootstrap/install_wg_install.sh