Introduction
Setting up OpenVPN on MikroTik should not be a mission. Unfortunately the problem doesn’t lie so much with MikroTik, but rather with the sheer amount of work to get an OpenVPN server (and client) going. Technically, you have to keep track of many things and you generally can’t get them wrong at any point.
In summary we have about this:
- Server work to generate and sign server certificates
- Client work to generate and sign a client certificate
- Exporting of these certificates
- Setting up a the OpenVPN client on Mac or PC
Thankfully due to the magic of the internet we have a great reference framework (a GIST), that shows us most of the heavy lifting. Except, I tried it, and, it didn’t work! So this article is about using this reference, and making it work. I used this guide as the starting point and then troubleshooted it until I got it going: https://gist.github.com/roysbike/c152ffe89a2207c480b7603e87502e9a
Here are some of the challenges we found using this script:
- Deleting certificates after making a mistake is hard, e.g. this doesn’t always just work:
- /certificate
- rem 0
- rem 0
- How to output global variables after assignment
- Removed the need for
:delay
- Confusing
I
for invalid when it’s actuallyISSUED
- The cipher commands in the example didn’t work: `cipher=aes128,aes192,aes256`, so we used all those with
-cbc
appended instead. The client side had-cbc
in anyway! Maybe “something” has changed 🙂 - For client side, we dropped the global `CN` variable.
- The Export commands simply disappearing on the console
- MikroTik WebFig refusing the download files on a Mac, simply displaying Unconfirmed Download
- Not understanding where by /interface/ in the UI there is no OpenVPN server
- On Mac, getting sorry, unsupported options present in configuration: UNKNOWN/UNSUPPORTED OPTIONS
- Not knowing to find “connection logs” for more details
- Find it and finding out all these options do not exist
- persist-key
- persist-tun
- pull
- mute
- Find it and finding out all these options do not exist
- Not knowing to find “connection logs” for more details
- Using the script’s DNS server, instead of 1.1.1.1
- Finally getting connected, but dealing with routing and NAT/MASQ issues
Server Side
Step 1 – Global Variables
:global CN [/system identity get name] :global COUNTRY "ZA" :global STATE "WC" :global LOC "Cape Town" :global ORG "Vander Host" :global OU "" :global KEYSIZE "2048" ## function to wait a certain amount of time after generation :global waitSec do={:return ($KEYSIZE * 10 / 1024)}
Step 2 – Generate the CA Certificate
## generate the CA certificate /certificate add name=ca-template country="$COUNTRY" state="$STATE" locality="$LOC" \ organization="$ORG" unit="$OU" common-name="$CN" key-size="$KEYSIZE" \ days-valid=3650 key-usage=crl-sign,key-cert-sign # the sign command below took 8 seconds on our system sign ca-template ca-crl-host=127.0.0.1 name="$CN" :delay [$waitSec]
Step 3 – Generate the Server Certificate
## generate the server certificate /certificate add name=server-template country="$COUNTRY" state="$STATE" locality="$LOC" \ organization="$ORG" unit="$OU" common-name="server@$CN" key-size="$KEYSIZE" \ days-valid=3650 key-usage=digital-signature,key-encipherment,tls-server # the sign command below also took about 8 seconds on our system sign server-template ca="$CN" name="server@$CN" :delay [$waitSec]
Step 4 – Create a Client Template
## create a client template /certificate add name=client-template country="$COUNTRY" state="$STATE" locality="$LOC" \ organization="$ORG" unit="$OU" common-name="client" \ key-size="$KEYSIZE" days-valid=3650 key-usage=tls-client
At this point the print command should show you that you have three items.
Step 5 – Create the IP Pool
## create IP pool /ip pool add name=VPN-POOL ranges=192.168.88.2-192.168.88.9
Step 6 – Add a VPN profile
## add VPN profile /ppp profile add dns-server=1.1.1.1 local-address=192.168.88.1 name=VPN-PROFILE \ remote-address=VPN-POOL use-encryption=yes
Step 7 – Set up the OpenVPN Server
## setup OpenVPN server /interface ovpn-server server set auth=sha1 certificate="server@$CN" cipher=aes128-cbc,aes192-cbc,aes256-cbc \ default-profile=VPN-PROFILE enabled=yes mode=ip netmask=24 port=1194 \ require-client-certificate=yes
Step 8 – Set up a firewall rule
## add a firewall rule /ip firewall filter add chain=input dst-port=1194 protocol=tcp comment="Allow OpenVPN"
Client Side (User Creation)
Step 1 – Set global variables
:global USERNAME "user" :global PASSWORD "secret"
Step 2 – Create a user using these variables
## add the user with the credentials created above /ppp secret add name=$USERNAME password=$PASSWORD profile=VPN-PROFILE service=ovpn
Step 3 – Generate a Client Certificate
## generate a client certificate /certificate add name=client-template-to-issue copy-from="client-template" \ common-name="$USERNAME@$CN" # the sign command below took around 20 seconds to complete on my system sign client-template-to-issue ca="$CN" name="$USERNAME@$CN" :delay 20
Step 4 – Export the CA, Client Certificate, and Private Key
Strange behavior below, export-certificate simply clears the console text!
## export the CA, client certificate, and private key /certificate export-certificate "$CN" export-passphrase="" export-certificate "$USERNAME@$CN" export-passphrase="$PASSWORD"
On your workstation
SFTP the files
sftp admin@MikroTik_IP:cert_export_\*
The amount of files always confuses me, but there are three:
- The CA Certificate
- The Client Certificate
- The Private Key
Once you have the files, create two new files:
user.auth
The above file is just your username and password, one item on each line.
username.ovpn
The above filename should contain the following (note commented out options):
client dev tun proto tcp-client remote a.b.c.d 1194 nobind #persist-key #persist-tun cipher aes-256-cbc auth SHA1 #pull verb 2 #mute 3 # Create a file 'user.auth' with a username and a password # # cat << EOF > user.auth # user # password # EOF auth-user-pass user.auth # Copy the certificates from MikroTik and change # the filenames below if needed ca cert_export_server.crt cert [email protected] key [email protected] # Add routes to networks behind MikroTik #route 192.168.10.0 255.255.255.0 route 192.168.88.0 255.255.255.0
Troubleshooting
Routing
/sbin/route add -net 192.168.88.0 -netmask 255.255.255.0 192.168.88.2 add net 192.168.88.0: gateway 192.168.88.2 /sbin/route add -net 192.168.88.0 -netmask 255.255.255.0 192.168.88.1 route: writing to routing socket: File exists add net 192.168.88.0: gateway 192.168.88.1: File exists
A masquerade rule seemed to work but then we got Ajax unsafe error.
Checking the OpenVPN log on a Mac
tail -f ~/Library/Application\ Support/OpenVPN\ Connect/log/ovpn.log
Reference
https://openvpn.net/vpn-server-resources/logging-and-debug-flag-options-for-access-server/