Debian buster setup Openconnect VPN with valid SSL certificate

Installation

## apt install
apt update && apt install socat ocserv -y

## install acme.sh
curl https://get.acme.sh | sh

## issue a cert
cd /root/.acme.sh/
./acme.sh --issue --standalone -d xxx.com

Configuration

// /etc/ocserv.conf

auth = "plain[/etc/ocserv/ocpasswd]"
tcp-port = 443
udp-port = 443
run-as-user = nobody
run-as-group = daemon
socket-file = /var/run/ocserv-socket
server-cert = /root/.acme.sh/xxx.com/fullchain.cer
server-key = /root/.acme.sh/xxx.com/us1.dadd.icu.key
ca-cert = /etc/ssl/certs/ssl-cert-snakeoil.pem
isolate-workers = true
max-clients = 20
max-same-clients = 5
keepalive = 86400
dpd = 90
mobile-dpd = 1800
try-mtu-discovery = true
cert-user-oid = 0.9.2342.19200300.100.1.1
compression = true
no-compress-limit = 256
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
#tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0:-VERS-TLS1.1:-VERS-TLS1.2"
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 = true
default-domain = xxx.com
#custom-header = "X-CSTP-Split-Include-IP6: fe80::/64"
ipv4-network = 10.8.3.0/24
#ipv4-netmask = 255.255.255.0
# The IPv6 subnet that leases will be given from.
#ipv6-network = fc00::
#ipv6-prefix = 64
ipv6-network = fef4:db8:1000:1001::/64
#route = fef4:db8:1000:1001::/64
custom-header = "X-CSTP-Split-Include-IP6: 2000::/3"
#ipv6-network = fef4:db8:1000:1001::/64
dns = 10.8.1.1
#dns = 9.9.9.9
ping-leases = false
mtu = 1400

output-buffer = 23000
cisco-client-compat = true
dtls-legacy = true

# No route
no-route = 2001:470:18:9da::2
no-route = fe80::42:44ff:fe9d:e371
no-route = fe80::216:3cff:fe5e:183d
no-route = fd08:620c:4df0:65eb::1
no-route = fe80::78c6:4bff:fec9:cad0
no-route = 172.17.0.0/255.255.0.0
no-route = 10.0.0.0/255.0.0.0
no-route = 167.179.66.255/255.255.255.255
no-route = 192.168.0.0/255.255.0.0

Create username and password

// Generate a new user name and password
ocpasswd -c /etc/ocserv/ocpasswd <username>

// Restart ocserv
service ocserv restart

Iptables firewall

// ens3 is the outgoing port on Vultr, usually is eth0
// IPv4
*nat
-A POSTROUTING -s 10.8.3.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 10.8.3.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

Photo by Taylor Vick on Unsplash

Enable Cert auth

cd /etc/ocserv/ssl/

// <username>-client-cert.cfg
nano julicahuang-client-cert.cfg

## Template client-cert

# X.509 Certificate options
# The organization of the subject.
organization = "vpn.xx.com"

# The common name of the certificate owner.
cn = "julicahuang"

# uid must be a username in the /etc/ocserv/ocpasswd file.
# A user id of the certificate owner.
uid = "julicahuang"

# In how many days, counting from today, this certificate will expire. Use -1 if there is no expiration date.
expiration_days = 3650

# Whether this certificate will be used for a TLS server
tls_www_client

# Whether this certificate will be used to sign data
signing_key

# Whether this certificate will be used to encrypt data (needed
# in TLS RSA ciphersuites). Note that it is preferred to use different
# keys for encryption and signing.
encryption_key

## End client-cert

// the following command to generate client certificate, which will be signed by the CA private key

certtool --generate-certificate --load-privkey client-privkey.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-privkey.pem --template julicahuang-client-cert.cfg --outfile julicahuang-client-cert.pem

// Mac/Windows/Android
certtool --generate-certificate --load-privkey client-privkey.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-privkey.pem --template client-cert.cfg --outfile julicahuang-client-cert.pem

// iOS -- PCKS12 format
certtool --to-p12 --load-privkey client-privkey.pem --load-certificate julicahuang-client-cert.pem --pkcs-cipher 3des-pkcs12 --outfile julicahuang-ios-client.p12 --outder

Source:
1. https://www.linuxbabe.com/ubuntu/certificate-authentication-openconnect-vpn-server-ocserv
2. https://www.alibabacloud.com/blog/how-to-set-up-an-openconnect-vpn-server_595185

Allow IPv6 forward on Cisco anyconnect source: https://www.spinics.net/lists/openconnect/msg05436.html