IPsec между Strongswan 5.0.4 (FreeBSD) и Strongswan 1.2.3 (Android) 29.10.2013 YetAnotherOnanym http://www.opennet.ru/tips/2808_ipsec_strongswan_tunnel_freebsd_android_ssl_openssl.shtml http://some-wise-man.livejournal.com/232203.html 1. Устанавливаем Strongswan на FreeBSD, компилируем ядро с поддержкой IPsec. Устанавливаем на Android Strongswan из Google Play. 2. Создаём сертификаты. Сначала ключ и сертификат CA: Code: openssl genrsa -out ipsec-test_CA_key.pem -aes256 -passout stdin 2048 openssl req -x509 -new -sha512 -days 3652 -set_serial 0 -out ipsec-test_CA.pem \ -key ipsec-test_CA_key.pem -passin stdin -passout stdin -verbose \ -subj "/C=RU/ST=My state/L=My city/O=My IT Lab/OU=My CA dept\ /CN=My personal CA/emailAddress=me@mymailhost" 3. После этого в /etc/ssl/openssl.cnf находим секцию "[usr_cert]" и добавляем строку с именем своего хоста: Code: subjectAltName = DNS:ipsec-test.dyndns.org Это должно быть реально существующее DNS-имя - по нему Android будет находить стационарный хост. В данном случае, когда провайдер назначает на внешний интерфейс модема/роутера динамический "белый" IP-адрес, используется имя на бесплатном сервисе dyndns.org. С другими провайдерами возможны какие-то другие варианты. Создаём сертификат стационарного хоста (поскольку это первый сертификат нашего CA, указываем параметр -CAcreateserial) Code: openssl genrsa -out 'ipsec-test.dyndns.org_key.pem' 2048 openssl req -new -sha512 -days 3652 -out 'ipsec-test.dyndns.org_req.pem' \ -key 'ipsec-test.dyndns.org_key.pem' -passin stdin -passout stdin \ -subj "/C=RU/ST=My state/L=My city/O=My IT Lab/OU=My CA dept\ /CN=ipsec-test.dyndns.org/subjectAltName=DNS:ipsec-test.dyndns.org\ /emailAddress=me@mymailhost" openssl x509 -req -sha512 -days 3652 -extfile /etc/ssl/openssl.cnf \ -extensions "usr_cert" -CA ipsec-test_CA.pem -CAkey ipsec-test_CA_key.pem \ -CAcreateserial -CAserial ipsec-test_CA_serial \ -in 'ipsec-test.dyndns.org_req.pem' -out 'ipsec-test.dyndns.org_cert.pem' Строго говоря, указывать параметр "subjectAltName=DNS:ipsec-test.dyndns.org" в строке subject не обязательно, значение имеет расширение x.509v3, заданное в openssl.cnf. В строку subject этот параметр добавлен для красоты, на самом деле . Проверяем сертификат: Code: openssl x509 -in ipsec-test.dyndns.org_cert.pem -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 8a:55:5e:dd:bb:22:20:cc Signature Algorithm: sha512WithRSAEncryption Issuer: C=RU, ST=My state, L=My city, O=My IT Lab, OU=My CA dept, CN=My personal CA/emailAddress=me@mymailhost Validity Not Before: Oct 14 23:13:38 2013 GMT Not After : Oct 14 23:13:38 2023 GMT Subject: C=RU, ST=My state, L=My city, O=My IT Lab, OU=My CA dept, CN=ipsec-test.dyndns.org/subjectAltName=DNS:ipsec-test.dyndns.org/emailAddress=me@mymailhost (...) X509v3 Subject Alternative Name: DNS:ipsec-test.dyndns.org (...) 4. Теперь создадим ключ и сертификат для мобильного устройства. Вообще-то, параметр "subjectAltName" в openssl.cnf можно теперь не указывать (закомментировать) - это связано с тем, что мобильный Strongswan в качестве своего ID передаёт строку subject своего сертификата (при том, что сам требует от партнёра ID, совпадающий с FQDN или IP-адресом). Всё же для соблюдения единообразия зададим в openssl.cnf "subjectAltName = DNS:android" и сгенерируем сертификат: Code: openssl genrsa -out android_key.pem 2048 openssl req -new -sha512 -days 3652 -out android_req.pem \ -key android_key.pem -passin stdin -passout stdin \ -subj "/C=RU/ST=My state/L=My city/O=My IT Lab/OU=My CA dept\ /CN=android/subjectAltName=DNS:android/emailAddress=me@mymailhost" Проверяем сертификат: Code: openssl x509 -in android_cert.pem -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 8a:55:5e:dd:bb:22:20:cd Signature Algorithm: sha512WithRSAEncryption Issuer: C=RU, ST=My state, L=My city, O=My IT Lab, OU=My CA dept, CN=My personal CA/emailAddress=me@mymailhost Validity Not Before: Oct 15 19:58:45 2013 GMT Not After : Oct 15 19:58:45 2023 GMT Subject: C=RU, ST=My state, L=My city, O=My IT Lab, OU=My CA dept, CN=android/subjectAltName=DNS:android /emailAddress=me@mymailhost (...) Теперь преобразуем сертификат в формат PKCS#12: Code: openssl pkcs12 -export -out android_cert.p12 -in android_cert.pem \ -inkey android_key.pem -name Android -passout stdin -passin stdin 5. Конвертируем сертификаты и ключи в формат DER (в debug-выводе charon присутствуют жалобы на плагин PEM, поэтому не будем пользоваться форматом PEM): Code: openssl x509 -in ipsec-test_CA.pem -out ipsec-test_CA.der -inform pem -outform der openssl rsa -in ipsec-test.dyndns.org_key.pem -out ipsec-test.dyndns.org_key.der -inform pem -outform der openssl x509 -in ipsec-test.dyndns.org_cert.pem -out ipsec-test.dyndns.org_cert.der -inform pem -outform der openssl x509 -in android_cert.pem -out android_cert.der -inform pem -outform Создаём ссылку: Code: ln -s /etc/ssl/certs/ipsec-test/ipsec-test_CA.der /usr/local/etc/ipsec.d/cacerts 6. Создаём файл конфигурации ipsec.conf: Code: # ipsec.conf - strongSwan IPsec configuration file config setup # strictcrlpolicy=no # uniqueids = yes ca ipsec-test cacert = /etc/ssl/certs/ipsec-test/ipsec-test_CA.der conn android keyexchange = ikev2 ike = AES_CBC_256-HMAC_SHA2_512-MODP4096 esp = AES_CBC_256-HMAC_SHA2_256 type = tunnel leftsourceip = 192.168.254.1 rightsourceip = 192.168.254.2 auto = start leftauth = pubkey rightauth = pubkey left = 192.168.203.3 right = %any leftsubnet = 192.168.203.3 leftca = "C=RU, ST=My state, L=My city, O=My IT Lab, OU=My CA dept, CN=My personal CA/emailAddress=me@mymailhost" rightca = "C=RU, ST=My state, L=My city, O=My IT Lab, OU=My CA dept, CN=My personal CA/emailAddress=me@mymailhost" leftcert = /etc/ssl/certs/ipsec-test/ipsec-test.dyndns.org_cert.der rightcert = /etc/ssl/certs/ipsec-test/android_cert.der leftid = "ipsec-test.dyndns.org" rightid = " C=RU, ST=My state, L=My city, O=My IT Lab, OU=My CA dept, CN=android/subjectAltName=DNS:android/emailAddress=me@mymailhost" 7. Создаём файл ipsec.secrets: Code: "ipsec-test.dyndns.org" : RSA /etc/ssl/certs/ipsec-test/ipsec-test.dyndns.org_key.der 8. Устанавливаем сертификаты на мобильное устройство. Копируем сертификат android_cert.p12 и сертификат УЦ ipsec-test_CA.crt (сменив расширение .pem на .crt - это существенно) в корень SD-карты мобильного устройства. Устанавливаем сертификаты: Настройки -> Безопасность -> Установить из памяти (Для сертификата в формате PKCS#12 надо буде ввести пароль, заданный в п.4). 9. Настраиваем мобильный Strongswan. В качестве шлюза задаём FQDN стационарного хоста ipsec-test.dyndns.org (оно же будет и "peer ID"), тип - IKEv2 Сертификат, выбираем загруженный и установленный сертификат мобильного устройства, указываем вручную сертификат нашего УЦ. 10. Сохраняем, устанавливаем соединение. Вуаля! 11. Проверяем состояние стационарного хоста (да, утилита setkey - это из racoon, но я к ней привык ): Code: setkey -D 192.168.203.3 XXX.XXX.XXX.XXX esp mode=tunnel spi=3944322401(0xeb199561) reqid=1(0x00000001) E: rijndael-cbc 7b45804f 3e75bd59 7092e7ac dae00600 A: hmac-sha1 ec42cbbf e49848a9 72620762 bc97d0cb 6bfb8412 seq=0x00000000 replay=32 flags=0x00000000 state=mature created: Oct 17 17:29:48 2013 current: Oct 17 17:30:05 2013 diff: 17(s) hard: 3600(s) soft: 2957(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=902 refcnt=1 XXX.XXX.XXX.XXX 192.168.203.3 esp mode=any spi=3276763214(0xc34f704e) reqid=1(0x00000001) E: rijndael-cbc 70c5b1df dc0932a9 d8c8558b bd44caf7 A: hmac-sha1 f3161cbc 50952da1 c298b3af 77008587 8bbc4f1f seq=0x00000000 replay=32 flags=0x00000000 state=mature created: Oct 17 17:29:48 2013 current: Oct 17 17:30:05 2013 diff: 17(s) hard: 3600(s) soft: 2560(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=902 refcnt=1 setkey -DP 192.168.254.2[any] 192.168.203.3[any] any in ipsec esp/tunnel/XXX.XXX.XXX.XXX-192.168.203.3/unique:1 created: Oct 17 17:29:48 2013 lastused: Oct 17 17:29:48 2013 lifetime: 2147483647(s) validtime: 0(s) spid=4 seq=1 pid=917 refcnt=1 192.168.203.3[any] 192.168.254.2[any] any out ipsec esp/tunnel/192.168.203.3-XXX.XXX.XXX.XXX/unique:1 created: Oct 17 17:29:48 2013 lastused: Oct 17 17:29:48 2013 lifetime: 2147483647(s) validtime: 0(s) spid=3 seq=0 pid=917 refcnt=1 XXX.XXX.XXX.XXX - IP-адрес внешнего интерфейса шлюза провайдера (трафик проходит через NAT). В одной консоли запускаем "tcpdump -i ep1 -n host XXX.XXX.XXX.XXX", в другой - "ping 192.168.254.2": Code: tcpdump -i ep1 -n host XXX.XXX.XXX.XXX listening on ep1, link-type EN10MB (Ethernet), capture size 65535 bytes 17:34:49.316449 IP 192.168.203.3.4500 > XXX.XXX.XXX.XXX.57488: isakmp-nat-keep-alive 17:34:50.578734 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: isakmp-nat-keep-alive 17:35:06.825124 IP 192.168.203.3.4500 > XXX.XXX.XXX.XXX.57488: UDP-encap: ESP(spi=0xeb199561,seq=0x1), length 132 17:35:07.826283 IP 192.168.203.3.4500 > XXX.XXX.XXX.XXX.57488: UDP-encap: ESP(spi=0xeb199561,seq=0x2), length 132 17:35:08.827392 IP 192.168.203.3.4500 > XXX.XXX.XXX.XXX.57488: UDP-encap: ESP(spi=0xeb199561,seq=0x3), length 132 17:35:09.094268 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: UDP-encap: ESP(spi=0xc34f704e,seq=0x1), length 132 17:35:09.154359 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: UDP-encap: ESP(spi=0xc34f704e,seq=0x2), length 132 17:35:09.194508 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: UDP-encap: ESP(spi=0xc34f704e,seq=0x3), length 132 17:35:09.828539 IP 192.168.203.3.4500 > XXX.XXX.XXX.XXX.57488: UDP-encap: ESP(spi=0xeb199561,seq=0x4), length 132 17:35:09.953676 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: UDP-encap: ESP(spi=0xc34f704e,seq=0x4), length 132 17:35:10.503650 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: isakmp-nat-keep-alive 17:35:10.829664 IP 192.168.203.3.4500 > XXX.XXX.XXX.XXX.57488: UDP-encap: ESP(spi=0xeb199561,seq=0x5), length 132 17:35:10.954139 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: UDP-encap: ESP(spi=0xc34f704e,seq=0x5), length 132 17:35:30.327819 IP 192.168.203.3.4500 > XXX.XXX.XXX.XXX.57488: isakmp-nat-keep-alive 17:35:31.118437 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: isakmp-nat-keep-alive 17:35:50.332414 IP 192.168.203.3.4500 > XXX.XXX.XXX.XXX.57488: isakmp-nat-keep-alive 17:35:52.174896 IP XXX.XXX.XXX.XXX.57488 > 192.168.203.3.4500: isakmp-nat-keep-alive