Один из наших заказчиков совершенно внезапно решил организовать VPN с двухфакторной аутентификацией. Проанализировав рынок, им был выбран FortiGate VPN. Для обеспечения двухфакторности Fortinet предлагает скачать на личный iPhone или другое мобильное устройство FortiToken Mobile, который раз в 30 секунд генерирует новый одноразовый пароль. Со стороны FortiGate сервера необходимо сгенерировать специальный токен для мобильного устройства и ввести его после установки. Собственно, интерфейс приложения в описании не нуждается -- один большой одноразовый пароль на весь экран.
Однако, при организации этого решения возникла проблема: FortiGate умеет организовывать VPN поверх SSL, либо поверх IPsec. В инфраструктуре заказчика используется IPsec VPN и всё бы хорошо, если бы Linux-клиент поддерживал что-то кроме SSL-VPN. Поэтому, пришлось искать обходные пути для наших разработчиков, использующих, преимущественно, GNU/Linux.
Собственно, решение было получено относительно простым путём. На macOS машину был установлен клиент FortiClient, установлено соединение и подсмотрены параметры подключения к FortiGate. Со стороны Linux был установлен Shrew VPN server:
# apt-get install ike
Далее создаём рабочий каталог и конфигурационный файл (имя конфигурационного файла должно совпадать с IP адресом сервера):
# mkdir -p ~/.ike/sites
# vi $HOME/.ike/sites/10.0.0.1
n:version:4
s:network-host:10.0.0.1
n:network-ike-port:500
s:client-auto-mode:pull
s:client-iface:virtual
n:network-mtu-size:1380
n:client-addr-auto:1
s:network-natt-mode:enable
n:network-natt-port:4500
n:network-natt-rate:15
s:network-frag-mode:enable
n:network-frag-size:540
n:network-dpd-enable:1
n:network-notify-enable:1
n:client-banner-enable:1
n:client-dns-used:1
n:client-dns-auto:1
n:client-dns-suffix-auto:1
s:auth-method:mutual-psk-xauth
s:ident-client-type:ufqdn
s:ident-client-data:KorG
s:ident-server-type:any
b:auth-mutual-psk:SECRET_IN_BASE64
s:phase1-exchange:aggressive
n:phase1-dhgroup:5
s:phase1-cipher:aes
n:phase1-keylen:128
s:phase1-hash:sha1
n:phase1-life-secs:86400
n:phase1-life-kbytes:0
n:vendor-chkpt-enable:0
s:phase2-transform:esp-aes
n:phase2-keylen:128
s:phase2-hmac:sha1
n:phase2-pfsgroup:5
n:phase2-life-secs:3600
n:phase2-life-kbytes:0
s:ipcomp-transform:disabled
s:policy-level:auto
n:policy-nailed:0
n:policy-list-auto:1
Обращаем внимание, что необходимо изменить:
10.0.0.1 # IP адрес VPN сервера
KorG # имя пользователя
SECRET_IN_BASE64 # Pre-shared key, созданный на сервере FortiGate VPN
Если у вас имеется PSK в plain text формате, можно его элементарно зашифровать:
# printf %s 'so_hardcore_key' |openssl base64
c29faGFyZGNvcmVfa2V5
У текущей реализации ike есть некая проблема, которая ожидает в качестве параметра ключа -r валидный IP адрес. В противном случае, client падает в segmentation fault. Кроме того, вспоминаем, что заказчик использует OTP, которое довольно забавно реализуется в FortiGate (и, полагаю, некоторых других серверных решениях; не знаю -- не сталкивался). Поэтому, пишем следующий скрипт для обеспечения подключения к серверу (я назвал его vpn):
#!/bin/sh -e
: ${1?}
SERV="10.0.0.1"
USER="KorG"
PASS="MyPermanentPassword"
cd $HOME/.ike/sites/
ike -r "$SERV" -u "$USER" -p "$PASS$1"
Не забываем убедиться, что сервис iked запущен:
# service ike status
* iked is running
После этого даём права на исполнение для скрипта и запускаем его:
# chmod +x ./vpn
# ./vpn
ii : ## : VPN Connect, ver 2.2.1
## : Copyright 2013 Shrew Soft Inc.
## : press the <h> key for help
>> : config loaded for site '10.0.0.1'
>> : attached to key daemon ...
>> : peer configured
>> : iskamp proposal configured
>> : esp proposal configured
>> : client configured
>> : local id configured
>> : remote id configured
>> : pre-shared key configured
ii : bringing up tunnel ...
>> : network device configured
VPN подключение установлено!
UPD: если при запуске эта замечательная утилита падает в кору, рекомендуется проверить конфиг-файл.
При использовании sudo для запуска конфиг нужно класть в домашний каталог root (это же логично :) ).
Если вам нужно сделать так, чтобы клиент не вываливался из LAN после подключения, можно исключить свои сети из диапазона. Для этого предлагаю следующий патч для конфига:
-n:policy-list-auto:1
+n:policy-list-auto:0
+s:policy-list-exclude:192.168.2.0 / 255.255.255.0,192.168.110.0 / 255.255.255.0,192.168.220.0 / 255.255.255.0