Развивая IT-инфраструктуру рано или поздно приходит задача интегрироваться с какими-либо сервисами крупной организации. Это может быть, например, банк или оператор связи. Как правило в крупных организациях действуют устоявшиеся политики информационной безопасности, которые в частности требуют реализации сервиса с внешней по отношению к ним инфраструктурой через шифрованные каналы — IPSec. В то же время в небольших организациях стартапах нет опыта организации таких схем, а из оборудования есть только VDS с Linuxом на борту. Более того, к моему удивлению, в рунете практически нет материалов с описанием инструментов траблшутинга под Linux. Попробуем устранить этот пробел и описать практическую часть настроек.
Общая схема сервиса представлена ниже. Как правило, в крупных организациях все уже стандартизировано, поставлено на поток, всякие возможные шифрования и прочие сетевые штуки делаются на отдельном оборудовании (циски-джуниперы и иже с ними), и, что важнее, отдельными людьми (возможно каждый синий квадратик на схеме ниже обслуживают разные люди). У вас же одна виртуалка, с которой будет и запускаться сервис, и организовываться IPSec.
Обратите внимание, сам IPSec организовывается между одними IP-адресами (в моем примере 10.0.255.1 <-> 10.0.1.1
), а сам сервис — между другими (192.168.255.1<-> 192.168.1.1
). Такие схемы еще называются IPSec Network-Network.
Простой пример — вы работаете в молодой, но очень амбициозной компании СуперСервис, и вам надо организовать взаимодействие с закрытым API компании МегаТелеком. Ваша инфраструктура — один сервер VDS, инфраструктура партнера — куча сетевого и серверного оборудования. Задача делится на два этапа:
ISAKMP — описание процедур IPSec, в литературе называют его фреймворком. В нем описываются термины SA, SP, SAD (Security Assotiations Database), SPD (Security Policy Database), необходимость установки вспомогательных туннелей… ISAKMP построен так, чтобы не зависеть от технологий туннелирования, алгоритмов аутентификации и шифрования. Он просто вводит необходимые определения.Перед шифрованием трафика стороны должны договориться о параметрах (и ключах) этого шифрования. Для этого между обоими сторонами поднимается вспомогательный туннель (его еще называют ISAKMP туннель), который действует все время. Туннель этот двунаправленный, представляет из себя соединение по UDP (по умолчанию на порту 500). Для организации этого вспомогательного туннеля стороны должны проверить подлинность друг друга (должен совпасть пароль). Этим занимается протокол IKEv1/2 (Internet Key Exchange). И уже по организованному ISAKMP туннелю стороны договариваются о шифровании непосредственно пользовательского трафика.
IKE(v1/2) — непосредственно протокол аутентифиации. Он уже реализовывает алгоритмы обмена ключами и их применение.
Благодаря концепции Cisco сейчас ISAKMP и IKE считаются синонимами.
Кстати, есть реальный пример использования AH-инкапсуляции. Предположим, у нас есть две сети, подключенные к разным маршрутизаторам. Хосты должны передавать информацию с MTU 1500 байт без фрагментации, но у нас есть промежуточный участок, который поддерживает только 1380 байт. Вся трасса доверенная. Мы можем воспользоваться тем, что IPSec не создает туннельных интерфейсов, в классическом смысле через которые трафик не маршрутизируется. Мы создадим SA туннель AH типа (нам же не надо шифровать), тогда трафик пойдет него. В трафике фрагментироваться будут только внешние IP-пакеты (по внешним IP-заголовкам), внутренние будут пересобираться без изменений.
Все манипуляции с IPSec добавляют заголовки служебной информации. Минимум они съедят еще 40 байт от исходного пакета. Таким образом, например, при стандартном MTU для PPPoE в 1380 байт соединений реальное MTU будет < 1340.
#Для deb-дистрибутивов команда сама подтянет необходимые ядреные модули
root@localhost: ~# apt-get install racoon ipsec-tools
/etc/racoon.conf
), запускается обычным init-скриптом (/etc/init.d/racoon <start|stop|restart>
).# Практически все данные в разделах remote и sainfo берутся из первоначального шаблона
#
# Мы рассмотрим простейший пример с PSK авторизацией
path pre_shared_key "/etc/racoon/psk.txt";
log debug;
listen {
# Указываем интерфейс, с которого будет строиться будущий ISAKMP туннель
isakmp 10.0.1.1 [500];
strict_address;
}
# В разделе remote перчислены настройки для первой фазы IPSec.
# Это в некотором смысле аналог tunnel-group в ASA.
# Вместо конкретного IP-адреса можно указать anonymous
# Это будет означать возможность подключения к вам с любого адреса.
# Так делаются присоединения типа user-network
# remote anonymous
remote 10.0.255.1 {
nat_traversal off;
exchange_mode main;
my_identifier address 10.0.1.1;
proposal {
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group modp1024;
lifetime time 86400 sec;
}
}
# Вторая фаза IPSec. Аналог transform-set в ASA.
#
# Предполагается, что для разных адресов взаимодействия
# можно применять разные параметры шифрования второй фазы.
# Конкретизация сервисов как раз указывается в первой строчке
# sainfo address <src> address <dst>
# Скорее всего вам это не понадобится, вы будете писать первую строку так
# sainfo anonymous
sainfo address 192.168.1.1 any address 192.168.255.1 any {
pfs_group modp1024;
lifetime time 28800 sec;
encryption_algorithm 3des;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
}
# Файлик с PSK-ключами
# Формат <REMOTE IP ADDR> <PASSWORD>
# Важно - владелец файла должен быть такой же, от чьего имени запускается racoon
10.0.255.1 SUPERPASSWORD
man 5 racoon.conf
/etc/init.d/setkey <start|stop|restart>
), но по факту она выполняет скрипт /etc/ipsec-tools.conf
. Как я и говорил, она уже задает создает туннели для пользовательского трафика. А именно задает SA и SP для них. Это что-то вроде crypto-map на ASA. Самый простой вариант для нас — добавить просто SP. Тогда SA построится автоматически исходя из параметров второй фазы, указанной в настройках racoon.man 8 setkey
. А я же приведу приведу пример простейшей конфигурации.flush;
spdflush;
spdadd 192.168.1.1/32 192.168.255.1/32 any -P out ipsec
esp/tunnel/10.0.1.1-10.0.255.1/require;
spdadd 192.168.255.1/32 192.168.1.1/32 any -P in ipsec
esp/tunnel/10.0.255.1-10.0.1.1/require;
man 8 ip-xfrm
.Взгляните еще раз на изначальную табличку. Там указаны разные IP-адреса для IPSec и сервиса. По внутреннему IP-адресу идет фильтрация внутри инфраструктуры Мегателеком. Но у нас всего лишь одна виртуальная машина. На ней должен как-то появиться внутренний IP-адрес, и пакеты в туннель должны уходить именно с него. Есть несколько вариантов добиться этого сценария:
- Статический маршрут без определения некстхопа, но с явным указанием исходящего интерфейса и IP-адреса.
- Задание маршрутов на основе policy based routing (PBR в Linux ака ip rule).
- Трансляция адресов (NAT/MASQARADE).
С моей точки зрения здесь подходит первый вариант.
Мы можем добавить на наш интерфейс дополнительный (secondary) IP-адрес, при этом лучше сделать alias для этого интерфейса
root@localhost: ~# ip addr add 192.168.1.1/32 dev eth1 label eth1:1
и настроить маршрут до сервера Мегателеком с этого IP-адреса.
root@localhost: ~# ip route add 192.168.255.1/32 dev eth1:1 src 192.168.1.1
Но если так сделать, ничего не заведется. Дело в том, что при добавлении маршрута в таком виде Linux-станция будет пытаться определить MAC-адрес получателя, делать она это будет через ARP… Компьютер будет слать запросы ARPWho has IP 192.168.255.1
. Так как 192.168.255.1 нет в той же сети, где и 192.168.1.1 (маска /32!), ответа на ARP не будет. Зато при попытке соединения будет возвращаться с локального IP-адреса будет возвращатьсяNo route to host
. Чтобы это победить, нам надо задать статическую ARP-запись:
root@localhost: ~# arp -s 192.168.255.1 00:00:00:00:00:01 -i eth1:1
Такой вот лайфхак. Кстати, такие манипуляции могут привести не совсем к коректной работе IP-стека Linux. В одном из случаев командыip route
не приводили к нужному результату, пришлось перезагружать сетевой стек.
root@localhost: ~# ping -I 192.168.1.1 192.168.255.1
root@localhost: ~# racoonctl show-sa isakmp
Destination Cookies Created
10.0.1.1.500 356a7e11111a93f:367111530375c065 2018-10-02 09:18:28
10.0.1.1 10.0.255.1
esp mode=tunnel spi=2148175815(0x800a8fc7) reqid=0(0x00000000)
E: 3des-cbc 799e587f 6a2b4b78 5590cc2a 3d3ee331 f7e7f472 01abcdef
A: hmac-sha1 01c5161f 46679a36 5d07ee9d f159fc9a 01abcdef
seq=0x00000000 replay=4 flags=0x00000000 state=mature
created: Oct 2 09:22:44 2018 current: Oct 2 10:39:21 2018
diff: 4597(s) hard: 28800(s) soft: 23040(s)
last: Oct 2 09:22:45 2018 hard: 0(s) soft: 0(s)
current: 84(bytes) hard: 0(bytes) soft: 0(bytes)
allocated: 1 hard: 0 soft: 0
sadb_seq=1 pid=3764 refcnt=0
10.0.255.1 10.0.1.1
esp mode=tunnel spi=45614328(0x02b804f8) reqid=0(0x00000000)
E: 3des-cbc 97cedcf1 644e8bbb c22b4e2c fa08a874 01abcdef 211ad19e
A: hmac-sha1 1ab3e79d 3fd924a0 01abcdef 6c9ac89a 01abcdef
seq=0x00000000 replay=4 flags=0x00000000 state=mature
created: Oct 2 09:22:44 2018 current: Oct 2 10:39:21 2018
diff: 4597(s) hard: 28800(s) soft: 23040(s)
last: Oct 2 09:22:45 2018 hard: 0(s) soft: 0(s)
current: 84(bytes) hard: 0(bytes) soft: 0(bytes)
allocated: 1 hard: 0 soft: 0
sadb_seq=0 pid=3764 refcnt=0
18:01:06.409631 IP 10.0.1.1.500 > 10.0.255.1.500: isakmp: phase 1 I ident
18:01:06.439276 IP 10.0.255.1.500 > 10.0.1.1.500: isakmp: phase 1 R ident
18:01:06.440840 IP 10.0.1.1.500 > 10.0.255.1.500: isakmp: phase 1 I ident
18:01:06.475244 IP 10.0.255.1.1.500 > 10.0.1.1.500: isakmp: phase 1 R ident
18:01:06.477032 IP 10.0.1.1.500 > 10.0.255.1.500: isakmp: phase 1 I ident[E]
18:01:06.487785 IP 10.0.255.1.500 > 10.0.1.1.500: isakmp: phase 1 R ident[E]
18:01:06.488048 IP 10.0.1.1.500 > 10.0.255.1.500: isakmp: phase 2/others I inf[E]
18:01:07.412451 IP 10.0.1.1.500 > 10.0.255.1.500: isakmp: phase 2/others I oakley-quick[E]
18:01:07.465363 IP 10.0.255.1.500 > 10.0.1.1.500: isakmp: phase 2/others R oakley-quick[E]
18:01:07.465940 IP 10.0.1.1.500 > 10.0.255.1.500: isakmp: phase 2/others I oakley-quick[E]
18:01:08.467373 IP 10.0.1.1 > 10.0.255.1: ESP(spi=0x7aabfa82,seq=0x1), length 116
18:01:08.480141 IP 10.0.255.1 > 10.0.1.1: ESP(spi=0x0386f867,seq=0x1), length 116
При удаленном подключении по SSH, чтобы не плодить кучу окон удобно запускать tcpdump в фоне:Также в логах можно увидеть успешный статус установления соединения. В нем видно успешное установление обоих фаз IPSec.
root@localhost: ~# tcpdump -i eth1 -w ipsec.pcap esp &
Запускаем ping, telnet, netcat…
root@localhost: ~# killall tcpdump
root@localhost: ~# tcpdump -vr ipsec.pcap
Oct 3 17:53:26 vm22433 racoon: INFO: IPsec-SA request for 10.0.255.1 queued due to no phase1 found.
Oct 3 17:53:26 vm22433 racoon: INFO: initiate new phase 1 negotiation: 10.0.1.1[500]<=>10.0.255.1[500]
Oct 3 17:53:26 vm22433 racoon: INFO: begin Identity Protection mode.
Oct 3 17:53:26 vm22433 racoon: INFO: received Vendor ID: CISCO-UNITY
Oct 3 17:53:26 vm22433 racoon: INFO: received Vendor ID: DPD
Oct 3 17:53:26 vm22433 racoon: INFO: received Vendor ID: draft-ietf-ipsra-isakmp-xauth-06.txt
Oct 3 17:53:26 vm22433 racoon: INFO: ISAKMP-SA established 10.0.1.1[500]-10.0.255.1[500] spi:ebddc300af62ae42:abcdef0123
Oct 3 17:53:27 vm22433 racoon: INFO: initiate new phase 2 negotiation: 10.0.1.1[500]<=>10.0.255.1[500]
Oct 3 17:53:27 vm22433 racoon: INFO: received RESPONDER-LIFETIME: 4608000 kbytes
Oct 3 17:53:27 vm22433 racoon: WARNING: attribute has been modified.
Oct 3 17:53:27 vm22433 racoon: INFO: IPsec-SA established: ESP/Tunnel 10.0.1.1[500]->10.0.255.1[500] spi=238677(0xe39eabc)
Oct 3 17:53:27 vm22433 racoon: INFO: IPsec-SA established: ESP/Tunnel 10.0.1.1[500]->10.0.255.1500] spi=7204011111(0x44b4aaa)
К сожалению, не доступен сервер mySQL