GRE/IPSec - am I getting this wrong?

Hi,

I am using GRE over IPSec for site to site connectivity. I require the GRE part as it provides me with an interface (pure policy based IPSec does not fit well into my environment). The additional overhead of GRE is not an issue. I use a Mikrotik CCR (6.42.12) on the one side and a VyOS (Vyatta) virtual router on the other side. Connectivity is up and BGP neighbors connected via the tunnel but I am seeing strange sporadic issue with ph2 not re-establishing after network interruptions. I a now thinking that I am fundamentally misunderstanding how GRE/IPSec should be configured.

I have basically configured the IPSec peer and policy beteeen the two routers in tunnel mode. The policy is configured with the private IP addresses of the GRE interfaces on both sides

Currect config:

/ip ipsec proposal
add enc-algorithms=aes-128-cbc lifetime=1h name=ipsec
/ip ipsec peer
add address=1.1.1.1/32 comment="vr1 via ISP-1" dh-group=modp1024 \
    dpd-interval=10s dpd-maximum-failures=3 enc-algorithm=aes-128 lifetime=8h \
    local-address=2.2.2.2 nat-traversal=no key-here

/ip ipsec policy
add comment="vr1 via ISP-1" dst-address=169.254.200.2/32 proposal=\
    ipsec sa-dst-address=1.1.1.1 sa-src-address=2.2.2.2 \
    src-address=169.254.200.1/32 tunnel=yes

/ip address
add address=169.254.200.1 interface=gre-vr1-via-ISP-1 network=\
    169.254.200.1
	
/interface gre
add allow-fast-path=no keepalive=5s,3 local-address=169.254.200.1 name=\
    gre-vr1-via-ISP-1 remote-address=169.254.200.2

This functionally works correctly but I understand that perhaps the correct way to configure it should be to:

  • Configure the GRE between the router’s public addresses


  • Configure the IPSec peer as usual


  • Configure the IPSec policy in transport mode and use the same src and dst addresses as the sa src and sa dst (router public IPs)


  • Configure a /30 private “link” network bewteen the 2 GRE interfaces

Is the latter accurate and if so, is that the preferred method to configure GRE/IPSec?

Thank you

FWIW I’ve been using exactly this kind of link between my home mikrotik ac2 and a linux server (first libreSwan now strongSwan).

Very reliable.

The setup is as described:

  • GRE interfaces on both sides use public IP addresses with private addresses inside the GRE
  • The IPSec policy on the Mikrotik also uses these public addresses, not the addresses inside the GRE, this is for both peer and sa
  • IPSec runs in transport mode
  • IPSec policy on the mikrotik and strongSwan config are both for GRE (not TCP or UDP…)
  • All routing configuration (to make use of the link) on the mikrotik side uses the GRE tunnel interface

This way the GRE itself is encrypted, it’s “GRE inside IPSec” not “IPSec inside GRE”.

Thanks once more for your reply. Yes, I think my implementation is incorrect even though it functions. Fixing the config will be a step in the right direction.

Just for laughs this is my configuration.

1 - Mikrotik (client) side

/ip ipsec peer
add address=139.0.0.1/32 exchange-mode=ike2 local-address=178.0.0.1 name=my_vpn
/ip ipsec profile
set [ find default=yes ] dh-group=ecp256 enc-algorithm=aes-128 hash-algorithm=sha256 nat-traversal=no
/ip ipsec proposal
set [ find default=yes ] auth-algorithms=sha256 enc-algorithms=aes-128-ctr pfs-group=ecp256
/ip ipsec identity
add auth-method=digital-signature certificate=ec_tunnel_client_ac2.crt_0 peer=my_vpn remote-certificate=\
    ec_tunnel_server.crt_0
/ip ipsec policy
add comment="my gre tunnel" dst-address=139.0.0.1/32 protocol=gre src-address=178.0.0.1/32

2 - strongSwan (server) side

connections {

	my_ec_tunnel {
		version = 2
		local_addrs  = 139.0.0.1
		proposals = aes128-sha256-ecp256

		local {
			auth = pubkey
			certs = ec_tunnel_server.crt
		}
		remote {
			auth = pubkey
			cacerts = ec_tunnel_CA.crt
		}

		children {
			my_mikrotik_vpn {
				local_ts  = dynamic[gre]
				remote_ts = dynamic[gre]

				mode = transport
				esp_proposals = aes128ctr-sha256-ecp256
			}
	}
}

Thanks for sharing this. The only additional thing that I am considering implementing is additional firewall rules to explicitly drop protocol 47 between the two public IPs of the routers so that in the scenario where case the IPSec ph2 fails, that the GRE traffic does not start flowing between the two routers encrypted. The one advantage of my original (incorrect) implementation is that the GRE is completely dependent on ph2 so that will never establish encrypted. But there are obviously other ways to address that.

Thanks again for you interest and assistance.

Yes makes sense. I’m not doing this right now (not that it’s necessary, due to what I use the VPN for…) but it got me thinking.

I’ve seen this done with scripts, but that seems a little unreliable and maybe hard on the Mikrotik (not sure if there are script hooks for IPSec up / down).

So I thought - what if I could prevent unencrypted (specifically) GRE from leaving the router?

Here is what I came up:

/ip firewall filter
add action=drop chain=output comment="prevent unencrypted gre" ipsec-policy=out,none out-interface-list=WAN \
    protocol=gre

I tested by turning the IPSec policy off and by messing up my “proposal” so the connection failed - in both cases my GRE tunnel traffic stopped flowing. Turned IPSec back on - GRE started to go through again.

Incidentally, someone just posted a near identical solution here:

http://forum.mikrotik.com/t/ensure-gre-is-going-trough-ipsec-with-firewall/129173/1

Thanks for the idea, wasn’t necessary but was fun!