RouterOS has nothing to do with security, so this article will focus on usability rather than security. All configurations related to security will be marked as optional.
First of all, let’s review all the limitations we have on the OpenVPN client on RouterOS 6.x:
- Supported protocol: TCP (TLS mode) only, no UDP, no static key
- Supported ciphers: none BF-CBC AES-128-CBC AES-192-CBC AES-256-CBC
- Supported digest algorithms: none MD5 SHA1
- Supported authentication methods: username, password and optional client certificate
- Does not support MPLS even if running in TAP mode
Server Configuration
We use Debian 10 as an example here.
Install OpenVPN
apt-get install -y openvpn
Create CA and Server Certificate
For the sake of simplicity, we directly generate the CA certificate on the same server. This is not safe and is not recommended for production; you should generate the CA private key on an air-gapped computer and generate the server private key and the CSR on the server.
cd /etc/openvpn/server
export EASYRSA=$(pwd)
export EASYRSA_EXT_DIR=/usr/share/easy-rsa/x509-types
/usr/share/easy-rsa/easyrsa init-pki
cp /usr/share/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/server/pki/
/usr/share/easy-rsa/easyrsa build-ca
# Will prompt for CA private key password, you should remember it
/usr/share/easy-rsa/easyrsa gen-req <server-name> nopass
/usr/share/easy-rsa/easyrsa sign-req server <server-name>
openssl dhparam -out dh.pem 2048
Create Server Configuration
dev ovpn-server1
port 1194
# Client IP pool
server 192.168.1.0 255.255.255.0
# connection properties
dev-type tap
proto tcp4-server
#comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
# security setup
cipher AES-256-CBC
script-security 2
user nobody
group nogroup
# MTU setup
mtu-disc yes
#link-mtu 1492
#mtu-test
#tun-mtu 1464
#mssfix
# server cert setup
ca pki/ca.crt
cert pki/issued/<server-name>.crt
key pki/private/<server-name>.key
dh dh.pem
# if you don't need client cert
username-as-common-name
verify-client-cert none
# username password auth script
auth-nocache
auth-user-pass-verify user-pass-auth.sh via-file
# If you need to put the interface into a VRF
#up "up-vrf.sh vrf1"
Create Username Password Authentication Script
OpenVPN does not support username/password database natively. Either you need to configure PAM (which means you need a corresponding Linux user for every VPN user or mess up with PAM configuration), or you write your own program to deal with username and password on each login. We’ll use the latter. When the program is invoked, it have a filename as an argument; the first line of the file will be the username and the second line will be the password. If the program returns 0 then it is a successful login. Let’s just quickly write a bash script and hardcode everything:
#!/bin/bash
# Simple OpenVPN user-pass-auth program
set -Eeuo pipefail
readarray -t line < $1
if [ "${line[0]}" == "username" ] && [ "${line[1]}" == "password" ]; then
exit 0
else
exit 1
fi
Save this file as user-pass-auth.sh and give it execute permission.
(Optional) Add Interface to VRF
#!/bin/bash
set -Eeuo pipefail
# User-provided arguments
VRF=$1
# Default arguments
DEV=$2
TUN_MTU=$3
LINK_MTU=$4
IFCONFIG_LOCAL_IP=$5
IFCONFIG_REMOTE_IP=$6
OPERATION=$7
#echo "Device: $DEV"
#echo "Args: $@"
ip link set $DEV up
ip link set $DEV vrf $VRF
Client Config on RouterOS
(Optional) Create Client Certificate
- Generate private key and CSR on the client
- Copy the CSR to the CA server
- CA server signs the CSR to generate the certificate
- Import the certificate back to the client
(Optional) Import CA
- Import the CA on the client
Create the Interface
/interface ovpn-client
add name=ovpn-out-test connect-to=<server-ip-or-fqdn> port=1194 mode=ethernet user=username password=password cipher=aes256
If you’ve imported the CA (recommended), then tick “Verify Server Certificate”. If you created a client certificate, choose it in the “Certificate” dropdown.