Why a source NAT rule?
I presume that some routing rule would be more suitable, or a change of the routes in the main routing table, but in both cases there would be the need for a script to generate the next “random” IP to be used and facilitate the change (there would be the issue with existing connections when you make the change, won’t it?).
Also, how often should the change be made (like every 10 minutes, 2 days or 1 week? Or should it also happen at “random” intervals))
If customers purchase a so called “ip-pack” with us anyway, they get 5 adjacent/consecutive IP’s.
depending on the config, that could 1 public fixed IP and the above 5-block routed to it for example.
Cycle or randomize are different things. You cannot do this with a NAT rule alone. And while “netmap” is very useful, not sure it can help here.
One way a “random” (per connection) change happen using ECMP route on gateway. @jvanhambelgium’s /29 ISP to customer is pretty common, as add-on to ISP. But in these kinda “/29 to customer”, the IP address are within the same subnet and L2 segment - the later make it a little tougher to use the “usual” multi-WAN things (possible just all firewall rules have IP-based matchers, which is not the default).
The easiest way in recent V7 version is using a MACVLAN. The basic steps:
Create new /interface/macvlan & have it listen on the WAN interface (ether1 typically)
Add /ip/address to new macvlan using an unused public IP from your IP
Add it to the “WAN” interface list. Or perhaps better a new src-nat to public IP using in-interface=macvlan in /ip/firewall/nat
Add /ip/route 0.0.0.0/0 router with gateway=macvlanX — at same distance= as your existing default gateway /ip/route
In /ip/route a “+” should appear next your the 0.0.0.0/0 for WAN/ether1, and the new MACVLAN using a 2nd public IP.
At this point, the LAN clients should be “load balanced”, or at least internet going out two different interface.
The way it works is NAT will select the IP of the interface it’s using, based on /ip/route “randomizing” between routes with the same distance=. ECMP, used here, is based on just src/dst address - so it’s not really that random but should be divided between all the same /ip/route distance= routes.
And ignoring the “why” question here… the extra IP are more for being able forward the same ports inbound to different device (using ports like 80/443/etc from 2nd, 3rd public IP assigned)…or put some server directly on the internet without the router…not load balancing them to achieve no speed advantage just occasionally different IP going outbound…
The customer wants to cycle through 5x IP addresses every 24 hours. ie 1x different public facing outgoing IP address for the internal subnet browsing, each day then it starts the cycle again.
They don’t have to be randomised, just to cycle throught the 5x that they have daily.
Seriously?
What is the reason?
Its starting to smell like your client is doing something illegal and suggest you dissolve your relationship.
Either that or the client is going to make your life difficult with a continuous stream of over the top requirements based on what ???
Despite the reason the simplest solution is to make a script dropping all connections and assigning “next” IP and let it execute every 24 h
WAN NAT rule should be set to mascarade to change the IP only, not the NAT rule too.
I'm with @BertozP if need is just daily... use /system/schedule that's set interval of 1d.
The following should work. You'd have to change the list of IP addresses to rotate, and the /ip/address that will be rotated must of the comment "cycle" (no spaces, but you change in the script). The rest of the script just uses the day of the month & modulo % operator on # of IP to rotate. So in theory, if you wanted to rotate more or less IP in the list, script still work.
{
:local before [/ip/address/get [find comment=$findComment]]
:if ([:typeof $before]!="array") do={:error "[:jobname] failure - no ip address to update"}
/log/debug "$[:jobname] rotating ip address for $($before->"interface") from $($before->"address")"
:local updated [/ip/address/get [find comment=$findComment]]
/log/info "$[:jobname] rotating ip address for $($updated->"interface") from $($before->"address") to $($updated->"address")"
}
n.b. Same approach work if you wanted to change the a src-nat rules - large change /ip/address to /ip/firewall/nat commands to use right attributes. Since I'm not sure of the use case, other than potentially appeasing a customer request, hard to know if change IP vs change a NAT rule is better/worse. Since default is masquerade already, changing /ip/address should just work.
What happens to the /ip/firewall/connections situation when this happens IDK. i.e. whether a flush would happen if /ip/address and/or /ip/firewall/nat, or perhaps be they remain using "old" for lifetime. But how you'd want to deal with connection be the 2nd part here.
It’s all pseudo-random anyway. There is a “Julian-Gregorian twister” here since the cycle will change between 30|31|29|28 to 1 in above script as it use the day of the month which can break the cycle .
If you want a more random one, change the index to be a random number. V7 has a built-in [:rndnum] to do these things nowadays. So above changes slightly if that’s what’s needed:
Change “:local index” line in above script to this
:local index [:rndnum from=0 to=([:len $addrs] - 1)]