Community discussions

MikroTik App
 
sbhokray
just joined
Topic Author
Posts: 14
Joined: Tue Jan 25, 2022 4:06 pm
Location: India
Contact:

question about the CGNAT script

Tue Jan 25, 2022 4:46 pm

hi!
I am looking out for an easy option to implement CGNAT in order to comply with the legal authority's in India.
as per the Mikrotik manual, below is the script to create some NAT entry's.

:global sqrt do={
:for i from=0 to=$1 do={
:if (i * i > $1) do={ :return ($i - 1) }
}
}

:global addNatRules do={
/ip firewall nat add chain=srcnat action=jump jump-target=xxx \
src-address="$($srcStart)-$($srcStart + $count - 1)"

:local x [$sqrt $count]
:local y $x
:if ($x * $x = $count) do={ :set y ($x + 1) }
:for i from=0 to=$x do={
/ip firewall nat add chain=xxx action=jump jump-target="xxx-$($i)" \
src-address="$($srcStart + ($x * $i))-$($srcStart + ($x * ($i + 1) - 1))"
}

:for i from=0 to=($count - 1) do={
:local prange "$($portStart + ($i * $portsPerAddr))-$($portStart + (($i + 1) * $portsPerAddr) - 1)"
/ip firewall nat add chain="xxx-$($i / $x)" action=src-nat protocol=tcp src-address=($srcStart + $i) \
to-address=$toAddr to-ports=$prange
/ip firewall nat add chain="xxx-$($i / $x)" action=src-nat protocol=udp src-address=($srcStart + $i) \
to-address=$toAddr to-ports=$prange
}
}

After pasting above script in the terminal function "addNatRules" is available. If we take our example, we need to map 6 shared network addresses to be mapped to 2.2.2.2 and each address uses range of 100 ports starting from 2000. So we run our function:

$addNatRules count=6 srcStart=100.64.1.1 toAddr=2.2.2.2 portStart=2000 portsPerAddr=100

now my question is, how will I add the out-interface too all this NAT rules created.
normally adding outt-interface to hundreds of NAT rules by hand is a never ending work for an ISP.
any work around?
thanks a lot in advance
Suman Bhokray
 
sbhokray
just joined
Topic Author
Posts: 14
Joined: Tue Jan 25, 2022 4:06 pm
Location: India
Contact:

Re: question about the CGNAT script

Thu Jan 27, 2022 4:30 pm

anyone?
 
Sob
Forum Guru
Forum Guru
Posts: 9119
Joined: Mon Apr 20, 2009 9:11 pm

Re: question about the CGNAT script

Thu Jan 27, 2022 5:28 pm

Just modify the script a bit, it's calling regular "/ip firewall nat add" commands, so if you need out-interface as extra parameter, add it there. Either with static value, or as another configurable parameter. Look at how it's done with e.g. "toAddr", you have toAddr=2.2.2.2 as script's parameter, and then it's added as to-address=$toAddr.
 
sbhokray
just joined
Topic Author
Posts: 14
Joined: Tue Jan 25, 2022 4:06 pm
Location: India
Contact:

Re: question about the CGNAT script

Tue Feb 01, 2022 9:19 pm

thank you. but I have zero knowledge in scripting. time to go school!
 
AidanAus
Member Candidate
Member Candidate
Posts: 177
Joined: Wed May 08, 2019 7:35 am
Location: Australia
Contact:

Re: question about the CGNAT script

Thu Feb 03, 2022 1:57 am

Its not about scripting really, as sob said all you need to do is add the command "out-interface=ether1" to the 2 lines at the bottom of the script where you add the TCP and UDP translations.

If you are after something that will just add an out interface to all existing nat rules you can use a foreach loop to do so :)
foreach i in=[ip firewall nat find] do={ ip firewall nat set $i out-interface=ether1}
 
sbhokray
just joined
Topic Author
Posts: 14
Joined: Tue Jan 25, 2022 4:06 pm
Location: India
Contact:

Re: question about the CGNAT script

Fri Feb 04, 2022 11:55 pm

its clear, let me try this. thank you so much to you both.
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: question about the CGNAT script

Sat Feb 05, 2022 12:07 am

Because only one manupilation is done, it can be shortened to:
/ip/firewall/nat/set out-interface=ether1 [find]
And giving the option to state different ether ports
:global sqrt do={
:for i from=0 to=$1 do={
:if (i * i > $1) do={ :return ($i - 1) }
}
}

:global addNatRules do={
/ip firewall nat add chain=srcnat action=jump jump-target=xxx \
src-address="$($srcStart)-$($srcStart + $count - 1)"

:local x [$sqrt $count]
:local y $x
:if ($x * $x = $count) do={ :set y ($x + 1) }
:for i from=0 to=$x do={
/ip firewall nat add chain=xxx action=jump jump-target="xxx-$($i)" \
src-address="$($srcStart + ($x * $i))-$($srcStart + ($x * ($i + 1) - 1))"
}

:for i from=0 to=($count - 1) do={
:local prange "$($portStart + ($i * $portsPerAddr))-$($portStart + (($i + 1) * $portsPerAddr) - 1)"
/ip firewall nat add chain="xxx-$($i / $x)" action=src-nat protocol=tcp src-address=($srcStart + $i) \
to-address=$toAddr to-ports=$prange out-interface=$interfaceOut
/ip firewall nat add chain="xxx-$($i / $x)" action=src-nat protocol=udp src-address=($srcStart + $i) \
to-address=$toAddr to-ports=$prange out-interface=$interfaceOut
}
}
When executing you add the interface you want to be used:
$addNatRules count=6 srcStart=100.64.1.1 toAddr=2.2.2.2 portStart=2000 portsPerAddr=100 interfaceOut=ether1
 
sbhokray
just joined
Topic Author
Posts: 14
Joined: Tue Jan 25, 2022 4:06 pm
Location: India
Contact:

Re: question about the CGNAT script

Sun Feb 06, 2022 4:58 pm

Because only one manupilation is done, it can be shortened to:
/ip/firewall/nat/set out-interface=ether1 [find]
And giving the option to state different ether ports
:global sqrt do={
:for i from=0 to=$1 do={
:if (i * i > $1) do={ :return ($i - 1) }
}
}

:global addNatRules do={
/ip firewall nat add chain=srcnat action=jump jump-target=xxx \
src-address="$($srcStart)-$($srcStart + $count - 1)"

:local x [$sqrt $count]
:local y $x
:if ($x * $x = $count) do={ :set y ($x + 1) }
:for i from=0 to=$x do={
/ip firewall nat add chain=xxx action=jump jump-target="xxx-$($i)" \
src-address="$($srcStart + ($x * $i))-$($srcStart + ($x * ($i + 1) - 1))"
}

:for i from=0 to=($count - 1) do={
:local prange "$($portStart + ($i * $portsPerAddr))-$($portStart + (($i + 1) * $portsPerAddr) - 1)"
/ip firewall nat add chain="xxx-$($i / $x)" action=src-nat protocol=tcp src-address=($srcStart + $i) \
to-address=$toAddr to-ports=$prange out-interface=$interfaceOut
/ip firewall nat add chain="xxx-$($i / $x)" action=src-nat protocol=udp src-address=($srcStart + $i) \
to-address=$toAddr to-ports=$prange out-interface=$interfaceOut
}
}
When executing you add the interface you want to be used:
$addNatRules count=6 srcStart=100.64.1.1 toAddr=2.2.2.2 portStart=2000 portsPerAddr=100 interfaceOut=ether1
many many thanks.
2 final questions before I implement this.
1. do I need to paste this script above in the terminal while am in the root. or do I need to navigate to /ip firewall nat and paste this.
2. will there will be any performance costs having this many nat entry's in nat, firewall? I will be adding around 512 addresses.
pasting the above script in putty dint work. I think this will only work in the terminal and I have to take my wife's support as the winbox and the terminal in the webfig is not accessible with the screen reading softwares.
once again, thank you guys, you were so good.
 
AidanAus
Member Candidate
Member Candidate
Posts: 177
Joined: Wed May 08, 2019 7:35 am
Location: Australia
Contact:

Re: question about the CGNAT script

Mon Feb 07, 2022 2:53 am

I would run this while at the root, there are delimiters at the front of actions and when moving around the configuration directories (like : and /) that should let it run from wherever but to keep it simple I would suggest running it from root.

As for the performance cost the script tries to get around this by using the jump targets, jump targets lets you match traffic and push it further down the firewall rules so the router does not have to check if the packet matches each rule.

For example my understanding is that if you have 20 firewall rules set up and if you left it how it is by default if your packet needed to hit the 11th rule it would have to go through all 10 rules behind it and check if this packet matches and the rule applies before getting to the 11th rule that applies to it.
If we make some changes to our rules and make our first 10 rules be in a chain called chain1 and the last 10 rules in a chain called chain2 what we then can do is make 1 more rule to filter out all the traffic that needs to get hit by chain2 and not by chain1 then set the action as jump so it then get moved all the way down the list to where chain2 starts so it bypasses all the rules behind it.

The CGnat rule has jump rules already and should help with the packet processing, we have used the default CG nat rule smaller access points like the old waps before they got the new arm processors for public wifi and it looks to run ok from the CPU perspective :)
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: question about the CGNAT script

Mon Feb 07, 2022 1:34 pm

NAT is performance wise not a big problem because only the first packets of a connection hit the NAT. After that, connection tracking takes over.
 
sbhokray
just joined
Topic Author
Posts: 14
Joined: Tue Jan 25, 2022 4:06 pm
Location: India
Contact:

Re: question about the CGNAT script

Sat Feb 12, 2022 9:31 am

added the nat entry's.
got over 1000 entry's under nat as I added total 2 subnets.
the problem
few customers from both the subnets had no Internet.
however I could see the traffic flowing through there nat entry.
as this is a production server, I had very less time to look into the problem in details, so role back to the old setup.
where did I go wrong?
sorry for not posting the config, as I forgot to take it before I rollback to the old setup.
thanks in advance

Who is online

Users browsing this forum: No registered users and 22 guests