“internet” paralel (1)

In mod traditional pentru schimbul de informatii considerate sensibile intre doua companii, indiferent de aplicatie, se stabileste o conexiune IPSec (da, stiu ca mai exista si OpenVPN dar nu se pune ca nu este suportat comercial pentru interoperare). Si treaba asta merge OK cand ai nu numar rezonabil de parteneri, dupa aia nu mai este chiar asa distractiv.

Cand ai o companie mare cu multe locatii, atunci se ajunge la configuratii de tipul Hub-and-Spoke fie configurate manual fie automat folosind DMVPN/GETVPN in functie de necesitati si situatie individuala.

Acum, cum impaci capra cu varza, sa ai o configuratia din asta dar intre companii, un fel de serviciu de IPSec-as-a-Service, ceva de genul:

ipsec-aas-v1_1

Unde VPN HUB este un la “provider” iar gateway-urile de VPN sunt la “clienti”. Si asta se poate extinde pana terminam alfabetul si o luam cu VPN Gateway AA pana la VPN Gateway ZZZZZ.

Cum ar functiona toata treaba asta fara sa se strice si sa fie scalabila? Teoretic ar fi in felul urmator:

  • IPSec intre capete
  • GRE over IPSec
  • BGP over GRE
  • se accepta doar adrese de IP sau subnet-uri “publice”

De ce BGP? Pai pentru ca:

  • permite o filtrare mult mai buna a rutelor si a anunturilor, astfel incat sa nu se poata anunta prefixe inexistente sau sa se poata face hijacking
  • pot anunta sau importa selectiv prefixe
  • pot folosi si pentru IPv4 cat si pentru IPv6
  • este mult mai scalabil decat OSPF care este folosit in mod traditional pentru “route based VPNs”

Ideea de baza ar fi in felul urmator:

  • Vreau sa comunic securizat cu un numar oarecare de entitati cu care am treaba insa nu vreau sa fac tunele VPN cu fiecare in parte
  • Prefer sa am un singur tunel facut care sa-mi dea acces la restul de tunele
  • Sa pot publica servicii “secure only” accesibile doar celor din clubul asta
  • Sa fie greu de detectat de catre o entitate ostila cine cu cine discuta si cat de mult

Pentru validare mi-am facut un setup de test care arata cam asa:

ipsec-aas_v2_2

Setarile sunt facute astfel:

  • vpn-hub
    • eth0: 10.15.0.1/24
  • internet-router
    • eth0: 10.16.0.1/24
    • eth1: 10.15.0.2/24
  • vpn-gw-a
    • eth0: 10.16.0.2/24
    • eth1: 172.16.1.1/24
  • vpn-gw-b
    • eth0: 10.16.0.3/24
    • eth1: 172.16.2.1/24
  • vpn-gw-c
    • eth0: 10.16.0.4/24
    • eth1: 172.16.3.1/24

internet-router este o masina care sa simuleze “internetul” in sensul de un hop intermediar intre gateway-urile de VPN si concentrator.

Prima oara am setat tunele VPN (pentru test le-am facut cu PSK ca e mai usor):

  • vpn-hub /etc/ipsec.conf
conn to-vpn-gw-a
 authby=secret
 auto=start
 type=transport
 left=10.15.0.1
 leftnexthop=10.15.0.2
 right=10.16.0.2
 rightnexthop=10.16.0.1
conn to-vpn-gw-b
 authby=secret
 auto=start
 type=transport
 left=10.15.0.1
 leftnexthop=10.15.0.2
 right=10.16.0.3
 rightnexthop=10.16.0.1
conn to-vpn-gw-c
 authby=secret
 auto=start
 type=transport
 left=10.15.0.1
 leftnexthop=10.15.0.2
 right=10.16.0.4
 rightnexthop=10.16.0.1
  • vpn-hub /etc/ipsec.secrets
10.15.0.1 10.16.0.2: PSK "supersecret"
10.15.0.1 10.16.0.3: PSK "supersecret"
10.15.0.1 10.16.0.4: PSK "supersecret"
  • vpn-gw-a /etc/ipsec.conf
conn to-vpn-hub
 authby=secret
 auto=start
 type=transport
 left=10.16.0.2
 leftnexthop=10.16.0.1
 right=10.15.0.1
 rightnexthop=10.15.0.2
  • vpn-gw-a /etc/ipsec.secrets
10.16.0.2 10.15.0.1: PSK "supersecret"
  • vpn-gw-b /etc/ipsec.conf
conn to-hub
 authby=secret
 auto=start
 type=transport
 right=10.15.0.1
 rightnexthop=10.15.0.2
 left=10.16.0.3
 leftnexthop=10.16.0.1
  • vpn-gw-b /etc/ipsec.secrets
10.16.0.3 10.15.0.1: PSK "supersecret"
  • vpn-gw-c /etc/ipsec.conf
conn to-hub
 authby=secret
 auto=start
 type=transport
 right=10.15.0.1
 rightnexthop=10.15.0.2
 left=10.16.0.4
 leftnexthop=10.16.0.1
  • vpn-gw-c /etc/ipsec.secrets
10.16.0.4 10.15.0.1: PSK "supersecret"
  • vpn-hub ipsec status
stats db_ops: {curr_cnt, total_cnt, maxsz} :context={0,0,0} trans={0,0,0} attrs={0,0,0}
"to-vpn-gw-a": 10.15.0.1<10.15.0.1>[+S=C]---10.15.0.2...10.16.0.1---10.16.0.2<10.16.0.2>[+S=C]; erouted; eroute owner: #2
"to-vpn-gw-a":     myip=unset; hisip=unset;
"to-vpn-gw-a":   ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0; nat_keepalive: yes
"to-vpn-gw-a":   policy: PSK+ENCRYPT+PFS+UP+IKEv2ALLOW+SAREFTRACK+lKOD+rKOD; prio: 32,32; interface: eth0;
"to-vpn-gw-a":   dpd: action:clear; delay:0; timeout:0;
"to-vpn-gw-a":   newest ISAKMP SA: #16; newest IPsec SA: #2;
"to-vpn-gw-a":   IKE algorithm newest: AES_CBC_128-SHA1-MODP2048
"to-vpn-gw-b": 10.15.0.1<10.15.0.1>[+S=C]---10.15.0.2...10.16.0.1---10.16.0.3<10.16.0.3>[+S=C]; erouted; eroute owner: #7
"to-vpn-gw-b":     myip=unset; hisip=unset;
"to-vpn-gw-b":   ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0; nat_keepalive: yes
"to-vpn-gw-b":   policy: PSK+ENCRYPT+PFS+UP+IKEv2ALLOW+SAREFTRACK+lKOD+rKOD; prio: 32,32; interface: eth0;
"to-vpn-gw-b":   dpd: action:clear; delay:0; timeout:0;
"to-vpn-gw-b":   newest ISAKMP SA: #18; newest IPsec SA: #7;
"to-vpn-gw-b":   IKE algorithm newest: AES_CBC_128-SHA1-MODP2048
"to-vpn-gw-c": 10.15.0.1<10.15.0.1>[+S=C]---10.15.0.2...10.16.0.1---10.16.0.4<10.16.0.4>[+S=C]; erouted; eroute owner: #11
"to-vpn-gw-c":     myip=unset; hisip=unset;
"to-vpn-gw-c":   ike_life: 3600s; ipsec_life: 28800s; rekey_margin: 540s; rekey_fuzz: 100%; keyingtries: 0; nat_keepalive: yes
"to-vpn-gw-c":   policy: PSK+ENCRYPT+PFS+UP+IKEv2ALLOW+SAREFTRACK+lKOD+rKOD; prio: 32,32; interface: eth0;
"to-vpn-gw-c":   dpd: action:clear; delay:0; timeout:0;
"to-vpn-gw-c":   newest ISAKMP SA: #17; newest IPsec SA: #11;
"to-vpn-gw-c":   IKE algorithm newest: AES_CBC_128-SHA1-MODP2048
#2: "to-vpn-gw-a":500 STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 19862s; newest IPSEC; eroute owner; isakmp#1; idle; import:admin initiate
#2: "to-vpn-gw-a" [email protected] [email protected] ref=0 refhim=4294901761
#16: "to-vpn-gw-a":500 STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 211s; newest ISAKMP; lastdpd=-1s(seq in:0 out:0); idle; import:admin initiate
#4: "to-vpn-gw-b":500 STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 19643s; isakmp#3; idle; import:admin initiate
#4: "to-vpn-gw-b" [email protected] [email protected] ref=0 refhim=4294901761
#15: "to-vpn-gw-b":500 STATE_MAIN_R3 (sent MR3, ISAKMP SA established); EVENT_SA_REPLACE in 393s; lastdpd=-1s(seq in:0 out:0); idle; import:not set
#7: "to-vpn-gw-b":500 STATE_QUICK_R2 (IPsec SA established); EVENT_SA_REPLACE in 20348s; newest IPSEC; eroute owner; isakmp#6; idle; import:not set
#7: "to-vpn-gw-b" [email protected] [email protected] ref=0 refhim=4294901761
#18: "to-vpn-gw-b":500 STATE_MAIN_R3 (sent MR3, ISAKMP SA established); EVENT_SA_REPLACE in 3022s; newest ISAKMP; lastdpd=-1s(seq in:0 out:0); idle; import:not set
#10: "to-vpn-gw-c":500 STATE_QUICK_R2 (IPsec SA established); EVENT_SA_REPLACE in 21719s; isakmp#9; idle; import:not set
#10: "to-vpn-gw-c" [email protected] [email protected] ref=0 refhim=4294901761
#17: "to-vpn-gw-c":500 STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 1169s; newest ISAKMP; lastdpd=-1s(seq in:0 out:0); idle; import:admin initiate
#11: "to-vpn-gw-c":500 STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 21348s; newest IPSEC; eroute owner; isakmp#8; idle; import:admin initiate
#11: "to-vpn-gw-c" [email protected] [email protected] ref=0 refhim=4294901761

 type=transport din /etc/ipsec.conf pentru fiecare conexiune in parte inseamna ca o “conexiune” IPSec se va stabili doar intre IP-urile gateway-urilor.

Acum ca totul e OK la partea de criptare, se seteaza tunelele GRE intre gatewa-uri si hub:

  • vpn-gw-a
ip tunnel add to-hub mode gre remote 10.15.0.1 local 10.16.0.2 ttl 255
ip addr add 192.168.168.2/30 peer 192.168.168.1/30 dev to-hub
ip link set to-hub up
  • vpn-gw-b
ip tunnel add to-hub mode gre remote 10.15.0.1 local 10.16.0.3 ttl 255
ip addr add 192.168.168.2/30 peer 192.168.168.1/30 dev to-hub
ip link set to-hub up
  • vpn-gw-c
ip tunnel add to-hub mode gre remote 10.15.0.1 local 10.16.0.4 ttl 255
ip addr add 192.168.168.2/30 peer 192.168.168.1/30 dev to-hub
ip link set to-hub up
  • vpn-hub
ip tunnel add to-gw-a mode gre remote 10.16.0.2 local 10.15.0.1 ttl 255
ip addr add 192.168.168.1/30 peer 192.168.168.2/30 dev to-gw-a
ip link link set to-gw-a up

ip tunnel add to-gw-b mode gre remote 10.16.0.3 local 10.15.0.1 ttl 255
ip addr add 192.168.168.5/30 peer 192.168.168.6/30 dev to-gw-b
ip link link set to-gw-b up

ip tunnel add to-gw-c mode gre remote 10.16.0.4 local 10.15.0.1 ttl 255
ip addr add 192.168.168.9/30 peer 192.168.168.10/30 dev to-gw-c
ip link link set to-gw-c up

Tunelele GRE sunt necesare pentru a putea ruta peste orice avem nevoie fara a crea SA-uri suplimentare in IPSec pentru fiecare subnet sau adresa IP individuala si abstractizeaza partea de transport. Din punct de vedere IP un gateway are conexiune directa cu hub-ul si atat.

Ultima partea este configurarea Quagga pentru a avea partea de BGP functionala.

  • vpn-hub /etc/quagga/bgpd.conf
router bgp 4200000000
 bgp router-id 192.168.168.9
 neighbor 192.168.168.2 remote-as 4200000001
 neighbor 192.168.168.2 next-hop-self
 neighbor 192.168.168.10 remote-as 4200000003
 neighbor 192.168.168.10 next-hop-self
  • vpn-gw-a /etc/quagga/bgpd.conf
router bgp 4200000001
 bgp router-id 192.168.168.2
 network 172.16.1.0/24
 neighbor 192.168.168.1 remote-as 4200000000
  • vpn-gw-c
router bgp 4200000003
 bgp router-id 192.168.168.10
 network 172.16.3.0/24
 neighbor 192.168.168.9 remote-as 4200000000

Configurarea de pe vpn-gw-b lipseste ca mi-am dat seama in timp ce scriam ca de fapt este OK de demonstrat si cu doar doua gateway-uri :)

  • vpn-gw-c sh ip bgp
BGP table version is 0, local router ID is 192.168.168.10
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

Network          Next Hop            Metric LocPrf Weight Path
*> 172.16.1.0/24    192.168.168.9                          0 4200000000 4200000001 i
*> 172.16.3.0/24    0.0.0.0                  0         32768 i

Total number of prefixes 2
  • vpn-gw-a sh ip bgp
BGP table version is 0, local router ID is 192.168.168.2
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

Network          Next Hop            Metric LocPrf Weight Path
*> 172.16.1.0/24    0.0.0.0                  0         32768 i
*> 172.16.3.0/24    192.168.168.1                          0 4200000000 4200000003 i

Total number of prefixes 2
  • vpn-hub sh ip bgp
BGP table version is 0, local router ID is 192.168.168.9
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

Network          Next Hop            Metric LocPrf Weight Path
*> 172.16.1.0/24    192.168.168.2            0             0 4200000001 i
*> 172.16.3.0/24    192.168.168.10           0             0 4200000003 i

Total number of prefixes 2

Daca de pe vpn-gw-a dau un ping spre vpn-gw-c (ping 172.16.3.1 -I172.16.1.1) in tcpdump pe vpn-hub am sa vad urmatoarele:

20:03:55.112851 IP 10.16.0.2 > 10.15.0.1: ESP(spi=0xbe68e78f,seq=0x338), length 132
20:03:55.112906 IP 10.15.0.1 > 10.16.0.4: ESP(spi=0xac29a868,seq=0x30f), length 132
20:03:55.113404 IP 10.16.0.4 > 10.15.0.1: ESP(spi=0xfdb78f7d,seq=0x2b7), length 132
20:03:55.113434 IP 10.15.0.1 > 10.16.0.2: ESP(spi=0xc07aaa19,seq=0x370), length 132

Adica ajunge pachetul de la vpn-gw-a la vpn-hub, vpn-hub il trimite la vpn-gw-c, vpn-gw-c raspunde la vpn-hub si vpn-hub da mai departe la vpn-gw-a.

Adica merge cum trebuie toata jucaria :)

Ce mai am de studiat, ca inca mi-o iau in freza:

  • sa folosesc un singur ASN. Am incercat tot felul de combinatii sa fac gateway-urile RR Client pentru vpn-hub insa n-a vrut sa schimbe next-hop nici batut. Nici macar pus in mod explicit cu neighbor X:X:X:X next-hop-self. Ca sa nu incalec ce este acum, am dat-o pe ASN-uri de 32biti reservate, ca alea ar ajunge sa conectez tot internetul la un mega VPN :))
  • sa trec prin IPSec doar GRE, dar din pacate ii da cu virgula lui OpenSWAN daca ii zic rightprotoport=47 (cu asta nu vrea nici batut) sau rightprotoport=47/%any (moare cu un mesaj dubios legat de “unable to route”)

Alte chestii mai putin importante:

  • sa vad cum trebuie salvate setarile corect cum vrea CentOS pentru toate optiunile (interfete, GRE, OpenSWAN, Quagga)
  • trecut pe certificate digitale pentru autentificarea gateway-urilor si IKEv2 pentru schimbul de chei cu niste algoritmi de criptare bine definiti
  • experimentat si un pic cu IPSec pentru IPv6, dar la cum arata acum parca vad ca o sa trec IPv6-le peste GRE-ul deja existent si scap usor (sper)
  • sa conving o multime de oameni sa-mi dea bani sa le fiu broker de VPN :))

PS:

  • am uitat o caruta de chestii, ma uitam (si in continuare ma uit) ca vaca la OpenSWAN si nu mai stiam (stiu) de unde sa-l iau
  • ce misto e sa ai mult RAM in laptop, poti sa-ti faci maisini virtuale pana te ia plictisul

Dupa ce-o sa-mi treaca durerea de cap de o am, o sa sap mai cu talent in OpenSWAN sa vad cum il fac sa mearga cat mai sigur si cat mai simplu, eventual automatizat un pic.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.