OpenVPN gateway inside Mikrotik router

I set up an OpenVPN endpoint at home so I can connect to my home network and access resources relatively securely and easily. Originally this post was me beating my head against the table to get it right, but I finally did before I hit publish, so I could post it as a success!

Quick design specs:

  • My internal network is 10.0.0.0/24
  • The internal gateway is a Mikrotik RB750G on 10.0.0.1
  • The VPN gateway IP is 10.8.0.1, and the same machine has 10.0.0.2 on the internal network.
  • The  VPN client(s) get assigned an IP in the range 10.8.0.0/24
  • Authentication’s done by certificates

The “pretty” view of the network is as follows:

VPN Gateway Server Configuration

I’m running Ubuntu 12.04.2 LTS as the OS on the gateway. To install OpenVPN, it’s the usual apt-get command.

sudo apt-get install openvpn

I copied the easy-rsa tools to a folder under etc so that updating the package won’t nuke my keys.

sudo mkdir /etc/openvpn/keys
sudo cp /usr/share/doc/openvpn/examples/easy-rsa/* /etc/openvpn/keys

The config file sets up all the parameters for the OpenVPN server. The certificates were generated by following the information on PKI here. I used a 2048 bit Diffie Hellman configuration just because I can. I didn’t call my boxes “server” and “client1/2/3”, but something descriptive in case I needed to look at the files later.

# Which local IP address should OpenVPN
# listen on? (optional)
;local a.b.c.d

# Which TCP/UDP port should OpenVPN listen on. If you want to run multiple OpenVPN instances
# on the same machine, use a different port number for each one.  You will need to open up this port on your firewall.
port 1194

# TCP or UDP server?
proto udp

# "dev tun" will create a routed IP tunnel, "dev tap" will create an ethernet tunnel.
# Use "dev tap0" if you are ethernet bridging and have precreated a tap0 virtual interface
# and bridged it with your ethernet interface. If you want to control access policies
# over the VPN, you must create firewall rules for the the TUN/TAP interface.
# On non-Windows systems, you can give an explicit unit number, such as tun0.
# On most systems, the VPN will not function unless you partially or fully disable the firewall for the TUN/TAP interface.
dev tun

# SSL/TLS root certificate (ca), certificate (cert), and private key (key).  Each client
# and the server must have their own cert and key file.  The server and all clients will
# use the same ca file.
#
# See the "easy-rsa" directory for a series of scripts for generating RSA certificates
# and private keys.  Remember to use a unique Common Name for the server
# and each of the client certificates.
#
# Any X509 key management system can be used. OpenVPN can also use a PKCS #12 formatted key file (see "pkcs12" directive in man page).
ca /etc/openvpn/easyrsa/keys/ca.crt
cert /etc/openvpn/easyrsa/keys/dnsbox.housenet.internal.crt
key /etc/openvpn/easyrsa/keys/dnsbox.housenet.internal.key  # This file should be kept secret

# Diffie hellman parameters.
# Generate your own with:
#   openssl dhparam -out dh1024.pem 1024
# Substitute 2048 for 1024 if you are using 2048 bit keys. 
dh /etc/openvpn/easyrsa/keys/dh2048.pem

# Configure server mode and supply a VPN subnet for OpenVPN to draw client addresses from.
# The server will take 10.8.0.1 for itself, the rest will be made available to clients.
# Each client will be able to reach the server on 10.8.0.1. Comment this line out if you are
# ethernet bridging. See the man page for more info.
server 10.8.0.0 255.255.255.0

# Maintain a record of client <-> virtual IP address associations in this file.  If OpenVPN goes down or
# is restarted, reconnecting clients can be assigned the same virtual IP address from the pool that was previously assigned.
ifconfig-pool-persist ipp.txt

# Push routes to the client to allow it to reach other private subnets behind the server.  Remember that these
# private subnets will also need to know to route the OpenVPN client address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.
push "route 10.8.0.0 255.255.255.0"
push "route 10.0.0.0 255.255.255.0"

# Certain Windows-specific network settings can be pushed to clients, such as DNS or WINS server addresses.  CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats The addresses below refer to the public DNS servers provided by opendns.com.
push "dhcp-option DNS 10.8.0.1"

# Uncomment this directive to allow different clients to be able to "see" each other. By default, clients will only see the server.
# To force clients to only see the server, you will also need to appropriately firewall the server's TUN/TAP interface.
client-to-client

# The keepalive directive causes ping-like messages to be sent back and forth over
# the link so that each side knows when the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during a 120 second time period.
keepalive 10 120

# For extra security beyond that provided by SSL/TLS, create an "HMAC firewall" to help block DoS attacks and UDP port flooding.
# Generate with:
#   openvpn --genkey --secret ta.key
# The server and each client must have a copy of this key.
# The second parameter should be '0' on the server and '1' on the clients.
;tls-auth ta.key 0 # This file is secret

# Select a cryptographic cipher. This config item must be copied to the client config file as well.
;cipher BF-CBC        # Blowfish (default)
;cipher AES-128-CBC   # AES
cipher DES-EDE3-CBC  # Triple-DES

# Enable compression on the VPN link. If you enable it here, you must also enable it in the client config file.
comp-lzo

# The maximum number of concurrently connected clients we want to allow.
max-clients 5

# It's a good idea to reduce the OpenVPN daemon's privileges after initialization.
# You can uncomment this out on non-Windows systems.
user nobody
group nogroup

# The persist options will try to avoid accessing certain resources on restart
# that may no longer be accessible because of the privilege downgrade.
persist-key
persist-tun

# Output a short status file showing current connections, truncated and rewritten every minute.
status openvpn-status.log

# Set the appropriate level of log file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3

# Silence repeating messages.  At most 20 sequential messages of the same message category will be output to the log.
mute 20

On the VPN Gateway

I added the following ti my /etc/rc.local to add the firewall rules on boot.

# Allow traffic initiated from VPN to access LAN
sudo iptables -I FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -d 10.0.0.0/24 -m conntrack --ctstate NEW -j ACCEPT

# Allow established traffic to pass back and forth
sudo iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

On the Router

Setting up the firewall to port forward for UDP port 1194 to the VPN gateway:

/ip firewall nat chain=dstnat action=dst-nat to-addresses=10.0.0.2 to-ports=1194 protocol=udp in-interface=pppoe-out1 dst-port=1194

Adding a static route to point any VPN-destined traffic to the VPN gateway:

/ip route dst-address=10.8.0.0/24 gateway=10.0.0.2 gateway-status=10.0.0.2 reachable via ether2-local-master distance=1 scope=30 target-scope=10

On the client

I’m using OSX on my laptop, and that’s the only thing I’ve tested. I’m using the Viscosity client and expect that once the trial period’s up I’ll spend the dosh on purchasing it, just because it worked first go 🙂

So far I’ve only connected a few times, but it seems to all work fine, I can ssh to things and SCP files if need be. If anything else changes I’ll update the page as time permits. Any questions? Comments in the box below!