Транспорт на IPSec

Решил задачку по построению IPSec транспорта между OS FreeBSD и CentOS (в примере 6 версия).

Есть 3 белых IP:

1.1.1.1 — FreeBSD 11.2 = A
2.2.2.2 — FreeBSD 11.2 = B
3.3.3.3 — CentOS 6 (6.10) = C

Задача — зашифровать трафик между серверами A-B, B-C, и авторизация по PSK.

Подготовка хостов FreeBSD

На обоих хостах нужно поставить пакет ipsec-tools и добавить в включить сервисы racoon и IPSec.

Через PKG

1
pkg install ipsec-tools

Через порты

1
2
cd /usr/ports/security/ipsec-tools
make install clean
1
2
3
sysrc ipsec_enable="YES"
sysrc racoon_enable="YES"
sysrc racoon_flags="-l /var/log/racoon.log"
touch /usr/local/etc/racoon/psk.txt /usr/local/etc/racoon/racoon.conf
chmod 600 /usr/local/etc/racoon/psk.txt /usr/local/etc/racoon/racoon.conf
chown root:wheel /usr/local/etc/racoon/psk.txt /usr/local/etc/racoon/racoon.conf

Грузим IPSec в ядро

1
2
kldload ipsec
sysrc -f /boot/loader.conf ipsec_load="YES"

… или пересобираем ядро со следующими параметрами

options   IPSEC          #IP security
# options   IPSEC_DEBUG  #debug for IP security
device    crypto

Подготовка хоста CentOS

1
2
yum install epel-release
yum install ipsec-tools

Настройка хостов FreeBSD

Host A 1.1.1.1

/etc/ipsec.conf

flush;
spdflush;
# A->B
spdadd 1.1.1.1/32 2.2.2.2/32 any -P out ipsec esp/transport//require;
spdadd 2.2.2.2/32 1.1.1.1/32 any -P in ipsec esp/transport//require;

/usr/local/etc/racoon/psk.txt

2.2.2.2 mySecureKey

/usr/local/etc/racoon/racoon.conf

path include "/usr/local/etc/racoon/racoon";
path pre_shared_key "/usr/local/etc/racoon/psk.txt";
path certificate "/usr/local/etc/racoon/cert";


padding
{
        maximum_length 20;    
        randomize off;         
        strict_check off;       
        exclusive_tail off;    
}

listen
{
        isakmp 1.1.1.1 [500];
        strict_address;  
}

timer
{
        counter 5;   
        interval 20 sec; 
        persend 1;    
        phase1 30 sec;
        phase2 15 sec;
}

remote 2.2.2.2
{
        my_identifier address 1.1.1.1;
        exchange_mode main;
        ike_frag on;
        proposal_check claim;

        doi ipsec_doi;
        situation identity_only;

        nonce_size 16;
        lifetime time 86400 sec;
        initial_contact on;
        support_proxy on;

        proposal {
                encryption_algorithm 3des;
                hash_algorithm sha1;
                authentication_method pre_shared_key;
                dh_group 2;
                lifetime time 28800 sec;
        }
}

sainfo anonymous
{
        pfs_group modp2048;
        encryption_algorithm 3des;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate;
        lifetime time 28800 sec;
}

Host B 2.2.2.2

/etc/ipsec.conf

flush;
spdflush;

# A->B
spdadd 2.2.2.2/32 1.1.1.1/32 any -P out ipsec esp/transport//require;
spdadd 1.1.1.1/32 2.2.2.2/32 any -P in ipsec esp/transport//require;

# B->C
spdadd 2.2.2.2/32 3.3.3.3/32 any -P out ipsec esp/transport//require;
spdadd 3.3.3.3/32 2.2.2.2/32 any -P in ipsec esp/transport//require;

/usr/local/etc/racoon/psk.txt

1.1.1.1 mySecureKey
3.3.3.3 mySecureKey

/usr/local/etc/racoon/racoon.conf

path include "/usr/local/etc/racoon/racoon";
path pre_shared_key "/usr/local/etc/racoon/psk.txt";
path certificate "/usr/local/etc/racoon/cert";


padding
{
        maximum_length 20;    
        randomize off;         
        strict_check off;       
        exclusive_tail off;    
}

listen
{
        isakmp 2.2.2.2 [500];
        strict_address;  
}

timer
{
        counter 5;   
        interval 20 sec; 
        persend 1;    
        phase1 30 sec;
        phase2 15 sec;
}

remote 1.1.1.1
{
        my_identifier address 2.2.2.2;
        exchange_mode main;
        ike_frag on;
        proposal_check claim;

        doi ipsec_doi;
        situation identity_only;

        nonce_size 16;
        lifetime time 86400 sec;
        initial_contact on;
        support_proxy on;

        proposal {
                encryption_algorithm 3des;
                hash_algorithm sha1;
                authentication_method pre_shared_key;
                dh_group 2;
                lifetime time 28800 sec;
        }
}

remote 3.3.3.3
{
        my_identifier address 2.2.2.2;
        exchange_mode main;
        ike_frag on;
        proposal_check claim;
        doi ipsec_doi;
        situation identity_only;
        nonce_size 16;
        lifetime time 86400 sec;
        initial_contact on;
        support_proxy on;
        proposal {
                encryption_algorithm 3des;
                hash_algorithm sha1;
                authentication_method pre_shared_key;
                dh_group modp2048;
                lifetime time 28800 sec;
        }
}

sainfo anonymous
{
        pfs_group modp2048;
        encryption_algorithm 3des;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate;
        lifetime time 28800 sec;
}

Host C 3.3.3.3

Файл /etc/ipsec.conf остается без изменений (листинг без комментариев)

# /etc/ipsec.conf - Libreswan IPsec configuration file

config setup
        protostack=netkey
        logfile=/var/log/pluto.log
        dumpdir=/var/run/pluto/
        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10
include /etc/ipsec.d/*.conf

И /etc/ipsec.secrets тоже не меняю

include /etc/ipsec.d/*.secrets
Создаем /etc/ipsec.d/2.2.2.2.conf и /etc/ipsec.d/2.2.2.2.secrets
touch /etc/ipsec.d/2.2.2.2.{conf,secrets}
chown root:root /etc/ipsec.d/2.2.2.2.{conf,secrets}
chmod 600 /etc/ipsec.d/2.2.2.2.{conf,secrets}

/etc/ipsec.d/2.2.2.2.conf

conn 2.2.2.2
        fragmentation=yes
        authby=secret
        auto=start
        type=transport
        left=2.2.2.2
        leftid=2.2.2.2
        right=3.3.3.3
        ike=3des-sha1;modp2048
        phase2=esp
        phase2alg=3des-sha1;modp2048
        salifetime = 28800s

/etc/ipsec.d/2.2.2.2.secrets

2.2.2.2 3.3.3.3: PSK "mySecureKey"
Стартуем IPSec
service ipsec start

Апендикс

Не забываем открыть 500/UDP между нашими серверами и поставить разные PSK на сервера
…пробуем отправить icmp с хоста B на C, tcpdump должен отловить ESP пакет

1
B $ ping -c 5 3.3.3.3
PING 3.3.3.3 (3.3.3.3): 56 data bytes
64 bytes from 3.3.3.3: icmp_seq=0 ttl=55 time=57.147 ms
64 bytes from 3.3.3.3: icmp_seq=1 ttl=55 time=57.156 ms
64 bytes from 3.3.3.3: icmp_seq=2 ttl=55 time=57.124 ms
64 bytes from 3.3.3.3: icmp_seq=3 ttl=55 time=57.185 ms
64 bytes from 3.3.3.3: icmp_seq=4 ttl=55 time=57.066 ms

--- 3.3.3.3 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 57.066/57.136/57.185/0.040 ms
1
C $ tcpdump -nnn -i any src or dst 2.2.2.2
14:10:28.869335 IP 2.2.2.2 > 3.3.3.3: ESP(spi=0x2d6544f5,seq=0x1e1), length 100
14:10:28.869408 IP 3.3.3.3 > 2.2.2.2: ESP(spi=0x0592c9c7,seq=0x1e0), length 100
14:10:29.895382 IP 2.2.2.2 > 3.3.3.3: ESP(spi=0x2d6544f5,seq=0x1e2), length 100
14:10:29.895450 IP 3.3.3.3 > 2.2.2.2: ESP(spi=0x0592c9c7,seq=0x1e1), length 100
14:10:30.915193 IP 2.2.2.2 > 3.3.3.3: ESP(spi=0x2d6544f5,seq=0x1e3), length 100
14:10:30.915252 IP 3.3.3.3 > 2.2.2.2: ESP(spi=0x0592c9c7,seq=0x1e2), length 100
14:10:31.965408 IP 2.2.2.2 > 3.3.3.3: ESP(spi=0x2d6544f5,seq=0x1e4), length 100
14:10:31.965466 IP 3.3.3.3 > 2.2.2.2: ESP(spi=0x0592c9c7,seq=0x1e3), length 100
14:10:32.995271 IP 2.2.2.2 > 3.3.3.3: ESP(spi=0x2d6544f5,seq=0x1e5), length 100
14:10:32.995344 IP 3.3.3.3 > 2.2.2.2: ESP(spi=0x0592c9c7,seq=0x1e4), length 100

Если ответа нет — смотрим логи FreeBSD /var/log/racoon.log и Linux /var/log/pluto.log,
Также пригодится setkey -D и setkey -DP.

Источники, которые помогли мне в решении задачи: