IPSec, ISAKMPD, FreeBSD, OpenBSD и x509 сертификаты. Конспект.

Источники информации ISAKMPD.CONF(5), ISAKMPD(8), ISAKMPD.POLICY(5), http://mirror.huxley.org.ar/ipsec/isakmpd.htm (http://web.archive.org/web/20090418044412/http://mirror.huxley.org.ar/ipsec/isakmpd.htm)

NB. Обратный резолв у адресов XXX.XXX.XXX.XXX, YYY.YYY.YYY.YYY должен быть обязательно.

Дано

На одном конце OpenBSD 4.2. Внешний IP: XXX.XXX.XXX.XXX, Внутренняя сеть 192.168.45.0/24, IP:192.168.45.3

На другом конце FreeBSD 6.2. Внешний IP: YYY.YYY.YYY.YYY. Внутренняя сеть 10.10.0.0/16, IP:10.10.22.125

Нужно организовать туннель посредством ISAKMPD и с авторизацией по x509 сертификатам.

Команды приведены для bash, выполняются от рута.

На OpenBSD.

Генерируем сертификаты:

openssl req -x509 -days 365 -newkey rsa:1024 -keyout /etc/ssl/private/ca.key -out /etc/ssl/ca.crt
openssl genrsa -out /etc/isakmpd/private/local.key 1024
openssl req -new -key /etc/isakmpd/private/local.key -out /etc/isakmpd/private/XXX.XXX.XXX.XXX.csr
openssl genrsa -out /etc/isakmpd/private/remote.key 1024
openssl req -new -key /etc/isakmpd/private/remote.key -out /etc/isakmpd/private/YYY.YYY.YYY.YYY.csr

cd /etc/isakmpd

export CERTIP=XXX.XXX.XXX.XXX; openssl x509 -req -days 365 -in private/$CERTIP.csr -CA /etc/ssl/ca.crt \
-CAkey /etc/ssl/private/ca.key -CAcreateserial -extfile /etc/ssl/x509v3.cnf \
-extensions x509v3_IPAddr -out $CERTIP.crt

mv $CERTIP.crt /etc/isakmpd/certs/

export CERTIP=YYY.YYY.YYY.YYY; openssl x509 -req -days 365 -in private/$CERTIP.csr -CA /etc/ssl/ca.crt \
-CAkey /etc/ssl/private/ca.key -CAcreateserial -extfile /etc/ssl/x509v3.cnf \
-extensions x509v3_IPAddr -out $CERTIP.crt

mv $CERTIP.crt /etc/isakmpd/certs/

cp /etc/ssl/ca.crt /etc/isakmpd/ca

openssl x509 -in /etc/isakmpd/ca/ca.crt -noout -subject

Получаем примерно следующее

subject= /C=RU/ST=Russia/L=MSK/O=ZZ/OU=ZZ-ZZZZZZ/CN=XXXXX.XXXXXXX.ru/emailAddress=AAAA@AAAAAAA.ru

Запоминаем subject

cd /etc/iskmpd

Создаем isakmpd.policy

cat isakmpd.policy

<<<<
KeyNote-Version: 2
Authorizer: "POLICY"
Licensees:"DN:/C=RU/ST=Russia/L=MSK/O=ZZ/OU=ZZ-ZZZZZZ/CN=XXXXX.XXXXXXX.ru/emailAddress=AAAA@AAAAAAA.ru"

Conditions: app_domain == "IPsec policy" &&
            esp_present == "yes" &&
            esp_enc_alg != "null" -> "true"; 
>>>>

Создаем isakmpd.conf

<<<<<<<

[General]
Listen-on=              XXX.XXX.XXX.XXX

[X509-certificates]
CA-directory=       /etc/isakmpd/ca/
Cert-directory=     /etc/isakmpd/certs/
Private-key=        /etc/isakmpd/private/local.key

[Phase 1]
XXX.XXX.XXX.XXX=          ISAKMP-peer-A

[Phase 2]
Connections=            IPsec-B-A

[ISAKMP-peer-A]
Phase=                  1
Transport=              udp
Local-address=          XXX.XXX.XXX.XXX
Address=                YYY.YYY.YYY.YYY
Configuration=          Default-main-mode

[IPsec-B-A]
Phase=                  2
ISAKMP-peer=            ISAKMP-peer-A
Configuration=          Default-quick-mode
Local-ID=               Net-B
Remote-ID=              Net-A

[Net-B]
ID-type=                IPV4_ADDR_SUBNET
Network=                192.168.45.0
Netmask=                255.255.255.0

[Net-A]
ID-type=                IPV4_ADDR_SUBNET
Network=                10.10.0.0
Netmask=                255.255.0.0

[Default-main-mode]
DOI=                    IPSEC
EXCHANGE_TYPE=          ID_PROT
Transforms=             3DES-SHA-RSA_SIG

