Настраиваем Wireguard VPN с Dynamic DNS на Raspberry Pi


vpn on a raspberry pi

Купил я значит себе домой Raspberri Pi 4B и думаю, что бы с ней такого сделать.

Первым делом настроил блокировщик рекламы по DNS для домашней сети, но это совсем просто, даже описывать не буду, просто оставлю ссылку на проект: https://github.com/0xERR0R/blocky, рекомендую, гораздо лучше, чем Pi-Hole в плане производительности.

Но этого мне показалось мало для девайса стоимостью $100. Да-да, со всеми комплектующими: корпусом, зарядкой, переходником micro HDMI -> HDMI, SD картой и радиаторами это не так дешево, как казалось мне изначально.

Мне пришла мысль настроить домашний VPN, чтоб в путешествиях можно было подключаться к домашней сети, ну и использовать домашний интернет как прокси. Сначала подумал взять старый добрый IPSec, но с его настройкой как-то много возни, нормальных готовых ansible ролей я не нашел, плюс захотелось попробовать новомодный Wireguard.

Но для того, чтобы подключиться к домашнему интернету, нужно знать внешний IP, у меня все-таки серый IP за NAT, а внешний IP постоянно меняется.

Решение — Dynamic DNS. Мой роутер совсем тупой простой и не поддерживает Dynamic DNS в своей прошивке, поэтому я решил настроить его самостоятельно на Raspberry PI. Т.к. я начал учить язык программирования Rust, то выбор пал именно на него. Для начала я пошел на Github в поисках готового проекта. Неудивительно, что проектов оказалось довольно много. Выбрав самый простой и элегантный (нам мой вкус), я решил немного модифицировать его под свои нужды. Критерий выбора был: минимум зависимостей, никаких баз данных или кэшей, маленькая кодовая база.

Для начала, что представляем из себя этот проект? Он узнает внешний ipv4 и ipv6 адреса с помощью DNS Cloudflare, кстати, я даже не знал, что так вообще можно было.

Пример команды:

dig @1.1.1.1 ch txt whoami.cloudflare +short

Потом эти IP адреса записываются, как A и AAA DNS адреса указанного домена, управляемого опять же Cloudlare. Да, у Cloudflare есть бесплатный DNS хостинг, если кто не знал.

Что я изменил? Во-первых, в изначальном решении обновлялся коренной домен, например, example.com. Мне это не подходило, я хотел использовать домен вида vpn.example.com

Во-вторых, мне не нравилось, что не было предусмотрено никакого кеширования. Даже если IP адрес не изменился, все равно делались запросы в API Cloudflare.

Мои изменения можете посмотреть здесь. Я изменил логику записи DNS домена и добавил кеширование в файл. Также я скомпилировал код под aarch64 (arm64), чтоб он запускался на Raspberry Pi.

Простой пример использования этого скрипта в кроне:

*/5 * * * * API_TOKEN=<YOUR-CLOUDFLARE-TOKEN> DOMAIN=vpn.example.com /usr/local/bin/ddns-cloudflare >> /var/log/ddns-cloudflare.log 2>&1

Еще я сделал примитивную ansible роль для автоматизации установки этого Dynamic DNS решения.

Итак, динамический DNS настроен и теперь можно приступать к настройке VPN. Сначала, было бы неплохо ознакомиться с самим Wireguard, как он работает, почему набирает популярность и пр.

Почитав некоторое количество статей я вынес для себя следующие тезисы:

  • кодовая база wireguard минимальна, около 4000 строк (на момент написания статьи), по сравнению со StrongSwan, где их около 400000. Это впечатляет.
  • wireguard использует UDP протокол
  • за счет использования определенных техник шифрования он быстрее других VPN протоколов
  • каждый клиент должен быть явно разрешен на сервере
  • авторизация происходит только по приватным ключам, уникальным для каждого узла сети (клиента), никаких паролей и сертификатов
  • клиентские приложения есть для любых устройств, в частности, я установил его на свой iPhone
  • настройка довольно простая и удобная, особенно на клиенте — отсканировал QR код и готово

Более подробно про сам протокол и его реализацию вы можете прочитать на сайте Wireguard. Если лень читать, то вот разъяснительное видео от автора (на английском языке): https://www.youtube.com/watch?v=88GyLoZbDNw

Перед установкой я, как обычно, сначала прошерстил ansible galaxy на наличие готовых ролей, взял понравившуюся и адаптировал под себя. Результат можете найти здесь: https://github.com/kshcherban/ansible-role-wireguard.

Что там происходит под капотом?

  1. Устанавливается пакет wireguard на сервере.
  2. Там же генерируются конфиги для сервера и клиента.
  3. Клиентский конфиг копируется на локальный компьютер, который вызывает ansible.

Если не знаете, как использовать роли ansible, то можете почитать тут. Для установки сделайте следующее:

  • Добавьте следующее в файл requirements.yml в своей директории с ansible кодом:
roles:
  - name: kshcherban.ddns_cloudflare
    src: https://github.com/kshcherban/ansible-role-ddns-cloudflare
  - name: kshcherban.wireguard
    src: https://github.com/kshcherban/ansible-role-wireguard
  • Выполните команду:
ansible-galaxy role install -r requirements.yml

После того, как вы применили ansible роль wireguard, вы можете сгенерировать QR код из конфига. Конфиг можно найти в ~/wireguard-<client-name>.conf

qrencode -t ansiutf8 < ~/wireguard-<client-name>.conf

Полученный конфиг можно отсканировать в приложении на мобильном телефоне, так настройка будет мгновенной.

Вот и всё! Несколько нехитрых манипуляций и вы имеете свой быстрый VPN сервер с блокировкой рекламы на борту.

comments powered by Disqus