Skip to content

About

WireGuard VPN installer for Linux servers

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

172 Commits

Folders and files

Repository files navigation

Установщик WireGuard

Проверки кода

Bash-скрипт для установки WireGuard на Linux-сервере и управления VPN-клиентами. Это форк angristan/wireguard-install, дополненный режимом самостоятельного управления межсетевым экраном — например, через nftables.

Клиент направляет выбранный трафик через зашифрованный туннель на сервер. При использовании masquerade сайты видят внешний адрес сервера. Скрипт создаёт конфигурации IPv4 и IPv6.

Требования

Нужен доступ root. Скрипт предусматривает следующие дистрибутивы (этот список не означает, что все версии проверены в данном форке):

  • AlmaLinux >= 8
  • Alpine Linux
  • Arch Linux
  • CentOS Stream >= 8
  • Debian >= 10
  • Fedora >= 32
  • Oracle Linux
  • Rocky Linux >= 8
  • Ubuntu >= 18.04

Установка и управление клиентами

Скачайте все три файла в один каталог и запустите установщик от root. Меню использует соседние файлы для бэкапа и восстановления:

curl -fO https://raw.githubusercontent.com/rmtshnik/wireguard-install/master/wireguard-install.sh
curl -fO https://raw.githubusercontent.com/rmtshnik/wireguard-install/master/wireguard-backup.sh
curl -fO https://raw.githubusercontent.com/rmtshnik/wireguard-install/master/wireguard-restore.py
chmod +x wireguard-install.sh
./wireguard-install.sh

Ответьте на вопросы установщика. Он установит WireGuard и необходимые инструменты, создаст конфигурацию сервера, настроит службу systemd (OpenRC на Alpine) и предложит создать первого клиента.

Сеть VPN выбирайте самостоятельно: она не должна пересекаться с сетями сервера, клиентов и другими сетями, к которым нужен доступ. Текущий скрипт использует маску /24 для IPv4 и /64 для IPv6. Для совместимости с выдачей клиентских адресов используйте адрес сервера вида X.Y.Z.1 и IPv6-адрес вида fdXX:XXXX:XXXX::1.

Например, для выбранной сети 10.66.66.0/24 адрес сервера будет 10.66.66.1. Это только пример, а не обязательная сеть.

Повторный запуск открывает меню:

1) Добавить клиента
2) Показать клиентов
3) Отозвать клиента
4) Создать резервную копию
5) Восстановить из резервной копии
6) Удалить WireGuard
7) Выход

Если /etc/wireguard/params ещё нет, доступны установка, восстановление и выход. Восстановление не запускает установку пакетов: заранее установите WireGuard, Python 3.8+ и службу wg-quick. Например, для Debian 11+/Ubuntu 20.04+: sudo apt update && sudo apt install wireguard python3. Для Alpine заранее подготовьте OpenRC-службу wg-quick.ИМЯ_ИНТЕРФЕЙСА. Пункт восстановления сообщает о недостающих инструментах; зависимости автоматически не скачиваются.

Управление межсетевым экраном

При установке введите номер режима: 1 или 2. Нажатие Enter выбирает 1 (auto).

  • 1) auto — режим по умолчанию. Скрипт добавляет команды firewalld либо iptables в PostUp/PostDown: правила создаются при запуске интерфейса и удаляются при его остановке.
  • 2) external — правилами управляете вы. Скрипт не добавляет firewall-хуки и не запрашивает установку iptables. Используйте этот режим, если уже настраиваете nftables самостоятельно.

В обоих режимах скрипт включает маршрутизацию IPv4 и IPv6 через /etc/sysctl.d/wg.conf. Выбор сохраняется в /etc/wireguard/params. Добавление и отзыв клиентов не меняют правила firewall. При удалении установки в режиме external ваши правила nftables сохраняются.

Пример правил nftables

Не забудьте добавить разрешающие правила в ваш nftables перед подключением клиентов. Нужны:

  1. Входящий UDP на порт WireGuard.
  2. Пересылка трафика из VPN во внешний интерфейс.
  3. Пересылка ответного трафика обратно в VPN.
  4. Masquerade для выбранной частной IPv4-сети, если у неё нет отдельной маршрутизации в интернете.

