NordVPN (IPSEC/IKEv2) + killswitch (For ROS6)

  1. IPSEC/IKEv2, NORDvpn no support port forwarding, but other service give this option.
  2. for torrent or for sharing something.
    I apologize, if offtopic, but this topic seems close and I didn’t want to create a separate topic for such a small question

You mark connections in Mangle with the connection mark op the VPN connection.You have so full control of which traffic is going throuh the VPN based on type, port, dest/src address or domain through a addres-list.

/ip firewall mangle add action=mark-connection chain=prerouting dst-address-list=under_vpn new-connection-mark=under_vpn passthrough=yes

Since connection is marked, what about use mark routing in the killswitch base of the connection-mark

/ip firewall mangle add chain=prerouting connection-mark=under_vpn action=mark-routing new-routing-mark=to_vpn passthrough=yes

Because routing is not used it is indeed free to be used as the trigger for the killswitch. I am using several VPN providers and connections so mark IKEv2 traffic with a single routing mark and the distrubution is done be connection marking.

This gives a lot of flexability in the end.

Hi, i have the hex S router and i followed the instructions in the first post to the letter, only changing the nordvpn server and password, and not implementing the kill switch.
all the configuration was done after the router was reset to factory defaults, FW 6.48.
when i try to use a pc through the vpn connection its everything is fine,
but when trying to access through android devices its like only very few sites actually work.
youtube.com is accessible but videos dont play through the browser, amazon.com is not opening at all, cant connect to ring cameras, etc.
ive tried lowering the mss value to 1200, but it had not effect.
will really appreciate a point in the right direction on this.
thank you !

/ip firewall mangle add action=mark-connection chain=prerouting dst-address-list=!no_vpn dst-address-type=!local new-connection-mark=under_vpn passthrough=yes
/ip firewall mangle add chain=prerouting connection-mark=under_vpn action=mark-routing new-routing-mark=to_vpn passthrough=yes

The above config doesn’t work, there are tx and rs packages on vpn_blackhole. add dst-address-list=!no_vpn, it worked. where is the problem?

I’m using android phone, VPN setup on router, without chang mss, some app like twitter, gmail and google account in setting can’t work, but they can access in web browser, set mss to 1360 all worked.
For youtube, See post #8 by erkexzcx.

I modified the mark connection, youtube worked.

/ip firewall mangle add action=mark-connection chain=prerouting dst-address-list=!no_vpn dst-address-type=!local new-connection-mark=under_vpn passthrough=yes

Thanks to the author for this comprehensive guide! The solutions described in the post do an excellent job. I recently purchased a router from Mikrotik and I like to use it, but since I like to use Nord VPN in my work, I also had to face some problems. Fortunately, Use-case # 2 from the guide helped to solve the problem. Thanks again!

Great thread. Thank you.

I am trying to do the opposite of Use-case #2… with SurfShark which appears to have a similar ip sec setup
Use-case #4: Specific traffic (by destination address and/or destination port preferably) routed AROUND (bypass)VPN server
Intent is for all traffic to go through the tunnel except my work SSL VPN connections to go straight to ISP. Will likely add other bypass destination ports/protocols. For now just trying to make it work for all HTTP/HTTPS for easy testing.
Tried what I read for some of the Netflix bypasses, but can’t make it work. Everything still goes through the vpn tunnel, but they appear to be suggesting routing-marks, not connection-marks…
Currently setup like Use-Case #1 plus marked route to ISP and mangle for any dest port 80,443…

/ip route add distance=1 gateway=96.38.160.1 routing-mark=BypassVPN 
/ip firewall mangle add action=mark-routing chain=prerouting dst-port=80,443 new-routing-mark=BypassVPN passthrough=no protocol=tcp src-address=10.236.1.0/24

Does something like this do the trick?

/ip firewall mangle add action=mark-connection chain=prerouting dst-port=!80,443 new-connection-mark=under_nordvpn passthrough=yes protocol=tcp

Thank you. Yes, I think, as you wrote it, that would work for global ports like that, or one specific destination, but what about multiple exceptions?
SSL VPN to work IP
80,443 to any site I want location services to work (Banking, Home Depot, Yelp)
FTPS to my web host
Not sure how to fit that in a single Mangle
My intent was to mark traffic I don’t want in the tunnel instead of that I do. Each way has its own challenges though as I am seeing.

but what about multiple exceptions?

Honestly I don’t know.

If I were you, I would just do something like this:

/ip firewall mangle add action=mark-connection chain=prerouting dst-port=80,443 new-connection-mark=novpn passthrough=yes protocol=tcp
/ip firewall mangle add action=mark-connection chain=prerouting dst-address=123.123.123.123 new-connection-mark=novpn passthrough=yes
/ip firewall mangle add action=mark-connection chain=prerouting connection-mark=!novpn new-connection-mark=under_nordvpn passthrough=yes

Thank you. Burned too much time on this for now… Will revisit later. Something about my config makes it all or nothing regardless.

I’ve been trying to implement this particular setup (specifically number 3) but I don’t seem to be having any luck whatsoever, every time I add an IP address to my list, that particular device cannot connect to the internet anymore. I’m out of options when it comes to debugging steps so I would like to ask your help.

So far, I have been able to determine that:

  1. The connection to NordVPN is setup, as I can see an active peer with traffic, I can see installed SAs for that peer and a dynamic policy is generated for the NordVPN peer


  2. The policy generates no-track rules and a src-nat rule is generated for the connection as well


  3. Running a ping and trace-route to 8.8.8.8 from the Mikrotik device with the NordVPN IP address as src-address shows that the connection exits on the other side of the VPN and the ping times are significantly higher then when running the same ping through my ISP

Any attempt to connect to the internet through NordVPN from a device inside my network by adding its IP address to the VPN list however does not work. It is like the return traffic gets to the Mikrotik device correctly but is not sent to the client.

Here are my IPSec settings for NordVPN

/ip ipsec profile
add dh-group=ecp256,modp3072 enc-algorithm=aes-256 hash-algorithm=sha384 \
    name="NordVPN profile"
/ip ipsec peer
add address=us8452.nordvpn.com exchange-mode=ike2 name="NordVPN peer" \
    profile="NordVPN profile"
/ip ipsec proposal
add auth-algorithms=sha256 enc-algorithms=aes-256-cbc,aes-128-cbc lifetime=0s \
    name="NordVPN proposal" pfs-group=none
/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

/ip ipsec mode-config
add connection-mark=NordVPN name=NordVPN responder=no
    
/ip ipsec identity
add auth-method=eap certificate=NordVPN eap-methods=eap-mschapv2 \
    generate-policy=port-strict mode-config=NordVPN notrack-chain=prerouting \
    password=[password] peer="NordVPN peer" \
    policy-template-group=NordVPN username=[username]

Here are my firewall rules

/ip firewall filter
# Input chain rules
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" in-interface-list=!LAN

# Forward chain rules
add action=accept chain=forward comment="Don't fasttrack NordVPN traffic" connection-mark=NordVPN dst-address-list=localnet
add action=accept chain=forward comment="defconf: accept in ipsec policy" ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-mark=!ipsec connection-state=established,related
add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid 
add action=drop chain=forward comment="defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat connection-state=new in-interface-list=WAN

/ip firewall mangle
add action=mark-connection chain=forward comment="Mark outgoing IPSec connections" ipsec-policy=out,ipsec new-connection-mark=ipsec passthrough=yes
add action=mark-connection chain=forward comment="Mark incoming IPSec connections" ipsec-policy=in,ipsec new-connection-mark=ipsec passthrough=yes
add action=mark-connection chain=prerouting comment="Mark NordVPN IPSec traffic" connection-mark=!ipsec dst-address-list=!localnet,ipsec-remote new-connection-mark=NordVPN passthrough=yes src-address-list=NordVPN
add action=change-mss chain=forward connection-mark=NordVPN new-mss=64 passthrough=yes protocol=tcp tcp-flags=syn tcp-mss=!0-64

/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none 

/ip firewall raw
add action=notrack chain=prerouting comment="notrack ipsec to local" disabled=yes dst-address-list=localnet src-address-list=ipsec-remote
add action=notrack chain=prerouting comment="notrack lcoal to ipsec" disabled=yes dst-address-list=ipsec-remote src-address-list=localnet

My question, do I have a glaring error in one of my rules? Or do I have a glaring error in the order of my rules? If not that, what debugging steps can I perform to figure out what went wrong?

Thank you in advance.

Hi,

Try to move below rules to the top and try again. Kill NordVPN IPSEC connection, clear conntrack list and try again.

add action=mark-connection chain=prerouting comment="Mark NordVPN IPSec traffic" connection-mark=!ipsec dst-address-list=!localnet,ipsec-remote new-connection-mark=NordVPN passthrough=yes src-address-list=NordVPN
add action=change-mss chain=forward connection-mark=NordVPN new-mss=64 passthrough=yes protocol=tcp tcp-flags=syn tcp-mss=!0-64

also those rules seem a bit odd to me. Why MSS 0-64? Or like “connection-mark=!ipsec”. I am not sure since your configuration has quite a lot of customization and it’s hard to say from your rules.

Also try to get rid of killswitch implementation for testing. For testing I like wtfismyip.com website as it shows your public IP which will change when you start using NordVPN. :slight_smile:

Thanks, I’ve just tried that but it didn’t work as expected. The MTU clamping is set to 64 cos that was the packet size that did not show up as corrupted in the Mikrotik ping tool. It is for testing purposes and should work well enough for ping messages.

I got rid of the ‘connection-mark=ipsec’ rules just to make sure that it didn’t make a difference but that did not help either.

I have the sense that this is a firewall issue so your suggestion strengthens my suspicion. I think it would be best to redesign the firewall rules offline, clear the current ones and load the new set. Any tips on what diagnostics I can perform?

Found the solution for my setup, turns out I had the [notrack-chain] option set to [prerouting] and that didn’t work at all. I changed it to [output] and suddenly everything started working like a charm.

peer=NordVPN peer auth-method=eap eap-methods=eap-mschapv2 mode-config=NordVPN 
      notrack-chain="output" certificate=NordVPN username=[username] 
      password=[password] generate-policy=port-strict policy-template-group=NordVPN

Great, I’ve revised my configuration after monitoring the firewall rules though, turns out that in this particular setup you don’t need any no-track rules generated at all, so removing the no-track completely is the best advice. It’s empty be default when creating a new identity so that is why nothing shows up in any of the config rules at the top of this thread.

I implemented it manually so I could do it all in one line for all expected IKEv2 connections. I use an address list, on which all external addresses are listed.

/ip firewall raw
add action=notrack chain=prerouting protocol=ipsec-esp src-address-list=IKEVtraffic
add action=notrack chain=output protocol=ipsec-esp dst-address-list=IKEVtraffic

Traffic entering the connections will use costly processing time and by NoTracking it the IPSEC traffic manager (policies?) of ROuterOS will still grab it but it won’t be in connections. It gives you about 30% of saving in processor time used for IPSEC-ESP traffic. As you can see I have one line for incoming traffic (prerouting) and one for outgoing traffic (output).

ps. you don’t have to use an address list if you don’t have any other ipsec-esp traffic! Just No-Track all ipsec-esp traffic then.

thank you!