[Openswan Users] Request for configuration help for non-trivial AWS VPC OpenSwan Remote User L2TP/IPsec VPN configuration
Michael Crawford
michael.crawford at mjcconsulting.com
Fri Aug 30 20:05:40 UTC 2013
I'm having some trouble getting an L2TP/IPSec VPN fully working with a
non-trivial AWS VPC setup.
Hoping those on this list can help spot what may be the problem.
I also thought this configuration may be of use to others attempting
something similar once the
kinks are worked out, so I'm including all aspects of the configuration.
===========================================================================
=========================
Summary of current status:
* I have the VPC fully setup with all subnets and routing tables. All
internal inter-host
communications working as expected.
* Not relevant to this problem, but I have setup successfully a
site-to-site VPN using the AWS VGW,
CGW and VPN connection into a Cisco ASA at company HQ.
This VPN is intended for use by employees when in the office.
* I also want to create an L2TP/Ipsec "remote-user" VPN, allowing direct
access to all hosts
in the VPC, from primarily Mac OS X and IOS devices in arbitrary
locations.
This VPN is intended for use by system administrators when on the road
or at home.
This is what I have partially working now.
* The current remote-user VPN is routing what appears to be a /24 route,
which lets me get to
instances which are on subnets which are within this /24 CIDR block. I
can not get to instances
which are not within this /24 CIDR, and fixing this is what I need help
with.
===========================================================================
=========================
Here's the network details of the VPC configuration. This is a multi-AZ
(availability zone) HA
configuration, with all key functions provided by a pair of hosts which
consist of a primary
active host in AZ A, and a second failover host in AZ B. We're using Route
53 failover DNS and
similar techniques to handle failover, mirroring, etc. I mention this only
to setup the subnet
and routing table layout.
VPC CIDR: 10.240.0.0/20 - this is the overall CIDR which defines the VPC
and all IP addresses
within it.
Subnets:
Tier/Use Type AZ-A CIDR AZ-B CIDR
-------------- ------- --------------- -------------
Web Servers Public 10.240.0.0/25 10.240.4.0/25
App Servers Private 10.240.1.0/25 10.240.5.0/25
DB Servers Private 10.240.2.0/25 10.240.6.0/25
Build Servers Private 10.240.3.0/25 10.240.7.0/25
Config Servers Private 10.240.3.128/26 10.240.7.0/26
VPN Users Private 10.240.3.192/26
Subnet Notes:
* I'm using specified Private IP addresses for all AWS hosts, so that I
can setup firewall rules
on the HQ end of the site-to-site VPN to control traffic flow.
* I want to include the subnet range assigned to remote-user vpn users who
directly VPN into
this VPC via OpenSwan, so that it's clear they are coming from this
source, and I can use the
single high-level VPC CIDR 10.240.0.0/20 to both host and remote-user
traffic where needed.
Using this same technique for remote-user VPNs into other offices
managed by Cisco ASAs.
Routing Tables:
Name Subnets Routes
Public Web Servers A+B (Public) 10.240.0.0/20 -> "local"
0.0.0.0/0 -> IGW (Internet
Gateway)
10.x.0.0/x -> VGW (VPN Gateway,
HQ CIDR)
Private All other subnets (Private) 10.240.0.0/20 -> "local"
0.0.0.0/0 -> "vn01" instance
(VPN/NAT)
10.x.0.0/x -> VGW (VPN Gateway,
HQ CIDR)
Routing Notes:
* This is a pretty standard VPC routing table configuration, with public
subnets routed via
a public route table which has the IGW (Internet Gateway) as it's
default gateway, and private
subnets using the "main" private route table which has an instance
configured to run NAT as
it's default gateway.
* Instead of using the NAT "appliance" which AWS provides, I've built my
own Ubuntu 12.04
instance to run both the NAT and VPN function, to minimize cost. The NAT
functionality basically
boils down to a single masquerade statement in iptables. More on that
below.
* There are a couple of web/proxy servers in the web subnets, one in each
AZ. These have EIPs
associated for inbound traffic.
* There's a single VPN + NAT instance in the Web Server Subnet for AZ A,
which I'll refer to as
host "vn01", which also has an EIP associated.
Security Group notes:
* There's a security group around each pair of servers performing a
specific role.
* There's a security group around the "vn01" VPN/NAT instance, which
allows all traffic from each
of the other security groups, to allow for outbound private network
traffic going through NAT.
* This security group also allows in (for VPN functionality) from
0.0.0.0/0:
TCP 4500
UDP 4500
UDP 500
ESP (50)
VPN/NAT host NAT setup:
* This host runs Ubuntu 12.04 Server
* This host's private IP address is: 10.240.0.4/25 with IGW (default
gateway) 10.240.0.1
* The ufw firewall is installed and setup to start at boot, and allows SSH
initially
* This script snippet shows the actions taken to configure NAT on the vn01
host:
#--------------------------------------------------------------------------
-------------------------
# Configure Networking to allow VPN/NAT Gateway
# - Uncomment IP forwarding, accept/send redirects
sed -i -r -e '/^#net.ipv4.ip_forward/s/^#//' \
-e '/^#net.ipv4.conf.all.accept_redirects/s/^#//' \
-e '/^#net.ipv4.conf.all.send_redirects/s/^#//' \
/etc/sysctl.conf
sysctl -p
# Configure UFW
# - Uncomment IP forwarding
sed -i -r -e '/^#net\/ipv4\/ip_forward/s/^#//' /etc/ufw/sysctl.conf
# Configure ufw to act as outbound NAT gateway
# - Set forward policy to accept
sed -i -e "/DEFAULT_FORWARD_POLICY/s/=.*$/=\"ACCEPT\"/" /etc/default/ufw
# Modify the ufw "before" rules to create the iptables nat table...
# - This sed script inserts the appropriate NAT table rules to perform NAT
# on the VPC CIDR
# - I reverse engineered how this works by studying how the AWS NAT
appliance
# configured IP tables.
cat << EOF > /tmp/ufw_before_$$.sed
/^# Don't delete these required lines, otherwise there will be errors/i\\
# Don't delete these required lines, otherwise there will be errors\\
*nat\\
:POSTROUTING ACCEPT [0:0]\\
# End required lines\\
\\
# Forward traffic from VPC with NAT\\
-A POSTROUTING -s 10.240.0.0/20 -o eth0 -j MASQUERADE\\
\\
# don't delete the 'COMMIT' line or these nat table rules won't be
processed\\
COMMIT\\
EOF
sed -i -f /tmp/ufw_before_$$.sed /etc/ufw/before.rules
rm -f /tmp/ufw_before_$$.sed
# Reload ufw rules
ufw disable
ufw --force enable
#--------------------------------------------------------------------------
-------------------------
Summary of what works at this point:
* Outside of this remote-user VPN, everything works as expected...
* All public hosts can communicate with any internet site as needed, via
ping, http, etc.
* All private hosts can communicate with any internet site as needed, via
ping, http, etc
- in this case via the vn01 VPN/NAT instance. This is per VPC standard
design pattern.
* I'm able to SSH into the vn01 instance, and from there "hop" to any
other instance via SSH
to configure and manage. One main goal of this remote-user VPN, is to
allow direct SSH
access to all hosts, private or public, without having to jump through
this vn01 host, while
the VPN is active.
===========================================================================
=========================
==== Start of Openswan L2TP/Ipsec Configuration
====================================================
===========================================================================
=========================
I've used these references to help me figure out how to set this up (kudos
to the authors!)
-
http://www.cryptocracy.com/blog/2012/05/13/ipsec-slash-l2tp-vpn-server-with
-ubuntu-precise
- http://blog.riobard.com/2010/04/30/l2tp-over-ipsec-ubuntu/
-
http://rootmanager.com/ubuntu-ipsec-l2tp-windows-domain-auth/setting-up-ope
nswan-xl2tpd-with-native-windows-clients-lucid.html
- https://raymii.org/cms/m.php?title=IPSEC_L2TP_VPN_on_ubuntu_12.04
Here's a shell script snippet which shows the actions I've taken to
install and configure
openswan. As above, I'm creating most config documents as "in-line"
document steps, and modifying
existing config files via sed scripts. I can update this email with the
end-result of running the
sed scripts on request:
For those interested, I'm creating the VPC via CloudFormation, and all
this stuff runs via a
UserData script as the vn01 instance is being created and hooked into the
routing tables. Same
for the NAT logic.
#--------------------------------------------------------------------------
-------------------------
# Install openswan
apt-get install -y openswan
# Configure openswan
cat << EOF > /etc/ipsec.conf
version 2.0
config setup
plutoopts="--perpeerlog"
dumpdir=/var/run/pluto/
nat_traversal=yes
virtual_private=%v4:10.240.0.0/20
oe=off
protostack=netkey
include /etc/ipsec.d/*.conf
EOF
cat << EOF > /etc/ipsec.d/l2tp-psk.conf
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3
rekey=no
dpddelay=10
dpdtimeout=90
dpdaction=clear
ikelifetime=8h
keylife=1h
type=transport
left=10.240.0.4
leftsubnet=10.240.0.0/20 <== added later, still doesn't work
with this.
leftprotoport=17/1701
right=%any
rightprotoport=17/%any
EOF
cat << EOF >> /etc/ipsec.secrets
10.240.0.4 %any: PSK "<redacted_long_string>"
EOF
# Confirm IPsec setup
# - showing current output commented out
ipsec verify
# Output from this is:
# Version check and ipsec on-path [OK]
# Linux Openswan U2.6.37/K3.2.0-52-virtual (net key)
# Checking for IPsec support in kernel [OK]
# SAref kernel support [N/A]
# NETKEY: Testing XFRM related proc values [OK]
# [OK]
# [OK]
# Checking that pluto is running [OK]
# Pluto listening for IKE on udp 500 [OK]
# Pluto listening for NAT-T on udp 4500 [OK]
# Checking for 'ip' command [OK]
# Checking /bin/sh is not /bin/dash [WARNING]
# Checking for 'iptables' command [OK]
# Opportunistic Encryption Support [DISABLED]
# Restart openswan to pick up changes
service ipsec restart
# Install xl2tpd
apt-get install -y xl2tpd
# Configure xl2tp
cat << EOF > /etc/xl2tpd/xl2tpd.conf
[global]
ipsec saref = yes
[lns default]
ip range = 10.240.3.200-10.240.3.254
local ip = 10.240.3.196
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
EOF
# Install ppp
apt-get install -y ppp
# Configure ppp
cat << EOF > /etc/ppp/options.xl2tpd
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4
EOF
# Configure test pop users
cat << EOF >> /etc/ppp/chap-secrets
testuser l2tpd <initial_password> *
EOF
# Configure openswan to start on boot
update-rc.d ipsec defaults
# Configure Networking for Openswan
# - This is in addition to the NAT configuration applied to this file
in the NAT section above.
echo '# Extra needed by Openswan' >> /etc/sysctl.conf
echo 'net.ipv4.conf.default.accept_redirects=0' >> /etc/sysctl.conf
echo 'net.ipv4.conf.default.send_redirects=0' >> /etc/sysctl.conf
sysctl -p
# Configure ufw firewall to allow IPsec and L2TP traffic
# - We can use standard statements to allow the NAT-T traffic
# - But we must edit the before.rules to restrict L2TP to over Ipsec
# - The statement for this is inserted via the sed script below
ufw allow 500/udp
ufw allow 4500
cat << EOF > /tmp/ufw_before_$$.sed
/^-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT/a\\
\\
# Allow L2TP only over IPSEC\\
-A ufw-before-input -m policy --dir in --pol ipsec -p udp --dport 1701 -j
ACCEPT
EOF
sed -i -f /tmp/ufw_before_$$.sed /etc/ufw/before.rules
rm -f /tmp/ufw_before_$$.sed
# Restart ufw to pick up changes
ufw disable
ufw --force enable
#--------------------------------------------------------------------------
-------------------------
Here's what works at this point:
* I have configured standard "L2TP over IPSec" VPN on a Mac running Mac
OSX 10.8.4 with this VPN
configuration, using the Public EIP associated with the "vn01" VPN/NAT
instance.
* I've done the same with most recent IOS on an iPad.
* In both cases, the VPN is connecting, and I'm showing log activity which
indicates it's working.
* On the Mac, I show the provided IP address as 10.240.3.200, the first
address in the range
I've configured, as expected, and the IP address of the Router as
10.240.3.196, also as expected.
* Here's the relevant sections of the Mac's routing table:
Destination Gateway Flags Refs Use Netif My Comments
------------ ------------ ----- ---- --- -----
-------------------------------
default 10.0.1.1 UGSc 262 0 en1
default 10.240.3.196 UGScI 1 0 ppp0
. . .
10.240.3/24 ppp0 Usc 1 0 ppp0 What configured
this as a /24?
10.240.3.196 10.240.3.200 Uhr 2 0 ppp0
* I can ssh into all hosts which fall within this 10.240.3/24 route,
meaning hosts on the subnets
10.240.3.0/25 and 10.240.3.128/26
* I cannot ssh into any hosts outside this route, such as a host on the
10.240.1.0/25 subnet.
Summary of help needed:
* I'm thinking this must be simple, probably missing one line to tell the
client end that the
route it should use must be bigger, to use 10.240.0.0/20 instead of
10.240.3.0/24, but I can't
seem to find any documentation which describes how to do this. Hopefully
an expert on this list
can help me get this last bit working.
* At that point, I think this configuration may be useful to many others,
as I've seen many
references on Google from people attempting to get something similar to
this to work.
Thanks in advance for any help!
--
Michael Crawford
More information about the Users
mailing list