Community discussions

MikroTik App
 
linerov
just joined
Topic Author
Posts: 11
Joined: Mon Jan 17, 2022 1:41 am

Updating NAT rule on interface IP address change (DHCP client)

Tue Oct 11, 2022 1:49 pm

Hi All,

The need is to have the NAT rule allowing access to DMZ server.
Current implementation uses as selector: in-interface-list=WAN
chain=dstnat action=dst-nat to-addresses=192.168.1.1 to-ports=10443 protocol=tcp [b]in-interface-list=WAN[/b] dst-port=443 log=no 
      log-prefix="" 
This works only for traffic arriving from outside and better would be to have selector by IP address of Mikrotik WAN interface.

After reading it seems like there's no easy way outside of going for scripting:
# https://wiki.mikrotik.com/wiki/Manual:S ... ve_changed
:global currentIP;

:local newIP [/ip address get [find interface="ether1"] address];

:if ($newIP != $currentIP) do={
    :put "ip address $currentIP changed to $newIP";
    :set currentIP $newIP;
}
The second problem is that on that external interface with IP set by DHCP server, there's another static local IP. I am not sure how to modify the script to select only the DHCP IP and not the static one? (if there would be sort of "grep -v" I could grep out the unwanted one).

With that said, am not sure what's the best way to amend existing NAT rule.
Looking at syntax, the only selector for rule to be amended is rule#, which might change over the time as NAT rules would be updated and all of the sudden script could be modifying wrong rule
/ip firewall nat edit number=....
What is better way to do it? The best would be is there would be a built-in list of objects, like IP addresses on interfaces and easy to use.
Looking at it for the second time, probably better will be to use Address List, which would be updated by script instead of the rule - though same worry comes - how to select the right one, as the Number is not the best selector.

Regardless of the worry of amending the rule, feeling is that the action should be added straight after
:set currentIP $newIP;
Please share if there are better ways to achieve this - seems like a common use case hence am finding surprising that it is that difficult.
Last edited by linerov on Thu Oct 13, 2022 5:16 pm, edited 2 times in total.
 
Sob
Forum Guru
Forum Guru
Posts: 9119
Joined: Mon Apr 20, 2009 9:11 pm

Re: Updating NAT rule on interface IP address change (DHCP client)

Tue Oct 11, 2022 2:59 pm

You want DHCP lease script. Check this: viewtopic.php?t=179343, mainly "(iii) DYNAMIC WAN IP" part.
 
linerov
just joined
Topic Author
Posts: 11
Joined: Mon Jan 17, 2022 1:41 am

Re: Updating NAT rule on interface IP address change (DHCP client)

Tue Oct 11, 2022 3:22 pm

Thank you!
I'm having some difficulties to understand these scripts. Looking at docs, can't find a good description of it - hence asking here.

In my case, due to two IP addresses on the ext interface:
/ip address> print where interface="ether1ext"
Flags: X - disabled, I - invalid, D - dynamic 
 #   ADDRESS            NETWORK         INTERFACE                                                                                     
 0   ;;; Bridge mode access to device behind
     192.168.200.5/24   192.168.200.0   ether1ext                                                                                     
 1 D 1.2.3.4/22         1.2.3.0         ether1ext     
