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/kreon/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;
Поделиться с друзьями
-->

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


  1. ValdikSS
    23.05.2016 04:58
    +1

    Честно говоря, не понимаю, что движет такими людьми, как вы, в выборе протокола. Вам для подключения нужно 4 сущности: имя группы, psk, имя пользователя и пароль, что уж точно не проще IKEv2, где вы можете настроить аутентификацию по сертификатам или по логину и паролю, или какую вам еще угодно. Используете racoon, который давно в состоянии стагнации, и скорее заброшен, чем жив, разрешаете Aggressive mode, который сделает вашу сеть ничем не надежнее PPTP.
    В общем, так себе инструкция. Лучше используйте мою. А если не хотите ничего вводить вручную, то для iOS и OS X можно сделать профили в виде файлов, на которые достаточно кликнуть, и все настройки добавятся сами.


    1. kreon
      23.05.2016 08:02
      +1

      Спасибо за комментарий. К сожалению, IKEv2 и «без боли» — это несовместимые понятия, как минимум из-за PKI. racoon не на «стадии стагнации», а «стабилен, хорошо работает и не требует напиллинга». Что касаемо strongSwan'а — да, попробовал, именно IKEv2, потому что agressive mode там забанен. С маком оно работать не захотело, много ошибок в логах и полное отсутствие понимания, что же именно происходит при ошибке -26432.

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

      Насчет настройки: 4 строчки текста, записанные где угодно или отправленные по sms/mail/im. Конечно это сложнее, чем установить CA, выставить ему доверие, установить клиентский сертификат и ключ и еще настроить само соединение, где полей поболее будет.


      1. ValdikSS
        23.05.2016 13:00

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


        1. kreon
          23.05.2016 13:25

          Неуместный, с моей точки зрения, сарказм

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

          Смотрел. Но задача была не смотреть ошибки, а сделать себе вменяемый VPN на PHDays, чтоб не попасть в список тех, кого еще похекали :)
          Сделал, посмотрел что солюшен умещается в 10 строчек баш-скрипта, выложил на хабр. Возможно это и не самое лучшее решение, но уж точно одно из самых простых и быстрых для настройки.


          1. ValdikSS
            23.05.2016 13:48

            Самый быстронастраевыемый VPN из современных — Cisco AnyConnect с сервером OpenConnect. Если серверный сертификат уже есть, то все настраивается буквально в течение трех минут: установить, указать путь к сертификату в конфигурационном файле, настроить клиент.


  1. zhovner
    23.05.2016 10:44
    +2

    Использую ikev2 без боли на ios/osx/windows вот таким образом https://hub.zhovner.com/geek/universal-ikev2-server-configuration/

    На маке особенно приятно, что можно создать профили автонастройки .mobileconfig и настройка VPN будет происходить буквально в два клика.


    1. qRoC
      01.06.2016 01:23

      Не подскажите как Вы боролись с DNS?


      1. zhovner
        01.06.2016 01:52

        Не сталкивался с такой проблемой. Вот как у меня выглядит

        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
        


  1. kirosvi
    23.05.2016 20:39

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