Иногда возникает необходимость получить доступ к сайтам, например, https://refactoring.guru или https://leafletjs.com, но по каким-то причинам эти сайты заблокирован в вашей стране. А может быть вы просто хотите получить доступ к сайтам, которые доступны только по IPv6, а ваш провайдер не предоставляет вам такой возможности. Одним из выходов может стать VPN. Однако покупать VPN где-то на стороне при наличии собственного VPS сервера, где интернет работает нормально, просто лишняя трата денег. В таком случае возникает вопрос: а как, собственно, организовать этот самый VPN? В интернете есть множество инструкций, но они обычно не затрагивают тему протокола IPv6 или затрагивают, но там используются спорные решения.

Одним из популярных вариантов организации VPN является Wireguard. Сам по себе, Wireguard, довольно прост, но при этом его можно использовать в любых схемах: «точка-точка», «звезда» и даже mesh-сеть. В дальнейшем будет использоваться схема «звезда», которая подразумевает использование отдельного сервера и наличие, минимум, одного или нескольких клиентов.

Если с IPv4 всё понятно, поскольку большинство руководств сходятся к решению с использованием серой адресации с организацией NAT на сервере. По сути, это стандартная схема для IPv4 адресации. Адресов IPv4 мало и стоят они дорого, поэтому никто, в здравом уме, не будет использовать «белые» адреса непосредственно на устройствах, если, конечно, это не сервер, который доступен в интернете. А вот с IPv6 не всё так однозначно.

Сам по себе протокол IPv6 строится на том, что никому не потребуется использовать NAT. При этом, это не означает, что сам по себе NAT в IPv6 недоступен. NAT для IPv6 доступен (обычно его называют NAT66), но его использование не рекомендуется, а в некоторых случаях это даже вредно. К тому же всегда есть возможность его не использовать, в противовес IPv4.

Выдавать IPv6 адреса хостинг-провайдеры могут по разному:

  1. Выдача IPv6 адресов поштучно. Самый странный вариант. Если у вашего хостинг-провайдера так, то, скорее всего, стоит просто сменить его на другого, даже к контексте использования VPS для обычного сервера, не говоря уже об использовании как VPN. С некоторой долей вероятности тоже можно получить VPN с IPv6, но далее этот вариант просто не рассматривается. После прочтения материала вы сами сможете понять что вам нужно делать, если вы всё-таки решитесь использовать подобного провайдера.

  2. Выдача сети /64. Наиболее часто встречающийся вариант для мелких провайдеров. Иногда есть возможность через поддержку получить сеть /63 или, даже, ещё большего размера, что будет рассмотрено в следующем варианте. Наличие только /64 не самый хороший вариант для VPN, но с ним уже можно работать.

  3. Вариант не особо отличается от предыдущего, но вместо сети /64 вам выдают сеть большего размера (до /48), т.е. в вашем распоряжении оказывается адресация некоторого количества сетей /64. Например при /48 - 65536 штук.

  4. Маршрутизация определённого префикса IPv6 на вашу виртуальную машину. Самый редкий вариант среди мелких провайдеров, в публичном доступе такое почти не встречается, но, возможно есть возможность получить префикс через техническую поддержку. Этот вариант подразумевает, что ваш хостинг провайдер прописал маршрут на ваш виртуальный сервер для выделенного вам префикса. Вам может быть выдана сеть от /64 до /48, которые без костылей могут быть использованы вами для организации VPN.

Сложность настройки VPN постепенно уменьшается от 1 до 4 варианта, поэтому начнём с 4 варианта и постепенно поднимемся вверх.

Шаг 1: Включение маршрутизации на сервере VPN

Самым простым для настройки является вариант, когда ваш провайдер прописал маршрут для сети или сетей /64 на вашу виртуальную машину. В таком случае единственное, что вам нужно будет сделать, чтобы обеспечить работу VPN - это включить маршрутизацию на вашей машине.

Для IPv4 маршрутизация включается с помощью sysctl путём установки

net.ipv4.ip_forward=1

Для IPv6 это делается аналогично:

net.ipv6.conf.all.forwarding = 1

Но есть одно НО! Если ваша машина получает адреса в автоматическом режиме, то после включения маршрутизации она перестанет принимать анонсы маршрутизаторов, а значит, больше не сможет получить адрес в автоматическом режиме. Чтобы это исправить, включите

net.ipv6.conf.ens3.accept_ra = 2

В данном примере `ens3` - это сетевой интерфейс нашего VPS, откуда мы хотим принимать анонсы маршрутизатора. На большинстве хостингов назначение IPv6 адресов на VPS производилось путём ручной настройки, а значит и принимать RA не требуется, т.е. данную настройку можно пропустить.

Теперь осталось выделить сеть /64 из доступного вам диапазона, назначить один из адресов на интерфейс Wireguard на VPS, а также выдать каждому клиенту по IPv6 адресу из этого же диапазона. Всё прописывается в конфигурации сервера и клиентов. На этом настройка VPN для 4 варианта будет закончена.

Шаг 2: Обеспечиваем маршрутизацию пакетов для сервера без выделенного префикса

Теперь перейдём к варианту, когда нам выделено, в лучшем случае, от /63 до /48, в худшем /64. Сначала рассмотрим лучший вариант.

Первое, что необходимо проверить, что сетевой интерфейс вашего сервера настроен на сеть стандартного размера /64. В этом случае принятый пакет из диапазона, выходящего за его пределы, будет передан в соответствии с таблицей маршрутизации.

В IPv6 есть функция обнаружения соседей. Это означает, что если хост хочет с кем-то связаться, то в первую очередь отправляет запрос на поиск соседа с заданным адресам. Если будет получен ответ, то хост сможет направить данные напрямую, минуя маршрутизатор. Если хост назначения недоступен, то узел воспользуется таблицей маршрутизации и отправит пакет на соответствующий маршрутизатор. Для IPv4 эта ситуация немного необычна. А в IPv6 пакеты между разными диапазонами адресов могут ходить напрямую между хостами, а также, существуют ситуации, когда даже хосты в одной сети будут общаться через маршрутизатор.

Поскольку мы назначили для своего сервера сеть /64, то при попытке маршрутизатора провайдера найти соседа с адресом, который не попадает в данную подсеть, наш хост будет эти запросы игнорировать. Чтобы этого не происходило, можно воспользоваться специальной службой NDP proxy. Этот служба может пересылать запросы на поиск соседей и возвращать ответы и отвечать на указанные запросы положительным ответом. К сожалению, Wireguard работает на более высоком сетевом уровне, поэтому единственным вариантом для нас является просто выдача положительных ответов при запросе адресов, которые используются в VPN.

Одним из вариантов решения задачи - это установка пакета ndppd. Пакет точно доступен в стандартных поставках Ubuntu и Fedora в официальных репозиториях. Установите его с помощью вашего пакетного менеджера. Конфигурация ndppd достаточно простая. Файл конфигурации сервиса расположен по адресу /etc/ndppd.conf. Содержимое этого файла должно быть примерно таким:

proxy ens3 {
rule 2001:0db8:827:fcde:cafb:073d:a65e:25b0 {
static
}
}

Данная конфигурация означает, что если приходит запрос на интерфейс ens3 с запросом соседа по адресу 2001:0db8:827:fcde:cafb:073d:a65e:25b0, то необходимо ответить, что это наш адрес. Записи rule можно повторить несколько раз и, даже, указать в каждой записи не отдельный адрес, а целый диапазон. Однако сам ndppd не приветствует широкую маску сети. Если клиентов VPN немного, лучше для каждого из них создать свою запись.

Шаг 2.1: Что делать, если у нас только сеть /64

Это самый неблагоприятный вариант, но при этом мы всё равно сможем обеспечить работу нашего VPN. Вообще, сама идея разделять диапазон /64 на сети меньшего размера, мягко говоря, не приветствуется. Но поскольку у нас нет другого выхода, то придётся это сделать.

Поскольку мы используем VPS, то вряд ли будем использовать механизм SLAAC, которы работает только с сетями /64. К тому же, в большинстве случаев, адресация для VPS прописывается вручную, просто потому, что у сервера должен быть строго определённый адрес. Исходя из этого можно разделить сеть /64 на сети меньшего размера. Как делить? Если вы не планируете запускать на сервере другие сервисы VPN, то самым оптимальным вариантом являются сети /65, т.е. сеть /64 мы делим пополам. В этом случае для клиентов VPN нам доступны почти все биты из диапазона /64, кроме старшего. При таком разделении наш адрес будет выглядеть как обычный адрес, который, например, мог бы быть выделен через SLAAC.

Если кроме Wireguard вы хотите, например, также запустить на вашем сервере ещё и OpenVPN, то вам может понадобиться ещё одна сеть для этого сервиса. В таком случае вы можете выбрать сеть /66. Конечно, в этом случае вам нужно учитывать уже не один старший бит, а два. Можно и дальше сужать сети, но при этом адреса ваших клиентов будут уже не так похожи на адреса, которые обычно выделяются при использовании механизма SLAAC. Вариант отличные от /65 вы можете организовать самостоятельно.

Чтобы ваш сервер обеспечил маршрутизацию пакетов, которые необходимо будет отправить клиенту VPN, необходимо урезать сеть в настройках сетевого интерфейса. Вместо /64 указываем выбранную маску, например, /65. После этого настройка вашего VPN сервера не отличается от настроек, которые мы делали на шаге 2. Конечно, маску /65 нужно указать и в настройках Wireguard на вашем сервере.

Практическая часть

Дабы не вдаваться в подробности, будем считать, что вы ознакомились с моей «Шпаргалкой по Wireguard» или любой другой инструкции, которых очень много в интернете, и вам не надо объяснять как генерировать ключи.

Включаем маршрутизацию на VPS путём установки параметров, например, путём добавления файла /etc/sysctl.d/20-vpn.conf и загрузки их через sysctl -p или путём перезагрузки VPS:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding = 1

Сгенерируйте пару ключей для своего VPN сервера, например так

wg genkey | tee private.key | wg pubkey > public.key

Для дополнительной безопасности для каждого клиента может быть сгенерирован ключ PSK, но это не обязательно:

wg genpsk > psk.key

Аналогичным образом сгенерируйте ключи для всех ваших клиентов. После этого можно сформировать серверную конфигурацию для Wireguard.

[Interface]
Address = 192.168.0.1/24, 2001:0db8:827:fcde::1/64
PrivateKey = <SERVER_PRIVATE_KEY>
ListenPort = <SERVER_PORT>

