Вдохновившись аргументами из статьи «IPv6 — прекрасный мир, стоящий скорого перехода на него», мне стало катастрофически не хватать IPv6. Конечная цель: обеспечить каждое из своих устройства уникальным публичным псевдостатическим IPv6.
Для дома решение довольно простое: при наличии статического IPv4, можно получить подсеть IPv6 от туннельного брокера и на этом вопрос можно считать закрытым.
А вот с мобильными устройствами так не получится: услуга статического IPv4 тут скорее редкость; да и при наличии бесплатного WiFi я выберу подключение к нему, а не к мобильной сети.
Остаётся единственный вариант — использовать VPN. Существующие на GitHub решения типа “wireguard-install” или “openvpn-install” имеют фатальный недостаток: они отдают клиенту единственный IPv6/128 адрес, а чтобы у клиентов появилась возможность автоконфигурации, нужна целая /64 подсеть.
Предлагается решение на основе WireGuard.
Вам понадобятся
-
Особый виртуальный сервер. Для реализации задуманного, нужно купить VDS, которому хостер согласится отдать хотя бы /60 подсеть. Как оказалось, найти такое — достаточно сложная задача: в худшем случае, хостеры почему-то продают IPv6 поштучно; в лучшем — только /64 подсети. В результате долгих поисков и благоприятного стечения обстоятельств, был найдена компания Melbicom, которая способна выделить /56 подсеть на VDS.
-
Linux + wireguard + udppd + nftables. На моём сервере установлен ArchLinux, но описанное решение может быть воспроизведено и на других дистрибутивах.
Условные обозначения
ens3
– имя сетевого интерфейса.
Далее в тексте используются следующие «IP» адреса:
-
2a06:X:X:a::2/128
и213.x.x.2/24
– IPv6 и IPv4 адреса VDS. Назначаются хостером автоматически и бесплатно к каждому приобретаемому VDS. -
2a06:X:X:100::/56
– Маршрутизируемая до VDS подсеть /56 IPv6. Заказывается отдельно. -
2a06:X:X:111::/64
– подсеть для клиента (мобильного устройства), которая выделяется из заказанной выше /56 подсети. -
2a06:X:X:111:a:b:c:d/64
– пример IPv6 клиента (мобильного устройства), гдеa:b:c:d
(interface id) выбирается клиентом самостоятельно.
Где заглавная буква X
означают одну группу шестнадцатеричных цифр IPv6 адреса, а строчная x
— одну группу десятичных цифр IPv4 адреса.
Тестирование наличия выделенной /56 подсети
Изначально, на сервере сеть не должна быть настроена, но должна маршрутизироваться до него. Содержимое /etc/systemd/network/ens3.network выглядит примерно так:
[Match] Name = ens3 [Network] Address = 213.x.x.2/24 Gateway = 213.x.x.1 Address = 2a06:X:X:a::2/128 Gateway = 2a06:X:X:a::1
Для проверки, выполним команду: tcpdump ip6 -nq -i ens3
Далее, пингуем любой IPv6 из выделенной подсети, например 2a06:X:X:111:a:b:c:d
. Если всё хорошо, то в дампе появятся строки типа:
19:14:39.689842 IP6 fe80::XX > ff02::XX ICMP6, neighbor solicitation, who has 2a06:X:X:111:a:b:c:d, length 32
Установка ndppd
Ndppd — это демон, задача которого слушать интерфейс: ожидать «neighbor solicitation» и отвечать «router advertisement» Таким образом, вышестоящий роутер узнает, куда адресовать трафик выделенной подсети. Далее этот трафик через wireguard будет передан клиенту.
К сожалению, в ArchLinux ndppd пока доступен только из AUR. Если в вашем дистрибутиве он доступен из репозиториев, переходите к следующем разделу.
Для начала ставим все необходимые компоненты: pacman -Suy git base-devel
Далее создаём пользователя, под которым будем все это собирать:useradd -m router
Переходим в пользователя:su router
cd /home/router
Теперь из-под пользователя выполняем команды:git clone https://aur.archlinux.org/ndppd.git
cd ndppd
makepkg
Возвращаемся в root:exit
Переходим в каталог ndppd:cd /home/router/ndppd
Находим в каталоге ndppd-*.zst файл и устанавливаем его:pacman -U ndppd-0.2.5-1-x86_64.pkg.tar.zst
Настройка ndppd
Создаём файл /etc/ndppd.conf с содержимым:
proxy ens3 { rule 2a06:X:X:100::/56 { static } }
Где:
-
ens3
– имя интерфейса -
static
— опция, которая сообщает ndppd, что он должен немедленно отвечать на Neighbor Solicitation, без дополнительных проверок.
Подробное описание параметров изложено в документации.
Далее активируем сервис:systemctl enable ndppd
и запускам:systemctl start ndppd
Установка системных переменных
Чтобы заработала пересылка IPv6 пакетов между интерфейсами, необходимо в каталоге /etc/sysctl.d/ создать файл wireguard.conf с содержимым:
net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1
Первая строка включает пересылку IPv4, вторая — IPv6. Подробное описание каждого из параметров можно узнать из документации.
Применяем настройки:sysctl --system
Настройка WireGuard на сервере
Создаём публичный и приватный ключи сервера:wg genkey | tee server-private.key | wg pubkey > server-public.key
Создаём публичный и приватный ключи клиента:wg genkey | tee client1-private.key | wg pubkey > client1-public.key
Создаём pre-shared key:wg genpsk > pre-shared.key
Создаём файл /etc/wireguard/wg0.conf:
[Interface] SaveConfig = false ListenPort = 52525 #Может быть любым PrivateKey = #содержимое server-private.key# Address = 10.20.30.1/24, 2a06:X:X:100::/56 [Peer] PublicKey = #содержимое client1-public.key# PresharedKey = #содержимое pre-shared.key# AllowedIPs = 10.20.30.17/32, 2a06:X:X:111::/64
Активируем и запускаем демона wireguard:systemctl enable wg-quick@wg0 && systemctl start wg-quick@wg0
В случае изменеия конфигурации, перезапуск удобно выполнять командой:wg-quick down wg0 && wg-quick up wg0
Настройка nftables
Поскольку iptables постепенно выходит из употребления, я предпочитаю nftables.
Установка командой:pacman -S nftables
Для конфигурации нужно создать или отредактировать файл /etc/nftables.conf :
#!/usr/sbin/nft -f # Start by flushing all the rules. flush ruleset # Документация https://man.archlinux.org/man/nft.8 # Определение переменных: интерфейсы и виртуальная локальная IPv4 подсеть define wan = ens3 define vpn = wg0 define vpn_net4 = 10.20.30.0/24 # Общие настройки для IPv6 и IPv4 table inet wg-common { # Все пересылаемые пакеты по умолчанию дропаем, за исключением тех, которые идут между vpn и wan chain forward { type filter hook forward priority 0; policy drop; iifname $wan oifname $vpn accept; oifname $wan iifname $vpn accept; } chain input { type filter hook input priority 0; # allow established/related connections ct state {established, related} accept # early drop of invalid connections ct state invalid drop # allow from loopback iifname lo accept # allow icmp ip protocol icmp accept meta l4proto ipv6-icmp accept # allow ssh tcp dport ssh accept # Разрешаем вкходящие соединения с WireGuard udp dport 52525 accept; # everything else reject with icmpx type port-unreachable } } # Настройка NAT для IPv4 table ip wg-nat { # Все исходяющие пакеты IPv4 c подсети vpn на интерфейс wan подвергаются маскараду chain pre { type nat hook postrouting priority 0; oifname $wan ip saddr $vpn_net4 masquerade persistent; } }
Настройка WireGuard на клиенте
Конфигурация клиента выглядит так:
[Interface] PrivateKey = #содержимое client1-private.key# Address = 10.20.30.17/32, 2a06:X:X:111:a:b:c:d/64 DNS = 9.9.9.9, 149.112.112.112, 2620:fe::fe, 2620:fe::9 [Peer] PublicKey = #содержимое server-public.key# PresharedKey = #содержимое pre-shared.key# AllowedIPs = 2000::/3 Endpoint = #Публичный IP сервера, или домен#:52525 PersistentKeepalive = 25
На этом конфигурация завершена. Всё, что осталось это установить на телефон WireGuard, импортировать полученный конфиг, включить и пользоваться IPv6. Важной особенностью тут является то, что в IPv6 адресе клиента вместо a:b:c:d
можно указать абсолютно любой interface id. Такой себе ручной SLAAC. А если хочется пустить через wireguard ещё и весь IPv4 трафик, в поле AllowedIPs
добавьте подсеть 0.0.0.0/0
.
Бонус: обход блокировок
Если из-за политики государства, часть Интернета заблокирована, при помощи клиента WireGuard на роутере с OpenWRT можно обойти блокировку.
Для этого переносим конфиг клиента на роутер с OpenWRT, указав в параметре AllowedIPs
заблокированные подсети. Например, чтобы разблокировать Яндекс из Украины, нужно указать:
AllowedIPs=5.45.192.0/18,5.45.196.0/24,5.45.202.0/24,5.45.205.0/24,5.45.213.0/24,5.45.229.0/24,5.45.240.0/24,5.255.192.0/18,5.255.195.0/24,5.255.196.0/24,5.255.197.0/24,5.255.255.0/24,37.9.64.0/18,37.9.64.0/24,37.9.73.0/24,37.9.112.0/24,37.140.128.0/18,77.88.0.0/18,77.88.8.0/24,77.88.35.0/24,77.88.44.0/24,77.88.54.0/24,77.88.55.0/24,87.250.224.0/19,87.250.247.0/24,93.158.128.0/18,95.108.128.0/17,100.43.64.0/19,141.8.128.0/18,141.8.174.0/24,178.154.128.0/19,178.154.131.0/24,178.154.160.0/19,185.32.187.0/24,199.21.96.0/22,199.36.240.0/22,213.180.192.0/19,213.180.199.0/24,2a02:6b8::/29,2620:10f:d000::/44
Список подсетей Яндекса взят отсюда https://ipinfo.io/AS13238
IPv4 заработает сразу. А чтобы заработал IPv6, нужно при помощи nat6 подменить префикс клиента. В разделе Firewall :: Custom Rules допишем следующие пользовательские правила:
ip6tables -t nat -A POSTROUTING -d 2a02:6b8::/29 -j NETMAP --to 2a06:X:X:111::/64 ip6tables -t nat -A POSTROUTING -d 2620:10f:d000::/44 -j NETMAP --to 2a06:X:X:111::/64
После этого можно перейти на https://yandex.ru/internet/ и убедиться, что всё работает.
ссылка на оригинал статьи https://habr.com/ru/post/565692/
Добавить комментарий