Creating a dynamic site-to-site VPN with OpenSwan on Ubuntu 10.04 on EC2
Wes Winham email@example.com
There are many tutorials floating around the web that almost get you a dynamic VPN in EC2. The goal of this tutorial is to be a one-stop-shop for this specific setup.
What You'll Get
- Config files that don't change when new instances are launched (the private ec2 ip doesn't matter).
- An EC2 box that can securely access a private subnet on the remote network.
- No special access from the remote endpoint to your EC2 box.
- The ability to use Elastic IPs to manage which box is connected.
- Compatibility with cisco and openswan endpoints.
- No need to update the remote endpoint config.
Things You'll Need
- A fresh Ubuntu 10.04 instance on EC2
$ELASTIC_IP: An elastic IP
$CONN_NAME: A unique name for your connection. eg.
$RIGHT_PUBLIC_IP: The public IP of your other VPN endpoint.
$SECURE_PSK: A random pre-shared key to secure your connection.
$RIGHT_SUBNET: The private subnet your EC2 box should access on the remote network:
Note: If you only need to access a single IP on the remote network,
/32 netmask for your
First, spin up your EC2 instance and attach your Elastic IP.
SSH into your EC2 instance and run:
$ sudo apt-get install openswan
Fix Linux Networking
Once OpenSwan is installed,
you'll have access to the
$ sudo ipsec verify command.
This command checks certain linux network paramenters
to ensure that your system properly supports OpenSwan.
Run this command and you should see something like:
$ sudo ipsec verify Checking your system to see if IPsec got installed and started correctly: Version check and ipsec on-path [OK] Linux Openswan U2.6.23/K2.6.32-318-ec2 (netkey) Checking for IPsec support in kernel [OK] NETKEY detected, testing for disabled ICMP send_redirects [FAILED] Please disable /proc/sys/net/ipv4/conf/*/send_redirects or NETKEY will cause the sending of bogus ICMP redirects! NETKEY detected, testing for disabled ICMP accept_redirects [FAILED] Please disable /proc/sys/net/ipv4/conf/*/accept_redirects or NETKEY will accept bogus ICMP redirects! Checking for RSA private key (/etc/ipsec.secrets) [OK] Checking that pluto is running [OK] Pluto listening for IKE on udp 500 [OK] Pluto listening for NAT-T on udp 4500 [OK] Two or more interfaces found, checking IP forwarding [FAILED] Checking for 'ip' command [OK] Checking for 'iptables' command [OK] Opportunistic Encryption Support [DISABLED]
The gist of this is that the Ubuntu AMI's must use the NETKEY stack and that you must make configuration tweaks to support that. You also need to enable IP forwarding because the EC2 instance has multiple network devices.
You will make these changes using the
This will cause changes in the
proc file system at paths like
but by editing this file,
you ensure those changes are reflected on reboot.
and add or uncomment the following lines:
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
Now use the
sysctl command to load your new configuration:
$ sudo sysctl -p /etc/sysctl.conf
If you succeeded,
$ sudo ipsec verify again
should show everything
with the exception of
Opportunistic Encryption Support,
which we don't need.
Open the EC2 Security Group
In order for the VPN to initiate a connection, we must allow the traffic to pass through EC2's firewall. This is managed via Security Groups.
To modify the ec2 security groups,
open the AWS Console,
EC2 and then select the
Security Groups section.
Open UDP access on ports
for a group in use by your EC2 instance.
You'll configure your IPSec connection using 3 different files:
/etc/ipsec.conf: This is the main configuration file, where we declare overall configurations and then define the
$RIGHT_SUBNETas a non-private range.
/etc/ipsec.d/$CONN_NAME.conf: Included via the
include /etcipsec.d/*.confline in
/etc/ipsec.conf, we use this to define our specific tunnel.
/etc/ipsec.secrets: Here we define the pre-shared key used by the connection.
You'll control reloading these configuration files with:
$ sudo service ipsec stop $ sudo service ipsec start
Modify the following files
to match this configuration,
remembering to replace the
with the actual value.
version 2.0 config setup nat_traversal=yes virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!$RIGHT_SUBNET protostack=netkey include /etc/ipsec.d/*.conf
conn $CONN_NAME authby=secret forceencaps=yes auto=start left=%defaultroute leftid=$ELASTIC_IP leftsourceip=$ELASTIC_IP right=$RIGHT_PUBLIC_IP rightid=$RIGHT_PUBLIC_IP rightsubnet=$RIGHT_SUBNET
0.0.0.0 for one side of the connection
to ensure that no matter the ec2 internal ip we use to identify ourselves
(as indicated by
we use this key
if the connection is coming from our expected remote endpoint.
$RIGHT_PUBLIC_IP 0.0.0.0: PSK "$SECURE_PSK"
Now let's actually load our spanking-new configuration files.
$ sudo service ipsec stop $ sudo service ipsec start
Test the Connection
To test the connection,
run the following command
$CONN_NAME with the appropriate value):
$ sudo ipsec auto --up $CONN_NAME
If everything is kosher,
you should see two lines similar to the following
apd is the value of
$CONN_NAME in this case):
117 "apd" #3: STATE_QUICK_I1: initiate 004 "apd" #3: STATE_QUICK_I2: sent QI2, IPsec SA established tunnel mode
Now our tunnel is up,
so let's see if we can send some traffic through.
Pick an IP address in your
that should respond to pings
$ ping <something_on_right_subnet>
You should see pings coming back.
Testing Without Ping
If you don't have a box to target that should respond to ping, you can try running a port scan to see if you can at least reach the machine.
$ nmap -PN <something_on_right_subnet>
While you're running your
you can view the traffic with
$ tcpdump -n host <RIGHT_PUBLIC_IP>
If you don't see ESP packets in
then they aren't being tunneled.
$ tcpdump -n host <something_on_right_subnet>
If that shows ICMP (or other if using nmap) packets, then you're sending packets around the tunnel.