Page 1 of 1

NordVPN (IPSEC/IKEv2) + killswitch

Posted: Fri Nov 20, 2020 2:51 am
by erkexzcx
I will try to explain the steps in a very practical example, because I've spent quite some time on this already and would like to help someone who is struggling like I used in the past. :)

Noticed that you can use identical setup with Surfshark. See this.

I am not a network engineer or professional, so if you notice any crap in these steps - let me know. Feedback is welcome. :)

Overview

This guide will cover 2 most used scenarios when NordVPN is setup in Mikrotik router:
  • Route all traffic from LAN through VPN server + killswitch
  • Route some traffic (e.g. single website) from LAN through VPN server + killswitch

Let's start with regular setup - simple "consumer-like" setup for a home router (without WiFi) where no VPN configurations are present:
# nov/20/2020 01:03:16 by RouterOS 6.47.7
# software id = K3YP-U8T7
#
# model = RB941-2nD
# serial number = D0550CECB2BA

# Create bridge for LAN, set IP, add ports to it
/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 LAN 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

# 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 not public 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 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=accept chain=forward comment="Drop everything else to WAN" out-interface=ether1

# Create NAT for WAN traffic
/ip firewall nat add action=masquerade chain=srcnat out-interface=ether1

Preparation

Import NordVPN CA to the router:
/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 scenarios I used "lv55.nordvpn.com".

Use-case #1: Whole LAN routed through VPN server + killswitch

This is the official way (posted in NordVPN website). I also added some configuration which was not documented, but needed in order to have perfectly functioning VPN connection.
# Create LAN network entry in firewall address-list
/ip firewall address-list add address=192.168.88.0/24 list=under_vpn

# Add mode config
/ip ipsec mode-config add name="NordVPN mode config" responder=no src-address-list=under_vpn

# IPsec/IKEv2 configuration
/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 routed through VPN server + killswitch

This is my preferred way. In this use-case, VPN is only used for https://wtfismyip.com website. You can even route whole LAN traffic using this method if you slightly modify the rules.
# Create entry in firewall address-list (Mikrotik will automatically resolve it's IP address)
/ip firewall address-list add address=wtfismyip.com list=under_vpn

# Mark connections that goes to "under_vpn" address list
/ip firewall mangle add action=mark-connection chain=prerouting dst-address-list=under_vpn new-connection-mark=under_vpn passthrough=yes

# Add mode config
/ip ipsec mode-config add connection-mark=under_vpn name="NordVPN mode config" responder=no

# IPsec/IKEv2 configuration
/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

Bypassing geo restrictions

If you want to get around geo restrictions (e.g. for bbc player, Netflix content), then you must use NordVPN DNS servers.

Re: [Guide] How to setup NordVPN (IPSEC/IKEv2) + killswitch

Posted: Fri Nov 20, 2020 6:44 am
by Sob
That killswitch is not great (*). Quite dangerous in fact. It will kill bidirectional communication to internet (under normal circumstances = when nobody is trying to get you), but it doesn't prevent leaking packets.

For example, if client uses VPN to ask some super secret DNS queries, they will go out to ISP when VPN is down. This killswitch doesn't prevent that. It doesn't matter how far will they get, there won't be any response coming back. But the point is, someone will have chance to see them. I chose DNS, because query is just one UDP packet and it can contain sensitive data.

And the lack of responses, well, it's not exactly true. There could be someone in ISP's network (Men in Black, ...) waiting for exactly this mistake. They can send fake responses to you. In fact, they can give you full internet access. They'll know that your LAN subnet is behind your router, so they will know where to route responses. And doing outgoing srcnat for you, so that the internet will work, is no problem either. And you won't know that you're not doing your super secret stuff through VPN (unless there's some IP-based blocking on target servers, or something else you'd notice).

Bad enough? It's even worse, they don't have to wait, they can sabotage (block) your connection to VPN server any time they want and get your secret traffic this way.

I'd use something else, for example (only briefly tested, improvements are welcome):
/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
Empty bridge is used as default gateway with alternative routing table "to_vpn". Everything from address list "under_vpn" (from your mode config) gets routing mark "to_vpn", so it will use this routing table. When VPN is down, packets will try to go to empty bridge and won't get anywhere. With VPN up, it will work, because of how IPSec works, it steals packets just before they are sent out, encrypts them and creates different packets. And those are output packets from router and there's new routing decision for them.

--
(*) Original version excluded outgoing traffic from NAT using accept rule in srcnat chain. Running tunnel adds dynamic srcnat rule at the top, so it has priority. With tunnel down, the traffic would go out with original source address (private address from LAN subnet), so communication with internet would not work, because servers can't send responses to private addresses, and ISP should drop such traffic anyway.

Re: [Guide] How to setup NordVPN (IPSEC/IKEv2) + killswitch

Posted: Fri Nov 20, 2020 9:42 am
by erkexzcx
That killswitch is not great. Quite dangerous in fact.
Thank you for your feedback. I completely agree with you, and after testing your provided commands seems that it's working perfectly. +1 for brief explanation.

I've updated commands in initial post. If someone has any better suggestions - let me know and I will update accordingly.

Re: [Guide] How to setup NordVPN (IPSEC/IKEv2) + killswitch

Posted: Fri Nov 20, 2020 2:47 pm
by msatter
Should I see traffic when I torch the bridge acting as blackhole for the VPN when it is going up or down?

The only traffic I saw was ARP. When I re-enable my own killswitch lines (dst 100.69.69.69) then those lines in NAT do catch traffic.

Looking in /IP routing the PPPoE-out has a distance of zero and the blackhole an distance of one. I can't set the blackhole to zero.

Re: [Guide] How to setup NordVPN (IPSEC/IKEv2) + killswitch

Posted: Fri Nov 20, 2020 4:45 pm
by erkexzcx
Should I see traffic when I torch the bridge acting as blackhole for the VPN when it is going up or down? The only traffic I saw was ARP. When I re-enable my own killswitch lines (dst 100.69.69.69) then those lines in NAT do catch traffic.
I see the same...

Looking in /IP routing the PPPoE-out has a distance of zero and the blackhole an distance of one. I can't set the blackhole to zero.
it does not matter since you specify which routing mark to use. You can even set distance to 10 and it would still work.

EDIT: I wrote some crap in this commented. Deleted it. :)

Re: [Guide] How to setup NordVPN (IPSEC/IKEv2) + killswitch

Posted: Fri Nov 20, 2020 5:59 pm
by Sob
The bridge is like any other non-point-to-point interface. If you use it as gateway, router needs to get MAC addresses for target IP addresses, to be able to send data to them, so it sends ARP requests. And in this case can't get any response.