The script might be falling, though it uses
$"lease-address"
- not sure if this works at all as even running as script
[code[/ip firewall address-list set [/ip firewall address-list find where comment="wan1ip"] address=$"lease-address" disabled=no[/code]
Leaves me with that set to 0.0.0.0.

Additionally, the "$bound=1" - doesn't seem to be set on my system.
Due to all these question marks, am wondering - how scripts could be troubleshoot, i.e. run from console?
:if ($bound=1) do={
/ip firewall address-list set [/ip firewall address-list find where comment="wan1ip"] address=$"lease-address" disabled=no
} else={
/ip firewall address-list set [/ip firewall address-list find where comment="wan1ip"] disabled=yes
}
Trying to go through that on my own, it seems like it tries to use these details (though that portion of the script referenced, doesn't include all these checks:
 /ip dhcp-client print where interface=ether1ext
Flags: X - disabled, I - invalid, D - dynamic 
 #   INTERFACE                                                         USE-PEER-DNS ADD-DEFAULT-ROUTE STATUS        ADDRESS           
 0   ;;; defconf
     ether1ext                                                         no           yes               bound         1.2.3.4/22
     
I'm still in deep woods around how to test script from command line to get some output/debug to see what/where/why fails.

Thanks in advancce for help!

p.s. am going through https://wiki.mikrotik.com/wiki/Manual:S ... and_Tricks
It's just not all user friendly - well not that easy as with python/bash/perl or even ANSII C ;)
 
Sob
Forum Guru
Forum Guru
Posts: 9119
Joined: Mon Apr 20, 2009 9:11 pm

Re: Updating NAT rule on interface IP address change (DHCP client)

Tue Oct 11, 2022 3:34 pm

The script belongs to DHCP client, which sets all required variables before it runs it. Other than that, debugging scripts in RouterOS is generally PITA, but in this case it shouldn't be a problem, just put it in right place and it must work.
 
linerov
just joined
Topic Author
Posts: 11
Joined: Mon Jan 17, 2022 1:41 am

Re: Updating NAT rule on interface IP address change (DHCP client)

Tue Oct 11, 2022 4:41 pm

Thanks @Sob. Would you mind to share more light on what you mean by runs as part of DHCP client? Is there a hook to attach script to DHCP client, once it runs/ip changes instead of blindly running it every X time?

I got it done based on scheduler, here is what works for me:
:global currentIPext;
:local bound [/ip dhcp-client get [find interface="ether1ext"] status];
:local leaseIP [/ip dhcp-client get [find interface="ether1ext"] address];

:if ($bound="bound") do={
  :if ($leaseIP != $currentIPext) do={
      :put "ip address $currentIPext changed to $leaseIP";
       /ip firewall address-list set [/ip firewall address-list find where comment="extIP-MikroTik"] address=$"leaseIP" disabled=no
      :set currentIPext $leaseIP;
  }
} else={
/ip firewall address-list set [/ip firewall address-list find where comment="extIP-MikroTik"] disabled=yes
}
This is added to scheduler run every 10 mins with "onEvent"
/system script run updateExtIP
 
Sob
Forum Guru
Forum Guru
Posts: 9119
Joined: Mon Apr 20, 2009 9:11 pm

Re: Updating NAT rule on interface IP address change (DHCP client)  [SOLVED]

Tue Oct 11, 2022 5:08 pm

It's exactly as you expect, DHCP client runs the script when it gets or loses address. Open properties of DHCP client (in WinBox or WebFig) and there's field for script, on/in Advanced tab/section. Or in CLI:
/ip dhcp-client set <other options> script="<code>"
 
linerov
just joined
Topic Author
Posts: 11
Joined: Mon Jan 17, 2022 1:41 am

Re: [SOLVED] Updating NAT rule on interface IP address change (DHCP client)

Thu Oct 13, 2022 6:03 pm

@Sob - thank you - that made the script even more simple.
I need to take a bit of a shame on me, that this time I didn't go and check docs around DHCP client - it is indeed there described, also variables.

Thanks again for all the help!
 
PhilipPeake
just joined
Posts: 14
Joined: Wed Jun 09, 2010 5:36 am

Re: Updating NAT rule on interface IP address change (DHCP client)

Sat Jul 01, 2023 7:11 pm

@sob @linerov
I find this thread really interesting, since it looks like I will be moving from a connection with a static IP to one with a a dynamic IP (sad Comcast story...).

Unfortunately, I am not really familiar with MikroTik coding (I am using an RB4011), I do pretty much all the config via the GUI.
All of my DSTNAT rules had the source address hard coded - then I read this, and replaced the address with a firewall list containing just that address - why did I never think of that?!?! - Works like a charm, now only one thing to change if the external IP changes.

Now on to detecting that change and updating the list address...

In the original link, and in @linerov's (IMHO cleaner) version, I see this:
set [/ip firewall address-list find where comment="extIP-MikroTik"] address=$"leaseIP" disabled=no
A couple of questions:

1) Why find the list by its comment field content? Why not just use its name?
2) Why flip the enable/disable flag? I can see ensuring that it is enabled when we have a valid WAN IP, but otherwise I don't see a lot of difference between disabling it and having a value in it which will never be seen?

Who is online

Users browsing this forum: ko00000000001 and 17 guests