Hello,
I’m curious to learn if I can configure RouterOS so that it changes a port redirection on the fly, i.e. depending on the last host that called a specific domain or IP address.
Setup: I’m running two virtual machines on a server behind my RB4011. NAT is activated on MikroTik and DDNS service is pointing to it. For this purpose, vm1.example.com and vm2.example.com point to the same DDNS-address. Each VM has its own local IP address and is running a webserver on port 80.
Internet --> RB4011 --> VM1 192.168.88.101
--> VM2 192.168.88.102
What I try to achieve: both VMs should be able to renew their letsencrypt certificates via http-challenge with my manual interaction needed. We can assume that both VM letsencrypt requests never occur at the same time. My idea:
When VM1 is trying to connect to domain D, RB4011 is marking the connection with VM1.
Automatically delete old rules
/ip firewall nat remove [/ip firewall nat find where dst-port="80"]
NAT rule to redirect incoming traffic at port 80 to VM1
Dear normis, what do you mean with “different ports”? The letsencrypt http challenge can only use port 80 or 443. Or did you mean different ports for the VMs?
Dear normis, there might be a misunderstanding. I want to use port 80 and not a different port.
It’s just that I have more than one webserver behind my MikroTik devices to redirect the traffic to. If I had a single webserver that should use letsencrypt http challenge, I could activate a simple port redirection, right?
Another idea that comes to my mind as I write:
Run a script that switches port 80 redirection between the virtual machines. For instance, odd days VM1 and even days VM2.
I’m for DNS too. But if you want it really simple and static and don’t mind one VM depending on the other, there’s also another way.
Just forward port to one VM, let’s say VM1. This one won’t have any problem. When VM2 tries to renew certificate, LE will try to verify challenge and it will connect to VM1 where it won’t find it. But you can configure VM1 to act as proxy and get the file from VM2, using either server’s proxy functionality, or with some script.
For example, in few places I have this as Apache config:
Alias "/.well-known/acme-challenge" "/path/to/challenges"
<Directory "/path/to/challenges">
AllowOverride None
Require all granted
Header set Content-Type "application/jose+json"
#
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^[a-zA-Z0-9\-_]+$ /.well-known/acme-challenge/le-proxy.php [L]
</Directory>
First half is normal config for LE and second with rewrite is for proxy. Php script is simple:
Dear sob, that’s an interesting approach. Thank you.
If I’m not mistaken it may even be possible to setup a static proxy redirect via apache2 domain conf file. I once had this kind of configuration to proxy database access via webserver to the database server.
I’ll definitively look into it!
I don’t have much experience with Apache as proxy, it depends if you can do the same config as rewrite in example has, i.e. local files need to be served for VM1’s use and only when requested file doesn’t exist, it must be taken from VM2.
I’m using an Apache2 proxy to pass the let’s encrypt http challenge to the appropriate host(s). Here for the apache2 domain config for the first VM. Possibly I could use RewriteRules to automate the ProxyPass target but that’s a challenge for another day.
<VirtualHost *:80>
ServerName vm1.example.com
# everything not the let's encrypt http challenge is forbidden
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/.well-known*
RewriteRule (.*) "-" [F]
ProxyPreserveHost On
ProxyPass / http://vm1.example.com:80/
ProxyPassReverse / http://vm1.example.com:80/
</VirtualHost>
To add some extra security, I may add pre/post hooks to the certbot renew statement to enable/disable the RB4011 firewall rule that forwards the http requests to the Apache2 proxy.