[3DES-SHA-RSA_SIG]
ENCRYPTION_ALGORITHM=   3DES_CBC
HASH_ALGORITHM=         SHA
AUTHENTICATION_METHOD=  RSA_SIG
ENCAPSULATION_MODE=     TUNNEL
AUTHENTICATION_ALGORITHM=HMAC_SHA

[Default-quick-mode]
DOI=                    IPSEC
EXCHANGE_TYPE=          QUICK_MODE
Suites=                 QM-ESP-3DES-SHA-PFS-SUITE

>>>>>>>>>

тарим всю эту радость в архив

cd /etc/isakmpd
tar czf isakmpdconf.tgz .

И несем на хост с FreeBSD

На хосте с FreeBSD. предполагается, что isakmpd стоит и ядро собрано с поддержкой IPSEC.

mkdir -p /usr/local/etc/isakmpd
mv isakmpdconf.tgz /usr/local/etc/isakmpd
cd /usr/local/etc/isakmpd
tar xzf isakmpdconf.tgz
rm isakmpdconf.tgz

Правим конфиги(достаточно поправить только isakmpd.conf):

cat isakmpd.conf

>>>>

[General]
Listen-on=              YYY.YYY.YYY.YYY

[X509-certificates]
CA-directory=       /usr/local/etc/isakmpd/ca/
Cert-directory=     /usr/local/etc/isakmpd/certs/
Private-key=        /usr/local/etc/isakmpd/private/remote.key

[Phase 1]
YYY.YYY.YYY.YYY=           ISAKMP-peer-B

[Phase 2]
Connections=            IPsec-A-B

[ISAKMP-peer-B]
Phase=                  1
Transport=              udp
Local-address=          YYY.YYY.YYY.YYY
Address=                XXX.XXX.XXX.XXX
Configuration=          Default-main-mode

[IPsec-A-B]
Phase=                  2
ISAKMP-peer=            ISAKMP-peer-B
Configuration=          Default-quick-mode
Local-ID=               Net-A
Remote-ID=              Net-B

[Net-B]
ID-type=                IPV4_ADDR_SUBNET
Network=                192.168.45.0
Netmask=                255.255.0.0

[Net-A]
ID-type=                IPV4_ADDR_SUBNET
Network=                10.10.0.0
Netmask=                255.255.0.0

[Default-main-mode]
DOI=                    IPSEC
EXCHANGE_TYPE=          ID_PROT
Transforms=             3DES-SHA-RSA_SIG

[3DES-SHA-RSA_SIG]
ENCRYPTION_ALGORITHM=   3DES_CBC
HASH_ALGORITHM=         SHA
AUTHENTICATION_METHOD=  RSA_SIG
ENCAPSULATION_MODE=     TUNNEL
AUTHENTICATION_ALGORITHM=HMAC_SHA

[Default-quick-mode]
DOI=                    IPSEC
EXCHANGE_TYPE=          QUICK_MODE
Suites=                 QM-ESP-3DES-SHA-PFS-SUITE

<<<<

Проверяем:

С обеих сторон запускаем: isakmpd -4 -L

Если все правильно, то команды на FreeBSD: setkey -a -D, setkey -a -DP должны показать примерно следующую картинку:

# setkey -a -DP
192.168.45.0/24[any] 10.10.0.0/16[any] any
        in ipsec
        esp/tunnel/XXX.XXX.XXX.XXX-YYY.YYY.YYY.YYY/use
        created: Jul  2 00:40:22 2008  lastused: Jul  2 00:40:22 2008
        lifetime: 0(s) validtime: 0(s)
        spid=16486 seq=1 pid=10552
        refcnt=1
10.10.0.0/16[any] 192.168.45.0/24[any] any
        out ipsec
        esp/tunnel/YYY.YYY.YYY.YYY-XXX.XXX.XXX.XXX/require
        created: Jul  2 00:40:22 2008  lastused: Jul  2 00:40:22 2008
        lifetime: 0(s) validtime: 0(s)
        spid=16485 seq=0 pid=10552
        refcnt=1

# setkey -a -D 
YYY.YYY.YYY.YYY XXX.XXX.XXX.XXX
        esp mode=any spi=2785257279(0xa603a73f) reqid=0(0x00000000)
        E: 3des-cbc  f5cbf27d 124d93e1 bedfd02b f62982b9 a38b852a bfee2523
        A: hmac-sha1  4e7ad7ae e8d39534 263c995e 69fbfa48 1de6d11d
        seq=0x00000000 replay=0 flags=0x00000000 state=mature 
        created: Jul  2 00:40:22 2008   current: Jul  2 00:42:50 2008
        diff: 148(s)    hard: 1200(s)   soft: 1080(s)
        last:                           hard: 0(s)      soft: 0(s)
        current: 0(bytes)       hard: 0(bytes)  soft: 0(bytes)
        allocated: 0    hard: 0 soft: 0
        sadb_seq=1 pid=10581 refcnt=1
XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY
        esp mode=any spi=4131964257(0xf648c561) reqid=0(0x00000000)
        E: 3des-cbc  56e216e7 f73d6e72 e9176a3f 89f5500f 22374d9f 552c7d4e
        A: hmac-sha1  8e7e8ed8 1defeabc a3b5678d c14cf8b9 55bc91bd
        seq=0x00000000 replay=0 flags=0x00000000 state=mature 
        created: Jul  2 00:40:22 2008   current: Jul  2 00:42:50 2008
        diff: 148(s)    hard: 1200(s)   soft: 1080(s)
        last:                           hard: 0(s)      soft: 0(s)
        current: 0(bytes)       hard: 0(bytes)  soft: 0(bytes)
        allocated: 0    hard: 0 soft: 0
        sadb_seq=0 pid=10581 refcnt=1

На OpenBSD:

# ipsecctl -sa
FLOWS:
flow esp in from 10.10.0.0/16 to 192.168.45.0/24 peer YYY.YYY.YYY.YYY srcid XXX.XXX.XXX.XXX/32 dstid YYY.YYY.YYY.YYY/32 type use
flow esp out from 192.168.45.0/24 to 10.10.0.0/16 peer YYY.YYY.YYY.YYY srcid XXX.XXX.XXX.XXX/32 dstid YYY.YYY.YYY.YYY/32 type require

SAD:
esp tunnel from YYY.YYY.YYY.YYY to XXX.XXX.XXX.XXX spi 0xa603a73f auth hmac-sha1 enc 3des-cbc
esp tunnel from XXX.XXX.XXX.XXX to YYY.YYY.YYY.YYY spi 0xf648c561 auth hmac-sha1 enc 3des-cbc

Проверка связи со стороны OpenBSD:

# ping -S 192.168.45.3 10.10.22.125
PING 10.10.22.125 (10.10.22.125): 56 data bytes
64 bytes from 10.10.22.125: icmp_seq=0 ttl=64 time=1.449 ms
64 bytes from 10.10.22.125: icmp_seq=1 ttl=64 time=1.376 ms
64 bytes from 10.10.22.125: icmp_seq=2 ttl=64 time=1.351 ms
64 bytes from 10.10.22.125: icmp_seq=3 ttl=64 time=1.194 ms
64 bytes from 10.10.22.125: icmp_seq=4 ttl=64 time=1.285 ms
64 bytes from 10.10.22.125: icmp_seq=5 ttl=64 time=1.502 ms
64 bytes from 10.10.22.125: icmp_seq=6 ttl=64 time=1.221 ms
--- 10.10.22.125 ping statistics ---
7 packets transmitted, 7 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 1.194/1.339/1.502/0.114 ms

Со стороны FreeBSD

# ping -S 10.10.22.125 192.168.45.3
PING 192.168.45.3 (192.168.45.3) from 10.10.22.125: 56 data bytes
64 bytes from 192.168.45.3: icmp_seq=0 ttl=255 time=1.484 ms
64 bytes from 192.168.45.3: icmp_seq=1 ttl=255 time=1.236 ms
64 bytes from 192.168.45.3: icmp_seq=2 ttl=255 time=1.234 ms
64 bytes from 192.168.45.3: icmp_seq=3 ttl=255 time=1.473 ms
64 bytes from 192.168.45.3: icmp_seq=4 ttl=255 time=1.464 ms
64 bytes from 192.168.45.3: icmp_seq=5 ttl=255 time=1.331 ms
^C
--- 192.168.45.3 ping statistics ---
6 packets transmitted, 6 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.234/1.370/1.484/0.108 ms

Настройки файрвола и роутинга оставлены за скобками.

Скрипт для генерации сертификатов

#!/usr/local/bin/bash
# Name: gen_certs.sh

if [ $# -ne 1 ]; then
        echo "Error in $0 - Invalid Argument Count"
        echo "Syntax: $0 IPADDR"
        exit
fi

openssl genrsa -out /etc/isakmpd/private/$1.key 1024
echo "Генерируем запрос на сертификат"
openssl req -new -key /etc/isakmpd/private/$1.key -out /etc/isakmpd/private/$1.csr
cd /etc/isakmpd
echo "Выписываем"

CERTIP=$1; export CERTIP; openssl x509 -req -days 365 -in /etc/isakmpd/private/$CERTIP.csr -CA /etc/ssl/ca.crt \
-CAkey /etc/ssl/private/ca.key -CAcreateserial -extfile /etc/ssl/x509v3.cnf \
-extensions x509v3_IPAddr -out /etc/isakmpd/certs/$CERTIP.crt

mkdir -p /tmp/$1
cp /etc/isakmpd/private/$1.key /etc/isakmpd/private/$1.csr /etc/ssl/ca.crt /etc/isakmpd/certs/$CERTIP.crt /tmp/$1/

cd /tmp/

tar czvf $1.tgz $1

echo Certs in /tmp/$1.tgz

PS/ см так же http://www.opennet.ru/base/sec/openbsd_ipsec_vpn.txt.html