Archive
Blog - Technical - posts for September 2014
Sep 01 2014
Tunnelling through the Internet
As mentioned in the previous post, I'm writing down some details concerning setting up a VPN, which can occasionally be quite useful, whether it be due to accessing the Internet from an insecure location or due to working around region restrictions. As before, I'm using Libreswan, along with xl2tpd and ppp. I'm also using winbind (part of the Samba project) in order to authenticate against a Windows domain.
VPN
Bits and pieces taken from this page.
As with the subnet-to-subnet configuration, you'll need to put the Libreswan repository file in /etc/yum.repos.d, put the the Libreswan GPG key in /etc/pki/rpm-gpg, and install the Fedora Extra Packages for Enterprise Linux 6 RPM. At this point, you can install the packages you need to move forward:
There are more moving pieces this time through, so the configuration is a bit more involved. Our example uses the following assumptions:
Libreswan
Configure /etc/ipsec.conf as noted in the previous article. We'll set up another configuration file for the dialin VPN, /etc/ipsec.d/dialin.conf. For the sake of simplicity (and compatibility), we'll do a pre-shared key (PSK) configuration:
# We're using a PSK for now.
authby=secret
# Add the VPN type, but don't start it (since clients will be initiating connections).
auto=add
forceencaps=yes
ike_frag=yes
# The outside-facing IP.
left=1.2.3.4
leftid=@left.internal
leftsubnet=0.0.0.0/0
right=%any
rightsubnet=0.0.0.0/0
# The internal DNS server's IP.
modecfgdns1=192.168.0.100
modecfgpull=yes
pfs=no
rekey=no
To define the PSK, create /etc/ipsec.d/dialin.secrets:
1.2.3.4 %any : PSK "pre-shared key"
As before, you can be paranoid with the secrets file:
$ chmod 0600 /etc/ipsec.d/*.secrets
And the same additional lines to /etc/sysctl.conf apply here:
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
Along with the verification step:
xl2tpd/ppp
xl2tpd and ppp are intertwined, so their configuration happens pretty much at the same time. Set up your /etc/xl2tpd/xl2tpd.conf roughly as follows, adjusting for the configuration above:
listen-addr = 1.2.3.4
[lns default]
ip range = 192.168.0.90-192.168.0.99
local ip = 192.168.0.1
require chap = yes
refuse pap = yes
require authentication = yes
name = l2tpd
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
For now, set up /etc/ppp/options.xl2tpd as follows:
ipcp-accept-remote
ms-dns 192.168.0.200
noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
lock
proxyarp
connect-delay 5000
Set up usernames and passwords in /etc/ppp/chap-secrets, one per line (replace $username and $password as appropriate):
iptables
As before, there need to be additional entries in the iptables configuration:
-N ICMPALL
# Set up a rejection bucket.
-N ZREJ
# Using connection tracking, accept packets we already know about.
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Trust the local network; you can choose to have more restrictive rules than this.
-A INPUT -i eth1 -j ACCEPT
-A INPUT -i ppp+ -j ACCEPT
-A FORWARD -i eth1 -j ACCEPT
-A FORWARD -i ppp+ -j ACCEPT
# Treat ICMP packets specially.
-A INPUT -p icmp -m icmp --icmp-type any -j ICMPALL
# Allow new connections to be made to ports 500 (IKE) and 4500 (IKE NAT-Traversal), both for Libreswan.
-A INPUT -p udp -m conntrack --ctstate NEW -m multiport --dports 500,4500 -j ACCEPT
# Allow connections to port 1701 (L2TP) for Libreswan.
-A INPUT -p udp -m udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT
-A INPUT -p udp -m udp --dport 1701 -j DROP
# Goes at the bottom of the INPUT section: reject all other packets.
-A INPUT -j ZREJ
# Only forward connections we know about from the "outside" to the "inside," using built-in connection tracking.
-A FORWARD -i eth0 -o eth1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o ppp+ -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Forward valid IPsec packets.
-A FORWARD -m policy --dir in --pol ipsec -j ACCEPT
# Goes at the bottom of the FORWARD section: reject all other packets.
-A FORWARD -j ZREJ
# Reject fragmented packets.
-A ICMPALL -p icmp -f -j DROP
# Accept: echo reply
-A ICMPALL -p icmp -m icmp --icmp-type 0 -j ACCEPT
# Accept: destination unreachable
-A ICMPALL -p icmp -m icmp --icmp-type 3 -j ACCEPT
# Accept: source quench
-A ICMPALL -p icmp -m icmp --icmp-type 4 -j ACCEPT
# Accept: echo
-A ICMPALL -p icmp -m icmp --icmp-type 8 -j ACCEPT
# Accept: time exceeded
-A ICMPALL -p icmp -m icmp --icmp-type 11 -j ACCEPT
# Drop all other ICMP packets.
-A ICMPALL -p icmp -j DROP
# Reject packet types as appropriate.
-A ZREJ -p tcp -j REJECT --reject-with tcp-reset
-A ZREJ -p udp -j REJECT --reject-with icmp-port-unreachable
-A ZREJ -j REJECT --reject-with icmp-proto-unreachable
Testing the VPN
At this point, you can set up the VPN from a client, with the following settings:
- Host: 1.2.3.4
- Type: L2TP/IPsec
- Pre-shared key (not a certificate): the key defined above
- Protocol: CHAP (not MS-CHAP v2)
- Username: a username defined above
- Password: a password defined above
You should be able to connect successfully, and connect to systems within the internal network at this point. If you are using a Windows system behind a NAT, you may need to set a registry setting and reboot your system prior to being able to connect to the VPN.
Connecting to a Windows domain
The way pppd works on Linux, authenticating against LDAP involves connecting the ppp daemon to RADIUS, then allowing RADIUS to validate credentials against LDAP. Unfortunately, RADIUS performs the validation itself, so it requires authenticating against the VPN server with PAP and storing plaintext passwords within LDAP, which is less than ideal. There is, however, a provision to allow pppd to authenticate against a Windows domain.
First, install winbind:
Set up your /etc/samba/smb.conf with the appropriate information (change the following settings to match those for your own domain):
# Must be all capitals. Adjust to your domain's NetBIOS name.
workgroup = INTERNAL
# Adjust to your system's desired NetBIOS name.
netbios name = VPN
interfaces = lo eth1
bind interfaces only = true
security = ads
# Must be all capitals. Adjust to your domain's FQDN.
realm = INTERNAL.LOCAL
# Set to your domain's PDC.
password server = pdc.internal.local pdc
winbind uid = 500-20000
winbind gid = 500-20000
winbind enum users = yes
winbind enum groups = yes
winbind use default domain = yes
Then, there are several commands to complete the domain setup:
$ service winbind restart
# Join the system to the domain.
$ net ads join -U Administrator
# See whether it's joined.
$ net ads testjoin
# Verify that it's joined by displaying the user list.
$ wbinfo -u
You can clear out the entries from /etc/ppp/chap-secrets, as you won't be using the passwords stored in a text file. Update the following settings in /etc/xl2tpd/xl2tpd.conf:
; require chap = yes
refuse chap = yes
And the following settings in /etc/ppp/options.xl2tpd:
ms-dns 10.0.0.250
# Add these lines.
require-mschap-v2
require-mppe-128
plugin winbind.so
# Set the following line with the group that controls the list of VPN users.
ntlm_auth-helper '/usr/bin/ntlm_auth --helper-protocol=ntlm-server-1 --require-membership-of="INTERNAL\\VPN Users"'
If you have SELinux enabled, you'll need to generate a policy to allow ntlm_auth to run. You can follow the instructions on this page to figure out how to do so. Your template file should look something like this:
require {
type pppd_t;
type winbind_helper_exec_t;
class file { read execute open getattr execute_no_trans };
}
#============= pppd_t ==============
allow pppd_t winbind_helper_exec_t:file execute_no_trans;
#!!!! This avc is allowed in the current policy
allow pppd_t winbind_helper_exec_t:file { read execute open getattr };
The end of the line
Ideally, we would go through and implement user authentication via domain username and password (as above) with machine authentication via certificates. Unfortunately, at least one of the targeted operating systems doesn't support machine certificates for L2TP/IPsec, so there isn't too much value in pursuing it further.