I have tried this a couple of times but I am never stratified with my solution, perhaps my situation is different from the guides to I thought let’s ask it here.
Situation
192.168.100.200 runs a webserver (nginx proxy) on poort 80 and 443
However I don’t like this setup as I have lots of ports open (some game servers some other stuff not everything to the same host) so this is a real hassle to configure.
However when I access mydomain.com with this setup I get the http page from the router and not from the .220 server.
So: What is the best way to configure hairpin nat? It would be fantastic if I could have a single rule (with port list or something) for each server I also have port-forwarding for.
You don’t need any extra dstnat rules, just fix original ones, in this case replace them with the new ones you added. Using in-interface-list=WAN is ugly shortcut, and it’s self-explanatory, it only works for connections from WAN. Rules with dst-address=1.1.1.1 work for connections to 1.1.1.1, no matter where they come from.
Srcnat rule for hairpin NAT can be just single one for all ports:
I have used a address-list instead of a fixed address. Officially it is dynamic (changes like once every 3/4 years when maintenance is done). So with the address-list I only need to change a single entry instead of all my rules And this seems to work perfectly, it still works from the outside and also from within my network absolutely perfect! And yes this is a single-line solution I was looking for
I also tried the ‘dst-port=80,443’ and yes you can use that but the ‘to-ports’ (needed if ports don’t match) only allow a single port or a port list. So yes I can perhaps merge a few rules but I think I’m gonna leave that the way it is. I don’t really mind a single rule per NAT entry.
Thank you for your assistance!
@anav:
See above, officially it is dynamic but I treat it as fixed.
You could also use DDNS (RouterOS has it built-in in IP->Cloud) and add hostname to list instead of address. That way you won’t have to do anything even when it changes. Although if it happens that rarely, what you have now is probably good enough too. Maybe even safer, in case there’s some problem with DNS.
If you don’t change port number, you don’t have to add to-ports at all, e.g. you do need “dst-port=8080 to-ports=80”, but it it’s “dst-port=80 to-ports=80”, then just “dst-port=80” is enough.
Yeah I’ll keep it like this for now, also have my own domain hardcoded to my IP. Then there is only myself to blame if my DNS is broken But I do have the DDNS activated (and somewhere in an email to myself) in case it ever changes while I am away from home.
And thanks for the suggestion for the “no dst-ports”, I’ll keep that in mind!
If your public IP is dynamic…
Use IPCLOUD in your address list. That will dynamically adjust the dst-address. That would allow one rule to work inside and out.
You would still need the loopback rule SEPARATE, that reads: src-address = 192.168.100.0/24 dst-address = 192.168.100.0/24 output interface=lan
As per SOB, not required (part in red) but action masquerade yes…
/ip firewall nat
add chain=srcnat src-address=192.168.100.0/24 dst-address=192.168.100.0/24 action=masquerade
Normally you can live without it, because router won’t send such packets anywhere else. But it doesn’t hurt when it’s there and in some cases (e.g. overlapping subnet for VPN clients) you’d want it.
Ideally I’d want to use connection-nat-state=dstnat, to match only dstnatted connections, but it’s not supported in /ip firewall nat.
At some place I don’t remember I am assigning a connection-mark based on connection-state=dstnat somewhere between chain=dstnat and chain=srcnat to deliver the info about connection-state=dstnat to the srcnat chain in a form it can accept. But in most setups you need to spare the connection-mark for more important purposes.
I did something similar somewhere, in prerouting I marked connections to router (dst-address-type=local) and when they appeared in srcnat, I knew that they didn’t really go to router, which must have been caused by dstnat (or ghosts :). But as you write, connection marks are too valuable for this, plus it doesn’t make things very clear.