IPSec VPN для OS X и iOS. Без боли

  • Tutorial
VPN (англ. Virtual Private Network — виртуальная частная сеть) — обобщённое название технологий, позволяющих обеспечить одно или несколько сетевых соединений (логическую сеть) поверх другой сети (например, Интернет).
© Wikipedia


VPN используется для удаленного подключения к рабочему месту, для защиты данных, для обхода фильтров и блокировок, для выдачи себя за гражданина другой страны и вообще — штука незаменимая. Практически повсеместно в качестве простого средства для организации пользовательского VPN используется всем известный OpenVPN, который использовал и я. Ровно до тех пор, пока у меня не появился Macbook и OS X в придачу. Из-за того, что подход Apple к конфигурации DNS сильно отличается от подхода других *nix-систем, проброс DNS через VPN нормально не работал.

После некоторых исследований у меня получилось два варианта:
— Использование DNS «мимо» VPN, что сильно небезопасно, но решает проблему.
— Использование нативных для OS X VPN-протоколов: PPTP и семейства IPSec.
Разумеется, я выбрал второе и разумеется — IPSec, а не устаревший PPTP.

TL;DR;
Настройка Linux ( в моем случае — Arch Linux )

#!/bin/bash
MYIP="1.2.3.4" # IP-адрес сервера
# Установка софта ( для Arch Linux )
pacman -S --noconfirm ipsec-tools pwgen
# Готовая конфигурация
wget https://gist.githubusercontent.com/annmour/e8d12dbfc4cd2c711c11588b4388afd4/raw/0929a169dde09ae3f041f4da4bf161614501d62c/racoon.conf \
-O /etc/racoon.conf
sed -i "s/0.0.0.0/$MYIP/g" /etc/racoon.conf
# Генерация группы и psk
mkdir -p /etc/racoon/ && echo $(pwgen -s 8 1) $(pwgen -s 64 1) > /etc/racoon/psk.key && \
chmod 0400 /etc/racoon/psk.key
# Добавление группы для VPN
groupadd vpn
# Запуск racoon
systemctl enable racoon && systemctl start racoon
# Создание пользователя для VPN и задание ему пароля
useradd -s /bin/nologin -G vpn -g vpn -M -N -d / vpn_user && \
passwd vpn_user
# Добавление правил для filter + nat
iptables -t filter -I INPUT -p esp -j ACCEPT
iptables -t filter  -I INPUT -p udp --dport 500 -j ACCEPT
iptables -t filter  -I INPUT -p udp --dport 4500 -j ACCEPT
iptables -t filter  -I FORWARD -s 192.168.100.0/24 -j ACCEPT
iptables -t filter  -I FORWARD -d 192.168.100.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j MASQUERADE
iptables-save > /etc/iptables/iptables.rules
# Включение форвардинга
echo net.ipv4.ip_forward=1 > /etc/sysctl.d/10-ip_fowrard.conf
sysctl -p /etc/sysctl.d/10-ip_fowrard.conf


Настройка OS X

  1. Открыть Настройки → Сеть
  2. Нажать (+) и выбрать VPN/Cisco IPSec
  3. Заполнить основную информацию ( адрес, имя пользователя и пароль )
  4. Выбрать «Настройки аутентификации» и указать группу и PSK ( из файла /etc/racoon/psk.key )
  5. Подключиться



OS X и IPSec

IPSec это не один протокол, а набор протоколов и стандартов, каждый из которых имеет кучу вариантов и опций. OS X поддерживает три вида IPSec VPN:
— IPSec/L2TP
— IKEv2
— Cisco VPN

Первый вариант избыточен — какой смысл пробрасывать ethernet-пакеты для пользовательского VPN?
Второй — требует сертификатов и сильно сложной настройки на стороне клиента, что тоже нехорошо.
Остается третий, который называется «Cisco», а на самом деле — XAuth+PSK. Его и будем использовать.

Препарация OS X

После некоторых неудачных попыток настроить VPN на OS X, я полез изучать систему на предмет того, как же именно там работает VPN.
Недолгий поиск дал мне файлик /private/etc/racoon/racoon.conf, в котором была строчка include "/var/run/racoon/*.conf";.
После этого все стало понятно: при нажатии кнопки OS X генерирует конфиг для racoon и кладет его в /var/run/racoon/, после окончания соединения — удаляет. Осталось только получить конфиг, что я и сделал, запустив скрипт перед соединением.
while true; for I in *.conf; do CP $I $HOME/$I; exit 0; done; done

