Ipsec > Mikrotik > AWS EC2 with VPC Subnet

I recent set myself a tasks of connecting my Mikrotik router to my AWS VPC subnet.

This took some additional configuration due to the way that AWS NAT the traffic.

This is described as below.

Your AWS instance has a temporary RFC1918 IP address. The Amazon cloud NATs this to your permanent public IP address, called the “elastic IP”.

If you are want to connect the elastic IP address to a remote VPN, you need to ensure that the encrypted packets created have the elastic IP as the source address. When using IPsec, the kernel needs to create packets with the elastic IP (eg a.b.c.d) as source address for packets to be encrypted, but it can only do this properly if the IP is actually configured on the host. It is recommended to configure the elastic IP as an additional IP on the loopback interface, for example on the amazon stock AMI

We will come back to this later, but as we see we may later have issues with aws NATTing.

Mikrotik Configuration

My setup is as below

192.168.1.0/24>>>>>WAN IP x.x.x.x>>>>>Internet>>>>ELI X.X.X.X>>> 172.31.0.0/16

If you are familiar with IPsec you will know that there are several phases these are.

  1. “Interesting traffic” initiates the IPSec process. Traffic is deemed interesting when the IPSec security policy configured in the IPSec peers starts the IKE process.
  2. IKE phase 1. IKE authenticates IPSec peers and negotiates IKE SAs during this phase, setting up a secure channel for negotiating IPSec SAs in phase 2.
  3. IKE phase 2. IKE negotiates IPSec SA parameters and sets up matching IPSec SAs in the peers.
  4. Data transfer. Data is transferred between IPSec peers based on the IPSec parameters and keys stored in the SA database.
  5. IPSec tunnel termination. IPSec SAs terminate through deletion or by timing out.

Now that we have a base line of what the phases of IPsec are lets take a look at what we will be configuring into our Mikrotik router, this will give us some “context” behind the configuration we will be doing, we will need to create a ipsec peer a proposal and a profile.

*


/ip ipsec policy > print 
 2  A  ;;; awstest
       src-address=YOUR_LOCAL_SUBNET src-port=any dst-address=AWS_VPC_SUBNET
       dst-port=any protocol=all action=encrypt level=require
       ipsec-protocols=esp tunnel=yes sa-src-address=YOUR.WAN.IP
       sa-dst-address=YOUR.ELASTIC.IP proposal=default ph2-count=1
/ip ipsec profile> print
Flags: * - default
 0 * name="default" hash-algorithm=sha1 enc-algorithm=aes-128 dh-group=modp1024
     lifetime=1d proposal-check=obey nat-traversal=yes dpd-interval=5s
     dpd-maximum-failures=3
[dean@MikroTik] /ip ipsec profile>
 /ip ipsec proposal> print
Flags: X - disabled, * - default
 0  * name="default" auth-algorithms=sha1
      enc-algorithms=aes-256-cbc,aes-192-cbc,aes-128-cbc lifetime=30m
      pfs-group=modp1024

Its is recommended that you create a group, this will isolate the different policies and proposals, if you are running multiple tunnels. This will allow you to present the right proposals to your peer.

/ip ipsec peer> print
Flags: X - disabled, D - dynamic, R - responder
0 name="aws" address=x.x.x.x/32 profile=default exchange-mode=ike2
send-initial-contact=yes
 /ip ipsec identity print
Flags: D - dynamic, X - disabled
 0    peer=aws auth-method=pre-shared-key secret="R+'your_super_long_secret"
      generate-policy=port-strict policy-template-group=awsgroup

That was a break down of what we will be configuring on the Mikrotik, additional firewall and NAT rules will also be required, we will go into details about this later.

The AWS Side

Log into the AWS Console and allocate an elastic ip to your chosen virtual machine.

During this step is is important that you allocate the elastic ip to the correct instance you can check this by checking the private IP address for the EC2 machine.

Next go to VPC and take note of your VPC ( this is used for subnet to subnet configuration)

If you wish to use host to host configuration just use the individual ip address of your EC2 machine.

S

Now we have some basic information, about the networks involved in our configuration lets get down to it.

First of all install libreswan

sudo yum install libreswan

Next we want to cd to the directory and create a configuration and secrets file.

cd /etc/ipsec.d
sudo nano awsec2.conf
conn amazonec2
     # preshared key
     authby=secret
     # load connection and initiate it on startup
     auto=start
     # Amazon does not route ESP/AH packets, so these must be encapsulated in UD                                                       P
     encapsulation=yes
     # use %defaultroute to find our local IP, since it is dynamic
     left=%defaultroute
     # set our ID to your (static) elastic IP
     leftid=x.x.x.x
     # remote endpoint IP
     right=x.x.x.x
     # If you want to only connect the amazon VPS using its elastic IP, use:
     #    leftsubnet=<elastic ip>/32
     # If you want to connect a local subnet on the AWS VPC to the remote endpoi                                                       nt, configure it as a normal subnet:
      leftsubnet=172.31.0.0/16
     # And if the remote endpoint is a subnet, you also use a regular subnet con                                                       figuration for the remote subnet:
     rightsubnet=192.168.1.0/24
     # Multiple subnets can be done using:
     #    leftsubnets=10.123.123.0/24,10.100.0.0/16
     #    rightsubnets=192.0.1.0/24,192.0.2.0/24
      ike="aes128-sha1;modp1024"
      phase2alg="aes128-sha1;modp1024"
      type=tunnel
      pfs=yes
      keyexchange=ike
      ikev2=yes
      nat_traversal=yes

