Installation Steps
Install OpenVPN Server
me@server:~$ sudo apt-get install openvpn
The following NEW packages will be installed:
liblzo2-2 libpkcs11-helper1 openvpn
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 513 kB of archives.
After this operation, 1,353 kB of additional disk space will be used.
me@server:~$ sudo apt-get install openssl
The following NEW packages will be installed:
openssl
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 492 kB of archives.
After this operation, 956 kB of additional disk space will be used.
Choose a routed VPN (rather than a bridged). Use username/password authentication (still requires server certificate authority (CA) and server certificate.
Edit /etc/default/openvpn and add:
# Ensure tunnel device is available
if [ ! -d /dev/net ]; then
mkdir /dev/net
fi
if [ -d /dev/net ]; then
if [ ! -e /dev/net/tun ]; then
mknod /dev/net/tun c 10 200
chmod 666 /dev/net/tun
fi
fi
Create a tunnel device:
me@server:~# openvpn --mktun --dev tun0
Create Certificate Authority
me@server:~# mkdir /etc/openvpn/ssl
me@server:~# cd /etc/openvpn/ssl
me@server:/etc/openvpn/ssl# openssl genrsa -out ca.key 2048
Generating RSA private key, 2048 bit long modulus
............+++
................................................................................................+++
e is 65537 (0x10001)
me@server:/etc/openvpn/ssl# openssl req -new -x509 -key ca.key -out ca.crt
Now we have ca.crt (the certificate authority certificate) and ca.key (the key for the certificate authority).
You can get the text form of the certificate (used later for the client configuration) by issuing the command:
me@server:/etc/openvpn/ssl# openssl x509 -in ca.crt -text
… and extracting the portion between (and including) the BEGIN CERTIFICATE and END CERTIFICATE lines.
Create Server Certificate and Sign Using Certificate Authority
me@server:/etc/openvpn/ssl# openssl genrsa -out signing.key 2048
Generating RSA private key, 2048 bit long modulus
.....+++
............................................................+++
e is 65537 (0x10001)
me@server:/etc/openvpn/ssl# openssl rsa -in signing.key -pubout -out signing.pub
writing RSA key
me@server:/etc/openvpn/ssl# openssl req -new -key signing.key -out request.csr
me@server:/etc/openvpn/ssl# openssl x509 -req -days 1500 -in request.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
Signature ok
Getting CA Private Key
me@server:/etc/openvpn/ssl# openssl x509 -in server.crt -noout -text
Now we have server.crt (the server certificate).
Create Difie-Hellman Key
me@server:/etc/openvpn/ssl# openssl dhparam -out dh1024.pem 1024
Create Static Shared Key
me@server:/etc/openvpn/ssl# openvpn --genkey --secret static.key
Create auth.pl
(taken from the example at /usr/share/doc/openvpn/examples/sample-scripts/auth-pam.pl)
#!/usr/bin/perl -w
use strict;
# Allowed username/password combinations
my %users = (
'jim' => 'letmein',
'mary' => 'password123',
);
# Get username/password from file
my $ARG;
if ($ARG = shift @ARGV) {
if (!open (UPFILE, "<$ARG")) {
print "Could not open username/password file: $ARG\n";
exit 1;
}
} else {
print "No username/password file specified on command line\n";
exit 1;
}
my $username = <UPFILE>;
my $password = <UPFILE>;
if (!$username || !$password) {
print "Username/password not found in file: $ARG\n";
exit 1;
}
chomp $username;
chomp $password;
close (UPFILE);
if ( $users{$username} && ( $password eq $users{$username} ) ) {
exit 0;
} else {
print "Auth '$username' failed.\n";
exit 1;
}
Create server.conf
tls-server
port 1194
proto udp
dev tun
mssfix 576
cipher AES-256-CBC
ca /etc/openvpn/ssl/ca.crt
cert /etc/openvpn/ssl/server.crt
key /etc/openvpn/ssl/signing.key
dh /etc/openvpn/ssl/dh1024.pem
tls-auth /etc/openvpn/ssl/static.key 0
script-security 2 # necessary for auth-user-pass-verify
auth-user-pass-verify /etc/openvpn/auth.pl via-file
client-cert-not-required
username-as-common-name
server 10.44.12.0 255.255.255.0 # subnet for clients
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
log /var/log/openvpn.log
verb 3
push "redirect-gateway def1"
push "dhcp-option DNS 1.1.1.1" # cloudflare DNS
Enabling/Starting/Stopping OpenVPN
me@server:~# systemctl enable openvpn@server.service
me@server:~# systemctl start openvpn@server.service
me@server:~# systemctl stop openvpn@server.service
Create .ovpn Configuration File for OpenVPN Android Client
tls-client
remote 192.0.2.44 # the IP address of my OpenVPN server
port 1194
proto udp
comp-lzo
auth-user-pass
key-direction 1
mssfix 576
cipher AES-256-CBC
<ca>
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
</ca>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
...
...
...
-----END OpenVPN Static key V1-----
</tls-auth>
On The Phone
Install “OpenVPN Connect – Fast & Safe SSL VPN Client” by “OpenVPN”.
Then add .ovpn file created above.
Install iptables Scripts
me@server:~# apt-get install iptables-persistent
The following NEW packages will be installed:
iptables iptables-persistent libnfnetlink0 netfilter-persistent
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 292 kB of archives.
After this operation, 1,804 kB of additional disk space will be used.
Edit /etc/iptables/rules.v4:
###############################################################################
# iptables IPv4 rules for reload on start-up
#
# To Reload:
# service netfilter-persistent restart
#
# To Test:
# iptables-restore -t </etc/iptables/rules.v4
###############################################################################
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.44.12.0/24 -o eth0 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
Issues
external program fork failed
If you see something like the following:
Wed Jun 20 03:33:31 2018 192.0.2.41:39523 WARNING: External program may not be called unless '--script-security 2' or higher is enabled. See --help text or man page for detailed info.
Wed Jun 20 03:33:31 2018 192.0.2.41:39523 WARNING: Failed running command (--auth-user-pass-verify): external program fork failed
… then you probably have a “script-security 1” parameter somewhere in your configuration (after any other script-security 2 directives). Grep for it and comment it out so that your “script-security 2” directive can take effect.
See Also
Recent Comments