Внутри я нашел именно ту информацию, которой мне не хватало для настройки сервера: IPSec proposals. Это списки поддерживаемых клиентом ( и сервером ) режимов аутентификации, шифрования и подписи, при несовпадении которых соединение не может быть установлено.
Итоговый proposal для OS X 10.11 и iOS 9.3 получился таким:
encryption_algorithm aes 256;
hash_algorithm sha256;
authentication_method xauth_psk_server;
dh_group 14;


Выбор VDS и настройка VPN

Для VPN-сервера я выбрал VDS от OVH, поскольку они дают полноценную виртуализацию с возможностью ставить любое ядро с любыми модулями. Это очень важно, поскольку ipsec работает на уровне ядра, а не пользователя, как OpenVPN.
Режим «Cisco VPN» (XAuth + PSK) предполагает двухэтапную аутентификацию:
— Используя имя группы и PSK для нее ( этап 1 )
— Используя имя пользователя и пароль ( этап 2 )

Настройка racoon

racoon — демон, который занимается управлением ключами ( IKE ). Именно он дает ядру разрешение на провешивание туннеля после того, как аутентифицирует клиента и согласует все детали протокола ( aka proposal ). racoon входит в стандартный пакет ipsec-tools и есть практически в любом дистрибутиве Linux «из коробки».

Конфигурация racoon
/etc/racoon.conf
# путь к файлу с pre-shared-key. Права должны быть 0400
path pre_shared_key "/etc/racoon/psk.key";
# указание внешнего ip-адреса обязательно, 0.0.0.0 не работает!
listen {
	isakmp 1.2.3.4 [500];
	isakmp_natt 1.2.3.4 [4500];
}

# anonymous aka road warrior - клиент с неизвестным внешним адресом
remote anonymous {
# passive - режим "ждать входящего"
	passive on;
# передача конфигурации клиенту
mode_cfg on;
# взято из racoon.conf для os x
	exchange_mode main,aggressive;
	ike_frag on;
	verify_cert off;
	verify_identifier off;
# имя сервера
	my_identifier fqdn "vpn.server";
# генерировать одноразовые политики ( spd ) автоматически
# еще их можно генерировать руками, но не нужно
	generate_policy on;
# режим прохода через NAT
	nat_traversal on;
# мертвые клиенты отваливаются через 5 минут
	dpd_delay 300;
# proposal - набор протоколов для клиента
# взято из racoon.conf для os x
	proposal {
  		encryption_algorithm aes 256;
  		hash_algorithm sha256;
  		authentication_method xauth_psk_server;
  		dh_group 14;
  	}
}


mode_cfg {
# аутентификация по unix-пользователям
	auth_source system;
# ... и unix-группам
	group_source system;
# ... и пускать только членов групп vpn
	auth_groups "vpn";
# ... разрешить клиенту сохранять пароль
	save_passwd on;
# брать конфигурацию из конфига ( а не из radius например )
	conf_source local;
# начальный адрес пула
	network4 192.168.100.100;
# маска пула
	netmask4 255.255.255.0;
# dns-сервер
	dns4 8.8.8.8;
# размер пула
	pool_size 50;
}

# настройка шифрования
sainfo anonymous {
	encryption_algorithm aes;
	authentication_algorithm hmac_sha1;
	compression_algorithm deflate;
}



Конфигурация psk-файла

/etc/racoon/psk.key
Используя случайные 64 бита группы и 512 бит ключа, я получаю достаточно вариантов, чтоб сделать перебор бессмысленным.
# group           key
z1x7VZto IgYLrXQdsTFPWKpH7DrV6H06GnbQGl1jlesLZbJ6hZi7BIEULk1MF3yqkqAGDWvM
U8WLLyuk so70ums1VqrCilBvEBEUTDN9kripEd8l5pyQHWf8PNMmnvdV4uqUUeDLhHsnpK5c
4eU8rxhB TublZZd0K03REBdRe8BmkGuuOqNOnsW5d26bbtIsv4x0M1xlZWDjwHcjt3QYg1rc
L2rSlX01 IaXcgzUNVCMkf2BFGcHR14s4rLLbA9ZckQG0H5vNqLWMh4g2tSBa807Y2fmhxPxy
2QkqRbEv GnClE7m3Aq2HrXa6vhSubxNc6ZnY7LSWAFqmasgi5pqThzWmVQY0vONAbAXYpBk4
2mC1aO86 Dmmmty5rbaOZY0Uh0PGIcVYOLTI8fYlGWJCJfHhZSyXTDzTsc7Qhnj75vfApju2c
kotVQ8eN 31cRpnVpEzkrrm58gWuiaCeOvYLwJYy42dglA3IHsuYkftER5tmLJbtV5vwktLZx
YXQX4YSm 74f2RND10NIDaRk2bQtuPEjgJWXxeZdD7KoBdYBzdIq053PNzlNvdQdfn1Taa6zV
4ZwwJuMP 1xNyfGJSYvDRX7MgId9AgmwygqVFiOJDet2ofLVJkOOUKUfBt3IIn2pksXFTyiN2
t9D9S59q euDKjEM73eONU8hmbPGm3mtnyz3h66AY3tHWo5WJOBTm7PULc1TlVXeoGwOIUapm


