This is a brief tutorial that aims to help those who are new in setting up an IPsec VPN connection with OpenSwan, hosted in cloud environments like Google Cloud and Amazon Web Services.
I imagine you have an instance, lets say on Google Cloud, and want to establish an IPSec tunnel with another client outside your infrastructure.
Follow this tutorial in order to learn how to easily achieve it!
Installing OpenSwan and its dependencies
# apt-get install openswan ipsec-tools
Let’s verify if everything is fine:
# ipsec verify
A normal configuration will look like this:

Gathering information and setting up the configuration
Before you start configuring the vpn connection, you will need some information to proceed:
- Customer VPN Gateway: This is the public IP of the other end of the tunnel.
- Customer Encryption Domain: This is the private network that you should access (it can be more than one)
On your end, you should supply to your customer your VPN Gateway and your encryption domain (the private network that you are going to use to access it)
In a nutshell then, let’s define these values just for the purpose of this guide:
- Customer VPN Gateway: 200.10.10.1
- Customer Encryption Domain: 10.50.2.0/24
- Your VPN Gateway: 104.10.10.1
- Your Encryption Domain: 192.168.90.1/32
Now you need to decide with your customer the phase 1 and phase 2 settings. We will assume the following for this particular guide:
Phase 1:
- Authentication Method: PSK (Pre-Shared-Key)
- Encryption Scheme: IKEv2
- Diffie-Hellman Group: Group 2
- Encryption Algorithm: AES-256
- Hashing Algorithm: SHA-2
- Lifetime: 86400 seconds
- Pre-Shared-Key (PSK) a_strong_PSK_here
Phase 2:
- Encapsulation: ESP
- Encryption Algorithm: AES-256
- Authentication Algorithm: SHA-2
- Diffie-Hellman Group: Group 2
- Perfect Forward Secrecy: No
- Lifetime: 3600 seconds
Setting up the OpenSwan Configuration
Having this information, now it’s time to play around with OpenSwan. First you need to open the config file /etc/ipsec.conf and create a new connection at the bottom of the file:
conn client-vpn # You can use any connection name here type=tunnel # Left security gateway, subnet behind it, nexthop toward right. left=192.168.90.1 leftsubnet=192.168.90.1/32 leftnexthop=%defaultroute # Right security gateway, subnet behind it, nexthop toward left. right=200.10.10.1 rightsubnets={10.50.2.0/24} #Separate by commas for more networks. rightnexthop=%defaultroute # Phase 1 keyexchange=ike # Default version is IKEv2 authby=secret ike=aes256-sha2;modp1024 # Algorithm: AES(256) / Hash: SHA2 / Group: DH 2 (1024) ikelifetime=86400s # Phase 2 phase2=esp # Algorithm: AES(256) / Hash: SHA2 / Group: DH 2 (1024) phase2alg=aes256-sha2;modp1024 keylife=3600s pfs=no # Port Forward Secrecy disabled auto=start # Start connection everytime OpenSwan is started keyingtries=3
Still, you need to set up the PSK within the file /etc/ipsec.secrets:
104.10.10.1 %any: PSK "a_strong_PSK_here"
Routes, iptables and global rules
As you may know, Google Cloud, AWS and almost every cloud environment out there, only provides one physical interface (eth0) per instance/server. In order to be able to set up ‘n’ different connections, you need to create a virtual interface for each one of them.
For this example it was used 192.168.90.1/32 (a host network) as the encryption domain on your end. Besides creating the virtual interface, it’s necessary to configure specific routes, iptables rules and global rules.
I personally recommend creating a script to have all this configuration well organized.
So let’s start then!
Create a file within /etc/init.d/ and name it as you want. In my case I named it firewall.
Then paste the following:
#!/bin/bash RETVAL=0 function start() { # VPN IPSEC: MyCompany x My Client # Creating a virtual interface eth0:1 192.168.90.1 /sbin/ifconfig eth0:1 192.168.90.1 netmask 255.255.255.255 # Creating a NAT IP Tables Rule /sbin/iptables -t nat -I POSTROUTING -d 10.50.2.0/24 -j SNAT --to 192.168.90.1 # Creating a route so packets are transmitted through the virtual interface /sbin/route add -net 10.50.2.0 netmask 255.255.255.0 gw 192.168.90.1 # GLOBAL RULES # Using masquerading /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # Enable IP Forwarding so packets could be transmitted between networks echo 1 > /proc/sys/net/ipv4/ip_forward RETVAL=0 } function stop() { # GLOBAL RULES # Disabling IP Forwarding echo 0 > /proc/sys/net/ipv4/ip_forward # Flushing iptables rules /sbin/iptables -F /sbin/iptables -F -t nat # VPN IPSEC: MyCompany x My Client # Removing route /sbin/route del -net 10.50.2.0 netmask 255.255.255.0 gw 192.168.90.1 #Removing the virtual interface eth0:1 /sbin/ifconfig eth0:1 down RETVAL=0 } case $1 in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo "Usage: firewall {start|stop|restart|status}" RETVAL=1 esac exit
The previous script will help you persist this configuration, and the ability to turn on and off, with these simple commands:
Turn on the configuration needed for the ipsec configuration:
# /etc/init.d/firewall start
Rollback to the default configuration:
# /etc/init.d/firewall stop
Testing the IPSec Tunnel
In order to use the new configuration it’s necessary to restart the ipsec service:
#service ipsec restart
Add the new ipsec connection:
# ipsec auto --add client-vpn
Start the IPSec tunnel:
# ipsec auto --start client-vpn
A successful connection would have the following message:
"client-vpn/0x1" #16: transition from state STATE_QUICK_I1 to state STATE_QUICK_I2 "client-vpn/0x1" #16: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode {ESP/NAT=>0xaaadccc7 <0x8bcbf8a0 xfrm=AES_256-HMAC_SHA2 NATOA=none NATD=104.10.10.1:4500 DPD=none}
In case you don’t see a message like that, you need to verify with your customer if every configuration is the same as yours. Remember that everything must be identical for the tunnel to be established.
After the tunnel is up and running, it’s important that you test the traffic through each end of the tunnel. You can use commands like ping, curl, nmap, telnet and nc.
If you can’t receive a response, the best way to debug possible issues is using tcpdump, in order to verify in/out packets through the interface.
Great tutorial. Just one thing, do you think keeping the suggestion of SHA-1 as handshake still a good idea?
I would probably recommend going up for SHA-2 at least.
Welcome to Conviso’s Blog Thalles!
Indeed, is a better idea to use a stronger handshake. Nevertheless, is still secure and widely used nowadays for IPSec purposes.
See, for SHA-1 you have 2^160 key value possibilities, and its quite very unlikely to obtain the value before the communication ends.
I will consider that and update the information 🙂
Thank you.
Excellent article, it saved my day… Thanks a lot!