Set up OpenConnect server on Ubuntu

Set up OpenConnect server on Ubuntu

update ocserv, sample configurations

Got the following error while connecting to the previously configured OpenConnect server (ocserv).

GnuTLS error: A packet with illegal or unsupported version was received.

Probably because I’ve upgraded a few libraries. After upgrading ocserv to the latest version (0.12.5), this problem got solved. Here, put down a short note on ocserv settings in case I have to reinstall it again…

Install ocserv

At present, using apt install ocserv will just give you an ealier version, but it’s fine to use this version.

sudo apt update

sudo apt install build-essential pkg-config libghc-nettle-dev libghc-gnutls-dev libprotobuf-c-dev libev-dev

sudo apt install ocserv openconnect

You can also install the latest version from the source.

Download latest ocserv

Check the recent release at ftp://ftp.infradead.org/pub/ocserv/.

wget ftp://ftp.infradead.org/pub/ocserv/ocserv-0.12.5.tar.xz
tar -xf ocserv-0.12.5.tar.xz
cd ocserv-0.12.5

Compile & install ocserv

Make sure you have installed all the packages in any notice from configure. I passed the configure with the following installations1:

sudo apt update
sudo apt install build-essential pkg-config libghc-nettle-dev libghc-gnutls-dev libprotobuf-c-dev libev-dev
./configure
sudo make
sudo make install

ocserv --version

Obtain TLS certificate with Let’s Encrypt

Install Let’s Encrypt client

sudo apt install software-properties-common
sudo add-apt-repository ppa:certbot/certbot

sudo apt update
sudo apt install certbot

Obtain cert with Nginx

If your Ubuntu server already has a web server listening on port 80 and 443, and you want ocserv to use a different port, then it’s a good idea to use the webroot plugin to obtain a certificate because the webroot plugin works with pretty much every web server.2

Since I’m running Nginx, let’s go ahead to obtain a cert with it. First, we need to create a virtual host, domain.example.com for example.

sudo nano /etc/nginx/conf.d/domain.example.com.conf

Paste the following lines into the file.

server {
    listen 80;
    server_name domain.example.com;

    root /var/www/domain.example.com/;

    location ~ /.well-known/acme-challenge {
        allow all;
    }
}

Save and close the file. Then create the web root directory.

sudo mkdir -p /var/www/domain.example.com

Set www-data (Nginx user) as the owner of the web root.

sudo chown www-data:www-data /var/www/domain.example.com -R

Reload Nginx to make changes take effect.

sudo systemctl reload nginx

Then, run the following command to get a Let’s Encrypt certificate using webroot plugin.

sudo certbot certonly --webroot --agree-tos --email your-email-address \
-d domain.example.com -w /var/www/domain.example.com

Edit ocserv configuration file

sudo nano /etc/ocserv/ocserv.conf

In the configuration file, find and adjust the following lines:

# use separate accounts instead of system accounts to login
auth = "plain[passwd=/etc/ocserv/ocpasswd]"

# change the port number
tcp-port = 443
udp-port = 443

# locate the Let's Encrypt server certificate and server key file
server-cert = /etc/letsencrypt/live/domain.example.com/fullchain.pem
server-key = /etc/letsencrypt/live/domain.example.com/privkey.pem

# change clients limits
max-clients = 16
max-same-clients = 2

# enable MTU discovery
try-mtu-discovery = true

# set default domain
default-domain = domain.example.com

# config ipv4-network (optional)
ipv4-network = 192.168.1.0
ipv4-netmask = 255.255.255.0

# tunnel all DNS queries
tunnel-all-dns = true

# set DNS server
dns = 9.9.9.9
dns = 8.8.8.8
dns = 1.1.1.1

# comment out all the route
#route = 10.10.10.0/255.255.255.0
#route = 192.168.0.0/255.255.0.0
#route = fef4:db8:1000:1001::/64
#no-route = 192.168.5.0/255.255.255.0

Save and close the file, then restart ocserv.

# check the configuration
ocserv -c /etc/ocserv/ocserv.conf -f -d 1

sudo systemctl restart ocserv

Fix DTLS handshake failure

If you’re going to use ports other than 443, it’s better to disable the ocserv.socket.

sudo cp /lib/systemd/system/ocserv.service /etc/systemd/system/ocserv.service

sudo nano /etc/systemd/system/ocserv.service

Delete the following two lines:

Requires=ocserv.socket

Also=ocserv.socket

Save and close the file, then reload systemd.

sudo systemctl daemon-reload

sudo systemctl stop ocserv.socket
sudo systemctl disable ocserv.socket

sudo systemctl restart ocserv.service

Create ocserv accout

sudo ocpasswd -c /etc/ocserv/ocpasswd username
# you'll prompt to set password

Enable IP forwarding

sudo nano /etc/sysctl.conf

# comment out the following line
net.ipv4.ip_forward = 1

Save and close the file, then apply the changes with following command to preserve the changes across system reboots.

sudo sysctl -p

Firewall for IP masquerading

ip addr
# find the name of the server's main network interface, something like ens3, eth0

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

sudo iptables -t nat -L POSTROUTING

I’ve cleared the iptables, and manage the firewall through the service providers’s web interface. Read this post may help you manage your iptables.

You can preserve the iptables rules using a systemd service.

# swith to root user
iptables-save > /etc/iptables.rules

Then create a systemd service.

nano /etc/systemd/system/iptables-restore.service

Paste the following content.

[Unit]
Description=Restore iptables
Before=network-pre.target
Wants=network-pre.target

[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables.rules
ExecReload=/sbin/iptables-restore /etc/iptables.rules
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Then, enable this service.

sudo systemctl daemon-reload
sudo systemctl enable iptables-restore

Remember that you have to save iptables rules to the file after making any changes.

And, if you’re also use IPV6, do the same processes again with ip6tables.

HAproxy settings (optional)

If you have configured ocserv to listen on ports other than 443 and you need to connect to ocserv with specify the port number, you can use HAproxy to help you.

Install the latest HAproxy

Find the latest HAproxy stable release at: http://www.haproxy.org/. Currently, it’s 2.0.

sudo add-apt-repository ppa:vbernat/haproxy-2.0
sudo apt update

sudo apt install haproxy

Configure HAproxy

Before that, enable listen-proxy-proto in ocserv.

sudo nano /etc/ocserv/ocserv.conf

Find the change the following item.

# comment out udp port since it's bypassed by HAproxy

# udp-port = 443

listen-proxy-proto = true

Close and save the file, then go to set HAproxy.

sudo nano /etc/haproxy/haproxy.cfg

Setting SNI request as follows:

frontend env_ssl_frontend
	bind *:443
	mode tcp
	tcp-request inspect-delay 5s
	tcp-request content accept if { req_ssl_hello_type 1 }

	use_backend ocserv if { req_ssl_sni -i domain.example.com }

backend ocserv
	mode tcp
	option ssl-hello-chk
	server ocserv localhost:6666 send-proxy-v2

In the example, the port number is 6666, change to your setted port number in ocserv.conf. And send-proxy-v2 is required for ocserv.

Then restart programs.

sudo systemctl restart ocserv
sudo systemctl restart haproxy

Now, you can connect to your ocserv without specify the port number.

林宏

Frank Lin

Hey, there! This is Frank Lin (@flinhong), one of the 1.4 billion 🇨🇳. This 'inDev. Journal' site holds the exploration of my quirky thoughts and random adventures through life. Hope you enjoy reading and perusing my posts.

YOU MAY ALSO LIKE

Setting up snap Nextcloud on Ubuntu

Tutorials

2019.12.05

Setting up snap Nextcloud on Ubuntu

Nextcloud, a fork of ownCloud, is a open-source file sharing server that allows you to store your personal content, like documents and pictures, in a centralized location, much like Dropbox. It also returns the control and security of your sensitive data back to you, thus eliminating the use of a third-party cloud hosting service. Here, I'm going to walk through the installing and configurations on Ubuntu 18.04 using the snappy packaging system.

Using Liquid in Jekyll - Live with Demos

Web Notes

2016.08.20

Using Liquid in Jekyll - Live with Demos

Liquid is a simple templating language that Jekyll uses to process pages on your site. With Liquid you can output an modify variables, have logic statements inside your pages and loop over content.