WireGuard на Rocky Linux 9: пошаговая установка
Rocky Linux 9 — прямой наследник CentOS: та же ветка RHEL, тот же dnf, тот же firewalld и SELinux по умолчанию. Именно эти три вещи чаще всего сбивают с толку тех, кто ставит WireGuard впервые — привычные команды из инструкций для Ubuntu просто не работают. Разберём установку с нуля: пакеты из EPEL, генерация ключей, firewalld вместо ufw и нюансы SELinux, которые на Debian-системах вообще не встречаются.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что нужно знать про Rocky Linux 9 перед установкой
Модуль WireGuard попал в апстрим ядра Linux начиная с версии 5.6, и в ядре RHEL 9 (а значит и Rocky Linux 9) он присутствует изначально — отдельно собирать kmod-wireguard, как раньше приходилось делать на Rocky 8 через репозиторий ELRepo, не нужно. Достаточно установить утилиты wireguard-tools, а сам модуль подключится через штатный wireguard.ko, либо через модуль wireguard из пакета kernel — проверим это командой ниже.
Второе отличие от Ubuntu/Debian — пакетный менеджер dnf и репозиторий EPEL (Extra Packages for Enterprise Linux), без которого wireguard-tools не найдётся в базовых репозиториях Rocky. Третье — SELinux в режиме enforcing по умолчанию: он не мешает WireGuard в стандартной конфигурации, но может заблокировать нестандартные пути или порты, если вы отходите от типовой схемы. Четвёртое — firewalld с бэкендом nftables вместо iptables, с которым работают через firewall-cmd, а не через сырые правила.
Из ресурсов WireGuard требует немного: 1 vCPU и 512 МБ–1 ГБ RAM хватает и для личного VPN, и для небольшой команды — шифрование в ядре не создаёт заметной нагрузки. Перед установкой обновите систему:
dnf update -y
Установка wireguard-tools из EPEL
Подключите репозиторий EPEL и поставьте пакет:
dnf install -y epel-release
dnf install -y wireguard-tools
Пакет wireguard-tools даёт утилиты wg и wg-quick, но не сам модуль ядра — его проверяем отдельно:
modprobe wireguard
lsmod | grep wireguard
Если команда modprobe отработала без ошибок и wireguard появился в выводе lsmod, ядро поддерживает WireGuard из коробки — на Rocky Linux 9 так и должно быть. Если модуля нет (например, вы используете нестандартное ядро или облачный образ с урезанным набором модулей), доустановите заголовки и kmod-wireguard из ELRepo:
dnf install -y https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm
dnf install -y kmod-wireguard
Для подавляющего большинства установок на чистом Rocky Linux 9 этот шаг не понадобится — переходите сразу к генерации ключей.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверГенерация ключей и конфиг сервера
WireGuard использует асимметричную схему: приватный ключ остаётся на устройстве, публичный передаётся собеседнику. Создайте директорию и пару ключей сервера:
mkdir -p /etc/wireguard
cd /etc/wireguard
umask 077
wg genkey | tee server_private.key | wg pubkey > server_public.key
umask 077 закрывает файлы ключей от чтения посторонними ещё до их создания — важно сделать это до, а не после генерации. Приватный ключ сервера — это фактически пароль от всего туннеля, храните его так же бережно, как SSH-ключ или пароль от root. Аналогично сгенерируйте пару для первого клиента:
wg genkey | tee client_private.key | wg pubkey > client_public.key
Теперь создайте конфиг интерфейса /etc/wireguard/wg0.conf:
[Interface]
Address = 10.66.66.1/24
ListenPort = 51820
PrivateKey = ПРИВАТНЫЙ_КЛЮЧ_СЕРВЕРА
SaveConfig = false
[Peer]
PublicKey = ПУБЛИЧНЫЙ_КЛЮЧ_КЛИЕНТА
AllowedIPs = 10.66.66.2/32
Address — внутренний IP сервера в VPN-подсети, ListenPort — стандартный порт WireGuard (можно сменить на любой свободный UDP-порт). SaveConfig = false защищает файл от перезаписи при остановке интерфейса — без этой строки wg-quick down иногда затирает ваши правки, сделанные вручную. Узнайте имя внешнего сетевого интерфейса — оно понадобится в следующем шаге:
ip route | grep default
Обычно это eth0 или ens3 в зависимости от провайдера — подставляйте своё значение вместо eth0 в примерах ниже.
Форвардинг, firewalld и NAT
Включите пересылку пакетов на уровне ядра — без неё сервер получает трафик от клиентов, но не выпускает его в интернет:
cat <<EOF > /etc/sysctl.d/99-wireguard.conf
net.ipv4.ip_forward = 1
EOF
sysctl --system
Дальше открываем порт и настраиваем маскарадинг в firewalld. В отличие от Ubuntu, где NAT обычно прописывают прямо в PostUp/PostDown конфига через iptables, на Rocky Linux удобнее и надёжнее работать через firewall-cmd:
firewall-cmd --permanent --zone=public --add-port=51820/udp
firewall-cmd --permanent --zone=public --add-masquerade
firewall-cmd --reload
Если внешний интерфейс не в зоне public, проверьте его зону командой firewall-cmd --get-active-zones и подставьте нужную. Альтернативный вариант — прописать те же команды прямо в PostUp/PostDown конфига wg0.conf, чтобы правила поднимались вместе с интерфейсом и не зависели от порядка запуска сервисов:
PostUp = firewall-cmd --zone=public --add-masquerade; firewall-cmd --zone=public --add-port=51820/udp
PostDown = firewall-cmd --zone=public --remove-masquerade; firewall-cmd --zone=public --remove-port=51820/udp
Оба варианта рабочие — постоянные правила через --permanent переживают перезагрузку сами, вариант с PostUp/PostDown удобнее, если вы часто пересоздаёте интерфейс или тестируете конфиг. Не смешивайте оба сразу — правила могут задвоиться.
SELinux: когда он мешает и как проверить
В стандартной схеме — порт 51820, файлы в /etc/wireguard, обычный systemd-юнит — SELinux не блокирует WireGuard, потому что wg-quick работает через уже размеченные пути и штатные системные вызовы. Проблемы начинаются, если вы переносите конфиги в нестандартную директорию или запускаете wg-quick от имени сервиса с изменённым контекстом.
Если туннель не поднимается без явной причины в логах, первым делом проверьте, не заблокировал ли что-то SELinux:
ausearch -m avc -ts recent
Если в выводе есть записи, связанные с wg-quick или wireguard, сгенерируйте разрешающее правило автоматически (нужен пакет setroubleshoot/policycoreutils-python-utils):
dnf install -y policycoreutils-python-utils
audit2allow -a -M wireguard_fix
semodule -i wireguard_fix.pkg
Это точечно разрешает именно то действие, которое было заблокировано, не отключая SELinux целиком. Полное отключение SELinux (setenforce 0 на постоянной основе) — плохая практика для боевого сервера: вы теряете весь слой защиты ради решения одной проблемы, которую обычно можно закрыть точечно.
Запуск, автозапуск и клиентский конфиг
Поднимите интерфейс и включите автозапуск, чтобы туннель поднимался после каждой перезагрузки VPS:
wg-quick up wg0
systemctl enable wg-quick@wg0
Проверьте статус — команда wg покажет активный интерфейс, публичный ключ и список пиров:
wg show
На клиенте создайте конфиг client.conf:
[Interface]
PrivateKey = ПРИВАТНЫЙ_КЛЮЧ_КЛИЕНТА
Address = 10.66.66.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = ПУБЛИЧНЫЙ_КЛЮЧ_СЕРВЕРА
Endpoint = IP_СЕРВЕРА:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0 заворачивает весь трафик клиента через сервер — это полный туннель. Если нужен только доступ к части ресурсов без замедления остального интернета, укажите конкретные подсети вместо 0.0.0.0/0. PersistentKeepalive = 25 держит соединение живым за NAT — особенно важно для мобильных сетей, где адрес клиента периодически меняется. Для телефона удобнее сгенерировать QR-код:
dnf install -y qrencode
qrencode -t ansiutf8 < client.conf
Отсканируйте код приложением WireGuard на телефоне — конфиг импортируется без ручного ввода. Подробности подключения с конкретных устройств смотрите в отдельных инструкциях: подключение к WireGuard с Android, с iPhone и с Windows 11.
Проверка и типичные ошибки
После подключения клиента проверьте на сервере, появился ли хендшейк:
wg show wg0 latest-handshakes
Если время последнего хендшейка обновляется — туннель работает. Если хендшейка нет вообще, проверьте по порядку: открыт ли порт (firewall-cmd --list-ports), совпадают ли публичные ключи в конфигах сервера и клиента местами (частая ошибка — перепутать, чей ключ где), не блокирует ли провайдер клиента исходящий UDP на нестандартный порт. Если хендшейк есть, а интернета через туннель нет — почти всегда забыт ip_forward или не настроен --add-masquerade в firewalld, разберитесь по шагам из раздела выше.
С внешней стороны проверьте IP, под которым вы выходите в сеть:
curl https://api.ipify.org
Ответ должен совпадать с IP вашего сервера, а не с домашним адресом. Если вместо этого вы получаете таймаут или закрытое соединение, посмотрите на общие причины разрыва туннеля — они разобраны в статье WireGuard на сервере: частые ошибки и решения. Для нескольких устройств заводите отдельную пару ключей и отдельный блок [Peer] на каждое — с уникальным внутренним адресом (10.66.66.3, 10.66.66.4 и так далее), не переиспользуйте один конфиг на двух устройствах сразу: сервер увидит конфликт адресов и туннель начнёт рваться.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Нужен ли отдельный модуль ядра для WireGuard на Rocky Linux 9?
Обычно нет — модуль встроен в ядро RHEL 9/Rocky 9 начиная с релиза. Проверьте командой modprobe wireguard && lsmod | grep wireguard; если модуля нет, доустановите kmod-wireguard из ELRepo.
Почему dnf install wireguard-tools не находит пакет?
Скорее всего, не подключён EPEL. Выполните dnf install -y epel-release и повторите установку.
Чем открытие порта в firewalld отличается от ufw?
Логика та же (разрешить порт, включить NAT), но команды другие — firewall-cmd --add-port и --add-masquerade вместо ufw allow. Не забывайте firewall-cmd --reload после --permanent правил.
SELinux нужно отключать для WireGuard?
Нет, в стандартной схеме он не мешает. Если после нестандартной настройки что-то не работает, проверьте ausearch -m avc -ts recent и создайте точечное разрешающее правило через audit2allow, а не отключайте SELinux целиком.
Как понять, что туннель реально пропускает трафик, а не просто поднят?
Проверьте wg show wg0 latest-handshakes — время должно обновляться при активности — и сравните внешний IP через curl https://api.ipify.org до и после подключения.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →