Automate Let’s Encrypt SSL Cert to Cisco VPN router

Automate Let’s Encrypt SSL Cert to Cisco VPN router

If you would like to completely automate the renewal of a Let’s Encrypt (or other) SSL Certificate and then deploy this to your Cisco IOS router (or ASA Firewall) using simple bash scripts, keep reading.

There are really three components to solving the issue, first of course is that your FQDN (vpn.yoursite.com) has to be registered with a DNS server – Google is best if you have a dynamic IP address. Here is how you would do that – https://support.google.com/domains/answer/6147083

Second component is to make sure that your ASA/IOS VPN device and an internal webserver can serve up the same FQDN or at least point to the same FQDN. Trick is that you point your port 80 to the Web Server and 443 to the IOS device. So for example, http://vpn.yoursite.com will be served up by an NGINX (or Apache or whatever web) server and https://vpn.yoursite.com will land on the router/firewall. The purpose of getting a webserver is so that we can register and automate the Let’s Encrypt SSL cert download

The last component is to run a couple of scripts (in cron) to automatically update the configuration of the router/VPN device by executing an expect script.

SSL Cert Download and Renewal:

Use acme.sh by Neil Pang (https://github.com/Neilpang/acme.sh) to automate this process. The script will pull down the cert and automatically update the certs every 90 days.
The Certs get downloaded to your “/home/username/.acme.sh/vpn.yoursite.com/” directory.

We’ll need to copy the contents of three files from this folder to the router’s running configuration but first we’ll need to convert vpn.yoursite.com.key to 3des and passphrase protected and renamed to vpn.yoursite.com.key.pem
#!/bin/bash
cert_dest_folder="/home/rajesh/certs"
cert_dnld_folder="/home/rajesh/.acme.sh/vpn.yoursite.com"
while inotifywait -e modify,move,create,delete,attrib -o /var/log/inotify.log $cert_dnld_folder;
do
echo "We have new Certs Downloaded…"
rm -rf $cert_dest_folder/*
cp $cert_dnld_folder/* $cert_dest_folder
openssl rsa -des3 -passout pass:yourpassphrase -in $cert_dest_folder/vpn.
yoursite.com.key -out $cert_dest_folder/vpn.
yoursite.com.key.pem
/home/rajesh/router.sh
#THIS LINE IS CALLING THE SCRIPT BELOW
done

Updating the IOS Router or ASA:

Now that we have the files, we’ll use and expect script to login to the router and update the certificates and restart the webvpn service.

These above script is added to crontab as @reboot so that it starts up every time the server is restarted.
!/usr/bin/expect
set timeout 5
set hostname "192.168.1.99" ! Your router/ASA IP address
set username "rajesh" !SSH username for Router
set password "password" !SSH Password
set send_slow {10 .001} !To slow down some parts of sending
spawn ssh rajesh@$hostname !Now we ssh to the router
expect "Password:" {
send "$password\n"
expect ">" {
send "en\n"
expect "Password:"
send "$password\n"
expect "#"
send "conf t\n"
expect "#"
send "no cry pki trustpoint CA_LETSENCRYPT\n"
expect {
":" {
send -s "yes\n"
exp_continue
}
"(config)#" {
send "cry pki trustpoint CA_LETSENCRYPT\n"
expect "YourRouterName(ca-trustpoint)#"
send "enrollment terminal pem\n"
}
}
expect "#"
send "exit\n"
expect "(config)#"
send "cry pki import CA_LETSENCRYPT pem terminal password $password\n"
expect {
":" {
send -s "yes\n"
exp_continue
}
"itself." {
send -- [exec cat /home/rajesh/certs/ca.cer]\n
send -s "quit\n"
}
}
expect "itself."
send -- [exec cat /home/rajesh/certs/vpn.yoursite.com.key.pem]\n
send -s "quit\n"
expect "itself."
send -- [exec cat /home/rajesh/certs/vpn.yoursite.com.cer]\n
send -s "quit\n"
expect "(config)#"
send "webvpn gateway yourvpngateway\n"
expect "(config-webvpn-gateway)#"
send "no inservice\n"
expect "(config-webvpn-gateway)#"
send "inservice\n"
send "end\n"
expect "#"
send "copy run start\n"
send "\n"
send "exit\n"
}
}

2 thoughts on “Automate Let’s Encrypt SSL Cert to Cisco VPN router

  1. Greets, and Happy New Year! Understandably, LetsEncrypt has been changing things around, however I’m curious if you’ve had a revisit on this topic of late; I’m trying to use the acme.sh and expect method to install a cert chain onto an IOS 15.1(4)M12a (AdvEnterpriseK9) router, but am unable to get the certs to decode.
    I stripped down the process to a manual terminal install (using acme.sh to get the certs and supporting files, then manually converting the private key to an encrypted private pem, then pasting the 3 cert/keys into the enrollment terminal by hand. The first two pastes cause no failure, but after typing “quit” for the 3rd (the actual site cert), I get the dreaded “Unable to Decode Key. // % PEM files import failed”.
    Through some alternate testing/googling, I also went back to LetsEncrypt’s site and pulled their X3 intermediate and Cross-signed certs and tried them in place of the ca.cer, with same results.
    Any thoughts?
    Regards,
    Ted.

    1. Hi Ted,
      I am running advipservices 15.8(3)M1 on an IOS router and able to post the three files without the PEM import error you mention. I am wondering if you were able to convert the key to a supported format like 3des? I do the conversion prior to the import and haven’t run into any issues.
      Raj

Leave a Reply

Your email address will not be published. Required fields are marked *

*