L2TP DHCP Relay ICMP Port Unreachable

Hello everyone. After a few days of battling mikrotik, i’ve finally decided to come here for help.

There’s a dead simple network topology, R1 being the DHCP and L2TP server, R2 being the “remote client” DHCP relay and L2TP client. Pictured on F1.
F1.PNG
There are local area networks behind both routers.
Imagine link between R1 and R2(ether1 on both) is the internet.
The task is to provide site-to-site link (without BCP) in order to get LAN to LAN connectivity.

When using PPTP(GRE tunnel) - the dhcp relay works as expected.
When setting up an L2TP tunnel(or an IPSec tunnel, not much difference), the DHCP relay-retransmitted DHCP Discover packets are being discarded by the R1 with an ICMP Type 3 Code 3(Port Unreachable).
There is no firewall set up.

The situation is reproducible with or without any additional routers or switches between routers.

Remote telnet works, the routers can ping each other, and the packets are being compressed and encrypted into L2TP tunnel as seen in Wireshark or /tool sniffer.

There is no difference whether local-address and dhcp-server addresses are set to in-L2TP(172.16..) addresses or internal(10…) addresses.

R1 export:

# aug/29/2017 07:47:29 by RouterOS 6.39.2
# software id =
#
/interface l2tp-server
add name=R2 user=R2
/ip pool
add name=dhcp_pool0 ranges=10.1.1.2-10.1.1.254
add name=dhcp_pool1 ranges=10.2.1.2-10.2.1.254
/ip dhcp-server
add address-pool=dhcp_pool1 disabled=no interface=ether2 name=dhcp2 relay=172.16.1.2
add address-pool=dhcp_pool0 disabled=no interface=ether2 name=dhcp1
/interface l2tp-server server
set enabled=yes
/ip address
add address=192.168.1.1/24 interface=ether1 network=192.168.1.0
add address=10.1.1.1/24 interface=ether2 network=10.1.1.0
/ip dhcp-server network
add address=10.1.1.0/24 dns-server=10.1.1.1 gateway=10.1.1.1
add address=10.2.1.0/24 dns-server=10.2.1.1 gateway=10.2.1.1
/ip route
add distance=1 gateway=ether1
/ppp secret
add local-address=172.16.1.1 name=R2 password=l2tpassword1 remote-address=172.16.1.2 routes=\
    "10.2.1.0/24 172.16.1.2 1" service=l2tp
/system logging
add topics=dhcp
add topics=debug

R2 export:

# aug/29/2017 07:47:57 by RouterOS 6.39.2
# software id =
#
/interface l2tp-client
add connect-to=192.168.1.1 disabled=no name=l2tp-out1 password=l2tpassword1 user=R2
/ip address
add address=192.168.2.1/24 interface=ether1 network=192.168.2.0
add address=10.2.1.1/24 interface=ether2 network=10.2.1.0
/ip dhcp-relay
add dhcp-server=10.1.1.1 disabled=no interface=ether2 local-address=10.2.1.1 name=relay1
/ip route
add distance=1 gateway=ether1
add distance=1 dst-address=10.1.1.0/24 gateway=172.16.1.1
/system logging
add topics=debug
add topics=dhcp

The problem is reproducible over the real internet and with real pair of mikrotik hAPs.

What is wrong? Why does it work with PPTP? Where to look?

Hello again everyone.

Changed my network topology. Added NAT gateway device, simulating ISP NAT, added a simple “internet” router to simulate ISP networks.
Moved DHCP Server to a separate router, in order to replicate the real topology.
Picture related:
F2.PNG
R1:

[admin@MikroTik] > /ip export
# sep/11/2017 09:26:27 by RouterOS 6.39.2
# software id =
#
/ip address
add address=1.1.1.2/24 interface=ether1 network=1.1.1.0
add address=10.0.0.1/24 interface=ether2 network=10.0.0.0
/ip firewall nat
add action=accept chain=srcnat dst-address=192.168.33.2 src-address=192.168.33.1
add action=masquerade chain=srcnat out-interface=ether1
/ip ipsec peer
add address=192.168.33.2/32 local-address=192.168.33.1 passive=yes secret=ipsecret1 send-initial-contact=no
/ip ipsec policy
add dst-address=10.0.1.0/24 sa-dst-address=192.168.33.2 sa-src-address=192.168.33.1 src-address=10.0.0.0/24 \
    tunnel=yes
/ip route
add distance=1 gateway=1.1.1.1
add distance=1 dst-address=10.0.1.0/24 gateway=l2tp-in1

R2:

[admin@MikroTik] > /ip export
# sep/11/2017 09:26:32 by RouterOS 6.39.2
# software id =
#
/ip address
add address=10.0.1.1/24 interface=ether2 network=10.0.1.0
add address=192.168.8.254/24 interface=ether1 network=192.168.8.0
/ip dhcp-relay
add dhcp-server=10.0.0.2 disabled=no interface=ether2 local-address=10.0.1.1 name=relay1
/ip firewall nat
add action=accept chain=srcnat dst-address=192.168.33.1 src-address=192.168.33.2
add action=masquerade chain=srcnat out-interface=ether1
/ip ipsec peer
add address=192.168.33.1/32 local-address=192.168.33.2 secret=ipsecret1
/ip ipsec policy
add dst-address=10.0.0.0/24 sa-dst-address=192.168.33.1 sa-src-address=192.168.33.2 src-address=10.0.1.0/24 \
    tunnel=yes
/ip route
add distance=1 gateway=192.168.8.1
add distance=1 dst-address=10.0.0.0/24 gateway=l2tp-out1

DHCP Relay works. However, when the R1 and R2 “talk” to each other, they obey the following logic:
Route look-up returns: dst-address=10.0.1.0/24 via l2tp-in1;
Src-address of l2tp-in is 192.168.33.1(static configuration);
Set src-address of a packet to 192.168.33.1, dst-address to 10.0.1.1(or 10.0.1.0/24);
Ipsec policy passes through that packet, and it is sent unencrypted via L2TP link.

I know there is a way to mark packets using /ip firewall mangle and then src-nat them, and i know that Sob has posted a solution to this somewhere, but I’ve lost the link, and can’t quite wrap my mind around packet marking.
The idea is that I need to mark any packet destined to 10.0.1.0/24 and source address 192.168.33.1, and then src-nat them, but won’t that affect anything else?
Is there a way to set a different gateway, so that the ip address would match? Would that approach require policy based routing or something?

I think any way of that will affect performance.

Update:
Researching packet flow diagrams gave me an idea.

First comes the NAT - we bypass it via /ip firewall add action=accept …;
Then comes routing decision source - the packet gets source address assigned;
Then comes ipsec policy matching - since ipsec is in tunnel mode, packet’s IP header is changed to sa-src and sa-dst addresses. The packet gets back to routing decision outbound, instead of going to routing decision destination, and is routed into l2tp.

So, in short: ipsec policy matching comes before routing.

R1:

[admin@MikroTik] > /ip route print
Flags: X - disabled, A - active, D - dynamic, C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme,
B - blackhole, U - unreachable, P - prohibit
 #      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
 0 A S  0.0.0.0/0                          192.168.8.1               1
 1 A S  10.0.0.0/24                        ether2                    1
 2 ADC  10.0.1.0/24        10.0.1.1        ether2                    0
 3 ADC  192.168.8.0/24     192.168.8.254   ether1                    0
 4 ADC  192.168.33.1/32    192.168.33.2    l2tp-out1                 0

R2:

[admin@MikroTik] > /ip route print
Flags: X - disabled, A - active, D - dynamic, C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme,
B - blackhole, U - unreachable, P - prohibit
 #      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
 0 A S  0.0.0.0/0                          1.1.1.1                   1
 1 ADC  1.1.1.0/24         1.1.1.2         ether1                    0
 2 ADC  10.0.0.0/24        10.0.0.1        ether2                    0
 3 A S  10.0.1.0/24                        ether2                    1
 4 ADC  192.168.33.2/32    192.168.33.1    l2tp-in1                  0

As you can see, the packet destined for another subnet is destined to a local interface, but is intercepted by ipsec and rerouted into l2tp interface.

Thanks wiki, nobody and Sob for helping me out, case solved.