There are some reasonably okay docs on the internet about how to use a MikroTik router to connect to a linux openvpn server, but none that encompassed everything I wanted to do. The official wiki even said I couldn’t do what I wanted. Hopefully this collects the thoughts into enough of a cohesive bundle that it’s useful for others.
I wanted to connect my network to a cloud server. I want this connection to be over an OpenVPN Peer-to-Peer connection. If I make the connection on the router itself, then my entire network will be able to route over that connection. This will facilitate having a server in the cloud that can reach the different servers I have running on this network.
1 2 3
/- machine1[192.168.0.1] cloudmachine[10.5.0.4] -- router[10.5.0.3] ----- machine2[192.168.0.2] \- machine3[192.168.0.3]
I’m running an RB800, so I’ve got plenty of CPU to spare. Your mileage may vary. The cloud machine is on the Google Cloud Platform, and it’s the “g1-small” instance, so 1ghz of shared vCPU, and 1.7 Gee Bees of ram. (I may upgrade this to a standard instance at some point, so I can keep more cpu for myself, but the shared vCPU is really good enough.) The linux server is running Ubuntu 16.04.
To do certificate based authentication with MikroTik’s OVPN Client, you first need a certificate and corresponding key imported.
Importing a certificate is pretty straightforward.
After uploading the VPN client certificate and key files to the Router:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
[admin@test_host] /certificate> import file-name=server.crt passphrase: certificates-imported: 1 private-keys-imported: 0 files-imported: 1 decryption-failures: 0 keys-with-no-certificate: 0 [admin@test_host] /certificate> import file-name=server.key passphrase: certificates-imported: 0 private-keys-imported: 1 files-imported: 1 decryption-failures: 0 keys-with-no-certificate: 0
After importing them, the certificate should show up with the
KT flag. If not, you haven’t imported them correctly.
You will probably also need to import the Certificate Authority you used to generate these certs, unless you used one of the paid for certificate authorities. I’m far too cheap to do that, and since I control both of the boxes, using easyrsa to generate a CA and certificates works fine for me.
Configure a PPP Profile
This part I had to figure out on my own. I needed to specify the IP address of the connection, not have it given to me by
the server. You have to create a PPP Profile that contains the local IP and the remote IP. I also disabled IPv6, because
I didn’t have any IPv6 connectivity to this at the time. Set
profile_name to whatever you want to call it. I used “cloudmachine”.
[admin@test_host] /ppp profile> add name="profile_name" local-address=10.5.0.3 remote-address=10.5.0.4 use-ipv6=no
Configure your openvpn server connection
The linux host that is going to be the server endpoint needs some special configs, not every OpenVPN feature is supported by the MikroTik Openvpn implementation. A couple limitations exist: * only supports TCP VPNs * Can’t do lzo compression
The site claims it cannot do authentication without username/password, but I have done this. I think perhaps the wiki
is out of date. I’ve verified this by doing the
verify-x509-name functionality, and the certificate is indeed presented
and validated. If I put a different name than the one presented in the
CN= field of the certificate, the connection
1 2 3 4
Dec 27 00:06:53 cloudmachine ovpn-mikrotik: TLS_ERROR: BIO read tls_read_plaintext error: error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed Dec 27 00:06:53 cloudmachine ovpn-mikrotik: TLS Error: TLS object -> incoming plaintext read error Dec 27 00:06:53 cloudmachine ovpn-mikrotik: TLS Error: TLS handshake failed Dec 27 00:06:53 cloudmachine ovpn-mikrotik: Fatal TLS error (check_tls_errors_co), restarting
This indicates to me that the TLS handshake is happening and certificates are being exchanged and verified!
A working OpenVPN Linux Server configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
mode p2p bind port 1192 proto tcp-server #float is the default unless --remote is specified float dev tun1 # this is mine \/ \/ is the client ifconfig 10.5.0.4 10.5.0.3 persist-tun # cannot use comp-lzo with the routerboard # can't use fragment with TCP connections, mssfix should be sufficient mssfix # Local route to the home network route 10.10.220.0 255.255.255.0 vpn_gateway keepalive 10 60 # 2048 dh params! dh /etc/openvpn/mikrotik.dh2048.pem tls-server # other end CA ca /etc/openvpn/mikrotik_ca.crt # My certificate and key cert /etc/openvpn/vpn.cloudmachine.kow.is.crt key /etc/openvpn/vpn.cloudmachine.kow.is.key # verify the certificate! only allowing a certificate that matches this CN verify-x509-name client-cert name
Fire this puppy up on your linux server, however your init system does it.
Configure your Mikrotik Client Ovpn connection
This is a little tricky, but not impossible. You always have to specify a user, but not a password. The user isn’t used, nor is the password, as best as I can tell. I’ve got a connection running, and it’s only authenticating using the certs.
Here you’ll need some bits of information from other entries.
* certificate name will match the name from
/certificate print for the cert/key combination you uploaded earlier
* profile will be the profile you created to set up the IP addresses of the connection.
* connect-to needs to be the IP address of your linux server
1 2 3 4 5
[admin@test_host] /interface ovpn-client add name="cloudmachine-vpn" connect-to=188.8.131.52 mode=ip user="user" password="" add-default-route=no certificate=cert_name_thing profile=profile_name auth=sha1 cipher=blowfish128
Once this is configured and enabled, your logs on the vpn server will show good stuff:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Dec 27 00:07:11 cloudmachine ovpn-mikrotik: OpenVPN 2.3.10 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Feb 2 2016 Dec 27 00:07:11 cloudmachine ovpn-mikrotik: library versions: OpenSSL 1.0.2g 1 Mar 2016, LZO 2.08 Dec 27 00:07:11 cloudmachine ovpn-mikrotik: TUN/TAP device tun1 opened Dec 27 00:07:11 cloudmachine ovpn-mikrotik: do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0 Dec 27 00:07:11 cloudmachine ovpn-mikrotik: /sbin/ip link set dev tun1 up mtu 1500 Dec 27 00:07:11 cloudmachine ovpn-mikrotik: /sbin/ip addr add dev tun1 local 10.5.0.4 peer 10.5.0.3 Dec 27 00:07:11 cloudmachine ovpn-mikrotik: Listening for incoming TCP connection on [undef] Dec 27 00:07:17 cloudmachine ovpn-mikrotik: TCP connection established with [AF_INET]184.108.40.206:34375 Dec 27 00:07:17 cloudmachine ovpn-mikrotik: TCPv4_SERVER link local (bound): [undef] Dec 27 00:07:17 cloudmachine ovpn-mikrotik: TCPv4_SERVER link remote: [AF_INET]220.127.116.11:34375 Dec 27 00:07:18 cloudmachine ovpn-mikrotik: WARNING: 'ifconfig' is present in local config but missing in remote config, local='ifconfig 10.5.0.3 10.5.0.3' Dec 27 00:07:18 cloudmachine ovpn-mikrotik: [test-client] Peer Connection Initiated with [AF_INET]18.104.22.168:34375 Dec 27 00:07:18 cloudmachine ovpn-mikrotik: send_push_reply(): safe_cap=940 Dec 27 00:07:20 cloudmachine ovpn-mikrotik: Initialization Sequence Completed
It complains about the other end doesn’t have the
ifconfig setting, but I haven’t had any problems, and it pings and routes.
I’ve noticed via a logwatch email that it seems to restart quite often. It may have been because the link was completely idle. I have yet to notice any connectivity problems, so other than the log noise, it doesn’t seem to be hurting anything. SSH connections have remained up. I would like to have it make less log noise, so maybe there’s further things to do.
It certainly gets the job done right now, though. ¯\_(ツ)_/¯