Утилита ipsecctl заменяет более старую ipsecadm, и упрощает процедуру установки IPsec соединения, поместив всю настройку в удобный конфигурационный файл /etc/ipsec.conf.
Для примера рассмотрим построение IPsec туннеля между хостами 192.168.10.1 (hostA) и 192.168.11.1 (hostB). Будем использовать Blowfish как алгоритм шифрования нагрузки ESP, а для аутентификации будем использовать HMAC-SHA2-512.
Сгенерируем ключи для аутентификации (512 бит) и шифрования (160 бит). Для других алгоритмов необходима иная длина ключа, например, для AES длина ключа должна быть 128 бит. Примеры можно посмотреть в файлах regress тестов (в директории /usr/src/regress/sbin/ipsecctl/.
hostA# mkdir -m 700 /etc/ipsec hostA# openssl rand 64 | hexdump -e '64/1 "%02x"' >/etc/ipsec/akey.local hostA# openssl rand 20 | hexdump -e '20/1 "%02x"' >/etc/ipsec/ekey
На втором узле создаем ключ для аутентификации:
hostB# mkdir -m 700 /etc/ipsec hostB# openssl rand 64 | hexdump -e '64/1 "%02x"' >/etc/ipsec/akey.local
Обмениваемся auth ключами и передаем на hostB ключ для шифрования:
hostA# scp /etc/ipsec/ekey 192.168.11.1:/etc/ipsec/ekey hostA# scp /etc/ipsec/akey.local 192.168.11.1:/etc/ipsec/akey.remote hostB# scp /etc/ipsec/akey 192.168.10.1:/etc/ipsec/akey.remote
Защищаем файлы от просмотра (на обоих узлах):
# chmod 600 /etc/ipsec.conf /etc/ipsec/{akey*,ekey}
Создадим на узле 192.168.10.1 файл /etc/ipsec.conf. Формат файла описан в man руководстве ipsec.conf(5). Значения SPI (индекс параметра безопасности) выбирается случайным 32-битным значением и уникально идентифицирует ассоциацию безопасности данного хоста.
# Конфигурация IPsec для 192.168.10.1 # flow esp from 192.168.10.1 to 192.168.11.1 esp from 192.168.10.1 to 192.168.11.1 spi 0x4d9b5ca0:0x832a16bf \ auth hmac-sha2-512 enc blowfish \ authkey file "/etc/ipsec/akey.local:/etc/ipsec/akey.remote" \ enckey file "/etc/ipsec/ekey:/etc/ipsec/ekey"
На узле 192.168.11.1 необходимо создать ответный файл:
# Конфигурация IPsec для 192.168.11.1 # flow esp from 192.168.11.1 to 192.168.10.1 esp from 192.168.10.1 to 192.168.11.1 spi 0x832a16bf:0x4d9b5ca0 \ auth hmac-sha2-512 enc blowfish \ authkey file "/etc/ipsec/akey.local:/etc/ipsec/akey.remote" \ enckey file "/etc/ipsec/ekey:/etc/ipsec/ekey"
Выполняем загрузку конфигурации на обоих хостах:
# ipsecctl -vf /etc/ipsec.conf flow esp out from 192.168.10.1 to 192.168.11.1 peer 192.168.11.1 type require flow esp in from 192.168.11.1 to 192.168.10.1 peer 192.168.11.1 type use esp from 192.168.10.1 to 192.168.11.1 spi 0x4d9b5ca0 \ auth hmac-sha2-512 enc blowfish authkey <...> enckey <...> esp from 192.168.11.1 to 192.168.10.1 spi 0x832a16bf \ auth hmac-sha2-512 enc blowfish authkey <...> enckey <...>
Если правила применились успешно, и вы хорошо оттестировали конфигурацию, необходимо разрешить конфигурирование IPsec при запуске системы. Для этого добавьте в файл /etc/rc.conf.local следующую строчку:
ipsec=YES
Проверяем. На хосте 192.168.10.1:
hostA# ipsecctl -sa FLOWS: flow esp in from from 192.168.10.1 to 192.168.11.1 \ peer 192.168.11.1 flow esp out from from 192.168.11.1 to 192.168.10.1 \ peer 192.168.11.1 SADB: esp from 192.168.10.1 to 192.168.11.1 spi 0x4d9b5ca0 \ enc blowfish auth hmac-sha2-512 esp from 192.168.11.1 to 192.168.10.1 spi 0x832a16bf \ enc blowfish auth hmac-sha2-512
Видно, что на втором хосте (192.168.11.1) часть, отвечающая за базу SA, та же самая, а описания IPsec потоков противоположные.
hostB# ipsecctl -sa FLOWS: flow esp in from from 192.168.11.1 to 192.168.10.1 \ peer 192.168.10.1 flow esp out from from 192.168.10.1 to 192.168.11.1 \ peer 192.168.10.1 SADB: esp from 192.168.10.1 to 192.168.11.1 spi 0x4d9b5ca0 \ enc blowfish auth hmac-sha2-512 esp from 192.168.11.1 to 192.168.10.1 spi 0x832a16bf \ enc blowfish auth hmac-sha2-512
Проверим, что творится в канале. Запускаем дампер сетевого трафика на 192.168.11.1:
hostB# tcpdump -nvi fxp0 host 192.168.10.1 and 192.168.11.1
Пытаемся присоединиться к порту 22 с машины 192.168.10.1:
hostA# telnet 192.168.11.1 ssh Trying 192.168.11.1... Connected to 192.168.11.1. Escape character is '^]'. SSH-1.99-OpenSSH_4.1
На 192.168.11.1 видим только пакеты ESP:
18:51:59.624908 esp 192.168.10.1 > 192.168.11.1 spi 0x4D9B5CA0 \ seq 559 len 68 [tos 0x10] (ttl 64, id 44596, len 88) 18:51:59.625505 esp 192.168.11.1 > 192.168.10.1 spi 0x832A16BF \ seq 436 len 68 (DF) (ttl 64, id 29087, len 88) ...
Стоит также обратить внимание на появившиеся маршруты в таблице маршрутизации:
hostA# netstat -rnf encap Routing tables Encap: Source Port Destination Port Proto SA(Address/Proto/Type/Direction) 192.168.11.1/32 0 192.168.10.1/32 0 0 192.168.11.1/50/use/in 192.168.10.1/32 0 192.168.11.1/32 0 0 192.168.11.1/50/require/out
Перейдем к настройке фильтра пакетов (pf). Основные идееи тут должны быть такими:
Примерный вид правил для узла (hostA) может выглядеть так:
# Определение внешнего интерфейса # ext_if = "fxp0" # Удаленный IPsec хост # hostB = "192.168.11.1" # Не фильтровать на loopback # set skip on lo # Политика блокирования по умолчанию # block block return-rst proto tcp # Разрешить исходящие пакеты (к hostB будет явно разрешен только ESP) # pass out to ! $hostB keep state # Разрешить входящие и исходящие соединения от/к hostB только по протоколу ESP # pass in on $ext_if proto esp from $hostB to ($ext_if) keep state pass out on $ext_if proto esp from ($ext_if) to $hostB keep state # Разрешить входящие соединения от hostB на необходимые порты # pass in on enc0 proto tcp from $hostB to ($ext_if) port { 80 8080 } \ keep state
Дополнительную информацию можно найти на страничке man руководства vpn(8). Использование IKE сервиса для обмена ключами описано в Как настроить ISAKMPD (IKE).