Difference between revisions of "Virtual Private Networks"

From YobiWiki
Jump to navigation Jump to search
m (Reverted edits by Etegohy (Talk) to last revision by PhilippeTeuwen)
 
(17 intermediate revisions by 2 users not shown)
Line 47: Line 47:
 
SOURCE=$1
 
SOURCE=$1
 
DEV=$2
 
DEV=$2
  +
# establishing Source NATing (hiding source address)
 
/sbin/iptables -t nat -A POSTROUTING -s $SOURCE -d 0.0.0.0/0 -j SNAT --to-source=<ext_ip>
 
/sbin/iptables -t nat -A POSTROUTING -s $SOURCE -d 0.0.0.0/0 -j SNAT --to-source=<ext_ip>
  +
# allowing explicitely to forward traffic from NATed interface in Netfilter (not needed if your policy allows all by default)
 
/sbin/iptables -I FORWARD -i <ext_if> -o $DEV -m state --state ESTABLISHED,RELATED -j ACCEPT
 
/sbin/iptables -I FORWARD -i <ext_if> -o $DEV -m state --state ESTABLISHED,RELATED -j ACCEPT
 
/sbin/iptables -I FORWARD -i $DEV -o <ext_if> -j ACCEPT
 
/sbin/iptables -I FORWARD -i $DEV -o <ext_if> -j ACCEPT
Line 80: Line 82:
 
</pre>
 
</pre>
 
It will start at boot time, for a first try: /etc/init.d/openvpn start
 
It will start at boot time, for a first try: /etc/init.d/openvpn start
  +
  +
'''UPDATE:''' after an upgrade on client side, I had troubles overwriting my default gateway with the tunnel one, I had to change this line in the server config:
  +
push "redirect-gateway"
  +
=>
  +
push "redirect-gateway def1"
  +
  +
With option ifconfig-pool-persist, clients will always get the same IP.
  +
<br>IPs are stored in /etc/openvpn/ipp.txt
  +
<br>You can modify IP attributions by editing the file after having stopped the openvpn daemon, this is very important otherwise openvpn will overwrite your changes when it's stopped.
   
 
====Setup on a Windows client====
 
====Setup on a Windows client====
Line 117: Line 128:
 
up /etc/openvpn/domain.up
 
up /etc/openvpn/domain.up
 
plugin /usr/lib/openvpn/openvpn-down-root.so /etc/openvpn/domain.down
 
plugin /usr/lib/openvpn/openvpn-down-root.so /etc/openvpn/domain.down
  +
# this is required for new openvpn versions >= 2.1~rc9
  +
script-security 2
 
Create /etc/openvpn/domain.up and make it executable:
 
Create /etc/openvpn/domain.up and make it executable:
 
<pre>
 
<pre>
Line 137: Line 150:
 
</pre>
 
</pre>
 
If you are not using Debian, see http://forums.gentoo.org/viewtopic-t-233080.html#1655552
 
If you are not using Debian, see http://forums.gentoo.org/viewtopic-t-233080.html#1655552
  +
 
=== Setup of a VPN server in a vserver===
 
=== Setup of a VPN server in a vserver===
 
*cf http://linux-vserver.org/Frequently_Asked_Questions#Can_I_run_an_OpenVPN_Server_in_a_guest.3F
 
*cf http://linux-vserver.org/Frequently_Asked_Questions#Can_I_run_an_OpenVPN_Server_in_a_guest.3F
  +
*You've to use persistent tun/tap, cf [[Vserver administration]]
 
*You cannot dynamically modify iptables, this has to be done on the host.
 
*You cannot dynamically modify iptables, this has to be done on the host.
 
*You've to create manually /dev/net/tun in the vserver:
 
*You've to create manually /dev/net/tun in the vserver:
 
cd <vserver>/dev; ./MAKEDEV tun
 
cd <vserver>/dev; ./MAKEDEV tun
  +
*I had also to give NET_ADMIN [http://linux-vserver.org/Capabilities_and_Flags capability] to the vserver
  +
echo NET_ADMIN >> /etc/vservers/<vserver>/bcapabilities
  +
=== Using CACert certificates with OpenVPN===
  +
Instead of creating your own CA you can rely on e.g. the CACert one.
  +
====Server side====
  +
Create a server certificate and get it signed by CACert
  +
<br>server.conf will contain:
  +
ca /etc/openvpn/CAcert_chain.pem
  +
cert /etc/openvpn/your_server.pem
  +
key /etc/openvpn/your_privatekey.pem
  +
tls-verify /etc/openvpn/verify-cn
  +
We don't want to accept ALL CACert signed certificate therefore verify-cn is a little script which is called every time to check a client certificat, cf man openvpn:
  +
--tls-verify cmd
  +
Execute shell command cmd to verify the X509 name of a pending TLS
  +
connection that has otherwise passed all other tests of certifica-
  +
tion (except for revocation via --crl-verify directive; the revoca-
  +
tion test occurs after the --tls-verify test).
  +
  +
cmd should return 0 to allow the TLS handshake to proceed, or 1 to fail. cmd is executed as
  +
  +
cmd certificate_depth X509_NAME_oneline
  +
[{{#file:verify-cn}} verify-cn]:
  +
<source lang=bash>
  +
#!/bin/bash
  +
  +
# clients file must contain one client subject per line (grep regexp actually)
  +
  +
logfile=/etc/openvpn/verify-cn.log
  +
clients=/etc/openvpn/verify-cn.allow
  +
  +
CA="/O=Root_CA/OU=http://www.cacert.org/CN=CA_Cert_Signing_Authority/emailAddress=support@cacert.org"
  +
  +
case "$1" in
  +
1)
  +
[ "$2" == "$CA" ] && exit 0
  +
;;
  +
0)
  +
echo $2 | grep -q -f $clients && exit 0;
  +
;;
  +
esac
  +
  +
echo "$(date +%Y%m%d-%H%M%S) FAILED: $*" >> $logfile
  +
exit 1
  +
</source>
  +
Example of verify_cn.allow:
  +
/CN=CAcert_WoT_User/emailAddress=my@email.org
  +
  +
====Client side====
  +
Create a client certificate and get it signed by CACert
  +
<br>openvpn connection .conf will contain:
  +
ca /etc/openvpn/cacerts/CAcert_chain.pem
  +
cert /etc/openvpn/certs/my@email.org.crt.pem
  +
key /etc/openvpn/private/my@email.org.key.pem
  +
tls-remote /CN=myvpn.mydomain.be
  +
#Fails on CACert certificates:
  +
#ns-cert-type server
  +
We don't want to accept ALL CACert signed certificate for the servers therefore we use the --tls-remote option and we specify the subject line of the server certificate we expect.
  +
<br>Note that normally specifying the common_name instead of the subject line should be enough but this does not work on CACert certificates, cf my [http://bugs.debian.org/483472 bugreport]
  +
<br>Note that we cannot use the --ns-cert-type option anymore as it also fails on CACert certificates, cf my other [http://bugs.debian.org/483473 bugreport]
  +
===OpenVPN on a Linksys WRT54GL===
  +
See [http://www.dd-wrt.com/wiki/index.php/OpenVPN OpenVPN with dd-wrt] and [http://www.dd-wrt.com/wiki/index.php/VPN_%28the_easy_way%29_v24%2B the easy way]
  +
  +
[http://www.cs.wustl.edu/~jain/cse567-08/ftp/ovpn/index.html Performances]: ''The largest bandwidth of 8.87 Mbps is measured for the TAP interface with bridging using the UDP transport protocol for the tunnel and no encryption. The bandwidth is cut to less than half to 3.70 Mbps when encryption using AES 256-bit is enabled'' And once using AES256, it doesn’t really matter if you’re doing TAP over UDP or TCP (except latency +10ms if you care).
  +
  +
So this requires installing dd-wrt on your WRT54GL.
  +
<br>My personal experience:
  +
* There was already an openwrt White Russian RC6 on it of which I couldn't remember the password
  +
** Set a fixed IP such as 192.168.1.10
  +
** <pre>tcpdump -nAi eth0 port 4919 and udp</pre>
  +
** power-cycle the router and watch for a UDP packet with sth like "Press reset now to enter failsafe mode"
  +
** Immediately press the reset button for 2 secs, you should see another UDP packet "Entering failsafe mode"
  +
** <pre>telnet 192.168.1.1</pre>
  +
** <pre>mount_root</pre>
  +
** <pre>passwd</pre>
  +
** power-cycle the router
  +
** Now you can access the web interface and go to the firmware upgrade page
  +
* I flashed it with dd-wrt.v24_mini_generic.bin (v24 preSP2 [Beta] Build 13064)
  +
* It rebooted itself, prompting for a new admin user/pwd
  +
* I flashed it again from the new dd-wrt web interface, with dd-wrt.v24_vpn_generic.bin (v24 preSP2 [Beta] Build 13064), with reset to defaults
  +
* It rebooted itself, prompting for a new admin user/pwd
  +
So I didn't use any hard reset 30/30/30 cycle, your mileage may vary.
   
 
==[http://vtun.sourceforge.net/ vtun]==
 
==[http://vtun.sourceforge.net/ vtun]==

Latest revision as of 21:33, 24 November 2010

OpenVPN

Intro

Setup of a VPN server for multiple dynamic clients with certificates

Thanks to Thierry Walrant for his contribution!

Characteristics of this setup

  • Ethernet tunneling (tap) over TCP port 1194
  • Full redirection of the traffic (redirection of the default gateway and DNS server), NATed by server towards Internet
  • Security by certificates
  • Works with Linux or Windows clients
  • Dynamic handling (à la DHCP) of the clients
  • Allows other ipsec VPN softwares to run on top (e.g. enterprise ipsec VPN for Windows)

Setup of the Certificate Authority (CA)

The CA should be another computer than the server!

cp -a /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn
cd /etc/openvpn/easy-rsa

Edit the file called vars and adapt the last KEY_xxx vars to your needs

. vars
./clean-all
./build-ca

To create a certificate and sign it in one single step (do that only if the certificate can be transferred to the client via a secure channel, otherwise generate the certificate and the request on the client and sign it on the CA), without password:

  • For the server, use (don't forget to give a Common Name):
./build-key-server server-cert
  • For a client: (don't forget to give a Common Name)
./build-key client-cert

For other situations, see easy-rsa/README.gz
To see content of a certificate:

openssl x509 -in cert.crt -text

Setup on the Linux server

Setup of ip forward

  • Uncomment the following line in /etc/sysctl.conf
net/ipv4/ip_forward=1
  • To try immediately
echo 1 >/proc/sys/net/ipv4/ip_forward

Import the server certificate and its key (securely!) as well as the CA certificate

  • CA:/etc/openvpn/easy-rsa/keys/ca.crt -> server:/etc/openvpn/ca.crt
  • CA:/etc/openvpn/easy-rsa/keys/server-cert.crt -> server:/etc/openvpn/server-cert.crt
  • CA:/etc/openvpn/easy-rsa/keys/server-cert.key -> server:/etc/openvpn/server-cert.key

Create the DH keys via etc-rsa/build-dh or directly with

openssl dhparam -out dh2048.pem 2048

Create /etc/openvpn/iptables.up and make it executable:

#!/bin/sh
SOURCE=$1
DEV=$2
# establishing Source NATing (hiding source address)
/sbin/iptables -t nat -A POSTROUTING -s $SOURCE -d 0.0.0.0/0 -j SNAT --to-source=<ext_ip>
# allowing explicitely to forward traffic from NATed interface in Netfilter (not needed if your policy allows all by default)
/sbin/iptables -I FORWARD -i <ext_if> -o $DEV -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -I FORWARD -i $DEV -o <ext_if> -j ACCEPT

Create /etc/openvpn/iptables.down and make it executable:

#!/bin/sh
SOURCE=$1
DEV=$2
/sbin/iptables -D FORWARD -i $DEV -o <ext_if> -j ACCEPT
/sbin/iptables -D FORWARD -i <ext_if> -o $DEV -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -t nat -D POSTROUTING -s $SOURCE -d 0.0.0.0/0 -j SNAT --to-source=<ext_ip>

Create /etc/openvpn/server.conf:

proto tcp
dev tap0
ca                    /etc/openvpn/ca.crt
cert                  /etc/openvpn/server-cert.crt
key                   /etc/openvpn/server-cert.key
dh                    /etc/openvpn/dh2048.pem
server                172.16.0.0 255.255.0.0
ifconfig-pool-persist /etc/openvpn/ipp.txt
push                  "redirect-gateway"
push                  "dhcp-option DNS <primary_DNS>"
push                  "dhcp-option DNS <secondary_DNS>"
keepalive             10 120
comp-lzo
max-clients           10
status                /var/log/openvpn-status.log
verb                  3
mute                  20
up                    "/etc/openvpn/iptables.up 172.16.0.0/16"
down                  "/etc/openvpn/iptables.down 172.16.0.0/16"

It will start at boot time, for a first try: /etc/init.d/openvpn start

UPDATE: after an upgrade on client side, I had troubles overwriting my default gateway with the tunnel one, I had to change this line in the server config:

push                  "redirect-gateway"

=>

push                  "redirect-gateway def1"

With option ifconfig-pool-persist, clients will always get the same IP.
IPs are stored in /etc/openvpn/ipp.txt
You can modify IP attributions by editing the file after having stopped the openvpn daemon, this is very important otherwise openvpn will overwrite your changes when it's stopped.

Setup on a Windows client

  • Download the windows installer and run it.
  • You can try the GUI

Setup on a Linux client

To avoid automatic starting of the tunnel at boot time, edit /etc/default/openvpn:

AUTOSTART="none"

Bring the needed certificate files in e.g.:

  • /etc/openvpn/cacerts/cacert.pem
  • /etc/openvpn/certs/openvpn-myclient.crt.pem
  • /etc/openvpn/private/openvpn-myclient.key.pem

Give read access to them only to root, especially the key file!
Create a configuration file to join the server "myserver": /etc/openvpn/myserver.conf
See the howto for an explanation of the different options.

client
proto                 tcp
remote                <IP_or_FQDN_of_myserver> 1194
dev                   tap
resolv-retry          infinite
nobind
http-proxy-retry
http-proxy            <local_http_proxy_we_have_to_passthrough> <proxy_port>
ca                    /etc/openvpn/cacerts/cacert.pem
cert                  /etc/openvpn/certs/openvpn-myclient.crt.pem
key                   /etc/openvpn/private/openvpn-myclient.key.pem
ns-cert-type          server
comp-lzo
verb                  3
status                /var/log/openvpn.log

To run it manually

/etc/init.d/openvpn start myserver

There is no automatic redefinition of the DNS servers under Linux, so we need a little trick (as seen here):
Be sure to have the resolvconf package.
Add the following to the config file of the client:

up /etc/openvpn/domain.up
plugin /usr/lib/openvpn/openvpn-down-root.so /etc/openvpn/domain.down
# this is required for new openvpn versions >= 2.1~rc9
script-security       2

Create /etc/openvpn/domain.up and make it executable:

#!/bin/sh
# really naff script to add nameserver entry on up
DEV=$1
set | sed -n "
s/^foreign_option_.* DNS \(.*\)'/nameserver \1/; T next; p;
:next; s/^foreign_option_.* DOMAIN \(.*\)'/domain \1/; T; p;
" | resolvconf -a $DEV
resolvconf -u

Create /etc/openvpn/domain.down and make it executable:

#!/bin/sh
# really naff script to delete nameserver entry on down
DEV=$1
resolvconf -d $DEV
resolvconf -u

If you are not using Debian, see http://forums.gentoo.org/viewtopic-t-233080.html#1655552

Setup of a VPN server in a vserver

cd <vserver>/dev; ./MAKEDEV tun
  • I had also to give NET_ADMIN capability to the vserver
echo NET_ADMIN >> /etc/vservers/<vserver>/bcapabilities

Using CACert certificates with OpenVPN

Instead of creating your own CA you can rely on e.g. the CACert one.

Server side

Create a server certificate and get it signed by CACert
server.conf will contain:

ca                    /etc/openvpn/CAcert_chain.pem
cert                  /etc/openvpn/your_server.pem
key                   /etc/openvpn/your_privatekey.pem
tls-verify            /etc/openvpn/verify-cn

We don't want to accept ALL CACert signed certificate therefore verify-cn is a little script which is called every time to check a client certificat, cf man openvpn:

 --tls-verify cmd
             Execute  shell  command cmd to verify the X509 name of a pending TLS
             connection that has otherwise passed all other tests  of  certifica-
             tion  (except for revocation via --crl-verify directive; the revoca-
             tion test occurs after the --tls-verify test).

             cmd should return 0 to allow the TLS handshake to proceed, or  1  to fail.  cmd is executed as

             cmd certificate_depth X509_NAME_oneline

[{{#file:verify-cn}} verify-cn]:

#!/bin/bash 

# clients file must contain one client subject per line (grep regexp actually)

logfile=/etc/openvpn/verify-cn.log
clients=/etc/openvpn/verify-cn.allow

CA="/O=Root_CA/OU=http://www.cacert.org/CN=CA_Cert_Signing_Authority/emailAddress=support@cacert.org"

case "$1" in
    1)
        [ "$2" == "$CA" ] && exit 0
    ;;
    0)
        echo $2 | grep -q -f $clients && exit 0;
    ;;
esac

echo "$(date +%Y%m%d-%H%M%S) FAILED: $*" >> $logfile
exit 1

Example of verify_cn.allow:

/CN=CAcert_WoT_User/emailAddress=my@email.org

Client side

Create a client certificate and get it signed by CACert
openvpn connection .conf will contain:

ca                    /etc/openvpn/cacerts/CAcert_chain.pem
cert                  /etc/openvpn/certs/my@email.org.crt.pem
key                   /etc/openvpn/private/my@email.org.key.pem
tls-remote            /CN=myvpn.mydomain.be
#Fails on CACert certificates:
#ns-cert-type          server

We don't want to accept ALL CACert signed certificate for the servers therefore we use the --tls-remote option and we specify the subject line of the server certificate we expect.
Note that normally specifying the common_name instead of the subject line should be enough but this does not work on CACert certificates, cf my bugreport
Note that we cannot use the --ns-cert-type option anymore as it also fails on CACert certificates, cf my other bugreport

OpenVPN on a Linksys WRT54GL

See OpenVPN with dd-wrt and the easy way

Performances: The largest bandwidth of 8.87 Mbps is measured for the TAP interface with bridging using the UDP transport protocol for the tunnel and no encryption. The bandwidth is cut to less than half to 3.70 Mbps when encryption using AES 256-bit is enabled And once using AES256, it doesn’t really matter if you’re doing TAP over UDP or TCP (except latency +10ms if you care).

So this requires installing dd-wrt on your WRT54GL.
My personal experience:

  • There was already an openwrt White Russian RC6 on it of which I couldn't remember the password
    • Set a fixed IP such as 192.168.1.10
    • tcpdump -nAi eth0 port 4919 and udp
    • power-cycle the router and watch for a UDP packet with sth like "Press reset now to enter failsafe mode"
    • Immediately press the reset button for 2 secs, you should see another UDP packet "Entering failsafe mode"
    • telnet 192.168.1.1
    • mount_root
    • passwd
    • power-cycle the router
    • Now you can access the web interface and go to the firmware upgrade page
  • I flashed it with dd-wrt.v24_mini_generic.bin (v24 preSP2 [Beta] Build 13064)
  • It rebooted itself, prompting for a new admin user/pwd
  • I flashed it again from the new dd-wrt web interface, with dd-wrt.v24_vpn_generic.bin (v24 preSP2 [Beta] Build 13064), with reset to defaults
  • It rebooted itself, prompting for a new admin user/pwd

So I didn't use any hard reset 30/30/30 cycle, your mileage may vary.

vtun

Older and with less features than openvpn but very easy to use for basic tunneling (tun or tap)

  • apt-get install vtun
  • transport is done over tcp or udp, default port 5000