Deploying AnyConnect Compatiable VPN Server With Certificate Verification on CentOS 7
AnyConnect is a remote access solution developed by Cisco. Well-known for its portability and stability, especially its DTLS capability, AnyConnect is used by many companies. We're going to use an open-source version,
ocserv, which is compatible with the protocol.
We're also going to deploy certificate verification. The server will identify the clients by checking that if the client's certificate is issued by the configured CA. This greatly simplifies the configuration on clients as we'll only need to import the certificate on the client (most of the times a pkcs12 file (
.p12)) and no passwords are required. This is also more secure since no passwords travel around the Internet.
- A newly-created CentOS 7 server with IPv6 enabled
- A working computer (can be the server itself; deprecated though (see below)) see note 1
- Some clients with AnyConnect (or OpenConnect) client software installed see note 2
Although it is possible (and rather convenient) to do everything on the server, the deploy process consists of generating private keys used for signing and due to security concerns, this process should be done on your own computer.
Due to licensing issues, I won't provide links to download the client software. Finding them for your client is pretty easy though. AnyConnect is an app in the App Stores on major mobile platforms (iOS, Android, BlackBerry OS (v10 or above), UWP) respectively and a simple search will bring them to you. For PC platforms, some Googling will present you with the suitable software.
Server-side software installation
Vultr's CentOS 7 machine's are configured with the EPEL repository. We just install
yum update yum install ocserv
We'll need a server certificate for things to work. If you have a domain name, Let's Encrypt will be the easiest choice.
yum install certbot certbot certonly
Choose "spin up a temporary Web server" to authenticate with ACME CA. If you don't have a domain, a self-signed certificate will be issued later.
Certificate generation and configuration
The traditional PKI is rather inconvenient to use, so we'll be using the
easyrsa utility from the OpenVPN project. Install git on your working machine and clone the repository:
git clone https://github.com/OpenVPN/easy-rsa cd easy-rsa/easyrsa3
We will build the CA and issue certificates. Do the following and write the PEM passphrase you set somewhere:
./easyrsa init-pki ./easyrsa build-ca
pki/private/ca.key somewhere safe. Leaking that will render your whole infrastructure useless.
If you choose to use a self-signed server certificate, do the following:
./easyrsa gen-req server
And input your server's IP address as the common name.
./easyrsa sign-req server server
This will sign a certificate for the server. Transfer
/etc/ssl/private on your server.
Next we will create client certificates. Do the following:
./easyrsa gen-req client_01 ./easyrsa sign-req client client_01
Choose a name of the client and fill it into the common name field. Remember the passphrase!
Next we're going to export the certificate in pkcs12 format for usage on mobile platforms. Do:
./easyrsa export-p12 client_01
Choose an export password which you will be prompted to enter when importing the certificate on the phone. Transfer
pki/private/client_01.p12 to your phone and import it.
Configuring the server
We'll fill in the certificate information.
server-cert section and fill in the following:
# If you use Let's Encrypt server-cert = /etc/letsencrypt/live/example.com/fullchain.pem server-key = /etc/letsencrypt/live/example.com/privkey.pem # If you use self-signed server certificate server-cert = /etc/ssl/certs/server.crt server-key = /etc/ssl/private/server.key ca-cert = /etc/ssl/certs/ca.crt
Note that if you're using a self-signed certificate, remember to remove the passphrase first by
openssl rsa -in server.key -out server-new.key so that
ocserv can use the private key.
auth section. Enable this line:
auth = "certificate"
And comment out all other
Uncomment this line:
cert-user-oid = 22.214.171.124
ipv6-network and fill in your server's ipv6 block. This is the block that the server will give leases from.
ipv6-network = 2001:0db8:0123:4567::/64 ipv6-subnet-prefix = 124
Set DNS servers.
dns = 126.96.36.199 dns = 188.8.131.52
Enable compatibility with Cisco clients.
cisco-client-compat = true
Open the ports you set in
udp-port and enable masquerade for both ipv4 and ipv6 in firewalld.
Start the server.
systemctl enable ocserv systemctl start ocserv
The server has been successfully configured. Create a connection in your client and connect. If things go wrong, use this command to debug:
journalctl -fu ocserv
Also, IPv6 should work on the client-side if your client software supports ipv6 even if your client's network doesn't provide you with an address. Go to this site to test.
All set! Enjoy your new AnyConnect-compatiable VPN server!