Утилита 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).