В предыдущих частях цикла статей (часть 1, часть 2) мы настроили подключение к IPv6-брокеру на VDS под управлением операционной системы CHR от Mikrotik. Подготовили туннелирование до устройств сети, которые как умеют, так и нет работать с VPN, используя PPTP, SSTP и статическую маршрутизацию. Уделили достаточно внимания обеспечению сетевой безопасности подключаемых к IPv6 пользователей.

Настало время перенести всё на Linux. При этом самая простая задача (конфигурирование клиента для подключения к брокеру) уже выполнена. В завершающей части цикла настроим туннелирование IPv6 до устройств домашней сети посредством старого доброго L2TP, а для работы мобильных устройств дополнительно организуем IKEv2-сервер. Чтобы лучше понимать происходящие процессы, рекомендуется ознакомиться с предыдущими двумя статьями, так как с целью исключения болтологии вводный материал повторяться не будет.

▍ Туннелирование IPv6 до устройств домашней сети


По аналогии с RouterOS первым организуем хоть и устаревший, но простейший в настройке VPN-протокол PPTP. С этим справится даже самый неподготовленный читатель. Установим необходимое программное обеспечение, сконфигурируем IPv4-адреса на концах туннеля, укажем данные аутентификации пользователя VPN, запустим службу:

apt install pptpd
nano /etc/pptpd.conf

localip 192.168.99.1
remoteip 192.168.99.2

nano /etc/ppp/chap-secrets
user01	*	123paS$woRd321	*

systemctl restart pptpd

Гораздо большее количество параметров при желании можно подкрутить в конфигурации VPN-сервера /etc/ppp/pptpd-options. Настройку клиента рассматривать не буду, она тривиальна. После установления соединения можно увидеть поднявшийся туннельный интерфейс:

