I’m migrating my current router (pf running on a FreeBSD server) to an RB1100, and I’m trying to figure out the best way to handle srcnat with some specific requirements. I have some applications that, although they function fine with NAT, prefer to have the source port unchanged with the translation.
My current pf config looks like this:
nat on $ext_if from 10.99.1.170 to any -> ($ext_if) static-port
nat on $ext_if from 10.99.1.171 to any -> ($ext_if) static-port
nat on $ext_if from 10.99.1.172 to any -> ($ext_if) static-port
nat on $ext_if from 10.99.1.173 to any -> ($ext_if) static-port
nat on $ext_if from 10.99.1.8 to any -> ($ext_if) static-port
nat on $ext_if from 10.99.1.155 to any -> ($ext_if) static-port
nat on $ext_if from $internal_net to any -> ($ext_if)
The first six statements are the hosts that need to have source ports remain static through the NAT, and the last statement should PAT everything else coming from the inside.
My major stumbling block here is that ether12 is a DHCP-client, and I would prefer not having to change the NAT statements every time my ISP decides to change my address.
This is what I’ve come up with in RouterOS so far to start – I’m a whole day into RouterOS, so forgive any errors here:
Will this work properly? Does action=src-nat require a “to-address”? If so, is there any other way for me to mix the src-nat action with an external interface that uses DHCP?
I answered my own question here; src-nat does indeed require “to-address”, which doesn’t address my problem.
Is there a way to use the outgoing interface address (or even a DHCP-client address) as a source when using the src-nat action? Conversely, is there a way to force static ports when using masquerade?
For now I’ve coded my DHCP IP explicitly in my src-nat statements, but those will break whenever my IP changes from my ISP.
You can use action=masquerade which will NAT using the IP that exists on the interface.
I do not know of a way to replicate PF’s static-port option. Out of curiosity, why are you moving away from PF? I stopped using OpenBSD & PF due to my requirement for MPLS. Otherwise I was happy with that setup.
Yep, and I have that as my “catch-all” at the end, but that will also translate ports (PAT), which I do not want happening for a couple of hosts.
Out of curiosity, why are you moving away from PF? I stopped using OpenBSD & PF due to my requirement for MPLS. Otherwise I was happy with that setup.
No specific reason, I just wanted to mess with a Routerboard (I was happy with PF, too). The FreeBSD server that was acting as my firewall/router is still on the network, but now it’s just doing backup MX, DNS, light web server stuff, etc.
‘masquerade’ will randomize source ports (and by default on a vanilla Linux actually only use ports above 61,000, or at least it used to). As far as I know there’s no method to override that, and even if there was it isn’t exposed in RouterOS.
You cannot specify an interface in src-nat.
What you can do is write a script that checks an interface IP address and rewrites all src-nat rules that match a pattern, and run it scheduled every 5 minutes. Ugly, but might suffice for your purposes if your address doesn’t change much. I have a DHCP address at home and it has changed twice in the last two years. One time there was a prolonged power outage that also affected the carrier and wiped the lease database, the other time they completely changed subnets.
The script would look something like this:
/ip firewall nat set [/ip firewall nat find action=src-nat and out-interface=ether12] to-address=[/ip address get [/ip address find interface=ether12] address]
Script code untested. Even if that doesn’t work it shows the general principle.
Thanks, fewi – I’ll give the script a shot (once I learn scripting in RB). My IP will change once every few months, so this isn’t a huge deal, but I already have to adjust a few things (domains, other files) when it does change, so I like to keep the actual IP out of configurations as much as I can.
It probably won’t hurt for me to turn this into a feature request.
I’m not sure that this can actually be done on a netfilter level, which would be a feature request outside of Mikrotik (unless they hack up netfilter themselves).