Friday, June 28, 2013

OpenVPN server setup on Raspberry Pi

Note: it is for bridge mode only


I found that Raspberry Pi is a good choice for setup OpenVPN server. I can always power on it as the power consumption is low. After setting it up, I can connect VPN to home in office or cafe outside. 

You may think port forwarding by router or via SSH is good enough. However, there are limitations when:
  1. there are lots of services you want to connect from outsider, then your port forwarding rules will be massive
  2. as the OpenVPN client can reconnect automatically, I can have a relative stable connection. Sometimes you would like to have a reserve connect from server to client. My own experience is that in my previous company, I setup OpenVPN client in office and connect to my home, leave the connection alive. Then when I go home I can reconnect to my office PC by remote desktop :)

Objective

  • Internal network: 192.168.28.0/24
  • Setup a OpenVPN server such that client connection will connect to the server and assign a 192.168.28.0/24 IP as if it is within the internal network
  • necessary install
    apt-get install  bridge-utils openvpn 

 

easy_rsa

easy_rsa is a tool to manage keys and certs. It is bundled in eariler version but now it is put in github (https://github.com/OpenVPN/easy-rsa) for latest version
Basic setup:
  1. under the easy_rsa directory (/usr/share/doc/openvpn/examples/easy-rsa , or anywhere for latest version), make a copy of the 2.0. (say, dummy)
    cp -pr 2.0 dummy
  2. in dummy directory, edit "vars". KEY_SIZE can be 1024 or 2048 bits, but 2048 is more secure but it will draw more computation power. Also those KEY_* can be resued when generating keys. it is recommend to preset it here ( and yes, I'm from Hong Kong):
    export KEY_SIZE=2048
    
    # In how many days should the root CA key expire?
    export CA_EXPIRE=3650
    
    # In how many days should certificates expire?
    export KEY_EXPIRE=3650
    
    # These are the default values for fields
    # which will be placed in the certificate.
    # Don't leave any of these fields blank.
    export KEY_COUNTRY="HK"
    export KEY_PROVINCE="HKSAR"
    export KEY_CITY="Hong Kong"
    export KEY_ORG="myorg"
    export KEY_EMAIL="mymail.com"
    #export KEY_EMAIL=mail@host.domain
    export KEY_CN=vpn.dummy.fqdn
    export KEY_NAME=vpn.dummy
    export KEY_OU=vpn
    export PKCS11_MODULE_PATH=changeme
    export PKCS11_PIN=1234
  3. source the file
    # . vars
    NOTE: If you run ./clean-all, I will be doing a rm -rf on /usr/share/doc/openvpn/examples/easy-rsa/dummy/keys
    # ./clean-all
  4. Build the CA. When finished, ca.crt and ca.key will be built in "keys" directory
    # ./build-ca
    Generating a 2048 bit RSA private key
    ........................................+++
    ..................+++
    writing new private key to 'ca.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [HK]:
    State or Province Name (full name) [HKSAR]:
    Locality Name (eg, city) [Hong Kong]:
    Organization Name (eg, company) [myorg]:
    Organizational Unit Name (eg, section) [vpn]:
    Common Name (eg, your name or your server's hostname) [vpn.dummy.fqdn]:
    Name [vpn.dummy]:
    Email Address [mymail.com]:
  5. Build server key
    # ./build-key-server server
    Generating a 2048 bit RSA private key
    ..........................+++
    ...+++
    writing new private key to 'server.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [HK]:
    State or Province Name (full name) [HKSAR]:
    Locality Name (eg, city) [Hong Kong]:
    Organization Name (eg, company) [myorg]:
    Organizational Unit Name (eg, section) [vpn]:
    Common Name (eg, your name or your server's hostname) [server]:
    Name [vpn.dummy]:
    Email Address [mymail.com]:
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/dummy/openssl-1.0.0.cnf
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    countryName           :PRINTABLE:'HK'
    stateOrProvinceName   :PRINTABLE:'HKSAR'
    localityName          :PRINTABLE:'Hong Kong'
    organizationName      :PRINTABLE:'myorg'
    organizationalUnitName:PRINTABLE:'vpn'
    commonName            :PRINTABLE:'server'
    name                  :PRINTABLE:'vpn.dummy'
    emailAddress          :IA5STRING:'mymail.com'
    Certificate is to be certified until Jun 26 04:18:32 2023 GMT (3650 days)
    Sign the certificate? [y/n]:y
    
    1 out of 1 certificate requests certified, commit? [y/n]y
    Write out database with 1 new entries
    Data Base Updated
  6. Build a client key (for testing)
    # ./build-key c1
    Generating a 2048 bit RSA private key
    ...........................................................+++
    ...............................+++
    writing new private key to 'c1.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [HK]:
    State or Province Name (full name) [HKSAR]:
    Locality Name (eg, city) [Hong Kong]:
    Organization Name (eg, company) [myorg]:
    Organizational Unit Name (eg, section) [vpn]:
    Common Name (eg, your name or your server's hostname) [c1]:
    Name [vpn.dummy]:
    Email Address [mymail.com]:
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/dummy/openssl-1.0.0.cnf
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    countryName           :PRINTABLE:'HK'
    stateOrProvinceName   :PRINTABLE:'HKSAR'
    localityName          :PRINTABLE:'Hong Kong'
    organizationName      :PRINTABLE:'myorg'
    organizationalUnitName:PRINTABLE:'vpn'
    commonName            :PRINTABLE:'c1'
    name                  :PRINTABLE:'vpn.dummy'
    emailAddress          :IA5STRING:'mymail.com'
    Certificate is to be certified until Jun 26 04:20:55 2023 GMT (3650 days)
    Sign the certificate? [y/n]:y
    
    
    1 out of 1 certificate requests certified, commit? [y/n]y
    Write out database with 1 new entries
    Data Base Updated
  7. Build DH
    # ./build-dh
    Generating DH parameters, 2048 bit long safe prime, generator 2
    This is going to take a long time
    ..............................................+..............................................................................................................................................................................................................................................................................+...............+................................................................................................................................................................................................................................................................+................................................................................................................+........................................................................+........................+.....................+..................................................++*++*
  8. All following files should be generated under keys directory:
    # ls -tlra keys
    drwxr-xr-x 4 root root 4096 Jun 28 12:12 ..
    -rw------- 1 root root 1704 Jun 28 12:13 ca.key
    -rw-r--r-- 1 root root 1692 Jun 28 12:13 ca.crt
    -rw------- 1 root root 1704 Jun 28 12:18 server.key
    -rw-r--r-- 1 root root 1058 Jun 28 12:18 server.csr
    -rw-r--r-- 1 root root    3 Jun 28 12:18 serial.old
    -rw-r--r-- 1 root root  119 Jun 28 12:18 index.txt.old
    -rw-r--r-- 1 root root   21 Jun 28 12:18 index.txt.attr.old
    -rw-r--r-- 1 root root 5409 Jun 28 12:18 server.crt
    -rw-r--r-- 1 root root 5409 Jun 28 12:18 01.pem
    -rw------- 1 root root 1704 Jun 28 12:20 c1.key
    -rw-r--r-- 1 root root 1054 Jun 28 12:20 c1.csr
    -rw-r--r-- 1 root root    3 Jun 28 12:21 serial
    -rw-r--r-- 1 root root   21 Jun 28 12:21 index.txt.attr
    -rw-r--r-- 1 root root  234 Jun 28 12:21 index.txt
    -rw-r--r-- 1 root root 5279 Jun 28 12:21 c1.crt
    -rw-r--r-- 1 root root 5279 Jun 28 12:21 02.pem
    -rw-r--r-- 1 root root  424 Jun 28 12:54 dh2048.pem

Key Files

Now we will find our newly-generated keys and certificates in the keys subdirectory. Here is an explanation of the relevant files:
Filename
Needed By
Purpose
copy to
ca.crt
server + all clients
Root CA certificate
server:/etc/openvpn, client
ca.key
key signing machine only
Root CA key
server:/etc/openvpn
dh2048.pem
server only
Diffie Hellman parameters
server:/etc/openvpn
server.crt
server only
Server Certificate
server:/etc/openvpn
server.key
server only
Server Key
server:/etc/openvpn
c1.crt
client1 only
Client1 Certificate
client
c1.key
client1 only
Client1 Key
client

Setup bridge

  1. Prepare up.sh and down.sh under /etc/openvpn
    • up.sh
      /usr/sbin/openvpn --mktun --dev tap0
      /sbin/ifconfig tap0 promisc up
      /sbin/brctl addif br0 tap0
      /sbin/brctl show
    • down.sh
      /sbin/brctl delif br0 tap0
      /sbin/ifconfig tap0 down
      /sbin/brctl show
  2. prepare server.conf. The file comment is good enough, just pay attention to the following lines
    port 1194
    
    ;proto tcp
    proto udp
    
    dev tap0
    ;dev tun
    
    ca ca.crt
    cert server.crt
    dh dh1024.pem
    
    ifconfig-pool-persist ipp.txt
    server-bridge 192.168.28.9 255.255.255.0 192.168.28.10 192.168.28.20
  3. edit /etc/init.d/openvpn, add up.sh and down.sh in start/stop functions:
    start_vpn () {
            /etc/openvpn/up.sh
            ...
    stop_vpn () {
             ...
             /etc/openvpn/down.sh
  4. if there is a router behind the Pi, make sure port fowarding (UDP : 1194) is set
  5. start openvpn by /etc/init.d/openvpn start

No comments: