V říjnu na konferenci EurOpen.CZ v klášteře Želiv jsem měl přednášku o stavu implementací IPsec v linuxových distribucích. Vyšly mi z toho čtyři různé implementace části v uživatelském prostoru, o kterých mělo smysl uvažovat: Racoon, Racoon2, Openswan a Strongswan. Racoon2 ani Strongswan nebyly mezi balíčky Fedory, což se mi později podařilo napravit. Současný stav jsem popisoval v únoru na Developer Conference v Brně.

Ale začněme trochu více od podlahy. Název IPsec vznikl jako zkratka IP Security, což napovídá, že je to standard, kteřý se stará o zabezpečení komunikace po protokolu IP. Je povinnou součástí implementací IPv6, takže patří mezi ty novinky, které nám protokol IPv6 přinesl. Ale stal se i doplňkem IPv4, a to do té míry, že je sladěný s dnešním světem IPv4 maškarády a ke své funkci IPv6 vůbec nepotřebuje.

IPsec je celá rodina protokolů. Jeho asi nejdůležitější součástí je protokol ESP, který umožňuje zapouzdřit IP pakety. Poskytuje integritu a utajení, ohledně autenticity spoléhá na symetrické klíče, jejichž výměna je mimo jeho působnost. ESP funguje ve dvou různých variantách, transportní a tunelové. Transportní varianta slouží k zabezpečení komunikace mezi koncovými stroji. Tunelová varianta je potřeba pro propojení celých sítí.

Implementace v kernelu

Linuxové jádro se stará pouze o zabezpečení jednotlivých IP paketů, implementuje tedy mimo jiné výše zmíněný protokol ESP. V jádře se nachází tabulka bezpečnostních politik a tabulka bezpečnostních asociací. První určuje pravidla pro odesílání, příjem a přeposílání paketů, druhá dává zabezpečení konkrétní podobu a klíče.

Kernelová implementace se ovládá jednoduše příkazem ip z balíku iproute. K otestování je kromě jádra s podporou IPsec a příkazu ip potřeba už jen mít k dispozici dva stroje. Říkejme jim alpha.example.net a beta.example.net. Konfigurace probíhá samostatně pro každý směr provozu.

Transportní kanál

Protože se jedná o experiment, vyrobíme si jednosměrný transportní ESP kanál.

alpha.example.net:

# ip address add 2001:db8::a/64 dev eth0
# ip xfrm policy add dir out \
    src 2001:db8::a dst 2001:db8::b tmpl proto esp
# ip xfrm state add \
    src 2001:db8::a dst 2001:db8::b proto esp spi 1 \
    enc 'cbc(aes)' 0x3ed0af408cf5dcbf5d5d9a5fa806b224

beta.example.net:

# ip address add 2001:db8::b/64 dev eth0
# ip xfrm policy add dir in \
    src 2001:db8::a dst 2001:db8::b tmpl proto esp
# ip xfrm state add \
    src 2001:db8::a dst 2001:db8::b proto esp spi 1 \
    enc 'cbc(aes)' 0x3ed0af408cf5dcbf5d5d9a5fa806b224

První příkaz nastavuje adresu IPv6. Úplně stejně byste mohli použít adresu protokolu IPv4. V tomto případě jsou vybrány ze stejného rozsahu, ale úplně stejně to funguje mezi stroji v různých sítích.

Druhý příkaz nastavuje bezpečnostní politiku. Mezi alfou a betou se liší pouze nastavením směru. Konfigurace na alfě se týká odchozích paketů vytvořených lokální aplikací. Říká, že každý odchozí paket musí být zašifrován pomocí odpovídající bezpečnostní asociace. Beta má naopak nastaveno, že přijímá pouze zabezpečené pakety.

Třetí příkaz je na obou stranách totožný a přidává bezpečnostní asociaci se stejným protokolem, šifrou a klíčem. Parametr spi umožňuje přidat více záznamů pro stejný zdroj a cíl, což pomáhá při plynulé změně klíčů.

# ping6 2001:db8::b
PING 2001:db8::b(2001:db8::b) 56 data bytes
64 bytes from 2001:db8::b: icmp_seq=1 ttl=255 time=0.630 ms
64 bytes from 2001:db8::b: icmp_seq=2 ttl=255 time=0.504 ms
IP6 2001:db8::a > 2001:db8::b: ESP(spi=0x00000001,seq=0x1), length 104
IP6 2001:db8::b > 2001:db8::a: ICMP6, echo reply, seq 1, length 64
IP6 2001:db8::a > 2001:db8::b: ESP(spi=0x00000001,seq=0x2), length 104
IP6 2001:db8::b > 2001:db8::a: ICMP6, echo reply, seq 2, length 64

Test ukazuje, že pakety od alfy na betu jsou chráněné protokolem ESP, zatímco pakety v opačném směru jsou nedotčené.

Tunel

Stejný experiment lze provést i pro tunelový mód mezi routery. Tunelový mód lze použít úplně stejným způsobem jako transportní, ale tím, že ESP obsahuje celý IP paket, je možné přes tunel zprostředkovat připojení k celým sítím.

alpha.example.net:

# ip address add 2001:db8::a/64 dev eth0
# ip address add 2001:db8:a:a::1/64 dev eth1
# ip xfrm policy add dir out \
    src 2001:db8::a:a::/64 dst 2001:db8:b:b::/64 \
    tmpl src 2001:db8::a/128 dst 2001:db8::b/128 \
    proto esp mode tunnel
# ip xfrm state add \
    src 2001:db8::a dst 2001:db8::b proto esp spi 1 mode tunnel \
    enc 'cbc(aes)' 0x3ed0af408cf5dcbf5d5d9a5fa806b224

beta.example.net:

# ip address add 2001:db8::b/64 dev eth0
# ip address add 2001:db8:b:b::1/64 dev eth1
# ip xfrm policy add dir in \
    src 2001:db8::a:a::/64 dst 2001:db8:b:b::/64 \
    tmpl src 2001:db8::a/128 dst 2001:db8::b/128 \
    proto esp mode tunnel
# ip xfrm state add \
    src 2001:db8::a dst 2001:db8::b proto esp spi 1 mode tunnel \
    enc 'cbc(aes)' 0x3ed0af408cf5dcbf5d5d9a5fa806b224

Bezpečnostní politika musí být jako tunelová označena a stejně tak i odpovídající bezpečnostní asociace. Politika navíc musí obsahovat adresy směrovaných sítí.

Síťové protokoly IPv4 a IPv6 jdou při tunelování libovolně kombinovat. ESP tak může sloužit jako zabezpečená náhrada za smíšené IP tunely.

Závěr

Ačkoli na otevření ESP transportního kanálu či tunelu nepotřebujete nic jiného než běžnou konfiguraci jádra a nástroj ip, nelze tento způsob doporučit pro nic jiného než hraní si a testování.

V praxi se konfigurace klíčů řeší dynamicky a odděleně od autentizace komunikujících stran. Místo příkazu ip se používají již zmíněné implementace v uživatelském prostoru, které spolu komunikují po síti pomocí protokolu IKE. O tom bude druhý díl.