Updated Jun 09, 2019
Installation step
// Step 1 - Install openconnect VPN package
apt update
apt install ocserv
// Step 2 - Install certbot to get free Let's encrypt SSL
apt install certbot
// Step 3 - generate SSL
// recommend
certbot certonly --rsa-key-size 4096 --standalone --agree-tos --no-eff-email --email [email protected] -d vpn.xxx.io
// alternative
certbot certonly --standalone -d vpn.example.com
// Step 4 - Replace generated PEM and Privkey in ocserv.conf
nano /etc/ocserv.conf
** Comment out all route and no-route
# 注释掉所有的 route 和 no-route,让服务器成为gateway
#route = 192.168.1.0/255.255.255.0
#no-route = 192.168.5.0/255.255.255.0
Recommended configuration
auth = "plain[/etc/ocserv/ocpasswd]"
# TCP and UDP port number
tcp-port = 443
udp-port = 443
run-as-user = nobody
run-as-group = daemon
socket-file = /var/run/ocserv-socket
server-cert = /etc/letsencrypt/live/xxx.com/fullchain.pem
server-key = /etc/letsencrypt/live/xxx.com/privkey.pem
ca-cert = /etc/ssl/certs/ssl-cert-snakeoil.pem
isolate-workers = true
max-clients = 16
max-same-clients = 2
keepalive = 32400
dpd = 90
mobile-dpd = 1800
try-mtu-discovery = true
cert-user-oid = 0.9.2342.19200300.100.1.1
compression = true
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0:-VERS-TLS1.1:-VERS-TLS1.2"
#tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
auth-timeout = 240
min-reauth-time = 3
max-ban-score = 50
ban-reset-time = 300
cookie-timeout = 300
deny-roaming = false
rekey-time = 172800
rekey-method = ssl
use-utmp = true
use-occtl = true
pid-file = /var/run/ocserv.pid
device = vpns
predictable-ips = false
default-domain = vpn.xxx.com
ipv4-network = 192.168.3.0/24
# The IPv6 subnet that leases will be given from.
ipv6-network = fef4:db8:1000:1001::/64
dns = 108.61.201.119
dns = 9.9.9.9
ping-leases = false
cisco-client-compat = true
dtls-legacy = true
// Step 5 - Modify ocserv.socket port number too
nano /lib/systemd/system/ocserv.socket
// Replace port number and save
[Socket]
ListenStream=443 // change this to your desire port number
ListenDatagram=443 // change this to your desire port number
// Step 6 - Generate user password
ocpasswd -c /etc/ocserv/ocpasswd <username>
// Step 7 - Start your server
service ocserv restart
// Step 8 - Ensure ocserv was successful fireup
netstat -tulpn | grep 443
Config your iptables
// ens3 is the outgoing port on Vultr, usually is eth0
// IPv4
*nat
-A POSTROUTING -s 192.168.0.0/24 -o ens3 -j MASQUERADE
-A POSTROUTING -o ens3 -j MASQUERADE
COMMIT
*filter
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p udp -m udp --dport 443 -j ACCEPT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
COMMIT
// IPv6
*filter
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p udp -m udp --dport 443 -j ACCEPT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s fef4:db8:1000:1001::/64 -m conntrack --ctstate NEW -j ACCEPT
COMMIT
*nat
-A POSTROUTING -s fef4:db8:1000:1001::/64 -o ens3 -j MASQUERADE
-A POSTROUTING -o ens3 -j MASQUERADE
COMMIT
Fixing DTLS Handshake Failure
On Debian9 or Ubuntu 18.04, ocserv daemon ocserv.socket
does not respect “listen-host” value from configuration file, which will cause the following error when clients connect to VPN server.
DTLS handshake failed: Resource temporarily unavailable, try again.
To fix this error, we need to edit the ocserv.service file. We first copy the original file in /lib/systemd/system/
directory to /etc/systemd/system/
directory, then edit it, because we don’t want new version of ocserv
package to override our modifications. (To learn more about systemd unit
files, run man systemd.unit
.)
sudo cp /lib/systemd/system/ocserv.service /etc/systemd/system/ocserv.service sudo nano /etc/systemd/system/ocserv.service
Comment out the following two lines.
Requires=ocserv.socket Also=ocserv.socket
Save and close the file. Then reload systemd
sudo systemctl daemon-reload
Stop ocserv.socket and disable it.
sudo systemctl stop ocserv.socket sudo systemctl disable ocserv.socket
Restart ocserv service.
sudo systemctl restart ocserv.service
The ocserv systemd service won’t output any message if it fails to restart, so we need to check the status to make sure it’s actually running.
systemctl status ocserv
References:
1. https://lowendbox.com/blog/install-openconnect-server-on-ubuntu-16-04/
2. https://nova.moe/deploy-openconnect-ocserv-with-letsencrypt/
3. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=837944