IPSec - routing problem

Hi,

I have a problem understanding how the IPSec policy works. I currently have a working IPSec tunnel between the branch and the headquarters. Now I would like to route all traffic from the department’s local network over the IPSec VPN link. My current rule in the department looks like this:
Src address: 192.168.170.0/24
Dst address: 0.0.0.0/0
and NAT is srcnat → out interface: WAN → masquarade
Despite such a configuration, Internet traffic is directed to the local WAN interface. How can I change it? How to route all traffic from the LAN through the IPSec tunnel?

It’s not “despite”, it’s “due to”. The “normal” routing and srcnat are performed before IPsec policy matching, hence if the route towards an IP address in the internet is found via WAN, the masquerade rule changes the source address of the packet to the WAN one, and thus the IPsec policy doesn’t match it.

One possible way out is to add to your action=masquerade rule a match condition ipsec-policy=out,none. This condition checks the existing IPsec policies before they are actually used to divert the packets, and in this form, it doesn’t match on packets whose headers match any existing IPsec policy. So with this condition in place, the masquerade will only apply to packets for which no IPsec policy exists.

Thank you for your advice - it’s amazing. This is exactly what I was looking for.

So in the future I understand that the sequence is as follows:

  1. routing
  2. firewall
  3. NAT
  4. IPSec policy

I still have a question, how can I test if ipsec is available? In case of unavailability, direct the traffic to the local WAN interface

This is a pretty incomplete sequence. Please see the packet flow diagrams

As part of the overall security concept provided by IPsec, if a policy is present, the packets matching it are neither sent outside the security association bound to that policy nor accepted if received outside that security association. This happens (or at least should happen) even the policy is not active. So if your policy is statically configured, you have to disable it using a script if you want the traffic to take another path when the SA is down. Policies dynamically created from a template are a different thing, they only exist while the IPsec “control session” is up.

So set up the “normal” routing to route the packets the way you need them to be routed when IPsec is down. IPsec policies will override this whenever existing and enabled. For statically configured policies, you have to use a script to disable/re-enable them; as there is no script item associated to peer or identity, allowing to trigger the execution of the script at each state change of a given IPsec session, it has to be a periodically scheduled script which checks the /ip ipsec active-peers table.

I searched the forum and couldn’t find a similar script that checked this / ip ipsec active-peers parameter. Can you show me what it would look like?

Only the script that checks ipsec sa was found:

:if ([/ping 10.6.51.11 interval=3 count=3]<2) do={
:log warning "IPSec KO, flushing SAs"
/ip ipsec installed-sa flush sa-type=all
} else={
:log info "IPSec OK"
}

When you want a plain tunnel between office branches that you can use to route whatever you like and still maintain the option to have local traffic to internet at both sites, it is better to change from direct IPsec tunnel to GRE/IPsec (or IPIP/IPsec) tunnel.
That will give you a virtual interface at each end where you can dump any traffic you want to send to the other side, without having to adjust the IPsec settings.
(in this configuration there is IPsec transport between the external addresses of the routers and only for protocol 47 (or 4), which is used to encrypt the GRE tunnel traffic)
The advantage of this configuration is that you can use all the powerful route marking, priority tagging, automatic routing etc etc mechanisms available in RouterOS without having to constantly struggle with the cut-through at the lowest layer that a direct IPsec tunnel does.

If you nevertheless prefer to stick with bare IPsec and its traffic selectors, the way to determine the peer state is something like
:if ([/ip ipsec active-peers get [find id=192.168.227.13] state] = “established”) do={:put “peer UP”} else={:put “peer DOWN”}
Pinging through the SA (e.g. using /tool netwatch) is definitely a faster way to detect an outage, however it cannot be used to re-enable the policy due to the chicken-and-egg problem. So you’d need one policy with a narrow selector, to allow for the diagnostic pinging, and another one for the actual data which would be enabled/disabled.
With the default settings (dpd-interval=2m dpd-maximum-failures=5), the DPD (Dead Peer Detection) mechanism normally reacts in minutes. Also, it does not check transparency of the SAs, so you can have a “clogged” SA e.g. due to a rekeying error, and the DPD won’t do anything.

If you follow @pe1chl’s solution, you can run the diagnostic ping through the GRE or IPIP tunnel all the time, and let the “normal” routes through that tunnel get inactivated if the pings stop being responded, I believe setting check-gateway=ping at the route is sufficient for this; the check periodicity was 10 seconds and could not be changed when I was looking at that the last time.

Thank you very much for your advice.
I will definitely test the options with the IP-IP tunnel. I understand that:
1.first, I connect the IP-IP tunnel
2. How does it add encryption to this tunnel? Is there any example of such a configuration somewhere?

You only need to make an IPIP (or GRE) tunnel and set the IPsec secret in the tunnel config. In that case you also need to set the Local address, it cannot be left blank.
RouterOS will then automatically create the required IPsec config. You can also do that manually when you want it to be slightly different. In fact, you can first try with the IPsec secret, watch the IPsec config tabs for the dynamically generated config, note it down, remove the IPsec secret, and then create that same IPsec config manually.

To complete the config, you set a /30 address on either end of the tunnel (from a network you do not yet use, e.g. 10.0.0.1/30 and 10.0.0.2/30) and then you can use normal routing to send the traffic to the other end (e.g. a static route to 192.168.1.0/24 via 10.0.0.2). You can also use automatic routing like BGP or OSPF.

I am running site to site connection via VPN IPSEC. Site A is running a UDM-SE router and site B is running a mikrotik. I configured IPSec on both routers but one main challenge i find it in the pinging of packets.
At every daily basis, you find the VPN IPsec on the UDM-SE Site A up and running and the Mikrotik on site B has the connections of the Policies in IPSec well established. How ever, when you ping the source address on the mikrotik (site A) from Site B it always times out and I have to disable and enable policies in the mikrotik to have a reply. I find this tiresome and a daily process.
How can I configure my mikrotik to have the pings from site A be replying all the time with out disabling and enabling on the mikrotik site B router?

The issue you describe is definitely not “normal” so it is either a misconfiguration or some issue between the Mikrotik’s and Ubiquiti’s implementations of IPsec. So as the first step, post the export of the Mikrotik configuration (after proper obfuscation - serial numbers, public addresses, logins to external services) and also the ouput of /ip ipsec installed-sa print detail - there, only obfuscate public addresses (if any), you can also obfuscate the keys but as they are ephemeral, they become useless in 30 minutes at the latest.