Cisco IOS SSL WebVPN with LetsEncrypt

Problem:

A while back I wrote a post on SSL VPN for IOS routers here: http://blog.dchidell.com/2016/03/21/cisco-ios-ssl-webvpn/

This post goes into detail of using the Certificate Authority StartCom. Since I wrote that article StartCom has been acquired by WoSign Limited (a Chinese company). As a result, many internet authorities no longer trust certificates provided by StartCom and outright block usage of SSL services using them. This, is a problem!


Solution:

Some suggestions would revolve around actually buying an SSL certificate - however I really didn't want to do that. Who wants to spend money on something which was working perfectly over a year without spending a penny?!

Another option would have been to simply use a self signed certificate on the router and deal with any warnings client sided. However in trying this the AnyConnect VPN client in some occasions would refuse to connect and complain about 'Service Provider is restricting your internet connection' which just didn't make sense. When using a 'proper' certificate this issue didn't seem to be a problem.

The third option, was to try and use another free SSL cert provider. LetsEncrypt came to mind. The issue here is that LetsEncrypt uses the ACME protocol to issue certificates - and of course the Cisco IOS VPN router is not capable of the ACME protocol.

The real solution came about when I was researching the mechanisms to issue SSL certificates to unsupported devices and I stumbled across a shell script called acme.sh

This shell script allows you to specify a domain name, which is validated by LetsEncrypt, and then the certificates are placed in a folder which you can then import into the router! Perfect!


Let's get to it

Enough rambling. Here's how to actually get it working.

  • Download and install the acme.sh shell script onto a linux server:
    wget -O - https://get.acme.sh | sh
    Easy enough! My install was actually present in /root/.acme.sh/acme.sh so I had to cd to the directory and execute the script from there.

  • Issue a certificate:
    acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
    We can use multiple -d entries to specify subdomains. The -w specifies the web root directory. Essentially LetsEncrypt must validate ownership of the domains / subdomains and will copy files into that directory then perform validation to each subdomain. I will cover how I did this in a later post!

  • If everything goes well you should end up with a folder with your domain name in the same directory as acme.sh. This contains the certificates you need in order to get the VPN working. This was covered in my previous guide but I'll go through the steps here as well.

  • First the private key needs converting to 3des format using openssl:
    openssl rsa -in /root/.acme.sh/dchidell.com/dchidell.com.key -out /root/.acme.sh/dchidell.com/dchidell.com.key.pem -des3
    This will prompt for a password which you will need later when entering the information into your router.

  • Now we're ready to import the certificates and private key into the router. You will need the intermediate certificate which can be found in ca.cer the private key which we just created, so in my case dchidell.com.key.pem and finally the server certificate, in my case dchidell.com.cer

  • Log into the router, and create the trustpoint:

crypto pki trustpoint CA_LETSENCRYPT  
    enrollment terminal pem
    exit
  • Now import the 3 certs / key.
    • ca.cer
    • domain.com.key.pem (3des)
    • domain.com.cer
crypto pki import CA_LETSENCRYPT pem terminal password <password from openssl>  
    <paste ca.cer>
    quit
    <paste domain.com.key.pem>
    quit
    <paste domain.com.cer>
    quit

If all goes well you'll be presented with the golden: % PEM files import succeeded.

  • Now all we have to do is set the VPN gateway to use our new trustpoint:
webvpn gateway <yourgateway>  
    ssl trustpoint CA_LETSENCRYPT
    no inservice
    inservice

`

Voila! You should be good to go!

Next step is to automate the process....the certificates from LetsEncrypt don't last very long, and you don't want to have to go through this process all the time - so best get automating. I suspect we'll have another blog post on that topic soon!


Summary:

Linux / Webserver:

sudo su  
wget -O -  https://get.acme.sh | sh  
cd /root/.acme.sh  
./acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
openssl rsa -in /root/.acme.sh/example.com/example.com.key -out /root/.acme.sh/example.com/example.com.key.pem -des3  

VPN Router:

crypto pki trustpoint CA_LETSENCRYPT  
    enrollment terminal pem
    exit
!
crypto pki import CA_LETSENCRYPT pem terminal password <password from openssl>  
    <paste ca.cer>
    quit
    <paste example.com.key.pem>
    quit
    <paste example.com.cer>
    quit
!
webvpn gateway <yourgateway>  
    ssl trustpoint CA_LETSENCRYPT
    no inservice
    inservice
!