

Sarath Pillai's picture



Read: Network Address Translation in Linux

Most of the companies these days have operational branches in geographically different locations, which needs inter connectivity between each other. However interconnection between these geographically isolated offices or branches can only be done through internet, which is an insecure medium. Internet is an insecure medium simply because there are many network devices that comes in between you and your destination, who can easily read your communication. And the interesting part is that you cannot reach your destination through internet, bypassing these interconnecting networks and devices.

However you can send your information in such a way that only the destination host can open it and read it. There are encryption technologies that are involved in protecting your communication that travels through the wire. Different technologies can be used to encrypt your communication. One of them is called as IPSec(Internet Protocol Security). For understanding IPSec and its working, you can refer the below link.

Read: What is IPSEC

There are other technologies as well that protect data communication over wire, some of them are mentioned below.

However we cannot reliably use them for our purpose of interconnecting two branch offices which are geographically isolated through internet. We can achieve this interconnection with the help of something called as VPN (Virtual Private Networks). VPN is a very useful technology that is widely deployed in organizations that require secure remote access to remote network.

Some noteworthy points about Virtual Private Networks are mentioned below.

  • Interconnecting of two private networks through internet
  • Security of communication traffic with the help of encryption
  • Access to internal network from outside

We will be configuring our VPN connectivity with the help of IPSec(A technology used to encrypt traffic at network layer. In other words an entire IP packet is encrypted for security). IPSec is used for authentication as well as encryption of the complete communication that happens between two hosts on the internet. As IPSec works in network layer, traffic generated by all applications are by default encrypted and sent, hence there is no modification required to be done on the existing application to make it compatible with IPSec.

We will be using one such IPSec implementation in Linux for creating a tunnel between two private networks through the internet. There was a project called as Free-Swan, which was the first implementation of IPSec on Linux, but due to some reason, the project did not last long(the last version of free-swan was released at 2004 ). However the same code base was used to continue another IPSec project called OpenSwan. We will be using OpenSwan for making a secure VPN tunnel. Openswan IPSec package is released under GNU GPL licence, and is available for all linux distributions.

site to site vpn using ipsec


In the above shown figure i have tried to depict, the VPN setup that we will be configuring now. There are two networks showin in the above diagram.

Network A:


Network B:

These two networks are geographically isolated from each other(and of course they are private network addresses and cannot be routed through internet to communicate with each other.). We will be interconnecting these two networks together, so that the hosts on network A can communicate with hosts on network B just like they communicate to any local network.

For making this work we will be having two VPN servers. These two VPN server's will be running ISPec application openswan. This kind of a setup is called as gateway to gateway or sometimes site to site VPN.

We will have two VPN servers (one for network A and one for network B). Both of them will need a public internet IP address, to communicate with each other through the internet. Also these two VPN server's will be doing a Source Network Address Translation of their respective internal hosts, while they access the other network behind VPN.


Initial configuration of VPN servers

We need to configure some basic settings on both the VPN servers (VPN server on network A and B). This configuration is very much necessary for clients on both the networks to reach the other network, as well as proper working of routing.

The first step is to configure IP forwarding. The name itself suggests that it is used to forward packets destined for other hosts. It is basically done when you need to make a linux machine act as a router. In our case of establishing a VPN tunnel between two networks, both the VPN servers will be acting as a router to reach the network on the other side. Hence we need to enable it.

IP forwarding can be enabled in Linux by the below command on the fly.

[root@VPN-server-1 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

If you see the above command, we have modified a file on /proc file system. Anything that resides on /proc is temporary, and does not persist after a reboot. Hence we need to make our ip forwarding permanent. This can be done by modifying sysctl.conf file.

open the /etc/sysctl.conf file and edit the below line and make it 1 instead of 0.

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

To make that change in sysctl effective, you can run the below command.

[root@VPN-server-1 ~]# sysctl -p /etc/sysctl.conf

Please do not forget to enable ip forwarding on both the VPN server's.

Let's add some Iptables rule that will modify the source IP address of a packet before that packet is send out. This is very much useful because this helps in modifying the source ip of the packet. On network A VPN server enter the below command.

[root@VPN-server-1 ~]# iptables -t nat -A POSTROUTING -s -j MASQUERADE

The above command on network A VPN server will modify the source address of a packet originating from network to its own outgoing interface(which will be a public IP address).

On the VPN server on the other side, apply the same above command with the source address of (its iternal network)

Now we are set to install and configure openswan ipsec server on both the VPN servers.


Openswan IPSec VPN configuration in Linux

Openswan ipsec tunnels allows you to authenticate the traffic going through the tunnel in two methods. The two methods are mentioned below.

  • Shared Secret
  • RSA key

We will see both the configuration one by one. Lets see shared secret for encryption in openswan ipsec first.

Shared secret authetication in Openswan IPSec

Creating a tunnel between two seperate networks using openswan shared secret is the easiest and fast method. For this to work properly we will begin with installing openswan on the linux machine (the package is available for almost all linux distributions.). You can use the system package manage for installing openswan.

Related: Yum tutorial in Linux

The below yum command can be used to install openswan in linux. I am using a centos/red hat distribution of linux for this illustration. However you can achieve the same result in any distribution without much modification.

[root@localhost ~]# yum install openswan

After the installation is complete you will get a file called as /etc/ipsec.conf.

Now the second step is configure our ipsec.conf file, where we will mention our remote VPN server public IP, remote subnet, subnet available on this side etc.

Let's see an example configuration of ipsec.conf file.

[root@localhost ~]# cat /etc/ipsec.conf
# /etc/ipsec.conf - Openswan IPsec configuration file
# Manual:     ipsec.conf.5

version 2.0     # conforms to second version of ipsec.conf specification

# basic configuration
config setup
        # klipsdebug=none
        # plutodebug="control parsing"
        # nhelpers=0

#include /etc/ipsec.d/*.conf
conn sample-connection-for-illustration
        left=<public ip of this VPN server>
        leftid=<Can be an IP address or a fully-qualified domain name of this VPN server>
        leftsubnet=<subnets that will be reachable through this vpn connection on this side>
        right=<public IP of VPN server on the other side>
        rightsubnet=<subnet that will be reachable through this vpn connection on the other side>

Let's understand some important fields shown in the above /etc/ipsec.conf configuration file.

protostack:On Linux, there are two IPSec stacks, NETKEY and KLIPS. KLIPS is currently the more stable one, the one which is easier to use. NETKEY on the other hand, is quite a new stack, but due to various reasons, KLIPS was not allowed to be included in the Linux kernel by default, where as NETKEY is.

nat_traversal: IPSec works by encrypting packets at the network level, in other words an entire IP packet is encrypted along with its headers, and sometimes a new header is attached if you are masquerading IP packets.Inorder to enable IPSec packet to go through NAT devices, we need to enable this option by setting it to the value of "yes".

virtual_private: The way NAT-T(nat traversal) works is that a client proposes a connection that has its non-NAT'ed IP address as part of the proposal. This can cause problems if the server you are connecting to is using the same IP range internally. Say that IPSec server connects you to and your client is on behind some public IP a.b.c.d, then where do packets go for The client side or the server side?. The best method is to add all private subnet except those ranges used by the server.

conn: This is the first argument that mentions the name of the connection. You can give any name as you wish, this is simply for identifying the tunnels.

authby: how the two security gateways should authenticate each other; acceptable values are secret(shared secret which will be same on both the vpn server) or rsasig

type: the type of the connection; currently the accepted values are tunnel, signifying a host-to-host, host-to-subnet, or subnet-to-subnet tunnel; transport, signifying host-to-host transport mode.

left: The ip address of the local IPsec server


leftsubnet: What are the subnet that will be reachable through this tunnel, on this side of the tunnel

rightsubnet: the subnet that can be reached through this tunnel, on the other end (basically private subnet behind the ipsec server at the other end)

An important fact to note about leftsubnet & rightsubnet is that, we can modify it and provide multiple subnet by using leftsubnets & rightsubnets instead if we want multiple subnet to be made reachable through this tunnel. Simply adding routes on both the sides without adding the subnet will not make the hosts reachable. Let's take an example.

Now if this configuration file(/etc/ipsec.conf) is configured properly with all the proper required fields (left, right, left subnet, right subnet, secret, virtual_private etc), the second file that we need to pay attention to is /etc/ipsec.secrets

An example of ipsec.secret file is shown below.

[root@localhost ~]# cat /etc/ipsec.secrets
<public ip> <public ip of other side>: PSK "password"

Or if you want to further simply the process of ipsec.secrets, then you can use one single password for all the ipsec tunnels by the following method.

%any %any : PSK "password"

But remember only one fact that for tunnel to work with preshared key passwords should be same on both vpn servers.

Now we need to have the exact same configuration on the other side VPN server (with the required changes in left, right, leftsubnet, rightsubnet, leftid, rightid)

To make the concept clear the value of right on the other vpn server must be the value of left on this VPN server. Also the ipsec.secrets file needs to configured properly(the password on the servers must be same).

Now once the configuration is perfect, restart the ipsec service on both the sides. Your tunnel must work flawlessly if you did not make any configuration mistake. You can check the tunnel by pinging any ip on the remote subnet.

rsasig authentication on openswan ipsec

Now as discussed before, lets see the second method that can be used for authentication of our IPSec. We will create rsa keys on both the vpn servers first then we will see the ipsec.conf file.

You can create an rsa key for your vpn server by the following command.

[root@localhost ~]#ipsec newhostkey --output /etc/ipsec.secrets --bits 2048 --verbose --hostname <your VPN server hostname>

The above command should create a 2048 key for your VPN server inside ipsec.secrets file.

Run the same command on the other side VPN server. So now you have two rsa keys of 2048 bit size on both the servers. Now comes the main part of configuring ipsec.conf file.

An example configuration file with rsasig authentication is shown below.


conn sample-connection-for-illustration
        left=<public ip of this VPN server>
        leftrsasigkey=MIIEpAIBAAKCAQEAvW9xa7kB0iL4D7PDM1QyLNczrKM+2MIZUTvOBL9rPOka+1y+......very long to display it here
        rightrsasigkey=MIIEpAIBAAKCAQEAvW9xa7kB0iL4D7PDM1QyLNczrKM+2MIZUTvOBL9rPOka+1y+...(rsa key created on the other vpn server)

Do the exact same configuration on both the servers and you are done.

Now restart ipsec service on both the servers, to make the tunnel active. As suggested before you can try pinging the remote subnet to test the connection status.

In our "initial configuration for VPN servers" section we made some config changes inside our VPN servers. That was maily for routing purpose, which will enable routing for client machines on both the networks to reach each others.

So on client machines inside (network A shown in our example) we need to add a route which will allow them to reach the other network.

[root@localhost ~]# route add -net netmask gw <vpn server ip>

Same kind of route for reaching network A must be added on the clients inside network B.

Rate this article: 
Average: 4.2 (59 votes)


It's a good explanation about how Openswan works. Congratulations!

Do you have any comment about having lefsubnet defined with the valid ip address
and not the internal ip address? Is it possible?
I have 8 valid address that are routed to my firewall.
The VPN is up but only the firewall can connect to the other side throught the VPN.
We have 2 interfaces: one connected to the Internet and another connected to the
internal subnetwork. The internal machine has a one-to-one or masquerade NAT with
the valid ip address but when it tries to connect throught the VPN, in reality it
doesn't connect and tries to reach the destination going throught the normal Internet link and not the VPN.

Please, do you have any idea?


Sarath Pillai's picture

Hi Claudia,

Thanks for your comment..

I guess you are asking about having your leftsubnet option with 8 different IP addresses instead of private subnets (correct me, and let me know if i got your query properly).

Unfortunately openswan does not allow you to mention IP addresses in leftsubnets option, even if you mention it with a /32 CIDR form. So the only possible solution that you can do is probably mentioning the entire subnets those 8 ip addresses belong to, if not an issue (You can block the rest from the firewall itself).

I believe your internal machines with private subnets are trying to reach the subnets on the other side of the VPN through your firewall (let me know if am wrong). That wont happen until and unless you have those private subnets added inside leftsubnets option in the openswan config.
You also need to add a masquerade rule on your firewall that will masquerade all your private subnets (which are trying to reach the other side of the VPN).

Also please try adding a more specific route on your private hosts who are trying to reach hosts on the other side of the VPN(not required if you already have a default route set to openswan device for all traffic).

Please let me know your issue in a little bit elaborate manner.


I want to setup IPSec VPN between two host machine. I have one Ubuntu installed as Host machine and in virtual box i have installedd another Ubuntu.
Please explain me and provide procedure for establishing IPSec VPN between these two machines.


Sarath Pillai's picture

Hi ravikant,

You are referring to host-to-host openswan configuration if i got your question correctly. Configuring that is quite simple. Install openswan on both the ubuntu machines.. Then run the below command, that will create a key pair.

root@workstation:~# ipsec newhostkey  --output /etc/ipsec.secrets --random /dev/urandom

You can also run the above command without the /dev/urandom option. However that will make it very slow..

The next step is to copy both the left and right side key's and put it inside a configuration file. This configuration file will be same on both the servers.

root@workstation:~# ipsec showhostkey --left
root@workstation:~# ipsec showhostkey --right

Running the above commands will show you the keys that can be used on both the sides.

Now make a configuration file that will hold the left and right ip addresses along with our keys. The file will look something like the below..

conn host-to-host
    left=[ipaddress of this host]
    leftrsasigkey=[Put the left key value here]
    right= [ip address of the other host]
    rightrsasigkey=[put the right key value here]

Place the same file on both the servers(/etc/ipsec.d/), and restart the ipsec service...and you are done..Check the logs to confirm whether its working...

Let me know if that worked..




Hello Sarath, greetings from Ukraine!
Thank you for your topic about Linux IPsec site-to-site, very informative! But i have a very specific question on this subject. I have Cisco ASA firewall from one side, and PC with Linux on the other side, and i need to provide ipsec site-to-site tunnel between them, using PSK. Also linux machine must provides NAT translating to another computer from its secondary network card (to windows or linux machine - doesn't matter). I've been searching for my answer for several days on many forums and sites, but didn't find anything similar to my problem, and hopes only for your help! Thanks for response!

In addition to my previous question, i must clearify one more thing: on one side with Cisco ASA i also have notebook, which must connect to client machine, which is connected to linux host. So, schema is: Notebook -> ASA - linux host <- client linux pc. And i have no idea, how to connect client linux pc to notebook through ASA and host. Sorry for my bad English, i hope you understand my problem... Thanks!!

Sarath Pillai's picture

Hi Sergey,

If i understood your question properly, then i believe you are searching for site-to-site VPN where one endpoint is a linux machine and the other end point is a CISCO ASA firewall.

Configure the openswan server on linux as shown below...

conn Linux-to-CISCO
type= tunnel
authby= secret
left= <IP address of your linux server>
leftsubnet= <subnets behind your linux system>
right= <IP of CISCO firewall>
rightsubnet= <subnets behind CISCO firewall>
esp= 3des-md5-96
keyexchange= ike
pfs= no
auto= start

Now you need to configure the same exact configuration withing ASA.. You can do this by using the GUI based ASA VPN configuration assistant. Select the VPN wizard from the "Wizards" option.

Select site-to-site---> then select preshared key and you can mention the right and left subnets here by mentioning the "Local and remote networks".

Start VPN on both the sides..It should work.. Please let me know if that worked.

Hello Sir,

I have added as per your suggestion but i m getting below error Im searching for site-to-site VPN where one endpoint is a linux machine and the other end point is a CISCO ASA firewall.

failed to start openswan IKE daemon - the following error occured:

Please suggest me

Hi Sarath

Thank you for a great post! I want to configure the same topology with one change: both hosts are behind a NAT.

So in essence: network with a gateway (which is behind a NAT with public IP must tunnel to host2's public IP yyy.yyy.yyy.yyy with NATed host (private) which has a VPN network on

What configuration and route changes must be made for to directly talk to through the IPSec tunnel?

Thank you


and thank you for this useful post.
I want to configure openswan in a Debian 7.3, but when I do a "apt-get install openswan" I'm getting a message that says this packet is not available. And instead of this I've got the proposition to install the packet "strongswan-ikev1".

So, is it necessary to enable an specific apt source in order to install openswan?

Thank you.


what's the difference between virtual_private & leftsubnet? I noticed some configs do not exclude the other side's subnets with virtual_private.

Sarath Pillai's picture

Hi pop222,

Virtual_private is used to mention subnet ranges that are allowed for remote clients. A good example is, if your vpn server gives access to then virtual_private can contain all private subnets except (this is primarily done to avoid ip conflict)

leftsubnet: The subnets mentioned in this field will be reachable once the vpn is connected from the other side. If you have more than one subnet that needs to be reachable, then you can use leftsubnets instead of leftsubnet.

Please let me know..



I have a production Asterisk server running fine. Now my company wants to connect it to another provider which requires site to site vpn for connectivity. My concern is can I install it on running system with out any impact on it? As the server is already configured with Fix IP and connected to internet, will installing OpenSwan change any network parameters that can make server inaccessible (I am connecting remotely via

Please help me out.

Thanks in advance.

Sarath Pillai's picture

Hi Nasir,

As far as your routes are proper (I mean the routes that will flow through your site to site tunnel), nothing will be impacted. It should work as normal.

Let me know how it goes. If you can elaborate your use case, i can help with my thoughts to get this done smoothly. Let me know.



and thank you for this useful post.
i doing step by step your explanation, but when i changed ipsec.conf and ipsec.secret file and verify ipsec arise the error pluto listening for IKE on udp 500= [FAILED]
please guidance me why I meet the error
I use VMware and fedora11
tanks very much.

Sarath Pillai's picture

Hi Mohammad,

Can you check two things here.

1. Is something running on port 500? do an lsof -i: 500 and see if something is running there.
2. Check the logs, during openswan startup, and see why is pluto not getting started. If you find an error about pluto startup, let me know..


hi thank you for your perfect guide but every time I'm trying to start a connection I receive the following

We cannot identify ourselves with either end of this connection.

this is the same for local and remote host. in leftid I have tryed everything(public IP, local IP, localhost, hostaname,FQD) but nothing is working for me, here I will post my ipconf

conn vpn_guida

my VPN SERVER is not my default gateway but is behind a router nat and port 500 UDP is correctley forwarded to server IP
thank you

How would you set this up to link to offices to a main office. Three sites in total. Thank you in advance.


THank you so much for this tutorial. I used it on my ubuntu machine but the issue I am having is now is I am getting an error pending Phase 2 for "xxx" replacing #0.

I had checked the shared keys and those are fine. I know when the ipsec goes thrugh this process I am pretty much unable to ping.

Can you please help.

could you tell me what ip should i give for centos1 and centos2 testing the VPN is working. could to list the ip for eg on left side and right side

What can be done to fix this problem .error :No KLIPS support found while requested, desperately falling back to netkey

Hi there,

I need to design site to Multi site..Means..I have multiple different network..[for ex. 10.x.y.y , 10.x1.y.y] to do VPN. Is it possible using openswan. if yes, then would you mind telling me how that config would be ?

My Goal is : once above stuff completes..I will put my VPN server into Nagios Monitoring to monitor all WAN IP's server and their endpoints.

Will wait for your reply!



Now that we are in a virtual environment and everything is dynamic, it is hard to restrict to particular IP range. Let me set a bit more context here.

Our setup is to have our application services instances connecting to a central messaging system (Every application instance needs to know the IP of central message instance, but messaging queue does not require the IP of other side). We need it to be through a secure channel as we send confidential information through public cloud networks.

What we use right now is stunnel which will allow you to have a server client model


ActiveMq (Listens on <- stunnel (<Listens on IP of the instance>:1234 and connect to 127:0.0.1:1234)

Now any instance with a valid certificate can connect to the activemq over IP:1234 which is basically stunnel fontend and gives the connection back to activemq in its loopback address.


My Application (Connects to -> Stunnel (Listens on and connects to <activemq ip>:1234)

Basically If I have the valid cert, I can connect to any instance with out publishing my IP like the usual IPSEC config where you need to define both the ends.

Is there any way we can do this in IPSEC? I know rancher is doing some end to end encryption with IPSEC, but not sure how the internal implementation is. It will be great if I can get some light to thig problem.

Hi Sarath,

Can you help me I've configured ipsec with openswan with RSA authby, I can access remote host but cannot to ping other remote LAN hosts

Can you help me out at which point I'm mistaking ?

Running ubuntu 14.04 on both hosts, one server has two interfaces (dedicated) and other is having one interface (AWS EC2).

-| Faraz

I have case where I want to route the traffic from public interface over tunnel to connect to Vendor side.

Below is my *.conf file, I have created secret key as well, But when I run

> service ipsec status

I get "no tunnels up"

And when I tried 'ipsec auto --up Left-Conn' I get the following error,

022 we cannot identify ourselves with either end of this connection

Please Help.


# /etc/ipsec.conf - Openswan IPsec configuration file
# Manual: ipsec.conf.5

version 2.0 # conforms to second version of ipsec.conf specification

# basic configuration
config setup
# klipsdebug=none
# plutodebug="control parsing"
# nhelpers=0

#include /etc/ipsec.d/*.conf
conn Left-Conn

it is excelent

I am trying to configure ipsec tunnel on linux machine on AWS with client who having Cisco ASA at their end.

SFTP SEVER (Public IP) <====>Linux VPN Server <======>Cisco ASA <=====> Client Servers with public IP.

I am using below configuration but tunnel is not coming up

I have ipv4 for forwarding on in my setup

[root@ip-10-0-10-26 ipsec.d]# sysctl -p /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0


config setup

conn myconnection
leftid= <Elastic IP>
leftsourceip= <Elastic IP>
rightsubnets={ <Client Public IPs of their servers>}


Please suggest what needs to be change in the configuration file. In case iptables needs to be started and set than what rules i need to add in it.

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.