Замените параметры примера своими значениями. Порт должен совпадать с ListenPort в конфигурации сервера: установщик предлагает случайный порт, не обязательно 51820.

# Параметры в начале вашего файла nftables
define WAN_IF = "ens3"
define WG_IF = "wg0"
define WG_PORT = 51820
define WG_NET4 = 10.66.66.0/24

Ниже показаны фрагменты существующих цепочек, а не готовая замена вашего firewall. Вставьте правила в соответствующие цепочки перед подходящими правилами drop/reject. Не создавайте повторно таблицы и цепочки, если они уже есть, и не добавляйте дубли существующих правил.

table inet filter {
    # ============================================================
    # ЦЕПОЧКА INPUT — ВХОДЯЩИЙ ТРАФИК К СЕРВЕРУ
    # ============================================================
    chain input {
        # В существующей цепочке сохраняются hook, policy и остальные правила
        iifname $WAN_IF udp dport $WG_PORT accept
    }

    # ============================================================
    # ЦЕПОЧКА FORWARD — ТРАФИК МЕЖДУ ИНТЕРФЕЙСАМИ
    # ============================================================
    chain forward {
        iifname $WG_IF oifname $WAN_IF ip saddr $WG_NET4 accept
        iifname $WAN_IF oifname $WG_IF ip daddr $WG_NET4 ct state established,related accept
    }
}

Правило NAT поместите в существующую цепочку postrouting. Если таблицы и цепочки NAT ещё нет, её структура может выглядеть так:

table ip nat {
    # ============================================================
    # ЦЕПОЧКА POSTROUTING — ПОДМЕНА АДРЕСА ПРИ ВЫХОДЕ В ИНТЕРНЕТ
    # ============================================================
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        ip saddr $WG_NET4 oifname $WAN_IF masquerade
    }
}

Пример предполагает, что остальные правила вашего firewall разрешают необходимый служебный трафик и исходящий трафик сервера. Правила доступа к сервисам самого сервера через VPN добавляются отдельно в input.

Сохраните изменения в постоянной конфигурации вашей системы. Для проверки полного файла без применения можно использовать nft -c -f /etc/nftables.conf, если ваша конфигурация находится по этому пути. Проверка синтаксиса не заменяет проверку соединения и порядка правил. Не очищайте действующий набор правил командой flush ruleset ради добавления VPN.

IPv6: включение и отключение

Что уже делает скрипт

Отдельного переключателя «включить/выключить IPv6» в текущем установщике нет. Он всегда запрашивает IPv6-адрес, добавляет IPv6 в конфигурации сервера и клиентов и включает net.ipv6.conf.all.forwarding = 1.

Параметр клиента AllowedIPs определяет, какой трафик направляется в туннель:

Значение Маршрутизация
0.0.0.0/0,::/0 Весь IPv4 и IPv6 через VPN
0.0.0.0/0 Только IPv4 через VPN; IPv6 может идти напрямую через сеть клиента

Как использовать IPv6 через VPN

Необходимы следующие условия:

  • На сервере работает выход в IPv6-интернет: есть глобальный IPv6-адрес и маршрут по умолчанию.
  • IPv6 включён в сетевом стеке клиента и сервера; на интерфейсах WireGuard назначены IPv6-адреса.
  • У клиента в [Peer] указан AllowedIPs = 0.0.0.0/0,::/0.
  • На сервере включена IPv6-маршрутизация и разрешена пересылка в firewall.
  • Для частной ULA-сети VPN настроен NAT66 (masquerade). Альтернатива — выделенный провайдером глобальный префикс с маршрутом к VPN-клиентам; тогда NAT66 не нужен. Одного наличия глобального адреса на сервере для маршрутизации клиентского префикса недостаточно.

Для ULA-сети добавьте параметр, соответствующий вашей IPv6-сети WireGuard:

define WG_NET6 = fd42:42:42::/64

Дополните существующую цепочку forward таблицы inet filter:

# IPv6: из VPN в интернет и ответный трафик
iifname $WG_IF oifname $WAN_IF ip6 saddr $WG_NET6 accept
iifname $WAN_IF oifname $WG_IF ip6 daddr $WG_NET6 ct state established,related accept

Для ULA-адресов добавьте masquerade в IPv6 NAT:

table ip6 nat {
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        ip6 saddr $WG_NET6 oifname $WAN_IF masquerade
    }
}

IPv6 также требует служебного ICMPv6, включая обнаружение соседей и сообщения об ошибках/MTU. Не блокируйте его целиком. Если ваш firewall ещё не разрешает ICMPv6, простой вариант для существующей цепочки input таблицы inet filter:

meta l4proto ipv6-icmp accept

При ограничивающей политике output разрешите необходимый исходящий ICMPv6 и UDP WireGuard; также проверьте прохождение связанных ICMPv6-ошибок в forward. Подробности: пример nftables для IPv4/IPv6, документация nftables.

Если сервер получает маршрут IPv6 через Router Advertisement, включение forwarding может изменить приём RA. Для такого внешнего интерфейса может потребоваться net.ipv6.conf.ens3.accept_ra = 2 (замените ens3 своим интерфейсом). При статической настройке маршрутов это обычно не требуется.

Как исключить IPv6 из VPN

При установке введите 0.0.0.0/0 в поле AllowedIPs. Для существующих клиентов измените AllowedIPs в их конфигурациях и переподключите VPN. Чтобы это значение использовалось при создании новых клиентов, установите ALLOWED_IPS=0.0.0.0/0 в /etc/wireguard/params; уже выданные файлы автоматически не обновляются.

Это не отключает IPv6 на устройстве. Если сеть клиента предоставляет IPv6, приложения могут обращаться к сайтам напрямую, вне VPN. Если нужен VPN только с IPv4 без обхода через IPv6, дополнительно отключите IPv6 на клиенте либо заблокируйте его вне туннеля средствами клиентского firewall. Точный способ зависит от ОС клиента.

Полного отключения IPv6 на сервере через меню скрипта нет. Одно изменение AllowedIPs не удаляет IPv6-адреса, маршрутизацию или NAT. Не отключайте IPv6 системно на сервере ради этого параметра: его могут использовать другие службы. Для текущего режима external можно не добавлять IPv6-правила VPN, если IPv6 через туннель не используется.

Можно ли заходить на IPv6-сайты, подключившись к VPN по IPv4?

Да. Адрес Endpoint определяет, как клиент связывается с сервером, а внутренний трафик туннеля может быть IPv4 или IPv6 независимо от этого. WireGuard поддерживает обе версии IP.

Например: клиент с IPv4-интернетом → WireGuard по UDP/IPv4 → сервер → сайт по IPv6. Нативное IPv6-подключение у провайдера клиента для этого не требуется, но IPv6 в ОС клиента должен быть включён. На сервере должны выполняться условия из раздела выше. Сам по себе WireGuard не создаёт IPv6-доступ, если его нет у сервера.

Проверяйте не только handshake: отдельно проверьте доступ к IPv4- и IPv6-ресурсам с подключённого клиента. Например, curl -6 https://www.wireguard.com/ проверяет IPv6-доступ к этому сайту, если он доступен по IPv6 и на клиенте установлен curl.

Переход существующей установки на external

Остановка интерфейса отключит VPN-клиентов, поэтому используйте доступ к серверу, не зависящий от этого туннеля.

  1. Сделайте защищённую резервную копию /etc/wireguard — в ней есть приватные ключи. Подготовьте постоянные правила nftables для выбранных сетей, UDP-порта, пересылки и NAT.
  2. До редактирования хуков остановите WireGuard: systemctl stop wg-quick@wg0. На Alpine: rc-service wg-quick.wg0 stop. Замените wg0 именем своего интерфейса. Так прежние команды PostDown смогут снять правила, добавленные при запуске.
  3. Проверьте результат остановки и действующие правила. Если правила установщика остались, удалите только их соответствующим инструментом firewall, не очищая весь набор.
  4. Удалите из /etc/wireguard/wg0.conf только созданные установщиком firewall-команды PostUp/PostDown. Сохраните собственные хуки и настройки интерфейса и клиентов.
  5. Добавьте или измените строку FIREWALL_MODE=external в /etc/wireguard/params.
  6. Запустите WireGuard: systemctl start wg-quick@wg0; на Alpine: rc-service wg-quick.wg0 start. Проверьте handshake и доступ клиента в интернет.

Автоматическая миграция не выполняется. Изменение только /etc/wireguard/params не удаляет прежние хуки.

Резервное копирование и восстановление

В репозитории есть отдельный скрипт wireguard-backup.sh. Запускайте его от root; нужны Bash, tar с поддержкой gzip и стандартные утилиты Linux.

Создание бэкапа

В основном меню выберите 4. Укажите каталог назначения (Enter — /root/wireguard-backups) и при необходимости дополнительный каталог с клиентскими файлами. Бэкап также можно запустить отдельно из каталога скачанных скриптов:

sudo bash wireguard-backup.sh

По умолчанию архив создаётся в /root/wireguard-backups. Его имя содержит время UTC и случайный суффикс. Можно указать свой каталог назначения, а затем дополнительные каталоги поиска клиентских файлов:

sudo bash wireguard-backup.sh /var/backups/wireguard /srv/vpn-clients

В архив попадают:

  • Весь каталог /etc/wireguard: конфигурации интерфейсов, серверные ключи, записи клиентов и файл params установщика.
  • /etc/sysctl.d/wg.conf, если он существует.
  • Обычные файлы *-client-*.conf, найденные рекурсивно в /root, /home и дополнительных каталогах. Пути сохраняются относительно корня системы.

Если клиентские файлы переименованы и больше не соответствуют шаблону, сохраните их отдельно. Символические ссылки при поиске клиентов не обходятся; ссылки внутри /etc/wireguard сохраняются как ссылки, без копирования внешних целей. Файлы, оставшиеся только на устройствах клиентов, с сервера скопировать невозможно. Серверная конфигурация содержит публичные ключи клиентов, но не позволяет восстановить их утраченные приватные ключи.

Скрипт не останавливает VPN и копирует состояние файлов на диске. Не добавляйте и не отзывайте клиентов и не меняйте конфигурацию во время копирования. Изменения, внесённые только через wg set и не сохранённые в файлы, в архив не попадут.

Архив проверяется на возможность чтения и получает права 600; рабочий каталог создаётся с доступом только для root. При ошибке временные файлы удаляются, а готовый архив не публикуется. Это проверка целостности упаковки, а не полноценный тест восстановления.

Архив содержит приватные ключи и не зашифрован. Храните каталог назначения под управлением root, а копию архива — в защищённом хранилище вне сервера. Старые архивы автоматически не удаляются: контролируйте свободное место и срок хранения. Бэкап в режиме external не включает nftables, сетевые настройки провайдера и пользовательские службы или хуки за пределами /etc/wireguard; сохраните их отдельно, включая файлы, подключаемые через include.

Восстановление через меню

Используйте доверенный архив и SSH-подключение, не зависящее от восстанавливаемого VPN. Запустите sudo ./wireguard-install.sh, выберите 5 в меню установленного сервера или 2 в начальном меню нового сервера. Введите полный путь к архиву .tar.gz.

Восстановление выполняет модуль wireguard-restore.py на Python 3.8+ без сторонних библиотек. Его можно запустить напрямую:

sudo python3 wireguard-restore.py /root/wireguard-backups/ИМЯ-АРХИВА.tar.gz