ifconfig ppp0

ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1396
        inet 192.168.99.1  netmask 255.255.255.255  destination 192.168.99.2
        inet6 fe80::c1b0:3c81:637d:e8cf  prefixlen 128  scopeid 0x20<link>
        ppp  txqueuelen 3  (Point-to-Point Protocol)
        RX packets 76  bytes 20727 (20.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13  bytes 330 (330.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Чтобы клиент вышел в IPv6-сеть, проще всего на сервере настроить приложение, которое сконфигурирует туннель правильным для этого образом. Посредством представленной выше технологии router advertisement устройства в lan-сети получат префикс, который нам делегирован брокером, и сами выставят IPv6-адрес. А вот добавить его на интерфейс Linux придётся вручную:

apt install radvd
nano /etc/radvd.conf

interface ppp0
{
   AdvSendAdvert on;
   prefix 2001:459:14:210::/64
   {
       AdvOnLink on;
       AdvAutonomous on;
   };
};

systemctl restart radvd
ip addr add 2001:459:14:210::1/64 dev ppp0

Для автоматизации последнего действия можно добавить в скрипт конфигурации туннельных интерфейсов код, который выполнится после установки VPN-соединения:

echo "ip addr add 2001:459:14:210::2/64 dev $PPP_IFACE" >> /etc/ppp/ip-up

Теперь клиент подключился к миру IPv6 точно так же, как и в схеме с CHR. Аналогично подкрутим правила в firewall filter и src-nat. В Linux рекомендуется использовать ufw, который, конечно же, проще старого и доброго iptables. Однако мы будем использовать проверенный временем вариант, потому что это позволит провести настройку аналогично с routeros, представленную во второй части цикла статей. В конце установим и сконфигурируем программный пакет, отвечающий за сохранение настроек firewall после перезагрузки сервера:

ip6tables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED -m comment --comment "Accept established,related"
ip6tables -A INPUT -j DROP -m state --state INVALID -m comment --comment "Drop invalid"
ip6tables -A INPUT -j ACCEPT -p icmpv6 -m comment --comment "Accept ICMP"
ip6tables -A INPUT -j ACCEPT -p udp --dport 33434:33534 -m comment --comment "defconf: accept UDP traceroute"
ip6tables -A INPUT -j DROP -m comment --comment "Drop all input"
ip6tables -A FORWARD -j ACCEPT -m state --state ESTABLISHED,RELATED -m comment --comment "Accept established,related"
ip6tables -A FORWARD -j DROP -m state --state INVALID -m comment --comment "Drop invalid"
ip6tables -A FORWARD -j ACCEPT -p icmpv6 -m comment --comment "Accept ICMP"
ip6tables -A FORWARD -j DROP -p tcp -m multiport --dports 135,445,1025,1026,1027,1030,1040,3389,5357 -i he-ipv6 -o ppp0 -m comment --comment "My windows TCP ports"
ip6tables -A FORWARD -j DROP -p udp -m multiport --dports 123,500,3702,4500,5353,5355 -i he-ipv6 -o ppp0 -m comment --comment "My windows UDP ports"

iptables -t nat -A POSTROUTING -s 192.168.99.0/24 -o eth0 -j SNAT --to ip_адрес_сервера

apt install iptables-persistent
dpkg-reconfigure iptables-persistent

Если на сервере работает Docker, то после запуска он перезатрёт все сохранённые IPv4 rules, поэтому их придётся применять повторно (в нашем контексте речь идёт о настройке src-nat). В работе правила будут выглядеть примерно так:

ip6tables -n -L -v --line-numbers

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1       16  1536 ACCEPT     all      *      *       ::/0                 ::/0                 state RELATED,ESTABLISHED /* Accept established,related */
2        0     0 DROP       all      *      *       ::/0                 ::/0                 state INVALID /* Drop invalid */
3        4   312 ACCEPT     icmpv6    *      *       ::/0                 ::/0                 /* Accept ICMP */
4        0     0 ACCEPT     udp      *      *       ::/0                 ::/0                 udp dpts:33434:33534 /* defconf: accept UDP traceroute */
5        0     0 DROP       all      *      *       ::/0                 ::/0                 /* Drop all input */

Chain FORWARD (policy ACCEPT 2 packets, 160 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     3999 2082K ACCEPT     all      *      *       ::/0                 ::/0                 state RELATED,ESTABLISHED /* Accept established,related */
2        0     0 DROP       all      *      *       ::/0                 ::/0                 state INVALID /* Drop invalid */
3        1    80 ACCEPT     icmpv6    *      *       ::/0                 ::/0                 /* Accept ICMP */
4        0     0 DROP       tcp      he-ipv6 ppp0    ::/0                 ::/0                 multiport dports 135,445,1025,1026,1027,1030,1040,3389,5357 /* My windows TCP ports */
5        0     0 DROP       udp      he-ipv6 ppp0    ::/0                 ::/0                 multiport dports 123,500,3702,4500,5353,5355 /* My windows UDP ports */

Chain OUTPUT (policy ACCEPT 51 packets, 4772 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Разобравшись с PPTP, переедем на более прогрессивный VPN-протокол L2TP с IPsec и настроим его реализацию с pre shared key, который хорош всем. Если последняя его характеристика вам не очень по душе, то в своей статье я рассматриваю это с точки зрения практической безопасности. Если коротко, то определённые риски есть и для enterprise он такой годится, но с оговорками. Обывателю можно не переживать, угрозы требуют очень даже больших возможностей со стороны атакующих.

Глушим сервер PPTP, устанавливаем демон IPsec с открытым программным кодом, настраиваем работу протокола, указываем данные аутентификации клиента VPN (командой openssl rand -base64 18 можно сгенерировать случайные значения) и запускаем службу:

systemctl stop pptpd
apt install strongswan
nano /etc/ipsec.conf

conn rw-base
    fragmentation=yes # фрагментация IKE
    dpdaction=clear # протокол обнаружения мёртвых узлов
    dpdtimeout=90s # отвечающий за обнаружение неактивных клиентов
    dpddelay=30s

conn l2tp-vpn
    also=rw-base
    ike=aes128-sha256-modp3072 # используемые шифры
    esp=aes128-sha256-modp3072
    leftsubnet=%dynamic[/1701]
    rightsubnet=%dynamic
    leftauth=psk # аутентификация по общему ключу 
    rightauth=psk
    type=transport # использовать транспортный режим IPsec
    auto=add

nano /etc/ipsec.secrets

%any %any : PSK "123Strong321"

systemctl restart strongswan-starter

Далее установим L2TP-сервер. Настроек, конечно, побольше. Файл с данными аутентификации будем использовать тот же, как и IPv4-адресацию (чтобы не править src-nat). Внесём правки в конфигурацию туннеля, оставив тип аутентификации mschapv2. Здесь же Windows-клиентам можно раздать IPv4-адреса DNS-серверов:

apt install xl2tpd
nano /etc/xl2tpd/xl2tpd.conf

[global]
port = 1701
auth file = /etc/ppp/chap-secrets # файл с данными для аутентификации
access control = no
ipsec saref = yes
force userspace = yes
[lns default]
exclusive = no
ip range = 192.168.99.2-192.168.99.9
hidden bit = no
local ip = 192.168.99.1 # адрес l2tp интерфейса сервера
length bit = yes
require authentication = yes
name = l2tp-vpn # имя сервера в файле chap-secrets
pppoptfile = /etc/ppp/options.xl2tpd # набор опций для ppp соединения
flow bit = yes

cp /etc/ppp/options /etc/ppp/options.xl2tpd
nano /etc/ppp/options.xl2tpd

asyncmap 0
auth
crtscts
lock
hide-password
modem
mtu 1460
lcp-echo-interval 30
lcp-echo-failure 4
noipx
-pap
-chap
-mschap
require-mschap-v2
multilink
mppe-stateful
ms-dns 8.8.8.8 # для windows клиентов (только ipv4)
ms-dns 8.8.4.4

Данные аутентификации VPN-клиента укажем в таком формате, закрепив за пользователем статический адрес для туннельного интерфейса (это опционально — если не нужно, то указываем *), после чего запускаем L2TP-сервер:

nano /etc/ppp/chap-secrets

user02   l2tp-vpn   123Strong321Password   192.168.99.2

systemctl restart xl2tpd

Данный протокол хотя и немного сложнее в настройке, но клиентская часть такая же элементарная, как и в первом случае, поэтому её настройку опущу. При подключении на сервере автоматически поднимется туннельный интерфейс, который будет уже настроен на работу с IPv6-программой radvd, сконфигурированной ранее, так как имена PPTP- и L2TP-интерфейсов совпадают:

ifconfig ppp0

ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1400
        inet 192.168.99.1  netmask 255.255.255.255  destination 192.168.99.2
        inet6 2001:459:14:210::2  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::7007:c553:e69f:2a9d  prefixlen 128  scopeid 0x20<link>
        ppp  txqueuelen 3  (Point-to-Point Protocol)
        RX packets 149  bytes 45471 (44.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 37  bytes 9441 (9.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


Windows-клиент дополнительно получил DNS сервера, настроил свой интерфейс и подключился к IPv6-миру. Firewall на Linux трогать не надо, всё сделано ранее. Однако есть нюанс. Оказывается, одна из самых распространённых в мире мобильных операционных систем iOS умеет работать с L2TP, но не умеет настраивать на нём IPv6. Разработчики Apple сосредоточены в первую очередь на поддержке современных перспективных технологий. Очевидно, что L2TP к ним не относится. А иметь IPv6 всегда под рукой тоже хочется, например, чтобы проведывать прямым подключением устройства из домашней сети, вроде видеокамер. Поэтому далее по плану идёт настройка хорошего всем IKEv2 VPN-протокола, работающего на VDS совместно с L2TP, который отключать не будем, ведь его поддержка оконечным оборудованием всё-таки более широкая.

▍ Туннелирование IPv6 до мобильных устройств


Настройка IKEv2-сервера позволит подключать мобильные устройства к Linux-серверу и получать при этом настройки IPv6. При конфигурировании этого протокола не получится обойтись без pki. Публичный сертификат удостоверяющего центра в обязательном порядке должен быть помещён в инфраструктуру сертификатов в операционной системе клиента VPN. Для Windows можно воспользоваться предназначенной для этого оснасткой certmgr.msc. В Linux скопировать его в нужный каталог, например /usr/local/share/ca-certificates/extra/, и выполнить после этого update-ca-certificates). В iOS проще всего отправить сертификат самому себе письмом и из интерфейса почтового клиента интерактивно импортировать в операционную систему.

Приступим к созданию инфраструктуры. Сгенерируем и подпишем необходимые ключи (сертификаты) центра сертификации и VPN-сервера (кому привычнее работать с easy-rsa, то можно воспользоваться ей):

mkdir -p ~/pki/{cacerts,certs,private}
pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/ca-key.pem			
pki --self --ca --lifetime 3650 --in ~/pki/private/ca-key.pem --type rsa --dn "CN=IKEv2 my_server.ru root CA" --outform pem > ~/pki/cacerts/ca-cert.pem
pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/server-key.pem
pki --pub --in ~/pki/private/server-key.pem --type rsa > ~/pki/certs/server-cert.req
pki --issue --lifetime 3650 --cacert ~/pki/cacerts/ca-cert.pem --cakey ~/pki/private/ca-key.pem \
	--dn "CN=доменное_имя_vpn_сервера" --san доменное_имя_vpn_сервера --flag serverAuth --flag ikeIntermediate \
	--outform pem --in ~/pki/certs/server-cert.req > ~/pki/certs/server-cert.pem 

Флаг serverAuth указывает на то, что сертификат будет явно использоваться для проверки подлинности сервера до того, как будет установлен туннель. Параметр ikeIntermediate нужен для поддержки старых клиентов macos. Значение CN (common name) является DNS-именем или IPv4-адресом VDS. Параметр san @ipv4_адрес_сервера необходим, так как некоторые клиенты будут проверять как наличие в сертификате tls записи DNS, так и записи IP-адреса для сервера при проверке его подлинности. Установим на VDS программное обеспечение:

apt install strongswan strongswan-pki libcharon-extra-plugins \
    libcharon-extauth-plugins libstrongswan-extra-plugins

В интернете имеется информация, что strongswan из репозитория Debian некорректно работает с Windows клиентами, поэтому при такой необходимости проведём сборку пакета на месте:

apt install autoconf libtool gettext gperf libgmp-dev bison flex
git clone https://github.com/strongswan/strongswan.git
cd strongswan/
./autogen.sh
./configure --enable-eap-identity --enable-eap-mschapv2 --enable-md4
make
make install

Сконфигурируем VPN-сервер. Поместим ключи и сертификаты в нужные каталоги, настроим IKEv2 для работы с IPv6 (указан широкий пул методов шифрования с целью поддержки наибольшего набора клиентов, так как с этим реально бывают проблемы):

cp -r ~/pki/* /etc/ipsec.d/
# Если сборка проводилась на месте, директории немного изменятся
# cp -r ~/pki/* /usr/local/etc/ipsec.d/

nano /etc/ipsec.conf
# nano /usr/local/etc/ipsec.conf

config setup
	charondebug="ike 1, knl 1, cfg 0" # детализация логирования
	uniqueids=no # разрешать дублирование соединений

conn ikev2-vpn
	auto=add # автоматически загрузить этот раздел конфигурации при запуске
	compress=no
	type=tunnel
	keyexchange=ikev2
	fragmentation=yes # включение внутренней фрагментации пакетов
	forceencaps=yes

	dpdaction=clear # очищать любые зависшие соединения
	dpddelay=300s # для неожиданного отключения клиента
	rekey=no # выключение инициации смены ключей со стороны сервера
	left=%any
	leftid=@доменное_имя_сервера
	leftcert=server-cert.pem
	leftsendcert=always
	leftsubnet=0.0.0.0/0,::/0 # ipv4 и ipv6 сети
	right=%any
	rightid=%any
	rightauth=eap-mschapv2	# аутентификация
	rightsourceip=192.168.99.10/24,2001:…8::/64 # указать ipv4 сеть vpn клиентов и свой ipv6 префикс
	rightdns=8.8.8.8,2001:4860:4860::8888
	rightsendcert=never

	eap_identity=%identity # запрашивать у клиента учётные данные пользователя при подключении
	ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
	esp=chacha20poly1305-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,3des-sha1!

Всё в том же месте зададим данные аутентификации пользователя VPN и сгенерированный ранее закрытый ключ, после чего можно запускать серверную часть IKEv2:

nano /etc/ipsec.secrets
# nano /usr/local/etc/ipsec.secrets

: RSA "server-key.pem"
user9 : EAP "123StronGkey321"

systemctl restart strongswan-starter
swanctl –L # посмотреть статистику

Конфигурирование клиентов для Windows и iOS как всегда тривиально. При их подключении на VDS не создаётся туннельного интерфейса, при этом протокол выполнит настройки адресации автоматически. На iPhone работающий VPN-клиент будет выглядеть примерно так, как показано на рисунке ниже:


Обращаю внимание, что в моём случае телефон получил IPv4-адрес, как и у туннельного интерфейса L2TP-сервера. При одновременной работе это вызовет конфликт. Чтобы его избежать, не составит труда изменить local ip на другое значения и подкорректировать ip range в настройках L2TP-сервера. Для Linux-клиентов IKEv2 придётся доустановить необходимые пакеты, а дальнейшую настройку можно будет провести через gui. Мне пришлось явно указать метод шифрования:

apt install strongswan strongswan-pki libcharon-extra-plugins \
    libcharon-extauth-plugins libstrongswan-extra-plugins


Этот раздел в первую очередь касается настройки IPv6 для iPhone, потому что для других операционных систем можно с помощью меньших усилий довольствоваться L2TP. Кстати, на некоторых устаревших Windows IKEv2-клиент так и не смог подключиться к VPN-серверу, какие бы правки в реестр я ни вносил. Причину установить так и не удалось.

▍ Заключение


В представленных материалах с практической точки зрения показано, как получить и сконфигурировать IPv6 на различных, в том числе мобильных устройствах там, где его нет. В работе используется dual stack, когда устройство одновременно настроено на работу обоих IP-протоколов. Рассмотрены различные сценарии проброса туннеля от сервера до клиента для организации последней мили, чтобы читатель различного уровня подготовки мог самостоятельно реализовать подходящий вариант на различных операционных системах (Windows, Linux, RouterOS и iOS): PPTP, SSTP, L2TP и IKEv2. Особое внимание уделено настройке сетевой безопасности для нового протокола.

Конечной целью статьи является популяризация IPv6 посредством отображения его доступности как с технической, так и финансовой точек зрения. Конечно, чтобы работать с VDS, нужно его арендовать, но сейчас для этого необходимы минимальные вложения, а у многих IT-специалистов этого добра уже хватает в наличии. Попробуйте начать работу с IPv6, и со временем нового протокола в вашем сетевом трафике будет становиться только больше.


Узнавайте о новых акциях и промокодах первыми из нашего Telegram-канала ????

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


  1. alexkuzko
    18.10.2023 06:50

    Статьи интересные. Но не оставляет ощущение сборки ядра линукса версии 2.6 или того старше... Совершенно непригодно к использованию средним продвинутым пользователем... Вот за это протокол и не любят.


    1. DaemonGloom
      18.10.2023 06:50

      Да нет, тут просто метод выбран максимально суровый. Если просто хочется ipv6 и оператор не даёт родной - то достаточно зарегистрироваться на tunnelbroker от Hurricane Electric и получить в ответ настройки для своего роутера или компьютера. Вбили настройки - всё заработало.


      1. olegtsss Автор
        18.10.2023 06:50

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