Community discussions

MikroTik App
 
MyThoughts
Member Candidate
Member Candidate
Topic Author
Posts: 218
Joined: Sat Sep 17, 2005 9:07 pm

Feature Suggestion - Dynamic DST-NAT

Wed Jan 25, 2023 6:45 pm

I think having an option for using an address list that could be used for DST-NAT (or SRC-NAT) would be very useful for improving the flexibility of the RouterOS firewall system.

An Example:
We have begun to automate many of our SSL server deployments, and we do have numerous deployments. Historically we bought 3 Year signed certificates, and it wasn't that bad to upon renewal. However since the switch to max 1 year signed certificates a few years back, and our own growth (more servers, more services, more need to deploy/renew/maintain the signed certificates) the process have become a pain.

In order to simply the process and limit costs we have begun to use services like Let's Encrypt / ZeroSSL etc.
We have no need of the more expensive SSL certificates from and these simple signed certificates work fine. However I have always hated the verification process using random source servers, requiring port 80 or 443. For some services we can use a reverse proxy to assist. However for some services, reverse proxy is undesired or not possible, using automated DNS verification is not doable in many cases, and at some locations we have many servers behind limited IP addresses.

I have been using port knocking and firewall rules to automate the opening of port 80 for a short time on our RouterOS firewalls when a server is doing its verification process with the certificate provider. The issue is when I have many servers all needing to do verifications (different time periods), but I only have a single public IP address. The port forwarding rules required cannot dynamically change the DST-NAT 'to address' and while I could script it, that becomes a pain and I hate running scripts on short time intervals, something that would be required to do as the verification occurs fairly quick.

This comes to my feature suggestion, currently when I preform the port knock, the internal server knocks the Routeros, the Routeros add's the server's IP to an address list with a 05:00 timeout. Once that occurs a firewall rule in the forward chain of the filters will allow traffic to flow to port 80 of the server doing the verification. Verification completes, and five minutes later the address expires and my filter rule is now blocking port 80 traffic.
If I could use a address-list for the DST-NAT 'to-address' I could have these same rules work for any number of servers doing verification on port 80 (or any port), all on a single WAN/public IP address.

The main feature would be the change of the DST-NAT 'to-address' to allow an address list to be specified.

The second feature would be to have a check-box on adding to an address-list called 'single address only' or something like that. This flag would trigger RouterOS to limit an address-list to a single entry. This second feature would be optional, and it isn't required. Without this limit it would just be up to the user to ensure they don't populate and address list with multiple entries when it is being specified for DST-NAT / SRC-NAT or they would get undesired affects.

I do understand that a rule of this sort would add some load to the router, but I do think it would be one heck of a useful feature for targeted applications.
 
User avatar
anav
Forum Guru
Forum Guru
Posts: 19106
Joined: Sun Feb 18, 2018 11:28 pm
Location: Nova Scotia, Canada
Contact:

Re: Feature Suggestion - Dynamic DST-NAT

Wed Jan 25, 2023 6:59 pm

Not likely to occur........... but I do recommend if you are SSTP situated to save yourself grief and hassles and check this out.
https://remotewinbox.com/
 
User avatar
mkx
Forum Guru
Forum Guru
Posts: 11439
Joined: Thu Mar 03, 2016 10:23 pm

Re: Feature Suggestion - Dynamic DST-NAT

Wed Jan 25, 2023 7:54 pm

If I could use a address-list for the DST-NAT 'to-address' I could have these same rules work for any number of servers doing verification on port 80 (or any port), all on a single WAN/public IP address.

The main feature would be the change of the DST-NAT 'to-address' to allow an address list to be specified.

I doubt it's as simple as you imagine.

Currently it is possible to set multiple addresses to property to-addresses (note the plural form of the property name). However, the way NAT works is that it chooses (randomly) one of addresses to forward to (because NAT works on L4; even if it worked on L7 where HTTP protocol includes header "Host" that information is available too late to decide target for NAT). So it's expected that any of servers with addresses from this list will serve the incoming connection the same way. In essence it behaves in a load-sharing manner (not even high-availability since NAT doesn't check if destination is alive). N.b.: property to-ports behaves similarly.
But connections due to certificate renewal process can not be treated in this manner, they have to hit a particular destination server which is renewing certain certificate. And that's a job for a reverse proxy.

I guess that having property to-address-list would leave NAT to behave the same way as it does now and is described above. Only management of addresses would be much easier.

BRW, how do you NAT traffic for port 443 when there are multiple HTTPS servers behind single WAN IP?
 
pe1chl
Forum Guru
Forum Guru
Posts: 10195
Joined: Mon Jun 08, 2015 12:09 pm

Re: Feature Suggestion - Dynamic DST-NAT

Wed Jan 25, 2023 8:55 pm

