Skip to content

Instantly share code, notes, and snippets.

@mikalv
Forked from stek29/ocserv-setup.md
Created December 16, 2020 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikalv/2cabbf4b13cc5be22d468fb9d8bb5168 to your computer and use it in GitHub Desktop.
Save mikalv/2cabbf4b13cc5be22d468fb9d8bb5168 to your computer and use it in GitHub Desktop.

openconnect vpn server

stek29 May 21 2018

Installing ocserv

Older version (0.10.11) is avaliable in ubuntu repos and it seems to work fine,
but I've built 0.12.1 from sources. This is not neccessary, but might be useful.
Describing building from source is out of scope of these instructions.

apt install ocserv

systemd socket issues

ocserv has some issues with UDP socket from systemd, so we'll disable it

systemctl mask ocserv.socket
sed -ie 's/^\(.*ocserv.socket\)$/#\1/' /lib/systemd/system/ocserv.service
systemctl daemon-reload

Generating certificates/keys

# CHANGE ME!
DOMAIN=yourvpnaddress.example.com
ORG=someorg
CACN=YetAnotherCA

cd /etc/ocserv/
cat >ca.tmpl <<_EOF_
cn = "$CACN"
organization = "$ORG"
serial = 1
expiration_days = 3650
ca
signing_key
cert_signing_key
crl_signing_key
_EOF_

cat >server.tmpl <<_EOF_
cn = "$DOMAIN"
organization = "$ORG"
serial = 2
expiration_days = 3650
signing_key
encryption_key
tls_www_server
dns_name = "$DOMAIN"
_EOF_

certtool --generate-privkey --outfile ca-key.pem
certtool --generate-self-signed --load-privkey ca-key.pem --template ca.tmpl --outfile ca-cert.pem
certtool --generate-privkey --outfile server-key.pem
certtool --generate-certificate --load-privkey server-key.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem --template server.tmpl --outfile server-cert.pem

Configuring ocserv

Change/add/check/ignore following lines to /etc/ocserv/ocserv.conf:

# Use certificates for auth
auth = "certificate"
# Or use username/password auth:
#auth = "plain[passwd=/etc/ocserv/ocpasswd]"
# Ports to use
tcp-port = 443
udp-port = 443

# server's cert and key, should be trusted by clients
server-cert = /etc/ocserv/server-cert.pem
server-key = /etc/ocserv/server-key.pem

# cert of ca issuing client certificates used for auth
ca-cert = /etc/ocserv/ca-cert.pem

# Use common name field in certificate for username
cert-user-oid = 2.5.4.3

# Tunnel device name
device = ocserv_vpns

# IPv4 subnet for clients
ipv4-network = 10.0.1.0
ipv4-netmask = 255.255.255.0

# dns server for clients
dns = 1.1.1.1

Auth methods

I'd cover certificate and password auth. I recommend certificates.

Cert auth: Generating certs for clients

Use following script:

#!/usr/bin/env bash

#!/usr/bin/env bash

set -euo pipefail

user="$1"

if [ -z "${user}" ]; then
	echo "Usage: $0 username"
	exit 1
fi

if [ -f "${user}.p12" ]; then
	echo "${user}.p12 already exists!"
	exit 1
fi

# cn is used for username
# don't forget to set cert-user-oid to 2.5.4.3 in ocserv conf

cat >"${user}.tmpl" << _EOF_
cn = "${user}"
unit = "admins"
expiration_days = 365
signing_key
tls_www_client
_EOF_


certtool --generate-privkey \
	--outfile "${user}-key.pem"

certtool --generate-certificate \
	--load-privkey "${user}-key.pem" \
	--load-ca-certificate /etc/ocserv/ca-cert.pem \
	--load-ca-privkey /etc/ocserv/ca-key.pem \
	--template "${user}.tmpl" \
	--outfile "${user}-cert.pem"

certtool --to-p12 \
	--load-privkey "${user}-key.pem" \
	--load-certificate "${user}-cert.pem" \
	--outfile "${user}.p12" \
	--p12-name="${user}-key" \
	--outder

rm "${user}-key.pem" "${user}-cert.pem" "${user}.tmpl"

echo "${user}.p12 generated"

it would ask for password, which you would need to enter on certificate import, and generate p12 file to import on client

Password auth: adding users

See man ocpasswd.

To add user "testuser":

ocpasswd -c /etc/ocserv/ocpasswd testuser

iptables/firewall

I have ufw disabled.

NATting is needed for vpn to work.

# Either enable masquerading
# iptables -t nat -A POSTROUTING -j MASQUERADE
# Or, preferred, SNAT:
# Where 10.0.1.0/24 is subnet used for openconnect (see ipv4-network and ipv4-netmask options)
# And $public_ip is public ipv4 address of server to be used for openconnect
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! -d 10.0.1.0/24 -j SNAT --to $public_ip

# you might need to explicitly accept packets on ocserv's ports:
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p udp --dport 443 -j ACCEPT

You might want to use some iptables-save/restore like thing to apply it on boot.

packet forwarding in kernel

Uncomment/add following to /etc/sysctl.conf:

net.ipv4.ip_forward=1

run sysctl -p to apply.

Multiple VPNs notes

I have OpenVPN on the same server, and with normal setup openvpn clients would be able to access openconnect clients, and vica versa.

So, it might be useful to add following iptables rules:

iptables -A FORWARD -s subnet1 -d subnet2 -j REJECT
iptables -A FORWARD -d subnet1 -s subnet2 -j REJECT

Where subnet1 and subnet2 are ocserv and openvpn subnets (i.e. 10.0.1.0/24 and 10.8.0.0/24) Once again, you might want to make those rules persist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment