mysurik.ru

WireGuard VPN: как я настроил безопасный доступ к дому

До недавнего времени я заходил на домашний сервер через SSH с пробросом порта на роутере. Сознаюсь, это было небезопасно, но удобно. Пока однажды в логах не увидел подозрительные попытки входа из Китая. Тут я задумался.

Перебрав варианты: OpenVPN — слишком громоздкий, IPSec — боль, Tailscale — удобно, но зависит от внешнего сервера. Остановился на WireGuard. Настройка заняла 15 минут: установил, сгенерировал ключи, прописал пару строк в конфиг.

Теперь захожу на сервер через VPN из любой точки мира. И никаких открытых портов. Телефон, ноутбук, рабочий ПК — везде стоит WireGuard и подключается к дому за секунду.

Кстати, скорость не проседает вообще. На тестах разница между прямым соединением и через WireGuard — меньше пяти процентов.

Установка на сервер. Я сидел на Ubuntu 24.04, там WireGuard уже в ядре, ставить ничего не пришлось. Просто apt install wireguard-tools, и всё. Дальше — генерация ключей. На сервере я создал пару ключей, на каждом клиенте — свою. Ключи хранятся в /etc/wireguard/. Один файл — server.conf, второй — клиентский конфиг, который я раскидываю по устройствам.

Серверный конфиг у меня выглядит так: интерфейс wg0, приватный ключ сервера, адрес 10.0.0.1/24, порт 51820. Дальше секция Peer для каждого клиента: публичный ключ клиента, разрешённые адреса (allowed-ips) — для телефона это 10.0.0.2/32, для ноутбука 10.0.0.3/32, и так далее. Важный момент — PersistentKeepalive = 25. Без этого мобильный клиент разрывает соединение через пару минут неактивности, и потом не может переподключиться, потому что NAT на роутере забыл про проброс.

Клиентские конфиги я генерирую сам. На каждом клиенте свой приватный ключ, свой IP в подсети 10.0.0.0/24. В конфиге клиента: интерфейс с приватным ключом и адресом, Peer — публичный ключ сервера, эндпоинт (мой домен или IP с портом), allowed-ips = 0.0.0.0/0 (чтобы весь трафик шёл через VPN), и DNS — я ставлю 1.1.1.1 или свой AdGuard Home.

Первая проблема, с которой я столкнулся — файрвол. ufw по умолчанию блокирует входящие на 51820 порт. Пришлось добавить правило: ufw allow 51820/udp. Без этого WireGuard просто не отвечал на запросы клиентов, и я полчаса тупил, думая что не настроил ключи.

Вторая проблема — роутинг. Если ты хочешь, чтобы весь трафик шёл через VPN (включая интернет) — ставишь allowed-ips = 0.0.0.0/0 на клиенте. Но тогда домашний сервер становится шлюзом для всего трафика клиента. На сервере нужно включить IP forwarding. Я прописал net.ipv4.ip_forward=1 в sysctl.conf и добавил iptables правило на masquerade. Без этого трафик уходит в VPN, но обратно не возвращается — роутер сервера не знает, что отвечать на пакеты с адресами из подсети 10.0.0.0/24.

Третья проблема — DNS утечки. Когда я включил полный туннель на ноутбуке, DNS запросы всё равно летели напрямую к провайдеру, потому что systemd-resolved не перенаправлял их через VPN. Пришлось править resolvectl и прописывать DNS-сервер в конфиге WireGuard. На мобильных клиентах этой проблемы нет — там DNS настраивается в конфиге приложения.

Про телефоны. На iPhone WireGuard ставится из App Store, конфиг импортируешь по QR-коду. Я генерирую QR прямо в терминале: qrencode -t ansiutf8 < client.conf. На Android то же самое. Удобно: поднёс камеру, считал, готово. Kill switch. Если VPN упадёт, клиент должен блокировать весь трафик, чтобы не утекли данные. В WireGuard на десктопе это настраивается через флаг DisabledOnActivation для маршрута — чтобы без VPN никуда не ходило. На телефонах kill switch есть в официальном приложении. Про IPv6. У провайдера есть IPv6, и сначала клиенты пытались ходить в интернет через IPv6 напрямую, минуя VPN. Пришлось добавить в allowed-ips ещё и ::/0. Теперь и IPv6 трафик идёт через туннель. Мониторинг. WireGuard встроил простую команду wg show. Она показывает все пиры, их последнее подключение, переданные байты. Я добавил это в crontab — раз в час логирую, кто и когда подключался. Полезно для отладки. Бекап. Конфиги WireGuard хранятся в /etc/wireguard. Я добавил эту папку в список бекапов Proxmox. Потерять ключи — значит потерять доступ к серверу. Как бонус — я настроил доступ к своей локальной сети через VPN. То есть, подключившись к WireGuard, я могу зайти не только на сервер, но и на роутер, и на другие устройства в домашней сети. Для этого я добавил в allowed-ips подсеть 192.168.0.0/24. На сервере прописал iptables, чтобы форвардить трафик между wg0 и локальной сетью. Итог. WireGuard — это единственный VPN, который я настроил и забыл. Он работает годами без перезапуска, не жрёт память, не требует обслуживания. Если у тебя есть домашний сервер и ты до сих пор не поставил WireGuard — ты рискуешь. Поставь, это реально 15 минут. Кстати, советую всем, кто ставит WireGuard впервые — используй wg-easy. Это веб-морда, которая сама создаёт конфиги, показывает QR-коды и управляет клиентами. Я сначала крутил всё ручками, но для быстрого старта — самое то. Ставится в Docker одной командой. Ещё один момент, о котором молчат в инструкциях. Если у тебя динамический IP, а домен привязан к нему — WireGuard может не переподключаться после смены IP, если DNS не обновился. У меня так было: провайдер перезагрузил оборудование, IP сменился, и я потерял связь с сервером на полдня. Решение — использовать DDNS-клиент на сервере и обновлять DNS запись. Или использовать статический IP, если провайдер даёт. Сравнение с другими решениями. OpenVPN я ставил года три назад. Настройка заняла вечер, конфиги были на десять страниц, скорость упала вдвое. IPSec я даже не пробовал — говорят, там без бубна не разобраться. Tailscale я использую параллельно — он удобен для быстрых подключений, но не даёт контроля над инфраструктурой. WireGuard же — золотая середина. Просто, быстро, под твоим полным контролем. Про аварию. Однажды я обновил ядро на сервере и забыл перезагрузить WireGuard. Модуль ядра обновился, а wg-quick не перезапустился. Я думал, что VPN сломался, час перепроверял конфиги, пока не заметил, что wg0 интерфейса просто нет. Команда wg-quick down wg0 && wg-quick up wg0 решила проблему. Теперь после каждого обновления ядра проверяю. Что касается нескольких серверов. У меня есть VPS в Европе и домашний сервер. Оба объединены в mesh через WireGuard. Серверы видят друг друга, а я подключаюсь к любому из них и имею доступ ко всей сети. Это удобнее, чем поднимать туннели по отдельности. Ещё из полезного — PreSharedKey. Если хочешь дополнительную защиту от квантовых компьютеров (ну, мало ли), добавляешь предварительный общий ключ к каждому пиру. WireGuard генерирует его через wg genpsk. На производительность это не влияет, а безопасность повышает. Я добавил PSK всем клиентам — на всякий случай. И последнее. WireGuard не умеет сам переподключаться при обрыве, как OpenVPN. Если соединение разорвалось — клиент просто ждёт следующий handshake. PersistentKeepalive решает эту проблему частично, но если сервер перезагрузился, клиент узнает об этом только через 2-3 минуты. Я решил это написанием простого скрипта, который пингует сервер через wg0 и, если пинг не проходит, перезапускает интерфейс. Скрипт висит в cron на клиенте.

Ваш комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *