Pull to refresh

VPN везде и всюду: IPsec без L2TP со strongSwan

Reading time 10 min
Views 320K
image
достаточно сильный лебедь

Если вы когда-либо искали VPN, который будет работать на десктопах, мобильных устройствах и роутерах без установки дополнительного ПО и перепрошивки роутера, вы, вероятно, выбирали между PPTP и L2TP+IPsec. У протокола PPTP имеются проблемы с безопасностью и прохождением через брандмауеры и NAT, так что в 2015 году его уже использовать не стоит, а использование L2TP излишне, т.к. L2 VPN, по моему мнению, для обычного удаленного доступа не нужен практически никогда.

Удивительно, что в интернете не так-то просто можно найти информацию о настройке чего-то помимо L2TP+IPsec в транспортном режиме, учитывая, что это обширный стек протоколов, который можно конфигурировать буквально как душе угодно, поэтому я попытаюсь устранить такое несовершенство мира.

Небольшое введение в мир IPsec

Вообще говоря, не совсем правильно называть IPsec VPN. IPsec не предназначен для построения «виртуальных частных сетей», а создан для шифрования или защиты от подмены передаваемых по IP данных. Это специальный слой поверх IP, который, в зависимости от режима и настроек, работает по-разному. В отличие от привычного VPN, который создает новый интерфейс в системе, на который вы, как это чаще всего бывает, назначаете IP-подсеть из диапазона частных адресов (т.е. создаете новый сетевой сегмент), и через который маршрутизируется трафик в зашифрованном виде, IPsec просто шифрует трафик магическим образом между «внешними» интерфейсами сервера и клиента.

В современном IPsec используются:
  • Authentication Header (AH) — протокол, обеспечивающий аутентификацию отправителя и целостность данных. Подписывает не только данные пакета, но и все заголовки, кроме изменяемых полей (ToS, TTL, чексумма).
  • Encapsulating Security Payload (ESP) — протокол, обеспечивающий аутентификацию, целостность и конфиденциальность
  • Security Association (SA) — параметр с настройками шифрования канала
  • Internet Key Exchange (IKE и IKEv2) — протокол обмена параметрами, настройками и согласования SA

AH и ESP — транспортные протоколы, инкапсулируемые прямо в IP, имеющие собственные значение для поля Protocol в IP-заголовке. В современном мире, где NAT стоит за NAT у NAT с NAT'ом, следует использовать что-то более привычное, поэтому сейчас повсеместно используется инкапсуляция ESP-пакетов в UDP. AH не поддерживает работу через NAT.

Сам IPsec поддерживает работу в двух режимах:
  • Транспортный режим. Подписывает заголовки и данные (если AH) или подписывает и шифрует данные (если ESP) пакета. Не скрывает IP-адрес получателя пакета, если он маршрутизируется. Этот режим используется для связки L2TP+IPsec.
  • Туннельный режим. Подписывает (если AH) и еще шифрует (если ESP) весь пакет.

Протокол IKE позволяет проводить аутентификацию клиента с использованием X.509-сертификатов, Pre-Shared Key и Extensible Authentication Protocol (EAP). Поддерживается двухэтапная аутентификация.

Все современные десктопные ОС (Windows Vista/7/8/8.1, OS X, Linux), мобильные устройства (Android, iOS, Windows Phone, Blackberry) и некоторые роутеры поддерживают VPN с использованием IPsec ESP в туннельном режиме и его настройкой через протокол Internet Key Exchange (IKE) версии 1 или 2, а значит IPsec мы именно так и будем настраивать.

Кстати, писать правильно IPsec, но Cisco IPSec.

IPsec в Linux

Сам IPsec (AH/ESP, SA) работает в ядре, поэтому нам нужен IKE-демон для передачи настроек подключающимся клиентам. Их довольно много, но полноценных и активных на данный момент всего два: strongSwan и libreswan. Вторым я не пользовался, ничего сказать о нем не могу, зато первый — прекрасный и удивительный, к тому же, это единственный демон, у которого есть своя userspace-реализация IPsec, поэтому его можно использовать в контейнерах OpenVZ со старым, как динозавры, ядром 2.6.32 с поломанной поддержкой маршрутизации IPsec.
Немного об IPsec в OpenVZ
В OpenVZ есть поддержка IPsec, и она вполне себе годна для запуска L2TP+IPsec, но там что-то явно не так с маршрутизацией на не-локальные интерфейсы. Вероятно, это можно починить добавлением пары правил на хостовую машину, но это довольно проблематично, если у вас нет доступа к ней, как бывает во подавляющем большинстве случаев. Поэтому для OpenVZ необходимо использовать userspace IPsec, который можно собрать параметром --enable-kernel-libipsec

Упоминания о баге:
lists.strongswan.org/pipermail/users/2014-February/005822.html
bugzilla.redhat.com/show_bug.cgi?id=1081804
forum.openvz.org/index.php?t=tree&goto=39937
lowendtalk.com/discussion/33226/need-someone-to-test-ipsec-on-their-boxes

Нам потребуется strongSwan версии минимум 5.0.0. Я рекомендую использовать версию не ниже 5.2.0, т.к. именно в этой версии появилась утилита «swanctl», которая заметно удобней старой «ipsec». Утилита потребуется, по большому счету, только для вывода какой-то информации или статистики, она не обязательна для настройки и можно обойтись только ipsec, но в статье будет использоваться только она.
Скрытый текст
Жизнь со swanctl:
image

Жизнь без swanctl:
image

Нам могут потребоваться некоторые модули, которых может не быть в стандартной поставке:
  • xauth-noauth — поддельный аутентификатор, позволяет вводить любой логин и пароль. Нужен для iPhone и iPad при аутентификации только по ключам, т.к. там нет возможности отключить аутентификацию по логину и паролю.
  • vici — интерфейс для swanctl.
  • libipsec — для userspace IPsec (для OpenVZ и, возможно, других контейнеров).

Если вас не смущает необходимость вводить логин и пароль на iPhone, вам не нужен swanctl и вы не собираетесь запускать это все в OpenVZ-контейнере, то и пересобирать ничего не нужно.
К большому сожалению, мейнтейнеры strongSwan в Debian не запаковали ничего из этого (на февраль 2015), поэтому я сделал патчик, который вы можете использовать.

Переходим к настройке

Будем настраивать подключение через IKEv2 (Windows, Linux, Blackberry), IKEv1+XAUTH (iOS, OS X, Android) и IKEv2+EAP-TLS (Windows Phone). Используем ключи, никаких PSK!
Разработчики strongSwan предлагают нам использовать команду «ipsec pki» для генерации ключей, но она настолько же неудобная, насколько и обычный openssl, поэтому я адаптировал Easy-RSA v3 из OpenVPN для генерации как OpenVPN, так и IPsec-совместимых ключей. С ним вы можете использовать одну связку ключей для двух протоколов!
github.com/ValdikSS/easy-rsa-ipsec
Easy-RSA чрезвычайно простой, поддерживать PKI-инфраструктуру с ним одно удовольствие!

Итак, инициализируем PKI и создаем CA, серверный и клиентский ключи. Важно, чтобы название серверного ключа совпадало с FQDN (доменом, проще говоря) вашего сервера!
$ git clone https://github.com/ValdikSS/easy-rsa-ipsec.git
$ cd easy-rsa-ipsec/easyrsa3
$ ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.

$ ./easyrsa build-ca nopass
Generating a 2048 bit RSA private key
…
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:IPsec CA
…

$ ./easyrsa build-server-full uk1.pvpn.pw nopass
Generating a 2048 bit RSA private key
…
Write out database with 1 new entries
Data Base Updated

$ ./easyrsa build-client-full client1 nopass    
Generating a 2048 bit RSA private key
…
Write out database with 1 new entries
Data Base Updated

$ ./easyrsa export-p12 client1 nopass
Successful export of p12 file. Your exported file is at the following
location…

Ключи сгенерированы. Я добавлял параметр nopass на каждом шагу, чтобы ключи не были защищены паролем (его можно установить позже в любое время).

Теперь нам необходимо скопировать их в нужные директории внутри /etc/ipsec.d/, чтобы strongSwan нашел их:
# cp pki/ca.crt /etc/ipsec.d/cacerts/
# cp pki/issued/uk1.pvpn.pw.crt /etc/ipsec.d/certs/
# cp pki/private/uk1.pvpn.pw.key /etc/ipsec.d/private/

Переходим к настройке strongSwan!
Первым делом, указываем наш приватный ключ в /etc/ipsec.secrets
# This file holds shared secrets or RSA private keys for authentication.

# RSA private key for this host, authenticating it to any other host
# which knows the public part.

# this file is managed with debconf and will contain the automatically created private key
include /var/lib/strongswan/ipsec.secrets.inc

: RSA uk1.pvpn.pw.key

Редактируем конфигурационный файл /etc/ipsec.conf
# ipsec.conf - strongSwan IPsec configuration file

# basic configuration

config setup
	# strictcrlpolicy=yes
	# uniqueids = no

include /var/lib/strongswan/ipsec.conf.inc

