OpenVPN Mikrotik server with Edgerouter client

From WTFwiki
Jump to navigation Jump to search


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=""
 /ppp profile add name="ovpn" local-address="" remote-address="ovpn-pool" dns-server=""
 /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=""
 /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 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"
 # set openvpn-option "--auth SHA1"
 # set openvpn-option "--auth-user-pass /config/auth/ovpn/vpn.auth"
 # set protocol tcp-active
 # set remote-host
 # 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
 # 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).

See Also