I found without the last lines in the configuration file, the connection would not establish and is required for the Mikrotik connection.

ike="aes128-sha1;modp1024"
      phase2alg="aes128-sha1;modp1024"
      type=tunnel
      pfs=yes
      keyexchange=ike
      ikev2=yes
      nat_traversal=yes

As we are authenticating via a “PSK – Pre Sharked Key” we need to create a .secrets file, this key needs to be the same key that has been configured on the router.

First of all lets lets take a quick look at our ipsec.secrets file to ensure that we have a include line for the file we will be creating.

[root@ip-172-31-46-222 ipsec.d]# cat /etc/ipsec.secrets
include /etc/ipsec.d/*.secrets

We have a include line we are ok to create our .secrets file in /etc/ipsec.d open up your text editor of choice and configure the below.

MIKROTIK_WAN_IP 0.0.0.0 : PSK "SUPERLONGSECRET"

We need to configure our ec2 to allow the ipsec ESP protocol, for testing we should also enable ICMP we can then verify we can reach each subnet.

We should now be ready to bring up our tunnel.

ipsec setup start
ipsec auto --add amazonec2
ipsec auto --up amazonec2

The tunnel will come up but will receive errors. We need to so some additional configuration on the EC2 machine and on the router this is due to the below as mentioned at the start.

The elastic IP and the RFC1918 native IP address

Your AWS instance has a temporary RFC1918 IP address. The Amazon cloud NATs this to your permanent public IP address, called the “elastic IP”.

If you are want to connect the elastic IP address to a remote VPN, you need to ensure that the encrypted packets created have the elastic IP as the source address. When using IPsec, the kernel needs to create packets with the elastic IP (eg a.b.c.d) as source address for packets to be encrypted, but it can only do this properly if the IP is actually configured on the host. It is recommended to configure the elastic IP as an additional IP on the loopback interface, for example on the amazon stock AMI create /etc/sysconfig/network-scripts/ifcfg-lo:elastic:

DEVICE=lo:elastic
# use your elastic ip here
IPADDR=a.b.c.d
NETMASK=255.255.255.255
ONBOOT=yes
NAME=elasticIP

You can manually add it without restarting using:

ip addr add a.b.c.d/32 dev lo:elastic


NAT exclusion

If you are using NAT or MASQUERADE to provide connectivity to a subnet behind your AWS machine, you need to exclude NAT for those source/destination combinations that need to be encrypted via IPsec. For example, if you have 10.0.2.0/24 behind your AWS server and 172.16.0.0/16 as subnet behind the remote IPsec gateway, use iptables rules similar to:

Next, you configure a “subnet” containing the elastic IP by setting leftsubnet=elasticip/32 and example is provided

iptables -t nat -I POSTROUTING -s 10.0.2.0/24 -d 172.16.0.0/16 -j RETURN
iptables -t nat -A POSTROUTING -s 10.0.2.0/24 -d 0.0.0.0/0 -j MASQUERADE -o eth0

Next…

So now we have configured a network interface with our elastic ip

Back to the Mikrotik.

At this point after a restart of the ipsec service we would have a tunnel initiated

[dean@MikroTik] /ip ipsec peer> print
Flags: X - disabled, D - dynamic, R - responder
 0     name="aws" address=x.x.x.x/32 profile=default exchange-mode=ike2
       send-initial-contact=yes
[dean@MikroTik] /ip ipsec pe

Ping will fail from from both ends as we need to configure some NAT rules for the internal networks, we should have already done this on the ec2 machine with iptables, make sure all routes are added as PERSISTANT.



 1    ;;; aws VPC subnet
      chain=srcnat action=masquerade src-address=172.31.0.0/16
      dst-address=172.31.0.0/16 log=no log-prefix=""

Filter Rules 
 ;;; AWS SUBNET
      chain=forward action=accept protocol=tcp src-address=172.31.32.0/20 dst-address=192.168.1.0/24 src-port="" dst-port="" log=yes log-prefix=""

 6    ;;; AWS SUBNET;; LOCAL >AWS
      chain=forward action=accept protocol=tcp src-address=192.168.1.0/24 dst-address=172.31.32.0/20 src-port="" dst-port="" log=yes log-prefix=""



TUNNELS SUP ?

If all has gone well our tunnel should now be up, lets have a look with sudo service ipsec status

sudo service ipsec status
Redirecting to /bin/systemctl status ipsec.service
● ipsec.service - Internet Key Exchange (IKE) Protocol Daemon for IPsec
   Loaded: loaded (/usr/lib/systemd/system/ipsec.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2021-02-15 17:56:45 UTC; 12min ago
     Docs: man:ipsec(8)
           man:pluto(8)
           man:ipsec.conf(5)
  Process: 3860 ExecStartPre=/usr/sbin/ipsec --checknflog (code=exited, status=0/SUCCESS)
  Process: 3856 ExecStartPre=/usr/sbin/ipsec --checknss (code=exited, status=0/SUCCESS)
  Process: 3262 ExecStartPre=/usr/libexec/ipsec/_stackmanager start (code=exited, status=0/SUCCESS)
  Process: 3260 ExecStartPre=/usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig (code=exited, status=0/SUCCESS)
 Main PID: 3874 (pluto)
   Status: "Startup completed."
   CGroup: /system.slice/ipsec.service
           └─3874 /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf --nofork

Feb 15 17:56:54 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: packet from X.X.X.X:4500: proposal 1:IKE:ENCR=AES_CBC_128;PRF=HMAC_SHA1;INTEG=HMAC_SHA1_96;DH=MODP1024 chosen from remote proposals 1:IKE:EN...4[first-match]
Feb 15 17:56:54 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #2: STATE_PARENT_R1: received v2I1, sent v2R1 {auth=IKEv2 cipher=aes_128 integ=sha1_96 prf=sha group=MODP1024}
Feb 15 17:56:54 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #2: IKEv2 mode peer ID is ID_IPV4_ADDR: 'X.X.X.X'
Feb 15 17:56:54 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #2: Authenticated using authby=secret
Feb 15 17:56:54 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #2: local ESP/AH proposals for amazonec2 (IKE SA responder matching remote ESP/AH proposals): 1:ESP:ENCR=AES_CBC_128;INTEG=HMAC_SHA1_96...E;ESN=DISABLED
Feb 15 17:56:54 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #2: proposal 1:ESP:SPI=04569cdf;ENCR=AES_CBC_128;INTEG=HMAC_SHA1_96;ESN=DISABLED chosen from remote proposals 1:ESP:ENCR=AES_CBC_256;EN...D[first-match]
Feb 15 17:56:54 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #3: negotiated connection [172.31.0.0-172.31.255.255:0-65535 0] -> [192.168.1.0-192.168.1.255:0-65535 0]
Feb 15 17:56:54 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #3: STATE_V2_IPSEC_R: IPsec SA established tunnel mode {ESP/NAT=>0x04569cdf <0x3702a09f xfrm=AES_CBC_128-HMAC_SHA1_96 NATOA=none NATD=9...0 DPD=passive}
Feb 15 17:57:01 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #1: suppressing retransmit because superseded by #3 try=1. Drop this negotitation
Feb 15 17:57:01 ip-172-31-46-222.eu-west-1.compute.internal pluto[3874]: "amazonec2" #1: deleting state (STATE_PARENT_I1) and NOT sending notification
Hint: Some lines were ellipsized, use -l to show in full.

FURTHER ISSUES I HAD

I thought all was well i could ping from both sides of my tunnel, when i tried to ssh to a host from either end the connection would time out. Odd ey………

MSS CLAMPING..

The maximum transmission unit (MTU) of a network connection is the size, in bytes, of the largest permissible packet that can be passed over the connection. The larger the MTU of a connection, the more data that can be passed in a single packet. Ethernet packets consist of the frame, or the actual data you are sending, and the network overhead information that surrounds it.

I will be honest, this was the first time i have ever had issues, so some research was required.

To overcome this issue, I ran some ping tests from the ec2 machine with different MTU sizes to see what was being dropped by the router.

x.x.x.x -f -l 1492

I then created a “MSS Clamping rule as below”

    chain=forward action=change-mss new-mss=1350 passthrough=yes tcp-flags=syn protocol=tcp src-address=172.31.0.0/16 dst-address=192.168.1.0/24
      tcp-mss=!0-1350 log=no log-prefix=""

 4    chain=forward action=change-mss new-mss=1350 passthrough=yes tcp-flags=syn protocol=tcp src-address=192.168.1.0/24 dst-address=172.31.0.0/16
      tcp-mss=!0-1350 log=no log-prefix="

ITS SALL GOOD.

WHAT IS NEXT ?

I PLAN ON USING RSA CERTIFICATES FOR AUTHENTICATION.

conn AWS
left=172.31.46.222
leftsubnets=172.31.46.222/32
leftid=@haws
leftsourceip=54.194.90.20
right
rightsubnets=192.168.1.0/24
rightid=@home
pfs=no
forceencaps=yes
authby=secret
auto=start
esp=aes256-sha1
type=tunnel
ike=aes256-sha1-modp1024
esp=aes256-sha1
ikelifetime=12h
lifetime=4h

About the Author

Leave a Reply

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