conn %default
	dpdaction=clear
	dpddelay=35s
	dpdtimeout=300s

	fragmentation=yes
	rekey=no

	ike=aes256gcm16-aes256gcm12-aes128gcm16-aes128gcm12-sha256-sha1-modp2048-modp4096-modp1024,aes256-aes128-sha256-sha1-modp2048-modp4096-modp1024,3des-sha1-modp1024!

	esp=aes128gcm12-aes128gcm16-aes256gcm12-aes256gcm16-modp2048-modp4096-modp1024,aes128-aes256-sha1-sha256-modp2048-modp4096-modp1024,aes128-sha1-modp2048,aes128-sha1-modp1024,3des-sha1-modp1024,aes128-aes256-sha1-sha256,aes128-sha1,3des-sha1!

	# left - local (server) side
	left=%any
	leftauth=pubkey
	leftcert=uk1.pvpn.pw.crt
	leftsendcert=always
	leftsubnet=0.0.0.0/0,::/0

	# right - remote (client) side
	right=%any
	rightauth=pubkey
	rightsourceip=192.168.103.0/24,2002:25f7:7489:3::/112
	rightdns=8.8.8.8,2001:4860:4860::8888

conn ikev2-pubkey
	keyexchange=ikev2
	auto=add

conn ikev2-pubkey-osx
	also="ikev2-pubkey"
	leftid=uk1.pvpn.pw

conn ikev1-fakexauth
	keyexchange=ikev1
	rightauth2=xauth-noauth
	auto=add

conn ikev2-eap-tls
	also="ikev2-pubkey"
	rightauth=eap-tls
	eap_identity=%identity

Как видите, конфигурационный файл состоит из нескольких секций. В секции config setup два закомментированных параметра: strictcrlpolicy = yes будет требовать неистекший лист отзывов для проведения аутентификации клиента, а uniqueids = no позволяет подключаться нескольким клиентам с одним сертификатом одновременно.
Далее идут секции с описаниями подключений. Секция с названием %default описывает подключение по умолчанию, от которого будут наследоваться другие подключения. Здесь устанавливаются следующие параметры:
  • dpdaction=clear включает механизм Dead Peer Detection (DPD) и указывает, что нужно забывать о клиенте, если он не отзывался дольше таймаута
  • dpddelay=35s — задержка до включения DPD
  • dpdtimeout=300s — таймаут для DPD
  • fragmentation=yes — включение внутренней фрагментации пакетов. Позволяет использовать IPsec с провайдерами, у которых сломана IP-фрагментация пакетов (привет, мобильный МТС!)
  • rekey=no — выключение инициации смены ключей со стороны сервера. Windows это не любит.
  • ike — перечень ciphersuites для использования с IKE (т.е. во время установки шифрованного соединения для передачи конфигурационных параметров, в том числе и ключей для установки SA)
  • esp — перечень ciphersuites для шифрования трафика
  • left и right — случаем все интерфейсы и принимаем всех клиентов
  • leftid — указываем наш FQDN. Нужно для сломанного IKEv2 в OS X El Capitan
  • leftauth/rightauth=pubkey — используем аутентификацию по ключам
  • leftsubnet — подсети, которые мы отправляем клиенту для маршрутизации (весь IPv4 и IPv6-интернет). Уберите IPv6, если не используете его.
  • rightsourceip — пул IP-адресов, из которого выдаем адрес клиенту. Уберите IPv6, если не используете его.
  • rightdns — IP-адреса DNS-серверов

Давайте разберемся с ciphersuites в ike и esp. Здесь перечислены методы шифрования в порядке убывания приоритета, и их так много из-за того, что некоторые из них могут быть недоступны на каких-то устройствах, например, мобильных. Первым делом идут так называемые AEAD-алгоритмы, т.е. такие шифры, которые не требуют отдельного алгоритма для аутентификации, с убывающей группой Диффи-Хеллмана для реализации Perfect Forward Secrecy (PFS). Это самые быстрые шифры, которые доступны в IPsec. Хоть это и AEAD-режим, в ike должны быть алгоритмы хеширования для процесса хендшейка. Затем идет привычный AES-CBC с группами Диффи-Хеллмана. Клиентам, которые не поддерживают PFS, мы не позволим подключиться.

Если у вас нет модуля xauth-noauth для соединения ikev1-fakexauth, то вы можете заменить его просто на xauth и создать пользователя в /etc/ipsec.secrets, например, с логином и паролем client1:
client1 : XAUTH "client1"

Теперь у нас есть три подключения: ikev2-pubkey для IKEv2, ikev1-fakexauth для IKEv1 с фейковой проверкой логина и пароля и ikev2-eap-tls — IKEv2+EAP-TLS для Windows Phone. Перезапускаем strongSwan.

