Notes:
- I've had quite a lot of headaches making Mikrotik to work perfectly with NordVPN server, so decided to write this guide and mention all the steps which are not mentioned in the official guide. :)
- You must have RouterOS 6. It must be minimum version of 6.45. Some steps in ROS7 will be different.
- Nearly identical setup is possible with Surfshark. See here.
- To get around geo restrictions (e.g. for bbc player, Netflix content) as well as DNS leaking, you must use NordVPN DNS servers. Disclaimer: I did not test if it works.
All the steps were tested against a simple "consumer-like" setup for a home router where no WiFi or VPN configurations are present. The initial router configuration is like this:
Code: Select all
# Create bridge for LAN, add ports to it and set IP
/interface bridge add name=bridge1
/interface bridge port add bridge=bridge1 interface=ether2
/interface bridge port add bridge=bridge1 interface=ether3
/interface bridge port add bridge=bridge1 interface=ether4
/ip address add address=192.168.88.1/24 interface=bridge1 network=192.168.88.0
# Set-up DHCP server on created bridge
/ip pool add name=dhcp_pool0 ranges=192.168.88.100-192.168.88.254
/ip dhcp-server add address-pool=dhcp_pool0 disabled=no interface=bridge1 name=dhcp1
/ip dhcp-server network add address=192.168.88.0/24 dns-server=1.1.1.2,1.0.0.2 gateway=192.168.88.1
# For WAN configuration, receive IP address from ISP automatically
/ip dhcp-client add disabled=no interface=ether1
# Add list of bogon IP addresses
/ip firewall address-list add address=0.0.0.0/8 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=172.16.0.0/12 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=192.168.0.0/16 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=10.0.0.0/8 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=169.254.0.0/16 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=127.0.0.0/8 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=224.0.0.0/4 comment=Multicast list=not_in_internet
/ip firewall address-list add address=198.18.0.0/15 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=192.0.0.0/24 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=192.0.2.0/24 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=198.51.100.0/24 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=203.0.113.0/24 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=100.64.0.0/10 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=240.0.0.0/4 comment=RFC6890 list=not_in_internet
/ip firewall address-list add address=192.88.99.0/24 comment="6to4 relay Anycast [RFC 3068]" list=not_in_internet
# Create basic firewall
/ip firewall filter add action=accept chain=input comment="Allow established,related" connection-state=established,related
/ip firewall filter add action=accept chain=input comment="Allow connections only from LAN" src-address=192.168.88.0/24
/ip firewall filter add action=accept chain=input comment="Allow ping" protocol=icmp
/ip firewall filter add action=drop chain=input comment="Drop everything else"
/ip firewall filter add action=fasttrack-connection chain=forward comment=FastTrack connection-state=established,related
/ip firewall filter add action=accept chain=forward comment="Established, Related" connection-state=established,related
/ip firewall filter add action=drop chain=forward comment="Drop invalid" connection-state=invalid
/ip firewall filter add action=drop chain=forward comment="Drop tries to reach private addresses in WAN" dst-address-list=not_in_internet out-interface=ether1
/ip firewall filter add action=drop chain=forward comment="Drop incoming packets from WAN that are not DST-NATed" connection-nat-state=!dstnat connection-state=new in-interface=ether1
/ip firewall filter add action=drop chain=forward comment="Drop incoming from WAN that has private src IP" in-interface=ether1 src-address-list=not_in_internet
/ip firewall filter add action=accept chain=forward comment="Allow to WAN from LAN" in-interface=bridge1 out-interface=ether1 src-address=192.168.88.0/24
/ip firewall filter add action=drop chain=forward comment="Drop everything else to WAN" out-interface=ether1
# Create NAT rule for WAN traffic
/ip firewall nat add action=masquerade chain=srcnat out-interface=ether1
Preparation
Notes:
- Below steps uses the "considered to be perfectly safe" ciphers & their levels, but NordVPN does support higher levels of encryption. Check what hardware acceleration is supported by your Mikrotik router and you might want to use such encryption instead for below steps. P.S. "SHA384 hash algorithm support for phase 1" is supported since 6.48 (might be CLI only).
- Instead of reducing MSS size using below given commands, one can also do this using IPSEC functionality. See here for instructions.
Import NordVPN CA to the router:
Code: Select all
/tool fetch url="https://downloads.nordcdn.com/certificates/root.der"
/certificate import file-name=root.der name="NordVPN CA" passphrase=""
Get recommended NordVPN server here. In below steps I used "lv55.nordvpn.com".
Use-case #1: Whole LAN routed through VPN server
Example: All devices on the LAN network (192.168.88.0/24) should reach internet through VPN server.
TODO: This seems like the same as "Use-case #3" but setup differently.
Code: Select all
# Create LAN network entry in firewall address-list
/ip firewall address-list add address=192.168.88.0/24 list=under_vpn
# IPsec/IKEv2 configuration
/ip ipsec mode-config add name="NordVPN mode config" responder=no src-address-list=under_vpn
/ip ipsec policy group add name=NordVPN
/ip ipsec profile add dh-group=modp2048 enc-algorithm=aes-256 hash-algorithm=sha512 name="NordVPN profile"
/ip ipsec peer add address=lv55.nordvpn.com exchange-mode=ike2 name="NordVPN server" profile="NordVPN profile"
/ip ipsec proposal add auth-algorithms=sha256 enc-algorithms=aes-256-cbc lifetime=0s name="NordVPN proposal" pfs-group=none
/ip ipsec identity add auth-method=eap certificate="NordVPN CA" eap-methods=eap-mschapv2 generate-policy=port-strict mode-config="NordVPN mode config" password=XXXXXXXXXX peer="NordVPN server" policy-template-group=NordVPN username=XXXXXXXXXX
/ip ipsec policy add dst-address=0.0.0.0/0 group=NordVPN proposal="NordVPN proposal" src-address=0.0.0.0/0 template=yes
# In "/ip ipsec policy" you should be able to see a new dynamic rule added next to your NordVPN policy. It MUST exist, otherwise configuration is not working.
# Implement a killswitch
/interface bridge add name=vpn_blackhole protocol-mode=none
/ip route add gateway=vpn_blackhole routing-mark=to_vpn
/ip firewall mangle add chain=prerouting src-address-list=under_vpn action=mark-routing new-routing-mark=to_vpn passthrough=yes
# Exclude such VPN traffic from fasttrack
/ip firewall filter add action=accept chain=forward src-address-list=under_vpn place-before=[find where action=fasttrack-connection]
# Reduce MSS (should be about 1200 to 1400, but 1360 worked for me)
/ip firewall mangle add action=change-mss chain=forward new-mss=1360 passthrough=yes protocol=tcp src-address-list=under_vpn tcp-flags=syn tcp-mss=!0-1360
Use-case #2: Specific traffic (by destination) routed through VPN server
Example: You want to reach website wtfismyip.com via VPN server, but the rest of the traffic should go as it is (without VPN).
Note: You can't effectively route all the traffic of Youtube, Netflix or any other big websites through VPN. They have many different domains and IP addresses which constantly change. Instead, route all the traffic of your device through VPN.
Code: Select all
# Mark traffic that you want to route through VPN server
/ip firewall address-list add address=wtfismyip.com list=under_vpn
/ip firewall mangle add action=mark-connection chain=prerouting dst-address-list=under_vpn new-connection-mark=under_vpn passthrough=yes
# IPsec/IKEv2 configuration
/ip ipsec mode-config add connection-mark=under_vpn name="NordVPN mode config" responder=no
/ip ipsec policy group add name=NordVPN
/ip ipsec profile add dh-group=modp2048 enc-algorithm=aes-256 hash-algorithm=sha512 name="NordVPN profile"
/ip ipsec peer add address=lv55.nordvpn.com exchange-mode=ike2 name="NordVPN server" profile="NordVPN profile"
/ip ipsec proposal add auth-algorithms=sha256 enc-algorithms=aes-256-cbc lifetime=0s name="NordVPN proposal" pfs-group=none
/ip ipsec identity add auth-method=eap certificate="NordVPN CA" eap-methods=eap-mschapv2 generate-policy=port-strict mode-config="NordVPN mode config" password=XXXXXXXXXX peer="NordVPN server" policy-template-group=NordVPN username=XXXXXXXXXX
/ip ipsec policy add dst-address=0.0.0.0/0 group=NordVPN proposal="NordVPN proposal" src-address=0.0.0.0/0 template=yes
# In "/ip ipsec policy" you should be able to see a new dynamic rule added next to your NordVPN policy. It MUST exist, otherwise configuration is not working.
# Implement a killswitch
/interface bridge add name=vpn_blackhole protocol-mode=none
/ip route add gateway=vpn_blackhole routing-mark=to_vpn
/ip firewall mangle add chain=prerouting dst-address-list=under_vpn action=mark-routing new-routing-mark=to_vpn passthrough=yes
# Exclude such VPN traffic from fasttrack
/ip firewall filter add action=accept chain=forward connection-mark=under_vpn place-before=[find where action=fasttrack-connection]
# Reduce MSS (should be about 1200 to 1400, but 1360 worked for me)
/ip firewall mangle add action=change-mss chain=forward new-mss=1360 passthrough=yes protocol=tcp connection-mark=under_vpn tcp-flags=syn tcp-mss=!0-1360
Use-case #3: Specific traffic (by source) routed through VPN server
Example: You want only 2 LAN devices (192.168.88.10 and 192.168.88.11) to reach internet through VPN server, but the rest of LAN devices to reach internet normally (without VPN server).
TODO: This seems like the same as "Use-case #1" but setup differently.
Code: Select all
# Mark traffic that you want to route through VPN server
/ip firewall address-list add address=192.168.88.10 list=under_vpn
/ip firewall address-list add address=192.168.88.11 list=under_vpn
/ip firewall mangle add action=mark-connection chain=prerouting src-address-list=under_vpn new-connection-mark=under_vpn passthrough=yes
# IPsec/IKEv2 configuration
/ip ipsec mode-config add connection-mark=under_vpn name="NordVPN mode config" responder=no
/ip ipsec policy group add name=NordVPN
/ip ipsec profile add dh-group=modp2048 enc-algorithm=aes-256 hash-algorithm=sha512 name="NordVPN profile"
/ip ipsec peer add address=lv55.nordvpn.com exchange-mode=ike2 name="NordVPN server" profile="NordVPN profile"
/ip ipsec proposal add auth-algorithms=sha256 enc-algorithms=aes-256-cbc lifetime=0s name="NordVPN proposal" pfs-group=none
/ip ipsec identity add auth-method=eap certificate="NordVPN CA" eap-methods=eap-mschapv2 generate-policy=port-strict mode-config="NordVPN mode config" password=XXXXXXXXXX peer="NordVPN server" policy-template-group=NordVPN username=XXXXXXXXXX
/ip ipsec policy add dst-address=0.0.0.0/0 group=NordVPN proposal="NordVPN proposal" src-address=0.0.0.0/0 template=yes
# In "/ip ipsec policy" you should be able to see a new dynamic rule added next to your NordVPN policy. It MUST exist, otherwise configuration is not working.
# Implement a killswitch
/interface bridge add name=vpn_blackhole protocol-mode=none
/ip route add gateway=vpn_blackhole routing-mark=to_vpn
/ip firewall mangle add chain=prerouting src-address-list=under_vpn action=mark-routing new-routing-mark=to_vpn passthrough=yes
# Exclude such VPN traffic from fasttrack
/ip firewall filter add action=accept chain=forward connection-mark=under_vpn place-before=[find where action=fasttrack-connection]
# Reduce MSS (should be about 1200 to 1400, but 1360 worked for me)
/ip firewall mangle add action=change-mss chain=forward new-mss=1360 passthrough=yes protocol=tcp connection-mark=under_vpn tcp-flags=syn tcp-mss=!0-1360