IKEv2 VPN with DNS in another internal VLAN

Hi everyone!
Looking for a help in configuring DNS in IKEv2. Internal routing is done via L3-switch. Switch routes traffic through vlan150 to MT. Local network to access through VPN is in vlan100. AD DNS servers are in vlan 200. All addresses are in format 10.vlanid.x.x (e.g. DNS servers are 10.200.0.x, LAN addresses are 10.100.x.x). I do include 10.100.0.0/16 as split-include. Windows clients only accept first split-include, so I can’t also include DNS-subnet. Can I add some sort of “virtual” IP to DNS property of split-include, and forward traffic to it internally into the real internal IPs? Like add something like 10.100.255.254 and NAT it to 10.200.0.x?

Here’s related configuration parts:

# apr/16/2024 00:22:45 by RouterOS 6.49.13
# software id = 6TTH-KAVK
#
# model = 2011iL
# serial number = 5BEC04B45E97

/interface bonding
add forced-mac-address=4C:5E:0C:EC:67:2E lacp-rate=1sec mode=802.3ad name=\
    switchLacp slaves=ether4,ether2 transmit-hash-policy=layer-2-and-3
/interface vlan
add interface=switchLacp name=InternetOnly vlan-id=50
add interface=switchLacp name=LAN vlan-id=100
add interface=switchLacp name=Management vlan-id=20
add interface=switchLacp name=RouterGW vlan-id=150
add arp=reply-only interface=switchLacp name=Voice vlan-id=40
add arp=reply-only interface=switchLacp name=WiFi vlan-id=10
/interface list
add name=Gateway
/interface wireless security-profiles
set [ find default=yes ] supplicant-identity=MikroTik
/ip ipsec policy group
add name=IKEv2
/ip ipsec profile
add enc-algorithm=aes-256,aes-128 hash-algorithm=sha256 name=IKEv2Profile
/ip ipsec peer
add exchange-mode=ike2 local-address=*WHITE_IP* name=IKEv2Peer passive=\
    yes profile=IKEv2Profile
/ip ipsec proposal
add auth-algorithms=sha512,sha256,sha1 enc-algorithms="aes-256-cbc,aes-256-ctr\
    ,aes-256-gcm,aes-192-cbc,aes-192-ctr,aes-192-gcm,aes-128-cbc,aes-128-ctr,a\
    es-128-gcm" lifetime=1h name=proposal_IKEv2 pfs-group=none
/ip pool
add name=l2tpPool ranges=192.168.230.0/24
add name=IKEv2Pool ranges=192.168.210.2-192.168.210.254
add name=DHCP_InternetOnly ranges=10.50.0.2-10.50.255.254
/ip ipsec mode-config
add address-pool=IKEv2Pool address-prefix-length=16 name=IKE split-include=\
    10.100.0.0/16 static-dns=10.100.0.10 system-dns=no
add address-pool=IKEv2Pool name=ManagementVLAN split-include=10.20.0.0/16
/snmp community
set [ find default=yes ] addresses=0.0.0.0/0
/certificate settings
set crl-use=yes
/interface l2tp-server server
set authentication=mschap2 default-profile=VPN230 enabled=yes use-ipsec=yes
/interface list member
add interface=ether1 list=Gateway
/ip address
add address=*WHITE_IP*/25 comment=WAN interface=ether1 network=\
    *ISP_GW*
add address=10.10.0.2/16 interface=WiFi network=10.10.0.0
add address=10.150.0.2/30 interface=RouterGW network=10.150.0.0
add address=10.40.0.1/16 interface=Voice network=10.40.0.0
add address=10.50.0.1/16 interface=InternetOnly network=10.50.0.0
/ip dhcp-client
add disabled=no interface=Management
add disabled=no interface=WiFi
add dhcp-options=clientid disabled=no interface=LAN
/ip firewall address-list
add address=*WHITE_IP* list=RealIP
add address=10.100.0.0/16 list="Hairpin NAT"
add address=10.10.0.0/16 list="Hairpin NAT"
add address=192.168.188.0/24 list="Hairpin NAT"
/ip firewall filter
add action=add-src-to-address-list address-list=port_scanners \
    address-list-timeout=2w chain=input comment="Port scanners to list" \
    in-interface-list=Gateway log=yes protocol=tcp psd=21,3s,3,1
add action=add-src-to-address-list address-list=port_scanners \
    address-list-timeout=2w chain=input in-interface-list=Gateway protocol=\
    tcp tcp-flags=fin,!syn,!rst,!psh,!ack,!urg
add action=add-src-to-address-list address-list=port_scanners \
    address-list-timeout=2w chain=input in-interface-list=Gateway protocol=\
    tcp tcp-flags=fin,syn
add action=add-src-to-address-list address-list=port_scanners \
    address-list-timeout=2w chain=input in-interface-list=Gateway protocol=\
    tcp tcp-flags=syn,rst
add action=add-src-to-address-list address-list=port_scanners \
    address-list-timeout=2w chain=input in-interface-list=Gateway protocol=\
    tcp tcp-flags=fin,psh,urg,!syn,!rst,!ack
add action=add-src-to-address-list address-list=port_scanners \
    address-list-timeout=2w chain=input in-interface-list=Gateway protocol=\
    tcp tcp-flags=fin,syn,rst,psh,ack,urg
add action=add-src-to-address-list address-list=port_scanners \
    address-list-timeout=2w chain=input in-interface-list=Gateway protocol=\
    tcp tcp-flags=!fin,!syn,!rst,!psh,!ack,!urg
add action=accept chain=input connection-state=established,related
add action=accept chain=input comment=VPN dst-port=1701,500,4500 protocol=udp
add action=accept chain=input protocol=icmp
add action=accept chain=input in-interface=Management
add action=drop chain=input
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward in-interface=RouterGW out-interface-list=\
    Gateway