Порядок работы:

  1. Проверка и распаковка. Архив читается в закрытый временный каталог. Отклоняются абсолютные пути, .., повторяющиеся пути, символические и жёсткие ссылки, специальные и неожиданные файлы. Лимиты — 10 000 записей и 256 МиБ суммарного размера файлов после распаковки. Проверка структуры не доказывает доверенность архива.
  2. Проверка конфигурации. Нужны params данного установщика и соответствующая конфигурация интерфейса. Параметры разбираются как данные, а не выполняются как shell-код. Разрешены только известные параметры и настройки forwarding. Проверяются имена интерфейсов, наличие внешнего интерфейса, инструменты WireGuard и службы. Интерфейс, запущенный вне службы, необходимо предварительно остановить вручную.
  3. Предварительный просмотр. Выводятся имена всех восстанавливаемых интерфейсов, количество peers и shell-хуков. Ключи не выводятся. Восстанавливаются все конфигурации *.conf верхнего уровня /etc/wireguard из архива; одноимённые действующие конфигурации будут заменены. Другие действующие интерфейсы не удаляются. Старый архив может вернуть отозванных клиентов.
  4. Подтверждение. Для продолжения нужно ввести RESTORE. Если архив содержит PreUp/PostUp/PreDown/PostDown, эти команды могут выполняться от root при управлении интерфейсами. Проверяйте их до подтверждения. Не используйте чужие архивы.
  5. Страховочная копия. Если /etc/wireguard существует, вызывается скрипт бэкапа. При его ошибке восстановление прекращается до остановки VPN. Дополнительно создаётся закрытый каталог /root/wireguard-backups/restore-recovery-… с предыдущими версиями заменяемых файлов. Путь выводится до изменений.
  6. Клиентские и дополнительные файлы. Они сохраняются в restore-recovery-…/recovered-files/ с исходной структурой путей и правами 600. Домашние каталоги пользователей автоматически не перезаписываются. Отсюда можно забрать клиентские конфигурации или вручную перенести их на исходные места с нужными владельцами. Прочие файлы из /etc/wireguard, помимо конфигураций верхнего уровня и params, также восстанавливаются сюда; если хуки ссылаются на такие файлы, подготовьте их вручную до запуска восстановления.
  7. Замена и запуск. Останавливаются затронутые активные службы. Восстанавливаются конфигурации, params и, если присутствует в архиве, /etc/sysctl.d/wg.conf. Применяется forwarding, запускаются восстановленные интерфейсы, проверяются состояние службы и wg show.
  8. При ошибке. Скрипт пытается остановить новые службы, вернуть заменённые файлы и прежние значения forwarding, запустить ранее активные службы. Если откат неполный, он явно сообщает об этом. Страховочный архив и каталог восстановления сохраняются. Изменения, сделанные shell-хуками в firewall или других службах, могут потребовать ручного исправления. Прерывание питания или принудительное завершение процесса также требует ручного восстановления.
  9. Проверка клиентом. Проверьте handshake, DNS и интернет, отдельно IPv4/IPv6 при их использовании. Запуск службы сам по себе не подтверждает работоспособность VPN. Автозапуск не меняется: на новом сервере после проверки выполните sudo systemctl enable wg-quick@wg0 (Alpine: sudo rc-update add wg-quick.wg0), подставив своё имя интерфейса.

Правила nftables не восстанавливаются автоматически. Подготовьте их отдельно. В режиме auto восстановленные firewall-хуки будут выполняться как часть запуска службы. При переносе проверьте имя внешнего интерфейса, порт, доступность IPv6 и публичный адрес сервера. Если публичный адрес изменился, обновите SERVER_PUB_IP в params и Endpoint в уже выданных клиентских конфигурациях.

Архивы со ссылками или нестандартными параметрами требуют ручного восстановления после проверки. Сначала проверьте процедуру на тестовом сервере. Сохранённые ключи позволяют существующим клиентам подключаться без перевыпуска конфигураций, если внешний адрес и остальные параметры остаются прежними.

Участие в разработке

Ошибки и предложения для форка можно оставить в Issues. Перед крупными изменениями желательно обсудить подход. Историю исходного проекта можно найти в его Issues и обсуждениях.

Для проверки кода используются ShellCheck и shfmt. Настройки CI находятся в .github/workflows/lint.yml.

bash -n wireguard-install.sh
bash -n wireguard-backup.sh
shellcheck -e SC1091,SC1117,SC2001,SC2034 wireguard-install.sh wireguard-backup.sh
shfmt -d wireguard-install.sh wireguard-backup.sh
python3 -B -m unittest discover -s tests -v

Эти проверки не подтверждают работоспособность VPN: установку, firewall и передачу трафика нужно дополнительно проверять в тестовой Linux-системе.

Благодарности и лицензия

Основано на проекте angristan/wireguard-install. Лицензия — MIT. Автору исходного проекта можно сказать спасибо.

About

WireGuard VPN installer for Linux servers

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages