Lampros - Weird Bricks

OpenConnect VPN server installation on CentOS 7.3

04 September, 2017 | CentOS

Sometimes you just need an encrypted tunnel. There's lots of options - You can use SSH ... or you can use cryptcat. Or you can use socat. The problem is that those will only work per application (per port) - For example, you can set up an SSH tunnel and then MySQL can use it. 

But what if you need to encrypt all traffic to a particular destination? That's when you really need to go the VPN route.

Here's my notes on how I set up OpenConnect VPN server and client to encrypt traffic between two servers. 

On the server side:

1. Install the EPEL repository:

yum -y install epel-release

2. Install the 'http-parser' package from Koji as the dependency is currently broken:

yum -y install

3. Install the 'ocserv' package which is the actual server as well as 'screen' and 'net-tools' for testing purposes (those 2 are optional of course):

yum -y install ocserv screen net-tools

Optional: To compile from source: 

yum -y install gcc gnutls-devel libev-devel lz4-devel readline-devel net-tools

cd /tmp/
curl -LO
tar -xJf ocserv-0.11.8.tar.xz
cd ocserv-0.11.8
make -j`nproc`
make -j`nproc` check
make install

4. If this server is going to be forwarding traffic then you'll need to enable IP forwarding - it's easy to do:

echo 1 > /proc/sys/net/ipv4/ip_forward

Please note you need to enable this even if you're not setting up the VPN server as an internet gateway - for example if you have more than 1 client and you want the client to "talk" to each other, you still need to enable this.

5. Add a user with a password:

ocpasswd --passwd=/etc/ocserv/ocpasswd lampros

In the above, we're adding the user 'lampros' to the file '/etc/ocserv/ocpasswd'. You'll be prompted for a password. 

6. Create an SSL cert for your public IP - you need this for the VPN to encrypt traffic:

publicip=`curl -4`
cd /etc/ssl/
openssl req -subj "/CN=$publicip/C=US" -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout ocserv.pem -out ocserv.crt

7. Move the default configuration out of the way:

mv /etc/ocserv/ocserv.conf /etc/ocserv/ocserv.conf-backup

8. Use this config in '/etc/ocserv.conf':

auth = "plain[passwd=/etc/ocserv/ocpasswd]"
tcp-port = 4443
udp-port = 4443
socket-file = /var/run/ocserv-socket
pid-file = /var/run/

# A banner to be displayed on clients
banner = "Welcome to mah VPN!"

compression = true
cookie-timeout = 300

# The name to use for the tun device
device = vpns

# The subnet that the VPN will use
ipv4-network =
# The route that will be forwarded to the clients
route =

# The path to the SSL cert you created earlier
server-cert = /etc/ssl/ocserv.crt
# The path to the SSL key you created earlier
server-key = /etc/ssl/ocserv.pem

9. In a screen session test the server config:

ocserv -f -c /etc/ocserv/ocserv.conf -t

10. If all worked fine start the server - this will run it in the foreground:

ocserv -f -c /etc/ocserv/ocserv.conf

11. Leave screen and check your open ports using netstat:

netstat -ntulp | grep ocserv
tcp 0 0* LISTEN 30701/ocserv
tcp6 0 0 :::4443 :::* LISTEN 30701/ocserv
udp 0 0* 30701/ocserv
udp6 0 0 :::4443 :::* 30701/ocserv

On the client:

1. Install the EPEL repository:

yum -y install epel-release

2. Install the 'openconnect' package - that's the VPN client ('screen' and 'net-tools' are for troubleshooting):

yum -y install openconnect screen net-tools

3. Inside screen try to connect to the VPN:

# once in screen:
openconnect --no-cert-check -u lampros 45.58.xx.yyy:4443

We use the '--no-cert-check' option so we don't get warnings about the SSL certificate being self-signed - this is normal.

the '-u lampros' is the user we created earlier

the 45.58.xx.yyy:4443 is the public IP of the server with the port that we set in the server's 'ocserv.conf' earlier.

Once connected you should be prompted for the password.

4. Once the connection is successful, you should have a new interface called 'tun0' and it should already have an assigned IP address:

inet netmask destination
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
RX packets 5 bytes 420 (420.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5 bytes 420 (420.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

5. Try to ping the VPN server:

ping -c3
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=1.11 ms
64 bytes from icmp_seq=2 ttl=64 time=1.27 ms
64 bytes from icmp_seq=3 ttl=64 time=1.32 ms

And we're done!