New Source NAT - specific port rangre for outbound interface any protocol

Started by Ametite, July 08, 2026, 09:10:49 AM

Previous topic - Next topic
Good morning all, I'm here to report a missing configuration from old outbound rules to new one. I know it's something that is my specific need/implementation but I put here some contest.

My ISP (Iliad Italia) uses MAP-E (not supported from OPNsense), but I use a trick and I connect the ISP router LAN ("router mode, no NAT") to the OPNSense WAN, then I know from ISP router GUI the port range (1:4) that is assigned to me (eg 24576:32767).
That range port was configured in the old outbound NAT, that allowed to set outbound interface WAN (with its IP address) AND the port range. The new Source NAT does not allow you to set the port range without choosing the TCP/UDP option, but - in this way - every protocol that is not TCP/UDP will not work (ICMP, etc...).
Now I have to roll back to old rules and all is working again.

Do you know if this can be implemented, or if I'm missing something?

Thanks a lot.

I don't understand, only UDP and TCP do have port numbers. ICMP has types. Other protocols don't have port numbers or use different schematics.
Hardware:
DEC740

I guess the issue is that the new interface won't allow specifying a target port range when the protocol is "any", so I suppose you'd have to create one rule for TCP/UDP (with port range) and another rule for "any", and use sequence numbers to ensure that the TCP/UDP one comes first? Seems kindof unnecessarily cumbersome?

Curiously PF shows a port range even for ICMP-specific rules:

root@opntest1:~ # pfctl -s nat | grep icmp
nat on igc1 inet proto icmp from (igc0:network) to any -> (igc1:0) port 1024:65535
root@opntest1:~ #


Quote from: Monviech (Cedrik) on July 08, 2026, 09:29:23 AMI don't understand, only UDP and TCP do have port numbers. ICMP has types. Other protocols don't have port numbers or use different schematics.

Yes, that's what I know too from the theory, but I think the old config works for a reason I don't know.

Quote from: dseven on July 08, 2026, 10:18:12 AMI guess the issue is that the new interface won't allow specifying a target port range when the protocol is "any", so I suppose you'd have to create one rule for TCP/UDP (with port range) and another rule for "any", and use sequence numbers to ensure that the TCP/UDP one comes first? Seems kindof unnecessarily cumbersome?

Curiously PF shows a port range even for ICMP-specific rules:

root@opntest1:~ # pfctl -s nat | grep icmp
nat on igc1 inet proto icmp from (igc0:network) to any -> (igc1:0) port 1024:65535
root@opntest1:~ #

Exactly, now I'trying to, I just configured SNAT with two rules, one TCP/UDP with the specific ports and the other with the generic one below the first one, but it doesn't seem to work.
Do you know what the command is to reload the NAT rules? I'm not sure if they are reloaded when the settings are saved.

Quote from: Ametite on July 08, 2026, 01:14:31 PMDo you know what the command is to reload the NAT rules?
You could try resetting the states ?!
Weird guy who likes everything Linux and *BSD on PC/Laptop/Tablet/Mobile and funny little ARM based boards :)


Quote from: dseven on July 08, 2026, 03:49:04 PMWhat does "pfctl -s nat" show?

Now it seems works, but only if I choose Hybrid rules and not manual. The rule I created should works even without auto generated rules.

root@fw-fe:~ # pfctl -s nat
no nat proto carp all
nat on vtnet0 inet proto tcp from (vtnet1:network) to any -> (vtnet0:0) port 24576:32767
nat on vtnet0 inet proto udp from (vtnet1:network) to any -> (vtnet0:0) port 24576:32767
nat on vtnet0 inet from (vtnet1:network) to any -> (vtnet0:0) port 1024:65535
nat on vtnet0 inet proto tcp from <LAN_udine> to any -> (vtnet0:0) port 24576:32767
nat on vtnet0 inet proto udp from <LAN_udine> to any -> (vtnet0:0) port 24576:32767
nat on vtnet0 inet proto tcp from (self) to any -> (vtnet0:0) port 24576:32767
nat on vtnet0 inet proto udp from (self) to any -> (vtnet0:0) port 24576:32767
nat on vtnet0 inet proto tcp from 192.168.1.50 to any -> (vtnet0:0) port 1024:65535
nat on vtnet0 inet proto udp from 192.168.1.50 to any -> (vtnet0:0) port 1024:65535
nat on vtnet0 inet from (vtnet1:network) to any port = isakmp -> (vtnet0:0) static-port
nat on vtnet0 inet from (lo0:network) to any port = isakmp -> (vtnet0:0) static-port
nat on vtnet0 inet from (ipsec10:network) to any port = isakmp -> (vtnet0:0) static-port
nat on vtnet0 inet from 127.0.0.0/8 to any port = isakmp -> (vtnet0:0) static-port
nat on vtnet0 inet from (vtnet1:network) to any -> (vtnet0:0) port 1024:65535
nat on vtnet0 inet from (lo0:network) to any -> (vtnet0:0) port 1024:65535
nat on vtnet0 inet from (ipsec10:network) to any -> (vtnet0:0) port 1024:65535
nat on vtnet0 inet from 127.0.0.0/8 to any -> (vtnet0:0) port 1024:65535
no rdr proto carp all
no rdr on vtnet1 proto tcp from any to (vtnet1) port = ssh
no rdr on vtnet1 proto tcp from any to (vtnet1) port = 24600
rdr on vtnet0 inet proto tcp from <Trusted_EXT> to (vtnet0) port = 24806 -> 192.168.2.5 port 8006
rdr on enc0 inet proto tcp from 192.168.1.254 to (self) port = domain -> 192.168.2.254 port 53530
rdr on enc0 inet proto udp from 192.168.1.254 to (self) port = domain -> 192.168.2.254 port 53530
rdr on vtnet1 inet proto tcp from any to ! (self) port = domain -> 127.0.0.1 port 53
rdr on vtnet1 inet proto udp from any to ! (self) port = domain -> 127.0.0.1 port 53
rdr on vtnet1 inet proto tcp from any to ! (self) port = domain-s -> 127.0.0.1 port 853
rdr on vtnet1 inet proto udp from any to ! (self) port = domain-s -> 127.0.0.1 port 853
rdr on vtnet1 inet6 proto tcp from any to ! (self) port = domain-s -> ::1 port 853
rdr on vtnet1 inet6 proto udp from any to ! (self) port = domain-s -> ::1 port 853
rdr on vtnet1 inet6 proto tcp from any to ! (self) port = domain -> ::1 port 53
rdr on vtnet1 inet6 proto udp from any to ! (self) port = domain -> ::1 port 53

I wanted to report that my previous statement is partially incorrect.

I did further testing and, with this hybrid SNAT configuration, only 1:4 of the ICMP pings are successful, exactly the same as the ratio of the IPv4 range port assigned to me by my provider.

Granted, there's no source port for ICMP, but I think some sort of "random port" is generated somewhere, something that is independent by the operating system I'm testing from (whether Linux or Windows makes no difference).

Just to be clear, now I have hybrid NAT, a manual rule that intercept TCP/UDP traffic and force the exit port range 24576:32767 and the other one generated by auto-conf LAN->WAN with any protocol and * as source NAT port.

A quick bit of research reveals that MAP-E uses the ICMP client identifier in place of a source port for tracking. The MAP-E CPE would normally rewrite the client ID to a number within your assigned port range. If your ping client supports it, try specifying a client ID within your range. On modern Linux, the '-e' option should work...