Настройка Linux


— Необходимо разрешить маршрутизацию: sysctl net.ipv4.ip_forward=1
— Необходимо разрешить протокол ESP и входящие соединения на порты 500/udp и 4500/udp: iptables -t filter -I INPUT -p esp -j ACCEPT; iptables -t filter -I INPUT -p udp --dport 500 -j ACCEPT; iptables -t filter -I INPUT -p udp --dport 4500 -j ACCEPT
— Необходимо включить NAT для нашей сети: iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j MASQUERADE
— Необходимо создать группу и создать/добавить туда пользователей: groupadd vpn и useradd -G vpn vpn_user
— Необходимо запустить racoon: racoon -vF

Настройка OS X

OS X в картинках
Настройки → Сеть


Выбрать (+) → VPN → Cisco IPSec → придумать название


Выбрать соединение → ввести адрес сервера, имя пользователя и пароль


Выбрать «Настройки аутентификации» → ввести имя группы и ключ ( именно в таком порядке )


Соединиться.


Настройка iOS

iOS в картинках
Настройки → Основные → VPN → Добавить конфигурацию VPN.

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



<<<EOF
Спасибо за внимание, шифруйте свой трафик!
EOF;
Поддержать автора
Поделиться публикацией

Комментарии 13

    +1
    Честно говоря, не понимаю, что движет такими людьми, как вы, в выборе протокола. Вам для подключения нужно 4 сущности: имя группы, psk, имя пользователя и пароль, что уж точно не проще IKEv2, где вы можете настроить аутентификацию по сертификатам или по логину и паролю, или какую вам еще угодно. Используете racoon, который давно в состоянии стагнации, и скорее заброшен, чем жив, разрешаете Aggressive mode, который сделает вашу сеть ничем не надежнее PPTP.
    В общем, так себе инструкция. Лучше используйте мою. А если не хотите ничего вводить вручную, то для iOS и OS X можно сделать профили в виде файлов, на которые достаточно кликнуть, и все настройки добавятся сами.
      +1
      Спасибо за комментарий. К сожалению, IKEv2 и «без боли» — это несовместимые понятия, как минимум из-за PKI. racoon не на «стадии стагнации», а «стабилен, хорошо работает и не требует напиллинга». Что касаемо strongSwan'а — да, попробовал, именно IKEv2, потому что agressive mode там забанен. С маком оно работать не захотело, много ошибок в логах и полное отсутствие понимания, что же именно происходит при ошибке -26432.

      Насчет «agressive mode»: да, менее безопасно чем main mode, но сильно лучше pptp как-минимум использованием aes+sha.

      Насчет настройки: 4 строчки текста, записанные где угодно или отправленные по sms/mail/im. Конечно это сложнее, чем установить CA, выставить ему доверие, установить клиентский сертификат и ключ и еще настроить само соединение, где полей поболее будет.
        0
        как минимум из-за PKI
        Не хотите PKI — берете сертификат Let's Encrypt или WoSign, или любой другой, который вам нравится, кидаете его на сервер, а аутентификацию делаете по логину/паролю. И это работает на iOS, Android, Blackberry, Windows, OS X и Linux, про Windows Phone не помню.
        С маком оно работать не захотело, много ошибок в логах и полное отсутствие понимания, что же именно происходит при ошибке -26432.
        Надо смотреть ошибки на серверной стороне, они более вменяемые. Конфигурация из моей инструкции вполне себе работает на OS X и iOS.
        Конечно это сложнее, чем установить CA, выставить ему доверие, установить клиентский сертификат и ключ и еще настроить само соединение, где полей поболее будет.
        Неуместный, с моей точки зрения, сарказм. Вы можете так же в почте хранить .mobileconfig, и достаточно будет просто кликнуть по нему, а не копировать строчки туда-сюда. Хотя никто вам не запрещает сделать .mobileconfig и для вашей текущей конфигурации.
          0
          Неуместный, с моей точки зрения, сарказм

          Сарказм на Хабре уместен ну почти всегда.
          Надо смотреть ошибки на серверной стороне, они более вменяемые. Конфигурация из моей инструкции вполне себе работает на OS X и iOS.

          Смотрел. Но задача была не смотреть ошибки, а сделать себе вменяемый VPN на PHDays, чтоб не попасть в список тех, кого еще похекали :)
          Сделал, посмотрел что солюшен умещается в 10 строчек баш-скрипта, выложил на хабр. Возможно это и не самое лучшее решение, но уж точно одно из самых простых и быстрых для настройки.
            0
            Самый быстронастраевыемый VPN из современных — Cisco AnyConnect с сервером OpenConnect. Если серверный сертификат уже есть, то все настраивается буквально в течение трех минут: установить, указать путь к сертификату в конфигурационном файле, настроить клиент.
      +2
      Использую ikev2 без боли на ios/osx/windows вот таким образом https://hub.zhovner.com/geek/universal-ikev2-server-configuration/

      На маке особенно приятно, что можно создать профили автонастройки .mobileconfig и настройка VPN будет происходить буквально в два клика.
        0
        Не подскажите как Вы боролись с DNS?
          0
          Не сталкивался с такой проблемой. Вот как у меня выглядит
          scutil --dns
          scutil --dns
          DNS configuration
          
          resolver #1
            nameserver[0] : 8.8.8.8
            nameserver[1] : 2001:4860:4860::8888
            if_index : 7 (ipsec0)
            flags    : Request A records, Request AAAA records
          Reachable, Transient Connection, Connection Required, Automatic Connection On Demand
          
          resolver #2
            domain   : local
            options  : mdns
            timeout  : 5
            flags    : Request A records, Request AAAA records
          Not Reachable
            order    : 300000
          
          resolver #3
            domain   : 254.169.in-addr.arpa
            options  : mdns
            timeout  : 5
            flags    : Request A records, Request AAAA records
          Not Reachable
            order    : 300200
          
          resolver #4
            domain   : 8.e.f.ip6.arpa
            options  : mdns
            timeout  : 5
            flags    : Request A records, Request AAAA records
          Not Reachable
            order    : 300400
          
          resolver #5
            domain   : 9.e.f.ip6.arpa
            options  : mdns
            timeout  : 5
            flags    : Request A records, Request AAAA records
          Not Reachable
            order    : 300600
          
          resolver #6
            domain   : a.e.f.ip6.arpa
            options  : mdns
            timeout  : 5
            flags    : Request A records, Request AAAA records
          Not Reachable
            order    : 300800
          
          resolver #7
            domain   : b.e.f.ip6.arpa
            options  : mdns
            timeout  : 5
            flags    : Request A records, Request AAAA records
          Not Reachable
            order    : 301000
          
          DNS configuration (for scoped queries)
          
          resolver #1
            search domain[0] : zhovner.com
            nameserver[0] : 192.168.33.12
            if_index : 5 (en1)
            flags    : Scoped, Request A records
          Reachable, Directly Reachable Address
          
          resolver #2
            nameserver[0] : 8.8.8.8
            nameserver[1] : 2001:4860:4860::8888
            if_index : 7 (ipsec0)
            flags    : Scoped, Request A records, Request AAAA records
          Reachable, Transient Connection, Connection Required, Automatic Connection On Demand
          



          Впрочем у меня DNS запросы без ipsec закрыты фаерволлом, так что системный резолвер не работает никогда и без vpn ничего не резолвится.
        0
        у нас проблем с DNS не замечено. нормально сотрудники ходят через OpenVPN, и я лично tunnelblick'ом пользуюсь у себя на маке, и днс во время сессии наш личный, который в офисе сидит. в конфиге клиента имеется push «dhcp-option DNS».
          0
          Второй — требует сертификатов и сильно сложной настройки на стороне клиента, что тоже нехорошо.

          Всё достаточно просто, сертификаты от Let's Encrypt, на стороне клиентов никаких сертификатов — адрес сервера, логин и пароль: https://blog.radic.ru/vpn-ikev2-digitalocean-easy/
            0
            Большое спасибо за статью, действительно все работает с ipone'ами и без боли!
              0
              Спасибо за статью. Я остановился в одном шаге от фразы: «все работает» :)
              При подключении я получаю ошибку
              INFO: login failed for user "<user_name>"
              ERROR: Attempt to release an unallocated address (port 0)
              ERROR: mode config 6 from <ip_client_mac>[57550], but we have no ISAKMP-SA.
              ERROR: unknown Informational exchange received.
              


              Я указываю в первой форме имя пользователя в системе и пароль заданный пользователю через passwd
              Заголовок спойлера
              image


              в настройка аутентификации указываю группу и ключ из файлы psk.key
              Заголовок спойлера
              image


              Например:
              группа: z1x7VZto
              ключ: IgYLrXQdsTFPWKpH7DrV6H06GnbQGl1jlesLZbJ6hZi7BIEULk1MF3yqkqAGDWvM

              Все ли я правильно делаю?
                0
                Возможно, что для новой osx что-то поменялось. У меня сейчас, к сожалению, нет OS X под рукой, так что проверить не могу.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое