IPSec with IPv6-in-IPv4 GRE tunnel

IPSec with IPv6-in-IPv4 GRE tunnel

Theory:

RFC 4891 discusses about IPSec with IPv6-in-IPv4 tunnels. It points out two different types of threats with IPv6-in-IPv4 tunnels which mandates the use of IPSec. The two types of threats are-

1) The IPv4 source address of the encapsulating (outer) packet can be spoofed

2) The IPv6 source address of the encapsulated (inner) packet can be spoofed.

RFC 4891 discusses two ways to use IPSec- in transport and tunnel modes.

IPSec in Transport mode:

In transport mode, the IPSec ESP or AH SA are established to protect traffic with the header {IPv4 Source address, IPv4 Destination address, Protocol = 41}. On receiving an IPSec packet, the receiver applies the IPSec transform (e.g. ESP or AH) and matches the packet against Security Parameter Index (SPI) and the inbound selectors associated with the SA to verify that the packet is appropriate for the SA via which it was received. The successful verification ensures that the packet came from correct IPv4 endpoint.

The transport mode takes care of threat # 1. But IPSec in Transport mode does not verify the payload of the IPSec packet which carries IPv6 addresses. Hence, the inner payload can be spoofed. The packet will be decapsulated and accepted. This shortcoming can be mitigated by Ingress filtering which is a check to ensure packet is received on the correct interface like RPF in IP multicasting.

IPSec in Tunnel mode:

In Tunnel mode, the IPSec SA is established to protect the traffic defined by {IPv6 Source address, IPv6 Destination address}. On receiving such an IPSec packet, the receiver first applies the IPSec transform and matches the packet against SPI and inbound selectors associated with the SA. The successful verification ensures that the packet came from correct endpoint.

In tunnel mode, the outer IPv4 addresses can be spoofed and IPSec cannot detect this in tunnel mode.

Network topology:

An IPv6-in-IPv4 GRE tunnel needs to be setup between R1 & R2 router connecting the two IPv6 domains separated by an IPv4 network.

Initial configuration on R1

ipv6 unicast-routing
!
interface Loopback 0
 ip address 1.1.1.1 255.255.255.255
!
interface serial 0/0
 description IPv4 WAN Interface
 ip address 10.1.1.1 255.255.255.252
!
interface fastethernet 0/0
 description Internal IPv6 network
 ipv6 address CAFE:1::1/64
!
router ospf 1
 network 1.1.1.1 0.0.0.0 area 0
 network 10.1.1.0 0.0.0.3 area 0
!

Initial configuration on R2

ipv6 unicast-routing
!
interface Loopback 0
 ip address 2.2.2.2 255.255.255.255
!
interface serial 0/0
 description IPv4 WAN Interface
 ip address 10.2.2.2 255.255.255.252
!
interface fastethernet 0/0
 description Internal IPv6 network
 ipv6 address CAFE:2::1/64
!
router ospf 1
 network 2.2.2.2 0.0.0.0 area 0
 network 10.2.2.0 0.0.0.3 area 0
!

GRE Tunnel configuration:

A GRE tunnel is setup between R1 and R2. The tunnel interfaces will have IPv6 addresses and they belong to the same network. IPv6 traffic for remote sites is manually forwarded over GRE tunnel using an IPv6 static route.

Tunnel configuration on R1

interface Tunnel 0
 tunnel mode gre ip
 ipv6 address 2001::1/64
 tunnel source Loopback 0
 tunnel destination 2.2.2.2
!
ipv6 route CAFE:2::/64 2001::2
!

Tunnel configuration on R2

interface Tunnel 0
 tunnel mode gre ip
 ipv6 address 2001::2/64
 tunnel source Loopback 0
 tunnel destination 1.1.1.1
!
ipv6 route CAFE:1::/64 2001::1
!

When traffic is generated from R1 router's IPv6 domain towards R2 router's IPv6 network, ICMPv6 packets are encapsulated in a GRE packet (protocol= 0x2F or decimal value 47) with packet's source IP address as R1's Loopback 0 interface and destination IP address as R2's Loopback 0 interface. At R2 router, these GRE packets are decapsulated and forwarded to the correct destination.

GRE Ping results

R1# ping  CAFE:2::1 source fa 0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to CAFE:2::1, timeout is 2 seconds:
Packet sent with a source address of CAFE:1::1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 44/64/96 ms
R1# debug ip packet detail
IP: s=1.1.1.1 (Tunnel0), d=2.2.2.2 (Serial0/0), len 124, sending, proto=47
IP: s=1.1.1.1 (Tunnel0), d=2.2.2.2 (Serial0/0), len 124, sending, proto=47
IP: s=1.1.1.1 (Tunnel0), d=2.2.2.2 (Serial0/0), len 124, sending, proto=47
IP: s=1.1.1.1 (Tunnel0), d=2.2.2.2 (Serial0/0), len 124, sending, proto=47
IP: s=1.1.1.1 (Tunnel0), d=2.2.2.2 (Serial0/0), len 124, sending, proto=47

IPSec over IPv6-in-IPv4 GRE tunnel:

Over this GRE tunnel, IPSec is configured using static crypto-map to encrypt the traffic on the GRE tunnel. This essentially adds extra overhead since the GRE packet is encapsulated by ESP (protocol value 50). All the traffic that travels over the GRE tunnel get encrypted hence no access-list is configured to match interesting traffic. Also, the peer address is set to the Loopback 0 interfaces of the routers since they are used as the source IP addresses for the GRE tunnel.

IPSec configuration on R1

crypto isakmp policy 10
 encryption des
 authentication pre-share
 hash md5
 group 2
!
crypto isakmp key 0 MY_K3Y address 2.2.2.2
!
crypto ipsec transform-set TS esp-des esp-md5-hmac
!
crypto ipsec profile PROFILE
 set transform-set TS
!
interface tunnel 0
 tunnel protection ipsec profile PROFILE
!

IPSec configuration on R2

crypto isakmp policy 10
 encryption des
 authentication pre-share
 hash md5
 group 2
!
crypto isakmp key 0 MY_K3Y address 1.1.1.1
!
crypto ipsec transform-set TS esp-des esp-md5-hmac
!
crypto ipsec profile PROFILE
 set transform-set TS
!
interface tunnel 0
 tunnel protection ipsec profile PROFILE
!

When traffic is generated from R1 router's IPv6 domain towards R2 router's IPv6 network, ICMPv6 packets are encapsulated in GRE packets, which are then encapsulated in an ESP packet. R1 router also initiates an IKE negotiation with R2 router, meanwhile all packets are dropped.

The debugging on R2 router shows how it negotiates SA with R1 router. It shows that when R2 router receives a packet from 1.1.1.1 peer, it checks to see if it has a pre-shared key. It initiates IKE Phase 1 during which it checks whether the policy sent by R1 matches any of its policy and if it agrees to the policy. After successful IKE Phase 1, it initiates IKE Phase 2 during which it checks IPSec transform-set. After successful transform-set negotiation IKE Phase 2 is completed after which communication is possible.

"debug crypto isakmp" on R2

ISAKMP (0:0): received packet from 1.1.1.1 dport 500 sport 500 Global (N) NEW SA
ISAKMP: Created a peer struct for 1.1.1.1, peer port 500
ISAKMP: New peer created peer = 0x64BB250C peer_handle = 0x80000004
ISAKMP: Locking peer struct 0x64BB250C, IKE refcount 1 for crypto_isakmp_process_block
ISAKMP: local port 500, remote port 500 insert sa successfully sa = 64BB6094
ISAKMP:(0:0:N/A:0):Input = IKE_MESG_FROM_PEER, IKE_MM_EXCH
ISAKMP:(0:0:N/A:0):Old State = IKE_READY  New State = IKE_R_MM1
ISAKMP:(0:0:N/A:0): processing SA payload. message ID = 0
ISAKMP:(0:0:N/A:0): processing vendor id payload
ISAKMP:(0:0:N/A:0): vendor ID seems Unity/DPD but major 245 mismatch
ISAKMP (0:0): vendor ID is NAT-T v7
ISAKMP:(0:0:N/A:0): processing vendor id payload
ISAKMP:(0:0:N/A:0): vendor ID seems Unity/DPD but major 157 mismatch
ISAKMP:(0:0:N/A:0): vendor ID is NAT-T v3
ISAKMP:(0:0:N/A:0): processing vendor id payload
ISAKMP:(0:0:N/A:0): vendor ID seems Unity/DPD but major 123 mismatch
ISAKMP:(0:0:N/A:0): vendor ID is NAT-T v2
ISAKMP:(0:0:N/A:0):found peer pre-shared key matching 1.1.1.1
ISAKMP:(0:0:N/A:0): local preshared key found
ISAKMP : Scanning profiles for xauth ...
ISAKMP:(0:0:N/A:0):Checking ISAKMP transform 1 against priority 10 policy
ISAKMP:      encryption DES-CBC
ISAKMP:      hash MD5
ISAKMP:      default group 2
ISAKMP:      auth pre-share
ISAKMP:      life type in seconds
ISAKMP:      life duration (VPI) of  0x0 0x1 0x51 0x80
ISAKMP:(0:0:N/A:0):atts are acceptable. Next payload is 0
ISAKMP:(0:1:SW:1): processing vendor id payload
ISAKMP:(0:1:SW:1): vendor ID seems Unity/DPD but major 245 mismatch
ISAKMP (0:134217729): vendor ID is NAT-T v7
ISAKMP:(0:1:SW:1): processing vendor id payload
ISAKMP:(0:1:SW:1): vendor ID seems Unity/DPD but major 157 mismatch
ISAKMP:(0:1:SW:1): vendor ID is NAT-T v3
ISAKMP:(0:1:SW:1): processing vendor id payload
ISAKMP:(0:1:SW:1): vendor ID seems Unity/DPD but major 123 mismatch
ISAKMP:(0:1:SW:1): vendor ID is NAT-T v2
ISAKMP:(0:1:SW:1):Input = IKE_MESG_INTERNAL, IKE_PROCESS_MAIN_MODE
ISAKMP:(0:1:SW:1):Old State = IKE_R_MM1  New State = IKE_R_MM1
ISAKMP:(0:1:SW:1): constructed NAT-T vendor-07 ID
ISAKMP:(0:1:SW:1): sending packet to 1.1.1.1 my_port 500 peer_port 500 (R) MM_SA_SETUP
ISAKMP:(0:1:SW:1):Input = IKE_MESG_INTERNAL, IKE_PROCESS_COMPLETE
ISAKMP:(0:1:SW:1):Old State = IKE_R_MM1  New State = IKE_R_MM2
ISAKMP (0:134217729): received packet from 1.1.1.1 dport 500 sport 500 Global (R) MM_SA_SETUP
ISAKMP:(0:1:SW:1):Input = IKE_MESG_FROM_PEER, IKE_MM_EXCH
ISAKMP:(0:1:SW:1):Old State = IKE_R_MM2  New State = IKE_R_MM3
ISAKMP:(0:1:SW:1): processing KE payload. message ID = 0
ISAKMP:(0:1:SW:1): processing NONCE payload. message ID =0
ISAKMP:(0:1:SW:1):found peer pre-shared key matching 1.1.1.1
ISAKMP:(0:1:SW:1):SKEYID state generated
ISAKMP:(0:1:SW:1): processing vendor id payload
ISAKMP:(0:1:SW:1): vendor ID is Unity
ISAKMP:(0:1:SW:1): processing vendor id payload
ISAKMP:(0:1:SW:1): vendor ID is DPD
ISAKMP:(0:1:SW:1): processing vendor id payload
ISAKMP:(0:1:SW:1): speaking to another IOS box!
ISAKMP:(0:1:SW:1):Input = IKE_MESG_INTERNAL, IKE_PROCESS_MAIN_MODE
ISAKMP:(0:1:SW:1):Old State = IKE_R_MM3  New State = IKE_R_MM3
ISAKMP:(0:1:SW:1): sending packet to 1.1.1.1 my_port 500 peer_port 500 (R) MM_KEY_EXCH
ISAKMP:(0:1:SW:1):Input = IKE_MESG_INTERNAL, IKE_PROCESS_COMPLETE
ISAKMP:(0:1:SW:1):Old State = IKE_R_MM3  New State = IKE_R_MM4
ISAKMP (0:134217729): received packet from 1.1.1.1 dport 500 sport 500 Global (R) MM_KEY_EXCH
ISAKMP:(0:1:SW:1):Input = IKE_MESG_FROM_PEER, IKE_MM_EXCH
ISAKMP:(0:1:SW:1):Old State = IKE_R_MM4  New State = IKE_R_MM5
ISAKMP:(0:1:SW:1): processing ID payload. message ID = 0
ISAKMP (0:134217729): ID payload
        next-payload : 8
        type         : 1
        address      : 1.1.1.1
        protocol     : 17
        port         : 500
        length       : 12
ISAKMP:(0:1:SW:1):: peer matches *none* of the profiles
ISAKMP:(0:1:SW:1): processing HASH payload. message ID = 0
ISAKMP:(0:1:SW:1): processing NOTIFY INITIAL_CONTACT protocol 1
        spi 0, message ID = 0, sa = 64BB6094
ISAKMP:(0:1:SW:1):SA authentication status:authenticated
ISAKMP:(0:1:SW:1): Process initial contact,bring down existing phase 1 and 2 SA's with local 2.2.2.2 remote 1.1.1.1 remote port 500
ISAKMP:(0:1:SW:1):SA authentication status: authenticated
ISAKMP:(0:1:SW:1):SA has been authenticated with 1.1.1.1
ISAKMP: Trying to insert a peer 2.2.2.2/1.1.1.1/500/,  and inserted successfully 64BB250C.
ISAKMP:(0:1:SW:1):Input = IKE_MESG_INTERNAL, IKE_PROCESS_MAIN_MODE
ISAKMP:(0:1:SW:1):Old State = IKE_R_MM5  New State = IKE_R_MM5
ISAKMP:(0:1:SW:1):SA is doing pre-shared key authentication using id type ID_IPV4_ADDR
ISAKMP (0:134217729): ID payload
        next-payload : 8
        type         : 1
        address      : 2.2.2.2
        protocol     : 17
        port         : 500
        length       : 12
ISAKMP:(0:1:SW:1):Total payload length: 12
ISAKMP:(0:1:SW:1): sending packet to 1.1.1.1 my_port 500 peer_port 500 (R) MM_KEY_EXCH
ISAKMP:(0:1:SW:1):Input = IKE_MESG_INTERNAL, IKE_PROCESS_COMPLETE
ISAKMP:(0:1:SW:1):Old State = IKE_R_MM5  New State = IKE_P1_COMPLETE
ISAKMP:(0:1:SW:1):Input = IKE_MESG_INTERNAL, IKE_PHASE1_COMPLETE
ISAKMP:(0:1:SW:1):Old State = IKE_P1_COMPLETE  New State = IKE_P1_COMPLETE
ISAKMP (0:134217729): received packet from 1.1.1.1 dport 500 sport 500 Global (R) QM_IDLE
ISAKMP: set new node 1046004050 to QM_IDLE
ISAKMP:(0:1:SW:1): processing HASH payload. message ID = 1046004050
ISAKMP:(0:1:SW:1): processing SA payload. message ID = 1046004050
ISAKMP:(0:1:SW:1):Checking IPSec proposal 1
ISAKMP: transform 1, ESP_DES
ISAKMP:   attributes in transform:
ISAKMP:      encaps is 1 (Tunnel)
ISAKMP:      SA life type in seconds
ISAKMP:      SA life duration (basic) of 3600
ISAKMP:      SA life type in kilobytes
ISAKMP:      SA life duration (VPI) of  0x0 0x46 0x50 0x0
ISAKMP:      authenticator is HMAC-MD5
ISAKMP:(0:1:SW:1):atts are acceptable.
ISAKMP:(0:1:SW:1): processing NONCE payload. message ID =1046004050
ISAKMP:(0:1:SW:1): processing ID payload. message ID = 1046004050
ISAKMP:(0:1:SW:1): processing ID payload. message ID = 1046004050
ISAKMP:(0:1:SW:1): asking for 1 spis from ipsec
ISAKMP:(0:1:SW:1):Node 1046004050, Input = IKE_MESG_FROM_PEER, IKE_QM_EXCH
ISAKMP:(0:1:SW:1):Old State = IKE_QM_READY  New State = IKE_QM_SPI_STARVE
ISAKMP: received ke message (2/1)
ISAKMP: Locking peer struct 0x64BB250C, IPSEC refcount 1 for for stuff_ke
ISAKMP:(0:1:SW:1): Creating IPSec SAs
        inbound SA from 1.1.1.1 to 2.2.2.2 (f/i)  0/ 0
        (proxy 1.1.1.1 to 2.2.2.2)
        has spi 0x4F11F20E and conn_id 0 and flags 2
        lifetime of 3600 seconds
        lifetime of 4608000 kilobytes
        has client flags 0x0
        outbound SA from 2.2.2.2 to 1.1.1.1 (f/i) 0/0
        (proxy 2.2.2.2 to 1.1.1.1)
        lifetime of 3600 seconds
        lifetime of 4608000 kilobytes
        has client flags 0x0
ISAKMP:(0:1:SW:1): sending packet to 1.1.1.1 my_port 500 peer_port 500 (R) QM_IDLE
ISAKMP:(0:1:SW:1):Node 1046004050, Input = IKE_MESG_FROM_IPSEC, IKE_SPI_REPLY
ISAKMP:(0:1:SW:1):Old State = IKE_QM_SPI_STARVE  New State = IKE_QM_R_QM2
ISAKMP: Locking peer struct 0x64BB250C, IPSEC refcount 2 for from create_transforms
ISAKMP: Unlocking IPSEC struct 0x64BB250C from create_transforms, count 1
ISAKMP (0:134217729): received packet from 1.1.1.1 dport 500 sport 500 Global (R) QM_IDLE
ISAKMP:(0:1:SW:1):deleting node 1046004050 error FALSE reason "QM done (await)"
ISAKMP:(0:1:SW:1):Node 1046004050, Input = IKE_MESG_FROM_PEER, IKE_QM_EXCH
ISAKMP:(0:1:SW:1):Old State = IKE_QM_R_QM2  New State = IKE_QM_PHASE2_COMPLETE

The show crypto isakmp peer [detail] command shows peer description.

show crypto isakmp peers

R1# show crypto isakmp peers
Peer: 2.2.2.2 Port: 500 Local: 1.1.1.1
 Phase1 id: 2.2.2.2

The show crypto session detail command provides details on currently active crypto sessions.

show crypto session detail

R1# show crypto session detail
Crypto session current status
Code: C - IKE Configuration mode, D - Dead Peer Detection
K - Keepalives, N - NAT-traversal, X - IKE Extended Authentication
Interface: Tunnel0
Session status: UP-ACTIVE
Peer: 2.2.2.2 port 500 fvrf: (none) ivrf: (none)
      Phase1_id: 2.2.2.2
      Desc: (none)
  IKE SA: local 1.1.1.1/500 remote 2.2.2.2/500 Active
          Capabilities:(none) connid:1 lifetime:23:59:34
  IPSEC FLOW: permit 47 host 1.1.1.1 host 2.2.2.2
        Active SAs: 2, origin: crypto map
        Inbound:  #pkts dec'ed 9 drop 0 life (KB/Sec) 4586052/3575
        Outbound: #pkts enc'ed 9 drop 11 life (KB/Sec) 4586052/3575

The show crypto isakmp sa and show crypto ipsec sa commands show IKE Phase 1 and Phase 2 SA respectively.

IKE Phase 1 & 2 SA

R1# show crypto isakmp sa
dst             src             state          conn-id slot status
2.2.2.2         1.1.1.1         QM_IDLE              1    0 ACTIVE
R1# show crypto ipsec sa
interface: Tunnel0
    Crypto map tag: Tunnel0-head-0, local addr 1.1.1.1
   protected vrf: (none)
   local  ident (addr/mask/prot/port): (1.1.1.1/255.255.255.255/47/0)
   remote ident (addr/mask/prot/port): (2.2.2.2/255.255.255.255/47/0)
   current_peer 2.2.2.2 port 500
     PERMIT, flags={origin_is_acl,}
    #pkts encaps: 9, #pkts encrypt: 9, #pkts digest: 9
    #pkts decaps: 9, #pkts decrypt: 9, #pkts verify: 9
    #pkts compressed: 0, #pkts decompressed: 0
    #pkts not compressed: 0, #pkts compr. failed: 0
    #pkts not decompressed: 0, #pkts decompress failed: 0
    #send errors 11, #recv errors 0
     local crypto endpt.: 1.1.1.1, remote crypto endpt.: 2.2.2.2
     path mtu 1514, ip mtu 1514, ip mtu idb Loopback0
     current outbound spi: 0x4F11F20E(1326576142)
     inbound esp sas:
      spi: 0x3861DD57(945937751)
        transform: esp-des esp-md5-hmac ,
        in use settings ={Tunnel, }
        conn id: 2001, flow_id: SW:1, crypto map: Tunnel0-head-0
        sa timing: remaining key lifetime (k/sec): (4586052/3201)
        IV size: 8 bytes
        replay detection support: Y
        Status: ACTIVE
     inbound ah sas:
     inbound pcp sas:
     outbound esp sas:
      spi: 0x4F11F20E(1326576142)
        transform: esp-des esp-md5-hmac ,
        in use settings ={Tunnel, }
        conn id: 2002, flow_id: SW:2, crypto map: Tunnel0-head-0
        sa timing: remaining key lifetime (k/sec): (4586052/3200)
        IV size: 8 bytes
        replay detection support: Y
        Status: ACTIVE
     outbound ah sas:
     outbound pcp sas:

The following output shows R1 sending ESP encapsulated packets (protocol 50).

debug ip packet detail

IP: tableid=0, s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), routed via FIB
IP: s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), g=10.1.1.2,len 176, forward, proto=50
IP: tableid=0, s=2.2.2.2 (Serial0/0), d=1.1.1.1 (Loopback0), routed via RIB
IP: s=2.2.2.2 (Serial0/0), d=1.1.1.1, len 124, rcvd 4, proto=47
IP: tableid=0, s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), routed via FIB
IP: s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), g=10.1.1.2,len 176, forward, proto=50
IP: tableid=0, s=2.2.2.2 (Serial0/0), d=1.1.1.1 (Loopback0), routed via RIB
IP: s=2.2.2.2 (Serial0/0), d=1.1.1.1, len 124, rcvd 4, proto=47
IP: tableid=0, s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), routed via FIB
IP: s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), g=10.1.1.2,len 176, forward, proto=50
IP: tableid=0, s=2.2.2.2 (Serial0/0), d=1.1.1.1 (Loopback0), routed via RIB
IP: s=2.2.2.2 (Serial0/0), d=1.1.1.1, len 124, rcvd 4, proto=47
IP: tableid=0, s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), routed via FIB
IP: s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), g=10.1.1.2,len 176, forward, proto=50
IP: tableid=0, s=2.2.2.2 (Serial0/0), d=1.1.1.1 (Loopback0), routed via RIB
IP: s=2.2.2.2 (Serial0/0), d=1.1.1.1, len 124, rcvd 4, proto=47
IP: tableid=0, s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), routed via FIB
IP: s=1.1.1.1 (local), d=2.2.2.2 (Serial0/0), g=10.1.1.2,len 176, forward, proto=50
IP: tableid=0, s=2.2.2.2 (Serial0/0), d=1.1.1.1 (Loopback0), routed via RIB
IP: s=2.2.2.2 (Serial0/0), d=1.1.1.1, len 124, rcvd 4, proto=47