mysurik.ru

WireGuard VPN на VPS: личный туннель за 10 минут

Я перепробовал кучу VPN-сервисов. NordVPN, Mullvad, Proton — все они либо тормозят, либо сливают логи, либо стоят как подписка на Netflix. У Mullvad, кстати, нормальные цены — 5 евро в месяц, но скорость на российских серверах проседала до 20 мегабит. Я живу в провинции, у меня и так 250 мегабит от местного провайдера, терять из них 90 процентов — глупо. В какой-то момент я понял: проще поднять свой VPN на VPS за 800 рублей в месяц. И знаешь что? Это реально работает быстрее, чем платные аналоги.

WireGuard — не просто очередной VPN-протокол. Он встроен в ядро Linux начиная с версии 5.6. Это значит, что он работает на уровне ядра, без лишних прослоек вроде OpenSSL или tun-устройств. Отсюда и скорость — на тестах WireGuard обгоняет OpenVPN в 3-4 раза. Я специально замерял: OpenVPN на том же VPS выдавал 60 мегабит, WireGuard — 200. Разница драматическая, особенно когда нужно смотреть видео в 4K или скачивать ISO образы для домашней лаборатории. В чём магия? WireGuard использует шифрование ChaCha20-Poly1305, которое современные процессоры обрабатывают аппаратно. OpenVPN же по старинке крутит OpenSSL с AES, и это создаёт дополнительную нагрузку на процессор. На слабых VPS с одним ядром разница особенно заметна — OpenVPN может загрузить CPU на 100 процентов на скорости 100 мегабит, а WireGuard едва дышит.

Выбор VPS — отдельная история. Я сначала взял самый дешёвый вариант у DigitalOcean за 6 долларов — те же характеристики, но через месяц пришёл счёт на 9 баксов из-за трафика. Hetzner даёт 20 терабайт трафика в месяц за 3.99 евро. Я столько не сожру даже если буду качать тонны фильмов. Ещё смотрел в сторону VPS от Timeweb — у них есть тариф за 300 рублей, но я не уверен в их сетевой связности с Европой. У Hetzner дата-центры в Финляндии — пинг из Москвы около 30-40 мс, что отлично для VPN.

Я купил самый дешёвый VPS у Hetzner за 3.99 евро. Одно ядро, 2 ГБ RAM, 20 ГБ SSD. Этого заглаза хватит и на VPN, и на пару мелких сервисов. Ставил Ubuntu 22.04 — с ней меньше всего танцев с бубном. Выбор дистрибутива — дело вкуса, но я предпочитаю LTS версии, потому что не хочу переустанавливать сервер раз в полгода. Если у тебя Debian — всё то же самое, только пакеты могут называться немного иначе. Кстати, в Debian WireGuard называется так же, но может потребоваться подключить backports репозиторий для свежей версии.

Первое, что я сделал после входа по SSH — обновил пакеты и поставил WireGuard. В Ubuntu 22.04 он уже есть в репозиториях:

sudo apt update && sudo apt upgrade -y
sudo apt install wireguard -y

Обновление пакетов — святое. Я как-то забыл обновить сервер перед настройкой, и WireGuard установился старой версии, которая не поддерживала какой-то опции в конфиге. Пришлось переустанавливать. С тех пор всегда сначала apt update.

Дальше — генерация ключей. WireGuard использует пару ключей для каждого пира. Я сгенерировал ключи для сервера и для клиента (ноутбука):

wg genkey | tee server-private.key | wg pubkey > server-public.key
wg genkey | tee client-private.key | wg pubkey > client-public.key

Важный момент: приватные ключи — это святое. Никому их не показывай. Я храню их в зашифрованном файле на домашней машине и в KeePassXC. Если приватный ключ сервера утечёт — злоумышленник сможет подключиться к твоему VPN. Публичные ключи можно передавать как угодно — они для того и публичные.

Конфиг сервера я положил в /etc/wireguard/wg0.conf. Выглядит он минималистично — никаких сертификатов и CA, как в OpenVPN. Просто интерфейс, порт, приватный ключ и пара пиров:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <содержимое server-private.key>

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <содержимое client-public.key>
AllowedIPs = 10.0.0.2/32

Строки PostUp и PostDown включают NAT — чтобы трафик с клиента уходил в интернет через сервер. Без этого VPN будет работать только внутри подсети 10.0.0.0/24, а нам нужно весь трафик гонять через сервер. Обязательно проверь имя интерфейса — у меня eth0, но у тебя может быть ens3 или enp1s0. Если ошибешься — NAT не сработает, и интернет через VPN не появится. Узнать имя интерфейса можно командой ip link show или ip addr. У Hetzner обычно интерфейс называется eth0, но на новых серверах бывает ens3.

Включил форвардинг пакетов — без него NAT не заработает:

sudo sysctl -w net.ipv4.ip_forward=1
echo «net.ipv4.ip_forward=1» | sudo tee -a /etc/sysctl.conf

Форвардинг — это разрешение ядру передавать пакеты между интерфейсами. Без этого пакеты будут доходить до сервера, но не смогут выйти в интернет. Параметр net.ipv4.ip_forward по умолчанию равен 0 в целях безопасности. После добавления в sysctl.conf он сохранится после перезагрузки.

Запустил WireGuard:

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

На клиенте (у меня Windows, но на macOS и Linux всё аналогично) я установил WireGuard, создал конфиг:

[Interface]
PrivateKey = <содержимое client-private.key>
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <содержимое server-public.key>
Endpoint = :51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Ключевой момент — AllowedIPs = 0.0.0.0/0. Это значит «гонять весь трафик через VPN». Если хочешь только для определённых сайтов — пропиши конкретные подсети. У меня, например, есть отдельный конфиг для доступа к домашней сети, где AllowedIPs = 192.168.0.0/24, чтобы я мог заходить на свои серверы из гостиницы. Для этого варианта PersistentKeepalive не нужен — соединение будет устанавливаться только при обращении к домашней подсети.

PersistentKeepalive = 25 — отправка keepalive пакетов каждые 25 секунд. Это нужно, если ты за NAT-ом (домашний роутер, гостиница, офис). Без keepalive NAT на роутере может закрыть сессию через 30-60 секунд неактивности, и VPN отвалится. У меня в гостинице постоянно терялось соединение, пока я не добавил этот параметр. После добавления — ни одного разрыва.

Первое подключение я сделал с опаской — вдруг что-то не взлетит. Но WireGuard подключился мгновенно. Буквально секунда — и я уже сидел через свой VPS. Проверил на ipleak.net — всё чисто, мой реальный IP не светится. DNS Leak Test тоже прошёл, хотя с некоторыми VPN-клиентами DNS начинает утекать — пришлось явно прописать DNS в конфиге клиента, чтобы запросы не уходили провайдеру. Кстати, на Windows WireGuard иногда не использует DNS из конфига — пришлось прописать DNS в настройках сетевого адаптера вручную.

Погонял speedtest. Без VPN: 250 Мбит/с. Через WireGuard на дешёвом VPS: 180-200 Мбит/с. Потери всего 20-30 процентов. Для сравнения — тот же OpenVPN на этом же сервере выдавал максимум 60 Мбит/с. Причина — WireGuard работает в ядре, а OpenVPN гоняет пакеты через userspace и tun-устройство, что создаёт лишние копирования данных между пользовательским пространством и ядром. Ещё WireGuard использует UDP, который не требует установки соединения и не делает тройное рукопожатие как TCP. OpenVPN может работать поверх TCP, и это создаёт проблему «TCP over TCP» — когда потери пакетов на линии заставляют оба протокола одновременно ретранслировать данные, и скорость падает катастрофически.

Сейчас у меня WireGuard крутится на VPS уже полгода. Я забыл, что он вообще существует — настолько стабильно работает. Ни разу не перезагружал, не лагал, не отваливался. Единственное, что я добавил — скрипт, который проверяет, что сервер доступен, и если нет — шлёт уведомление в Telegram. За полгода скрипт ни разу не сработал, но я всё равно держу его в cron для спокойствия. Скрипт простой: раз в 5 минут пингует 8.8.8.8 через VPN-интерфейс, и если три пинга подряд не проходят — шлёт сообщение в Telegram через bot API.

UPD: через пару месяцев я добавил второго пира — настроил WireGuard на телефоне. Тот же конфиг, только Endpoint заменил на домен вместо IP, потому что у VPS динамический IP может меняться (хотя у Hetzner он статический, но мало ли). У меня есть бесплатный динамический DNS на DuckDNS — скрипт на сервере раз в 5 минут обновляет IP, и Endpoint на клиентах указывает на duckdns домен. На телефоне WireGuard жрёт процентов 2-3% батареи за день — незаметно. Я использую его в командировках, чтобы заходить в домашний NAS и забирать файлы. Скорость на телефоне через 4G — около 80 мегабит, что более чем достаточно для любых задач. Из неочевидного — на Android WireGuard может автоматически отключаться при бездействии. Пришлось в настройках батареи исключить приложение из оптимизации, чтобы VPN не обрывался когда телефон в кармане.

Ещё один важный момент — файрвол. Не забудь открыть порт 51820 в ufw или iptables на VPS. Я об этом забыл и потратил 15 минут на диагностику — WireGuard на сервере запущен, а подключиться не могу. Команда sudo ufw allow 51820 решила проблему за секунду, но до этого я успел проверить весь конфиг, перегенерировать ключи и даже переустановить WireGuard. И проверь, что порт не занят другим сервисом. У меня как-то на 51820 висел ShadowSocks, и WireGuard отказывался стартовать — systemctl status показывал ошибку «Address already in use». Пришлось менять порт.

Перспективы: я планирую добавить failover на второй VPS через Keepalived, чтобы если основной сервер ляжет — VPN автоматически переключится на запасной. WireGuard поддерживает несколько пиров с одинаковым AllowedIPs, и клиент сам выберет работающий. Пока не настроил, потому что и так всё работает, но мысль держу в голове. Ещё хочу попробовать WireGuard в режиме роутера — настроить Split Tunneling, чтобы часть трафика шла через VPN (например, доступ к домашней сети), а часть — напрямую через провайдера (для экономии трафика на VPS, если смотрю YouTube).

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

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