Cloud Hosted Router: L2TP/IPsec server behind 1:1 NAT on Amazon EC2

I’m trying to set a L2TP/IPsec server on CHR running on Amazon EC2.

I’ve already made PPTP and pure L2TP connections work, but I’m currently facing a problem with L2TP/IPsec which I believe is caused by the fact EC2 virtual machines run behind one-to-one NAT (the machine is provided with a private address, but is fully reachable using a public one).

I have UDP 500, 1701, 4500 and ESP/AH accept rules both in CHR and EC2 security groups and, as far as I can see, both machines create SAs and policies, but won’t establish connection.

CHR (private IP - 172.31.A.B, public IP - 52.C.D.E) has the following in logs:
__

  • IPsec-SA established: ESP/Transport 89.X.Y.Z[4500]->172.31.A.B[4500] spi=185292923(0xb0b587b)
  • IPsec-SA established: ESP/Transport 172.31.A.B[4500]->89.X.Y.Z[4500] spi=96929448(0x5c706a8)
  • first L2TP UDP packet received from 89.X.Y.Z

A client (also MikroTik, public IP - 89.X.Y.Z) has the following in logs:
__

  • IPsec-SA established: ESP/Transport 52.C.D.E[4500]->89.X.Y.Z[4500] spi=96929448(0x5c706a8)
  • IPsec-SA established: ESP/Transport 89.X.Y.Z[4500]->52.C.D.E[4500] spi=185292923(0xb0b587b)
  • l2tp-out1: initializing…
  • l2tp-out1: connecting…
  • phase1 negotiation failed due to time up 89.X.Y.Z[500]<=>52.C.D.E[500] b076b99198a6e7fa:0000000000000000
  • l2tp-out1: terminating… - session closed
  • 2tp-out1: disconnected

Both CHR and the client have identical IPsec settings. The client perfectly works as a L2TP/IPsec server. EoIPv6 with IPsec works, but GRE with IPsec won’t work which supports my hypothesis about 1:1 NAT being the root of the problem.

Is there any chance to make L2TP/IPsec server work on CHR running on Amazon EC2?

Update:
Taking this post http://forum.mikrotik.com/t/l2tp-ipsec-policy-autogeneration-when-both-roadwarrior-client-and-routeros-device-behind-nat-issue/88687/1 into account (thanks, atlanticd), I can make L2TP/IPsec server on my CHR work if I add the following policy:

	src-address=172.31.A.B/32 src-port=any dst-address=89.X.Y.Z/32 
       dst-port=any protocol=udp action=encrypt level=require 
       ipsec-protocols=esp tunnel=no sa-src-address=172.31.A.B 
       sa-dst-address=89.X.Y.Z proposal=default priority=0

So now the problem turns into - how to make CHR create such a policy dynamically for each client?

I tried to add a template policy with the private address (172.31.A.B) in src-address and 0.0.0.0/0 in dst-address, but it doesn’t allow me to enter 172.31.A.B in sa-src-address.

Anyone?

http://blog.pessoft.com/2016/05/29/mikrotik-ipsec-tunnel-with-ddns-and-nat/


/system script add name="ipsec-policy-update-kv74" policy=read,write source=":local peerid    \"kv74\"\
    \n:local peerhost  \"40d0025d4ad1.sn.mynetname.net\"\
    \n:local peerip    [:resolve \$peerhost]\
    \n:local policyuid\
    \n:set policyuid   [/ip ipsec policy find comment=\"\$peerid\" and sa-dst-address!=\"\$peerip\"]\
    \n:if (\$policyuid != \"\") do={\
    \n  /ip ipsec policy set \$policyuid sa-dst-address=\"\$peerip\" dst-address=\"\$peerip/32\"\
    \n  :log info \"Script ipsec-policy-update updated policy '\$peerid' with address '\$peerip'\"\
    \n}"
/ip ipsec policy add comment=kv74 dst-address=37.113.149.58/32 protocol=udp sa-dst-address=37.113.149.58 sa-src-address=172.31.60.80 src-address=172.31.60.80/32
/system scheduler add interval=1m name=ipsec-policy-update-kv74 on-event="/system script run ipsec-policy-update-kv74" policy=read,write