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.
- “Interesting traffic” initiates the IPSec process. Traffic is deemed interesting when the IPSec security policy configured in the IPSec peers starts the IKE process.
- 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.
- IKE phase 2. IKE negotiates IPSec SA parameters and sets up matching IPSec SAs in the peers.
- Data transfer. Data is transferred between IPSec peers based on the IPSec parameters and keys stored in the SA database.
- 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.
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