add action=accept chain=forward in-interface=WiFi out-interface-list=Gateway
add action=accept chain=forward in-interface=InternetOnly out-interface-list=\
    Gateway
add action=accept chain=forward comment="Allow NAT" connection-nat-state=\
    dstnat connection-state=new
add action=accept chain=forward comment="L2TP forward rule" in-interface=\
    all-ppp out-interface=LAN
add action=accept chain=forward comment="IKEv2 forward rule" ipsec-policy=\
    in,ipsec out-interface=LAN
add action=accept chain=forward dst-address=10.20.0.0/16 ipsec-policy=\
    in,ipsec
add action=drop chain=forward comment="Drop everything else"
/ip firewall nat
add action=src-nat chain=srcnat out-interface-list=Gateway to-addresses=\
    *WHITE_IP*
add action=src-nat chain=srcnat src-address-list="Hairpin NAT" to-addresses=\
    10.150.0.2
/ip firewall raw
add action=drop chain=prerouting log-prefix="port_scanner drop" \
    src-address-list=port_scanners
add action=drop chain=prerouting src-address-list=Blacklist
/ip ipsec policy
add dst-address=192.168.210.0/24 group=IKEv2 proposal=proposal_IKEv2 \
    src-address=0.0.0.0/0 template=yes
/ip route
add check-gateway=ping distance=1 gateway=*ISP_GW*
add distance=1 dst-address=10.200.0.0/29 gateway=10.150.0.1 pref-src=\
    10.150.0.2

Any ideas on that?
What I’ve tried so far:

  1. Enable DNS on Mikrotik itself, enable remote requests. Add an address on LAN interface. Add FW rule chain input, dst address - LAN ip, protocol udp, port 53 - counters increase on this rule. Pings are ok from VPN to LAN ip (e.g. 10.100.0.250/24). DNS cache is created on mikrotik for responses, but VPN clients doesn’t receive response (Powershell Resolve-DnsName -server “Lan ip” “internal record” - returns timeout).
  2. Create an address on LAN interface. Add netmap rule from this address to the actual DNS server. Counters increase on this rule, but PS test is same - timeout

set the correct DNS l.ip of vlan200 in the ike conf and create a rule where the traffic coming from ike is destined for the DNS server therefore protocol udp dst-port 53 action masquerade

How clients would know about this ip (10.200.0.2/29 in my case), if the only route pushed is for vlan100 (10.100.0.0/16)? I know multiple routes is acceptable configuration in MikroTik, but most OSes only take first route into account. Adding a custom route on clients is, well, not very desired solution for the problem.

Any ideas on how to accomplish this?

The PPP profile for the VPN sets the DNS and WINS server if need be … set an address don’t leave it blank and the client uses it.

Its the last entries before the radio boxes for Change TCP MSS

That’s what I’m doing already - in ip/ipsec/mode configs I have System DNS unchecked and manual DNS address is set. It works perfectly fine now, the question is not about this. Here’s a visualized setup I have now

The setup works fine for now; however, the red text info is the problem here. Near the IKEv2 client box I’m showing current settings pushed to clients.

I’ve tried DNS remote requests on mikrotik with RB having IP address in vlan100. When DNS request is received, correct dns record appends to MT dns cache, however the client doesn’t receive it - seems like some kind of firewall issue, but adding an input accept rule to udp port 53 didn’t do the trick.

Another idea was to somehow have some kind of ghost IP on RB and NAT all DNS traffic to internal servers - dunno if this is even possible, but that’s what I’m asking. If it is possible, this looks like a better idea for me, to bypass remote requests feature.

Yes of course that is possible, that is just a dst-nat rule (possibly combined with a src-nat rule to translate the source address as well)…
I thought you already tried that.

Yes, I’ve tried that, but maybe did something wrong since it didn’t do the job for me. What I did was:

  1. 10.100.0.2/16 on LAN interface (vlan100)
  2. dst-nat rule protocol=udp dst-port=53 dst-address = 10.100.0.2 action dst-nat to address=10.200.0.2 to port=53 (have an /ip/route to 10.200.0.0/29 through 10.150.0.1 reachable)

Not tried src-nat rule, however I have a hairpin rule in first post and tried adding DC subnet to the list, that didn’t work either

What I’ve tried now:

/interface bridge
add arp=disabled name=lo protocol-mode=none

/ip address
add address=10.100.2.0 interface=lo network=10.100.2.0

/ip firewall nat
add action=dst-nat chain=dstnat dst-address=10.100.2.0 dst-port=53 \
    ipsec-policy=in,ipsec protocol=udp to-addresses=10.200.0.2 to-ports=53

10.100.2.0 is pingable through ipsec interface
The last rule I’ve tried with and without ipsec-policy parameter. The traffic is not passing through the rule.

I also added

/ip firewall filter
add action=accept chain=input connection-nat-state=dstnat connection-state=new log=yes

Now I feel lost at the point

It is impossible to debug such things remotely. All I know is that such constructs work for me.

Maybe you can provide an example config with firewall rules and if/ip configuration that works with IPSec, so I can adjust it to my config? That would be nice

I’ve added a firewall rule to input chain

add action=accept chain=input connection-nat-state="" connection-state="" ipsec-policy=in,ipsec log=yes

Now in logs I see

input: in:ether1 out:(unknown 0), src-mac 00:00:5e:00:01:0f, proto UDP, 192.168.210.252:57921->10.100.2.0:53, len 73

Why is this packet not catched by dst-nat rule above?

While investigating CHR in my test vm, I can see there’s input/output chains in NAT in ROS7 now, seems like it’s what I’m looking for, but there’s no such option in 6.49. Is there any workaround for this or should I upgrade to ROS7?