How to make connection of Strongswan with Azure?


In this post, I will write the way how to create the connection using Strongswan for IPsec connection for Azure VPN connection. In AWS, it is not difficult, because AWS offer the configuration for Strongswan and Openswan. However, Azure does not offer it. Because of I can not know the Peer VPN status. it is not simple. 


1. About test environment.


My test environment is like below.


On-prem Host and VPN server <------> Internet <------> Azure VPN <------> Azure vNet <------> Azure Host


A) On-prem Host and VPN server - 10.0.0.0/8 

B) Azure Host - 172.21.0.0/16


2. Create local network gateway


Local network gateway means the on-premise site. Therefore, I need to insert on-premise network information into these fields.




A) IP address : On-premise VPN Device Public IP address.

B) Address space : On-premise Network range which is used.  


In my case, Address space should be "10.0.0.0/8". After generation, I can modify in the configuration of the resource. If I need to add more network range. I have add in here.




3. Create virtual network gateway


Virtual network gateway means the endpoint of Azure site. I insert the Azure vNet information into here. Before, I create the virtual network gateway. I need to create the "gateway subnet" where VPN instance is located in. In subnet of vNet, I can see the button "Gateway subnet".



Don't worry if I create the gateway subnet or not. If I don't, It will be created automatically. The menu for create virtual network gateway look like below.



A) SKU


SKU

S2S/VNet 

P2S

BW
VpnGw1

Max 30*

Max 128**650Mbps
VpnGw2Max 30*Max 128**1Gbps
VpnGw3Max 30*Max 128**1.25Gbps
BasicMax 10

Max 128

100Mbps

B) Virtual Network : The vNet which I want to connect with on-premise site.

C) Public IP address : Azure VPN Public IP address. (Note, I can not make static IP address


After creation, I can see that virtual network gateway and public IP address are created in my resource group like below.



4. Create connection


Now, I prepare each point for the Azure and On-premise site. I need to connect between them. So I will create connection. During this process, I need to select "local network gateway" and "virtual network gateway" which are created at above.



A) Shared key (PSK) : It is kind of the password. Therefore, I should be secret and shared with peers.


And I can see more detail. Also I can change PSK values




After connection, I can download the configuration file. 

It looks like


tidcne-s2s-connection-1.txt



5. Update the routing table.


Now, I prepared all of infrastructure. However, it is not perfect. Because of I need to control the traffic flow. I hope I remember "I choose Route-based, not Policy-based VPN". I need to update my routing table like below. In my route table, I need to watch the subnet which are associate. In my case, I want to all network to connect with my on-premise. therefore I associated all networks.



In route tap, I add the on-premise network range with "virtual network gateway" as next hop. In my case, 10.0.0.0/8 network should be transfer to the virtual network gateway.




6. Create on-premise VPN server.


From now, I create the on-premise VPN server which are installed with Strongswan. I use "apt-get". 


# apt-get install strongswan


# ipsec version

Linux strongSwan U5.3.5/K4.4.0-134-generic

Institute for Internet Technologies and Applications

University of Applied Sciences Rapperswil, Switzerland

See 'ipsec --copyright' for copyright information.


7. Configure packet forwarding enable.


# vi /etc/sysctl.conf

# Uncomment the next line to enable packet forwarding for IPv4

net.ipv4.ip_forward=1


# sysctl -p /etc/sysctl.conf

net.ipv4.ip_forward = 1


# cat /proc/sys/net/ipv4/ip_forward

1


8. Configure preshared key (PSK)


This PSK is similar with the password. It should be the same between peers. This information will be inserted into /etc/ipsec.secrets. The string is <leftside IPaddress> <rightside IPaddress> : PSK "xxxxxxxxx"


# vi /etc/ipsec.secrets

1xx.7x.3x.4x 1x.1xx.1xx.7x : PSK "xxxxxx_xxxx"


9. Configure IPsec configuration.


This is the IPsec configuration. I will add some information in /etc/ipsec.conf.


# vi /etc/ipsec.conf

conn azure

        authby=secret

        type=tunnel

        left=147.75.105.103 # My Public IP address

        leftsubnet=0.0.0.0/0 # My IP address space / protected network(s)

        right=52.231.73.164 #Azure Dynamic Gateway

        rightsubnet=172.21.0.0/24,172.21.1.0/24 #Azure Vnet prefixes

        auto=route

        keyexchange=ikev2 # Mandatory for Dynamic / Route-based gateway

        mark=100


There are some important things I need to focus. First, Azure only support ikev2. Second, I can write multiple subnet in left/rightsubnet field because the mode is ikev2. If I want to use ikev1, only first subnet before comma is valid. Third, mark field is necessary when the VPN should have multiple connection. This mark value is used to separate interface 


This is the Sample configuration for IKEv2

config setup

        # strictcrlpolicy=yes

        uniqueids = no


# Add connections here.


# Sample VPN connections