Если все верно, вы увидите следующий вывод команды swanctl -L
$ swanctl -L
ikev2-pubkey: IKEv2
  local:  %any
  remote: %any
  local public key authentication:
    id: CN=uk1.pvpn.pw
    certs: CN=uk1.pvpn.pw
  remote public key authentication:
  ikev2-pubkey: TUNNEL
    local:  0.0.0.0/0 2000::/3
    remote: dynamic
ikev1-fakexauth: IKEv1
  local:  %any
  remote: %any
  local public key authentication:
    id: CN=uk1.pvpn.pw
    certs: CN=uk1.pvpn.pw
  remote public key authentication:
  remote XAuth authentication:
  ikev1-fakexauth: TUNNEL
    local:  0.0.0.0/0 2000::/3
    remote: dynamic
ikev2-eap-tls: IKEv2
  local:  %any
  remote: %any
  local public key authentication:
    id: CN=uk1.pvpn.pw
    certs: CN=uk1.pvpn.pw
  remote EAP authentication:
  ikev2-eap-tls: TUNNEL
    local:  0.0.0.0/0 2000::/3
    remote: dynamic

Проблемы MTU

Из-за особенностей и ошибок в реализации разных IPsec-клиентов, MTU внутри туннеля нельзя угадать заранее, а на Android вообще устанавливается MTU 1500, из-за чего большие пакеты не передаются и вообще ничего не работает. Чтобы нивелировать этот недостаток, достаточно изменять параметр TCP MSS в момент установки TCP-соединения на стороне сервера. Будем использовать значение 1360 для IPv4 и 1340 для IPv6, чтобы размер пакета не превышал 1400 байт внутри туннеля:
# iptables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir in --syn -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
# iptables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir out --syn -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
# ip6tables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir in --syn -m tcpmss --mss 1341:1536 -j TCPMSS --set-mss 1340
# ip6tables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir out --syn -m tcpmss --mss 1341:1536 -j TCPMSS --set-mss 1340

На этом настройка сервера закончена. Не забудьте настроить NAT, если вам он нужен!

Настройка клиентов

Алгоритм настройки клиентов в общих чертах заключается в импорте сертификатов из файла *.p12, создании нового подключения с типом IPsec PKI, IPsec XAUTH RSA или IKEv2 (в зависимости от устройства), указания клиентского сертификата и адреса сервера.
Внимание! Нужно вводить именно тот адрес сервера, который вы вводили при создании серверного ключа. Подключиться по другому домену или просто по IP-адресу, если сертификат был сгенерирован на домен, не получится!

Windows

Windows 7, 8, 8.1 (IKEv2)
Установка сертификатов
Создание соединения
Подключение

Windows Vista (IKE)
IKE на Windows Vista

OS X и iOS

Настройка подключения на iOS и OS X

Android

Вы можете использовать как IPsec-клиент Android и подключаться по протоколу IKE, так и клиент strongSwan и использовать IKEv2. Клиент strongSwan работает стабильнее и надежно переподключает в случае потери соединения.

Импортируйте сертификат либо через файловый менеджер, либо используя пункт «Установка с SD-карты» в разделе «Безопасность». Перейдите в настройки VPN, создайте новое подключение с типом «IPSec Xauth RSA», в поле «Адрес сервера» впишите, собственно, адрес сервера, в поле «Сертификат пользователя IPSec» и «Сертификат ЦС IPSec» укажите сертификат «client1». Нажмите на соединение, введите любые логин и пароль и попробуйте подключиться.

Заключение

IPsec, по моему мнению, является замечательной альтернативой OpenVPN, который любят многие администраторы. Почему большинство VPN-провайдеров все еще используют L2TP+IPsec для меня остается загадкой, т.к. strongSwan предоставляет всю необходимую функциональность для такого рода серивисов (полная поддержка Radius, море плагинов). Я использую strongSwan на своем сервисе уже около полугода в режиме закрытого тестирования и он оставил о себе исключительно положительные впечатления.
IPsec, как я уже говорил, очень гибкий и поддерживает уйму аутентификаторов, поэтому вы можете делать даже такие сумасшедшие вещи, как аутентификация по SIM-карте в мобильном устройстве и хранение публичных ключей в IPSECKEY-записи домена, защищенной DNSSEC.
Если вы боитесь использовать IPsec из-за документов NSA, которые опубликовывал Эдвард Сноуден, пожалуйста, прочитайте статью Don’t stop using IPsec just yet, чтобы развеять сомнения.
Tags:
Hubs:
+48
Comments 166
Comments Comments 166

Articles