IPSEC VPN hub questions

Hello,

I have a couple of mikrotik routers connected through an IPSEC VPN:

central mikrotik router (static public IP) <---------> remote cpe (dynamic public IP) <-------->remote mikrotik router (non public IP)
172.30.254.250/32 172.30.254.3/32

Using this guide RouterOS - RouterOS - MikroTik Documentation", and it's working fine with these 2 endpoints.

However I'm trying to add another remote router under the same conditions (NAT, dynamic IP) but it's not working as I expected.

These are my configs,

Central router:

/ip ipsec mode-config
add address=172.30.254.3 address-prefix-length=32 name=Td3 split-include=172.30.254.250/32 system-dns=no
add address=172.30.254.4 address-prefix-length=32 name=Td4 split-include=172.30.254.250/32 system-dns=no
/ip ipsec policy group
add name=Tds
/ip ipsec profile
add dh-group=ecp256,modp2048,modp1024 enc-algorithm=aes-256,aes-192,aes-128 name=ike2f1
/ip ipsec peer
add exchange-mode=ike2 name=Td3 passive=yes profile=ike2f1 send-initial-contact=no

This entry is unreachable

add exchange-mode=ike2 name=Td4 passive=yes profile=ike2f1 send-initial-contact=no
/ip ipsec proposal
add auth-algorithms="" enc-algorithms=aes-128-gcm name=ike2f2 pfs-group=none
/ip ipsec identity
add generate-policy=port-strict mode-config=Td3 peer=Td3 policy-template-group=Tds secret=testvpn
add generate-policy=port-strict mode-config=Td4 peer=Td4 policy-template-group=Tds secret=testvpn
/ip ipsec policy
add dst-address=172.30.254.3/32 group=Tds proposal=ike2f2 src-address=172.30.254.250/32 template=yes
add dst-address=172.30.254.4/32 group=Tds proposal=ike2f2 src-address=172.30.254.250/32 template=yes

remote router A:

/ip ipsec mode-config
add name=Td3 responder=no
/ip ipsec policy group
add name=Tds
/ip ipsec profile
add dh-group=ecp256 enc-algorithm=aes-256 name=ike2f1
/ip ipsec peer
add address=./32 exchange-mode=ike2 local-address=172.30.254.253 name=Cor profile=ike2f1
/ip ipsec proposal
add auth-algorithms="" enc-algorithms=aes-128-gcm name=ike2f2 pfs-group=none
/ip ipsec identity
add generate-policy=port-strict mode-config=Td3 peer=Cor policy-template-group=Tds secret=testvpn
/ip ipsec policy
add dst-address=172.30.254.250/32 group=Tds proposal=ike2f2 src-address=172.30.254.253/32 template=yes

after adding the second router config, I got this message of "# This entry is unreachable" under the peer section and that tunnel is not working

Can you advice what is wrong with my config?

First of all, a lot is wrong with your post, please edit it and use this site’s formatting capabilities instead of html.

Second, it’s a misunderstanding of how the structure of IPsec configuration works.

You don’t need a separate configuration object “peer” for each actual remote peer (a device). In your scenario, the actual IP addresses of the remote devices are unknown in advance, so the peer object must accept initial requests from any source address, which is expressed by setting its address parameter to 0.0.0.0/0, which is the default value so it is not shown in configuration export. Hence the second peer is “unreachable”, because the previous one has exactly the same match parameters to which the incoming initiation requests are compared - address, exchange-mode, and local-address. So all the incoming initial requests which come will be matched by the previous peer.

As the remote device cannot be identified by its IP address, you have two possibilities - either to accept incoming connections from anywhere if they know the secret, which means a single /ip ipsec identity linked to the /ip ipsec peer will be used for all of them, or to start using the IPsec IDs to distinguish the clients from one another and let each of them use their own secret. In this case, you have to specify the remote-id for each /ip ipsec identity row at the responder (the hub) and set a matching my-id in the single /ip ipsec identity row at the initiator (the remote “client”). And doing so allows you to also link an individual mode-config row to each identity, so you can provision each remote peer device with a pre-assigned IP address.

Sindy, thanks for your advice. Now I’m able to configure different remote sites with a working tunnel.

After some days of testing I noticed that some remote sites were turned off at night because there’s no activity after hours and next morning when the remote mikrotik is turned back on, the IPSec tunnel is restored but the GRE tunnel is not.

The only way I found to make it work again was to first modify the GRE tunnel (on the remote side) with local-address as 0.0.0.0 and then restored the original local-address, which is the looopback interface associated to bridge interface.

Using sniffer and ip firewall connections I found that when the problem is present (GRE tunnel down), it always uses the WAN (ether1) IP address as the reply-dst-address,
/int gre p
Flags: X - disabled, R - running
0 name=“TunelC5” mtu=auto actual-mtu=1414 local-address=172.30.254.253 remote-address=172.30.254.250 keepalive=10s,10 dscp=inherit clamp-tcp-mss=yes dont-fragment=no
allow-fast-path=yes
/ip firewall conn print det
3 C s protocol=gre src-address=172.30.254.253 dst-address=172.30.254.250 reply-src-address=172.30.254.250 reply-dst-address=192.168.15.45 gre-key=0 timeout=27s
orig-packets=23 orig-bytes=1 104 orig-fasttrack-packets=0 orig-fasttrack-bytes=0 repl-packets=0 repl-bytes=0 repl-fasttrack-packets=0
repl-fasttrack-bytes=0 orig-rate=0bps repl-rate=0bps

after changed local-address to 0.0.0.0 and back to 172.30.254.253, it works,
/int gre p
Flags: X - disabled, R - running
0 R name=“TunelC5” mtu=auto actual-mtu=1414 local-address=172.30.254.253 remote-address=172.30.254.250 keepalive=10s,10 dscp=inherit clamp-tcp-mss=yes dont-fragment=no
allow-fast-path=yes
/ip firewall conn p d
6 SAC protocol=gre src-address=172.30.254.250 dst-address=172.30.254.253 reply-src-address=172.30.254.253 reply-dst-address=172.30.254.250 gre-key=0 timeout=2m59s
orig-packets=9 orig-bytes=336 orig-fasttrack-packets=0 orig-fasttrack-bytes=0 repl-packets=42 repl-bytes=3 876 repl-fasttrack-packets=0
repl-fasttrack-bytes=0 orig-rate=0bps repl-rate=864bps

Also tried disabling/enabling the GRE tunnel with no luck.

Can you advice?

Thanks in advance

I already have a support ticket open on this issue. There’s something wrong with connection tracking of GRE “sessions” in the firewall, there was a vulnerability in GRE handling by the firewall which has been fixed, but the fix has brought some unexpected issues.

And the way how GRE keepalive has been implemented makes things even less obvious.

When things work normally in connection tracking and keepalive is activated in the configuration of GRE interface at both ends, both ends send GRE packets to each other periodically (the keepalive ones), so the tunnel gets up even if the firewall drops everything coming form outside except connection-state=established, because each end creates an “established” connection in its own firewall. But when connection tracking of GRE is broken, you have to add some permissive rules to the firewall as a workaround.

Assuming that you have a proper restrictive firewall which drops anything that you haven’t explicitly permitted, you have to add a rule
action=accept chain=input protocol=gre ipsec-policy=in,ipsec src-address-list=permitted-gre-peers
to /ip firewall filter, at the right place somewhere between the action=drop chain=input connection-state=invalid one and the final “drop the rest” one in chain input (the elements in grey must be customized to your situation, but in order not to deny the purpose of the firewall, at least one of them must be present; of course, if you use the address-list, you have to fill it with the relevant IP addresses).
Even if you do not have the “drop the rest” rule in the end of chain=input, you have to add protocol=!gre to the existing action=drop chain=input connection-state=invalid rule, because the connection tracking in some cases labels incoming GRE packets as connection-state=invalid.

But the above is just one part of the story. You also have to take care about the keepalive “responses” to be let through if you use them, otherwise the interfaces would never come up. And here one needs to know that the keepalive implementation in GRE is very clever in terms that it doesn’t require any special responder functionality, because the keepalive “request” carries, as its payload, another GRE packet which the recipient of the “request” handles exactly the same way as any other packet unpacked from the received GRE one, and its source address is the one of the keepalive “responder” and the destination address is the one of the “requestor”. This idea works fine, but from the point of the firewall, such packet is not an output one (sent by the “responder” itself) but a forwarded one (as its in-interface is the GRE interface). So again, if you have a proper firewall which doesn’t let anything through “implicitly”, you have to add rules explicitly permitting these keepalive “responses” to be forwarded.

So I’ve solved this part the following way:
/interface list add name=all-gre
:foreach greIF in=[/interface gre find] do={/interface list member add list=all-gre interface=$greIF}

And then, on an appropriate place in the forward chain, add the following rule:
action=accept chain=forward in-interface-list=all-gre src-address-type=local protocol=gre