Note that for Letsencrypt DNS verification, you only need to add a record to the _acme-challenge.example.com subdomain of your domain example.com.
So you can register and DNS-serve your domain at any service provider where you can add an NS record for _acme-challenge pointing to your own external IP address,
and then you can run a DNS service locally on your premises that has the proper linkage to your certbot script to temporarily serve the DNS name.
You only need a small DNS service and if you run it on a Linux system you can put a firewall entry like:
iptables -A firewall -p udp --dport 53 -m string --string '_acme-challenge' --to 256 --algo bm -j ACCEPT
in front of it, so it will not be servicing any other requests.

This is a much more convenient method than to have certbot fiddle with the webserver or listen on a port, and as a bonus it can also be used to get wildcard certificates.
 
gotsprings
Forum Guru
Forum Guru
Posts: 2102
Joined: Mon May 14, 2012 9:30 pm

Re: Feature Suggestion - Dynamic DST-NAT

Wed Jan 25, 2023 11:34 pm

I tired to follow it... but I can't.

dst-nat TO ADDRESS?

You knock.
You get added to SRC-ADDRESS-LIST
A Filter rule allows connection from that SRC-ADDRESS-LIST
That Entry times out... (but established connections would allow it to continue...

If lay it out more like 1 2 3 4... maybe i could understand and come up with something???
 
MyThoughts
Member Candidate
Member Candidate
Topic Author
Posts: 218
Joined: Sat Sep 17, 2005 9:07 pm

Re: Feature Suggestion - Dynamic DST-NAT

Fri Jan 27, 2023 1:13 am

@mkx
  • For services operating on the same ports (eg. 443) we use a reverse proxy to preform SNI
  • I would not concerned with how RouterOS operates (selecting address from list) when a DST-NAT was using the suggested feature (address list for DST-NAT to address). For users wanting it to operate as a pseudo cheap load-balancer, or in my case allowing a rule to serve multiple servers at different times that would be up to the operator. You could even use the port knock method to have servers knock the RouterOS to maintain their presence on the address-list creating a cheap HA check

@pe1chl
  • DNS verification requires a new/updated DNS entry (CNAME/TXT depending on certificate provider). Many providers using CNAME during verification requires a new subdomain entry and value on issue and renewal. So the solution would not really work well for say ZeroSSL. My opinion would be that the suggestion you offered only increases the complexity and increases management. At the end of the day the solution you offered doesn't achieve the desired result of what I suggested.

@gotsprings
I'll post the three primary rules created to achieve what I am doing thus far.

Internal Server IP xxx.xxx.xxx.xxx

Rule 1) NAT
chain=dstnat action=dst-nat to-addresses=xxx.xxx.xxx.xxx to-ports=80 protocol=tcp in-interface='WAN' dst-port=80
  • only dst-nat when traffic enters from WAN to the internal server at IP xxx.xxx.xxx.xxx
  • The to-addresses field is what I would like to be changed to allow address-list to be specified

Rule 2) Filter Knock
chain=input action=add-src-to-address-list protocol=tcp src-address-list='Allowed - Port Knock' address-list='Allowed - Port 80' address-list-timeout=5m dst-port=9999
  • Restricts activating the port knock to only the specified internal servers in the 'Allowed - Port Knock' address list
  • Adds the server IP to the address list 'Allowed - Port 80' in a dynamic fashion with timeout of 5mins

Rule 3) Filter Forward (before any allow/accept for established connections)
chain=forward action=drop protocol=tcp dst-address=xxx.xxx.xxx.xxx dst-address-list=!'Allowed - Port 80' dst-port=80
  • Since the NAT rule is always active I needed a forward filter rule to block port 80 when the dynamic list was not populated
  • If my suggestion were implemented this rule would not be required as the DST-NAT rule wouldn't have a destination if the dynamic address list was empty and the packets would be dropped

You can imagine what would happen if my suggestion was implemented. The internal server xxx.xxx.xxx.xx1 knocks the Routerboard, the address xxx.xxx.xxx.xx1 is added to the list 'Allowed - Port 80' this address list is used in the DST-NAT rule 'to-address' a connection then comes in on port 80 (maybe its a certificate verification) the DST-NAT fires and forwards said port 80 traffic to the internal server at xxx.xxx.xxx.xx1 and the verify passes, or the server answers back with the requested data. 5 minutes later the address times out and the list is empty, the DST-NAT rule now has no destination and packets coming in on port 80 go nowhere. A few days go by and a different internal server xxx.xxx.xxx.xx2 needs to renew, it does a port knock, and its address xxx.xxx.xxx.xx2 is added to the address list, the DST-NAT rule once again has a destination and port 80 traffic coming in is forwarded to xxx.xxx.xxx.xx2. Verify passes, and 5 mins later the address lists is empty.

This would just be an example for what I would like the feature for. There are many other applications I could think of.
 
accarda
Member Candidate
Member Candidate
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Re: Feature Suggestion - Dynamic DST-NAT

Fri Jan 27, 2023 6:32 am

Have you considerate the possibility to run a script that sets the NAT rule, based on the address list entry ?
In this case a script reads the address list that you have on item #2 and creates a NAT rule as indicated on item #1; then the script can remove such rule, either after 5 min or if the address list is empty again.
Even in this case you won't need item #3.

In case you want to try the script approach, here a simple one that should match your case.
The assumption is that you will have one address at the time in the address-list, which I think it's your case from the reading, as you can't assign to-address to multiple destinations within the same dst-port for such rule to work properly (unless you have multiple WAN IPs).
:local dstnatIP
:local dstnatList "dst_nat"
:local keyMatch "LE-CERT-VALIDATION"

:if ([:len [/ip firewall address-list find where list=$dstnatList]] > 0) do={
	:set dstnatIP [/ip firewall address-list get [find where list=$dstnatList] address]
	:if ([/ip firewall nat find where to-addresses=$dstnatIP] = "") do={
		/ip firewall nat add chain=dstnat in-interface-list=WAN protocol=tcp dst-port=80 action=dst-nat to-addresses=$dstnatIP comment="$keyMatch to $dstnatIP"
	}
} else={
	/ip firewall nat remove [find where comment~$keyMatch]
}
You just need to set the variable dstnatList to match your list name; you can also set the keyword matcher with variable keyMatch to something unique for the scope which is not used anywhere in NAT table.
This keyMatch it's used to easily remove the NAT rule once the address list is empty; it also sets a comment to easily find your NAT rule.
 
User avatar
mkx
Forum Guru
Forum Guru
Posts: 11439
Joined: Thu Mar 03, 2016 10:23 pm

Re: Feature Suggestion - Dynamic DST-NAT

Fri Jan 27, 2023 8:54 am

@mkx
  • For services operating on the same ports (eg. 443) we use a reverse proxy to preform SNI

My solution is to run letsencrypt certificate updated (certbot in my case) on RP host ... which makes lots of sense since it's the place where all those certificates are then actually used. Or do you actually terminate TLS on backend servers and you use RP only to redirect connections (I'm not sure this is actually possible) to correct backend server which tehn performs full TLS handshake?
I'm using certbot in stand-alone configuration in RP so whoever tries to use port 80 when none of certificates is being renewed, it simply won't work because port is not being served.

BTW, even with all-https there's still place to have http ports open for all sub-domains ... if none other, simply to redirect clients to https (which can again be done entirely by RP). AFAIK many clients, when user enters site name manually, still try first with http. If that fails, they might try https next, but initial https connection has to time out. With redirection this are smoother for users.

Knocking by internal servers might work most of time with small number of internal servers ... with increased number of internal servers chance of two running certificate renewal at the same time would increase and if that happens, one of them would fail to perform the procedure.
 
pe1chl
Forum Guru
Forum Guru
Posts: 10195
Joined: Mon Jun 08, 2015 12:09 pm

Re: Feature Suggestion - Dynamic DST-NAT

Fri Jan 27, 2023 11:05 am

@pe1chl
  • DNS verification requires a new/updated DNS entry (CNAME/TXT depending on certificate provider). Many providers using CNAME during verification requires a new subdomain entry and value on issue and renewal. So the solution would not really work well for say ZeroSSL. My opinion would be that the suggestion you offered only increases the complexity and increases management. At the end of the day the solution you offered doesn't achieve the desired result of what I suggested.
I don't know the requirements of ZeroSSL, I use Letsencrypt.
I use this solution to full satisfaction on different installations. Small local Linux system runs the DNS which is only used for this.
Firewall admits only the required requests, so no need to fiddle with address lists.
And it is possible to request wildcard records so often far less certificates have to be requested.
Plus it works today, no new MikroTik feature required!

But when it is not for you, find another solution.
 
MyThoughts
Member Candidate
Member Candidate
Topic Author
Posts: 218
Joined: Sat Sep 17, 2005 9:07 pm

Re: Feature Suggestion - Dynamic DST-NAT

Fri Jan 27, 2023 6:26 pm

@accarda

The script method is something I tried, it does technically work. It was the timing issue that was tricky. The renewals only occur once every 2-3 months and they occur pretty quickly.
I wanted to avoid using the Scheduler to continually run the script over and over on short time intervals. The solution I had for my scripting test was to create a static IP on the server doing the renewal and using NetWatch to monitor said IP. When the IP went active the netwatch would fire the script similar to what you linked to adjust the DST-NAT rule. I was using a pre-renewal script on the server to activate the IP address, and open port 80 locally.
Doable, however not as simplistic or dynamic and that was why I came up with the feature suggestion.

Obviously there are many ways in the pc world to achieve the same outcome. In my case of certificate renewals I appreciate the feedback on alternatives. However, I still feel allowing the 'to address' to be an address-list for the DST-NAT/SRC-NAT rule would be a useful albeit limited use feature. In my opinion it would likely not be a huge undertaking to implement. Not a make it or make it type of feature just something I think would be useful.

Only Mikrotik and their dev team will be able to determine if it is worthwhile.

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], GoogleOther [Bot], neki and 79 guests