OpenVPN Mikrotik server with Edgerouter client
Overview
When connecting an EdgeOS (Ubiquiti Edgerouter) OpenVPN client to a Mikrotik RouterOS OpenVPN server, one may run into some unclear documents and missing details.
Used for this document:
- Ubiquiti EdgeRouter X (ER-X, ERX) running EdgeOS 2.0.8-hotfix.1
- Mikrotik Routerboard RB2011UiAS-2HnD running RouterOS 6.48.4
This information may or may not date itself quickly, as upstream firmware versions evolve. Good luck.
RouterOS (server)
First, we'll need to add an IP pool, a PPP profile+secrets (RouterOS doesn't support any other kind of auth with OpenVPN):
/ip pool add name="ovpn-pool" ranges="10.5.5.10-10.5.5.199" /ppp profile add name="ovpn" local-address="10.5.5.1" remote-address="ovpn-pool" dns-server="10.5.5.1" /ppp secret add name="client1" password="somefreakishlylongpasswordupto233chars" profile=ovpn
Next, we'll create a purpose-built CA, a server certificate, and a certificate for our client (client1):
/certificate add name="SomeCA" days-valid=3650 country="US" state="AK" locality="TundraTown" common-name="SomeCA" key-usage=key-cert-sign,crl-sign /certificate add name="server" days-valid=3650 country="US" state="AK" locality="TundraTown" common-name="server" key-usage=digital-signature,key-encipherment,tls-server /certificate add name="client1" days-valid=3650 key-usage="digital-signature,tls-client" /certificate sign SomeCA ca-crl-host="10.5.5.1" /certificate sign server ca=SomeCA /certificate set server trusted=yes /certificate sign client1 ca=SomeCA /certificate export-certificate SomeCA /certificate export-certificate client1 export-passphrase="somefreakishlylongpassphrase"
"key-usage=...." above is very important and largely undocumented, but without it you'll run into errors like this when connecting your client:
Oct 11 15:35:54 gw openvpn[9640]: Validating certificate key usage Oct 11 15:35:54 gw openvpn[9640]: ++ Certificate has key usage 00b6, expects 00a0 Oct 11 15:35:54 gw openvpn[9640]: ++ Certificate has key usage 00b6, expects 0088 Oct 11 15:35:54 gw openvpn[9640]: VERIFY KU ERROR Oct 11 15:35:54 gw openvpn[9640]: OpenSSL: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed Oct 11 15:35:54 gw openvpn[9640]: TLS_ERROR: BIO read tls_read_plaintext error Oct 11 15:35:54 gw openvpn[9640]: TLS Error: TLS object -> incoming plaintext read error Oct 11 15:35:54 gw openvpn[9640]: TLS Error: TLS handshake failed Oct 11 15:35:54 gw openvpn[9640]: Fatal TLS error (check_tls_errors_co), restarting Oct 11 15:35:54 gw openvpn[9640]: SIGUSR1[soft,tls-error] received, process restarting
The defaults used by RouterOS certificate manager (and the documented suggestions) are bad and unusable with at least the openvpn client shipped with EdgeOS. Strongly doubting this is the only one affected.
Next, we'll configure the openvpn server itself:
/interface ovpn-server server set certificate=server default-profile=ovpn cipher=aes256 enabled=yes
After going through all that trouble, we'll need to remember to retrieve our exported certificates on the client.
If you need/want to add more clients to this server instance, add a ppp secret, then create/sign/export a certificate as above.
EdgeOS (client)
First, let's fetch our exported certificates to some persistent storage that we can make available in our config:
$ sudo -i # mkdir -p /config/auth/ovpn # cd /config/auth/ovpn # sftp admin@routerboard Password: ..... sftp> ls -l cert_export* -rw-r--r-- 0 0 0 1858 Oct 11 15:48 cert_export_client1.key -rw-r--r-- 0 0 0 1249 Oct 11 15:48 cert_export_client1.crt -rw-r--r-- 0 0 0 1371 Oct 11 15:33 cert_export_SomeCA.crt sftp> get cert_export* ... sftp> quit # mv cert_export_client1.key client1.key # mv cert_export_client1.crt client1.crt # mv cert_export_SomeCA.crt ca.crt
Next, we'll need to generate some plaintext (yep..) password files in our persistent storage in order to let openvpn read our certificate and auth to our server:
# cd /config/auth/ovpn # printf "somefreakishlylongpassphrase\n" >cert.passphrase # printf "client1\nsomefreakishlylongpasswordupto233chars\n" >vpn.auth # exit
Now get into config mode and edit an unused openvpn interface. In our example, this will be vtun0. Our example router has no other openvpn instances:
$ configure [edit] # edit interfaces openvpn vtun0 [edit interfaces openvpn vtun0] # set encryption aes256 # set mode client # set openvpn-option "--resolv-retry infinite" # set openvpn-option --persist-key # set openvpn-option --persist-tun # set openvpn-option --nobind # set openvpn-option --mute-replay-warnings # set openvpn-option "--remote-cert-tls server" # set openvpn-option "--ping 15" # set openvpn-option "--ping-restart 45" # set openvpn-option "--askpass /config/auth/ovpn/cert.passphrase" # set openvpn-option "--route 10.100.0.0 255.255.0.0" # set openvpn-option "--auth SHA1" # set openvpn-option "--auth-user-pass /config/auth/ovpn/vpn.auth" # set protocol tcp-active # set remote-host myovpnserver.example.com # set remote-port 1194 # set tls ca-cert-file /config/auth/ovpn/ca.crt # set tls cert-file /config/auth/ovpn/client1.crt # set tls key-file /config/auth/ovpn/client1.key # top [edit] # commit # save
Tail your log and make sure it connects ok:
$ tail -f /var/log/messages
If not, let the troubleshooting begin. It's probably a typo, or your firewall rules (on either or both ends).