[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 192.168.0.2, 2001:0db8:827:fcde::1ce:1ce:babe
PresharedKey = <PRESHARED_KEY>

Не сложно догадаться, что <SERVER_PRIVATE_KEY> - это закрытый ключ сервера, а <CLIENT_PUBLIC_KEY> - это публичный ключ клиента. 192.168.0.0/24 - это сеть IPv4 для нашего подключения, а адрес 192.168.0.1 будет присвоен интерфейсу Wireguard. По аналогии, 2001:0db8:827:fcde::/64, соответственно сеть IPv6, а адрес 2001:0db8:827:fcde::1 - адрес интерфейса Wireguard. Опция PresharedKey не обязательная, но если она указана на сервере, то она также должна быть указана в конфигурации клиента, значение ключей на сервере и клиенте должно совпадать.

Секция [Peer] должна быть создана для каждого клиента. В AllowedIPs должны быть указаны IP адреса и сети, которые мы ожидаем от клиента.

Конфигурации клиентов должны иметь вид

[Interface]
Address = 192.168.0.2, 2001:0db8:827:fcde:beef:1ce:1ce:babe
PrivateKey = <CLIENT_PRIVATE_KEY>

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
AllowedIPs = 0.0.0.0/0, 2000::/3
Endpoint = <SERVER_NAME>:<SERVER_PORT>
PresharedKey = <PRESHARED_KEY>
PersistentKeepalive = 20

Аналогично, на клиенте: <CLIENT_PRIVATE_KEY> - закрытый ключ клиента, <SERVER_PUBLIC_KEY> - публичный ключ сервера. В Endpoint необходимо указать адрес <SERVER_NAME> и порт <SERVER_PORT> сервера, которые соответствуют указанным параметрам в настройках сервера. Параметр PresharedKey должен присутствовать, если он есть в секции [Peer] для этого клиента, содержимое ключа должно совпадать.

PersistentKeepalive может также отсутствовать. Но если указано, то клиент каждое указанное количество секунд будет отправлять пакет данных. Это полезно в тех случаях, когда клиент находится за NAT или Firewall, которые при отсутствии активности могут запретить удалённому хосту присылать вам ответы.

Чтобы обеспечить доступ клиентов в интернет по протоколу IPv4, необходимо включить NAT, например, с помощью скриптов, которые необходимо добавить в секцию `[Interface]` на сервере, и отключить их, если клиенты отключаются.

PostUp = iptables -A FORWARD -i %i -j ACCEPT -w 10; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE -w 10
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE

Автоматизация

Конечно, делать все необходимые настройки руками, особенно если новый клиент вашего VPN появляется не часто, это просто сущее наказание. Поэтому я задумался об автоматизации. В качестве базы был найден скрипт nebulakl/wireguard-config-generator. Он не совсем подходил под мои нужды, поэтому я его переделал и выложил в fsa/wireguard-config-generator.

Скрипт позволяет генерировать конфигурацию для сервера VPN на базе Wireguard. Далее можно генерировать необходимое количество конфигураций клиентов. Скрипт сохранил возможность использования NAT66, как было в оригинальном скрипте, но включение NAT66 производится явно через редактирование конфигурации сервера. По умолчанию скрипт использует «серую» адресацию, как в оригинальном скрипте.

Комментарии (29)


  1. MaxSoniX
    06.08.2023 20:58

    используются спорные решения.

    самым оптимальным вариантом являются сети /65

    При /64 на VPS, для пира маршрутизатора логичней передать (почти) всю /64 - хотя бы автоматизация в виде slaac будет работать.

    [Interface]
    Address = 2001:0db8:827:fcde::1/128
    
    [Peer]
    AllowedIPs = 2001:0db8:827:fcde::/64
    # На маршрутизаторе не использовать адреса gateway (если он из этой /64) и 2001:0db8:827:fcde::1/128 т.к. они уже используются.

    Либо для любых клиентов пиров указывать по /128, всё равно автоматизацией не выйдет нормально пользоваться.


  1. apevzner
    06.08.2023 20:58

    Если это всё только лишь ради того, чтобы получить доступ к запрещенным сайтам, IMHO, это некоторый overkill

    Я для этой цели написал программучину, https://github.com/alexpevzner/froxy

    Со стороны сервера ей не надо ничего, кроме доступа по SSH, и чтобы port forwarding был открыт (по умолчанию он обычно открыт). На клиенте настройка тоже не сложная

    Она - http-proxy, ее прописывают в качестве прокси для веб-бровсера (или для любой другой программы, которая использует HTTP). И у нее можно регулировать, какие сайты посещаются напрямую, а какие - через VPS


    1. FSA Автор
      06.08.2023 20:58

      Вообще для socks-прокси достаточно одной команды: ssh server -D 1080. Прописываем 127.0.0.1:1080 в качестве socks прокси прямо в браузере, либо в расширении, которое будет туда отправлять только нужные домены.

      А, вообще, заметка о том как сделать себе именно VPN сервер с IPv6. Как уж вы его будете применять, это ваше дело. Например, можно получать доступ к IPv6 ресурсам через сотового оператора, который этот протокол не поддерживает (Tele2, Yota, Билайн, Мотив). Тогда просто настройки для IPv4 можно полностью убрать.


      1. apevzner
        06.08.2023 20:58

        Вообще для socks-прокси достаточно одной команды: ssh server -D 1080

        Я знаю, да. Моя утилитка добавляет мультиплексирование по именам доменов, куда ходить через SSH, а куда - напрямую

        А, вообще, заметка о том как сделать себе именно VPN сервер с IPv6

        Это понятно, да, Ну просто Вы приводите в качестве примера именно этот случай...


    1. grebnebo
      06.08.2023 20:58

      Существует еще прекрасная наработка по wireguard клиент-серверу: easy-wg-quick с гитхаба. Умеет всё вышеперечисленное из коробки + генерацию конфигов с QR. Статья разве только для самообразования пригодится.


      1. FSA Автор
        06.08.2023 20:58

        У меня была цель описать как я настраивал свой сервер в условиях ограничений на IPv6. Изначально вообще было непонятно как и что нужно настраивать.

        Скрипт для настройки родился чуть раньше. Мне просто надоело руками генерировать ключи. Но потом оказалось, что и остальное тоже можно автоматизировать так или иначе.

        За ссылку спасибо, обязательно посмотрю что там другие придумали.


  1. therealman_tm
    06.08.2023 20:58

    Очень смущает директива AllowedIPs у клиента. Какой клиентский трафик вы хотите пропускать через WG сервер?

    [Peer]

    AllowedIPs = 192.168.0.0/24, 2000::/3


    1. FSA Автор
      06.08.2023 20:58

      Вы правы, недоглядел. Исправил.


      1. therealman_tm
        06.08.2023 20:58

        Тогда и для IPv6 нужно: ::/0


        1. FSA Автор
          06.08.2023 20:58

          В данный момент достаточно 2000::/3. Позже, когда начнут выделять диапазоны 4000:: и дальше, нужно будет переделывать. Впрочем, можно и сейчас указать ::/0, если желаете.


  1. osj
    06.08.2023 20:58
    +4

    Странно почему все молчат, но Wireguard начали блокировать большинство провайдеров, рукопожатие не проходит уже неделю на европейские/американские сервера.


    1. GennPen
      06.08.2023 20:58

      Какой провайдер?

      Домру, Ростелеком, Мегафон не блокируют на нестандартном порту. Сервер в Нидерландах.


      1. osj
        06.08.2023 20:58
        +1

        МГТС, МТС, Билайн, Мегафон, Orange блокируют на любом порту.


        1. Darkformer
          06.08.2023 20:58

          Странно. У меня таких проблем не наблюдается.

          У МГТС есть своя специфика, что они в принципе почти все порты блокируют, пока не куплена услуга с белым IP (даже если и так выдавался белый).

          А у МТС наблюдал отдельные базовые станции, на который действительно не работал WG (но это скорее исключение, чем правило).


        1. GennPen
          06.08.2023 20:58

          А preshared key используется?


          1. WapGraf
            06.08.2023 20:58

            И с ним не работает.


        1. KyJIep-79
          06.08.2023 20:58

          Мобильный МТС- wireguard работает без проблем - два дня назад из Ярославля вернулся- и там нет проблем, и дома не возникало. Стационарный МГТС- нет проблем и не возникало.


    1. bndo
      06.08.2023 20:58
      +1

      +++, тоже на данный момент не работает с мобильного интернета -- Билайн, Мтс, Йота и Мегафон. С проводного пока еще все в норме.


  1. AlexHighTower
    06.08.2023 20:58

    а на oracle free tier кто нибудь настраивал ipv6 для wireguard?
    они вроде как дают /64 подсеть, однако на ens3 интерфейс адрес можно получить только через dhcpv6 и он ставится /128
    попытки прописать любой другой адрес на внешний интерфейс из /64 подсети дают нерабочий v6 вариант


  1. denisemenov
    06.08.2023 20:58

    Но ведь сейчас операторы активно блокируют ovpn и wireguard... ????


  1. shadrap
    06.08.2023 20:58

    Да wireG блокируют в Мегафон. Сначала помогала смена порта, теперь и она не помогает.


    1. AlexHighTower
      06.08.2023 20:58

      у меня сегодня на мегафоне перестал работать WireGuard в асмтердам
      да и ikev2 и l2tp тоже
      внутри россии всё работает без проблем


      1. WapGraf
        06.08.2023 20:58

        И WireGuard внутри страны работает?


        1. AlexHighTower
          06.08.2023 20:58

          да, с мобильного (мегафон, теле2) wg работает внутри страны без проблем, а за границу — нет. аналогично с ikev2 и l2tp
          через проводной инет всё работает за границу


  1. WapGraf
    06.08.2023 20:58

    Все это не актуально, так как у большой части России сегодня WireGuard перестал работать. Порт не имеет значения.


    1. FSA Автор
      06.08.2023 20:58

      Возможно тестируют в европейской части России. На Урале и за ним даже на Ростелекоме работает. Какое-то неудачное время я выбрал для публикации... Обсуждение идёт не материала, а проблем :(


      1. cadmi
        06.08.2023 20:58

        в Красноярском крае не работает :)


      1. Ryav
        06.08.2023 20:58

        Так вы предложите решение проблемы — статья сразу интереснее станет :)


        1. FSA Автор
          06.08.2023 20:58

          Мне не на чем тестировать. У меня всё работает. Есть подозрение, что проблема связана с CGNAT.