conn Tunnel1

        auto=start

        left=%defaultroute

        leftid=46.101.124.161

        right=52.231.191.30

        type=tunnel

        leftauth=psk

        rightauth=psk

        keyexchange=ikev2

        ike=aes256-sha1-modp1024

        ikelifetime=1h

        esp=aes256gcm128

        lifetime=1h

        keyingtries=%forever

        leftsubnet=0.0.0.0/0

        rightsubnet=0.0.0.0/0

        dpddelay=10s

        dpdtimeout=30s

        dpdaction=restart

        mark=100

Please Look  https://wiki.strongswan.org/projects/strongswan/wiki/IKEv2CipherSuites



10. Create virtual tunnel interface on VPN host.


If I remove "mark" value in /etc/ipsec.conf, All of packet are transferred over encryption by VPN. That is not what I want. I want to specific network traffic can transfer over VPN. This is the reason why I use mark and virtual tunnel interface is necessary. At first I need to merge the routing table because the strongswan create another route table to handle.


# vi /etc/strongswan.d/charon.conf

install_routes=no


I will create "tunnel interface" with "ip link add". Look at the below. I used the name "vti1" as interface name. Please, note that the mark values should be the same.


# sudo ip link add vti1 type vti local 147.75.105.103 remote 52.231.73.164 key 100

sudo ip link set vti1 up mtu 1419

sudo ip route add 172.21.0.0/24 dev vti1

sudo ip route add 172.21.1.0/24 dev vti1

sysctl -w "net.ipv4.conf.vti1.disable_policy=1"


11. Check the IPsec status.


Now, I can do all of things for the IPsec VPN connection. I can check the status for this with "ipsec status" command. 


# ipsec status azure

Routed Connections:

       azure{1}:  ROUTED, TUNNEL, reqid 1

       azure{1}:   0.0.0.0/0 === 172.21.0.0/24 172.21.1.0/24

Security Associations (1 up, 0 connecting):

       azure[1]: ESTABLISHED 76 minutes ago, 147.75.105.103[147.75.105.103]...52.231.73.164[52.231.73.164]

       azure{3}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c4e7887b_i f62d7a96_o

       azure{3}:   0.0.0.0/0 === 172.21.0.0/24 172.21.1.0/24


On the GUI of Azure, I also can check the status for VPN connection.





12. Troubleshooting 


My Azure Host has the IP address with "172.21.1.4". Therefore, I try to ping on on-premise VPN host like below. However, there is no answer.


# ping 172.21.1.4

84 packets transmitted, 0 received, 100% packet loss, time 83664ms


So I dump the packet to analysis this issue. I can see the NONESP and ESP pakcets. Thus, the ICMP is sending to destination. 


# tcpdump -ni bond0 host 52.231.73.164

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on bond0, link-type EN10MB (Ethernet), capture size 262144 bytes

07:30:44.805879 IP xxx.xxx.xxx.xxx.4500 > yy.yyy.yy.yyy.4500: NONESP-encap: isakmp: child_sa  inf2

07:30:44.806508 IP yy.yyy.yy.yyy.4500 > xxx.xxx.xxx.xxx.4500: NONESP-encap: isakmp: child_sa  inf2[IR]

07:30:50.168456 IP xxx.xxx.xxx.xxx > yy.yyy.yy.yyy: ESP(spi=0x60237774,seq=0xc), length 132

07:30:51.176661 IP xxx.xxx.xxx.xxx > yy.yyy.yy.yyy: ESP(spi=0x60237774,seq=0xd), length 132


I will give you answer for this issue. It is happen due to the source IP address. In this case, the ICMP packet will send to destination with interface IP address which is selected by routing table.  I will check my  network security group for Azure. I will add the interface IP address.



Please, note on-premise network range should be added in this network security group. Now I can do ping.


# ping 172.21.1.4

PING 172.21.1.4 (172.21.1.4) 56(84) bytes of data.

64 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=42 time=191 ms

64 bytes from xxx.xxx.xxx.xxx: icmp_seq=2 ttl=42 time=192 ms


However, the IP address which is returned is not private IP address of the Azure host. It will be the Public IP address. Because, the source IP address from on-premise VPN host is the public IP address. So I will do some trick for this. I will use the SNAT like below.


# iptables -t nat -A POSTROUTING -d 172.21.0.0/24 -o vti1 -j SNAT --to-source 10.99.8.131

# iptables -t nat -A POSTROUTING -d 172.21.1.0/24 -o vti1 -j SNAT --to-source 10.99.8.131


Now, I will do ping again.


# ping 172.21.1.4

PING 172.21.1.4 (172.21.1.4) 56(84) bytes of data.

64 bytes from 172.21.1.4: icmp_seq=1 ttl=64 time=192 ms

64 bytes from 172.21.1.4: icmp_seq=2 ttl=64 time=193 ms


So, I have done all of things. I can have IPsec VPN connection between on-premise and Azure.


Reference 


[ 1 ] https://tscr.io/2018/01/03/azure-routed-vpn-with-strongswan-on-linux/

[ 2 ] https://docs.microsoft.com/ko-kr/azure/vpn-gateway/vpn-gateway-about-vpngateways

[ 3 ] https://wiki.strongswan.org/projects/strongswan/wiki/IKEv2CipherSuites

+ Recent posts