DNAT missing in LuCI? How to DNAT?

I can see, there is “Source NAT” section in Firewall - Traffic rules, but there is no “Destination NAT” section. What I’m trying to do is:

If anyone from LAN is going to X.X.X.X on WAN redirect it on Y.Y.Y.Y on LAN

I’m doing this using DNAT on my Mikrotik, but I cannot find it in LuCI on my Turris Omnia.
Any ideas how this should be done on Turris?

you want to add dnat rule (described in eg. http://linux-ip.net/html/nat-dnat.html ) into “Firewall - Custom Rules”

1 Like

Thank you. I’ll try it. But why is it missing from LuCI? Why it needs to be done in custom and is not next to Source NAT? Am I missing something?

So, I tried it, but still no luck.

I set this to custom firewall settings (/etc/firewall.user):
iptables -t nat -A PREROUTING -d 217.11.249.139 -j DNAT --to-destination 192.168.32.10

What I expect is, that when I go to 217.11.249.139 from my PC on wifi of my turris wit that setting above, it should end up on 192.168.32.10 which is LXC container with ubuntu with apache on turris.

What I get is “page unreachable”. Without the rule, I get what’s on the remote server. If I go to 192.168.32.10, 8 get what’s on the LXC’s apache. So it could be ready and the problem is somewhere in the DNAT.

Any ideas what am I doing wrong?

if you have a internal web server accessible from internet using DNAT on TO, you can be interested on NAT Reflection. Look available options on TO firewall (search for “reflection”):
https://wiki.openwrt.org/doc/uci/firewall

The usecase is, that I cannot access my public IP from the inside, so I can’t get to my internal server using domain name, while at home.

Could you please show me an example of the iptables command (I’m newbie in networking on linux)? Let’s assume X.X.X.X is the public IP, to what my domain is resolved by DNS, Y.Y.Y.Z is my server’s local IP and Y.Y.Y is the same for Turris and my PC I’m trying to open my domain on.

Am I clear?

Thank you all.

IMHO DNAT is relatively rare configuration with just few use cases (I have used it for some CGNAT workarounds in the past) and technically clean solution is… …to move to ipv6.

I guess nobody from opensource community has big motivation to develop such feature for legacy technology, so… …time to read man iptables :slight_smile:

I’ll try to reproduce it on my box and let you know here.

iptables -t nat -A PREROUTING -d 217.11.249.139 -j DNAT --to-destination 192.168.32.10

I would use not “-A” but “-I” - not append, but insert. Thats first possible problem.

Then, if you will open wireshark on target box, you should see the packets correctly coming… But as the source IP is in LAN segment, 192.168.32.10 will repond on LAN interface with LAN source address… This will make your client machine confused - replies from 217.11.249.139 will return from 192.168.32.10. That’s not what tcp would like. (And I guess ping is working for you, but tcp (so http too) not :slight_smile: )

So you want to try “hairpin NAT” = second masquerade to workaround this. If google or serverfault (linux - Accessing the DNAT'ted webserver from inside the LAN - Server Fault) will not help, let us know.

1 Like

If you have a firewall redirect as:

config redirect
        option src wan
        option src_dport 80
        option proto tcp
        option dest dmz
        option dest_ip 192.168.10.10
        option target DNAT

Try to add option “reflection”:

config redirect
        option src wan
        option src_dport 80
        option proto tcp
        option dest dmz
        option dest_ip 192.168.10.10
        option target DNAT
        option reflection 1

And if you want: option reflection_src x.x.x.x

i’m not sure if nat reflection will work for client/server in same l3 network…

You say, that using DNAT for my usecase is not optimal solution. So how to do it the right way? Altering (spoofing) DNS?

nobody’s saying that.
Have you read the provided link about hairpin nat?

If this is your only usecase, you can can use a static host entry for your local DNS resolver on TO:

In /etc/hosts add:

<local ip> <domain name>
(e.g. 192.168.1.102 mydomain.tld)

In /etc/config/resolver:

below

config resolver 'kresd'

add

option hostname_config '/etc/hosts'

And restart resolver:

/etc/init.d/resolver restart

Then your domain resolves to the local ip of your machine while you are inside your LAN. I’m using this solution in production for several years and I can confirm that it works stable.

2 Likes

The “hairpin NAT” link seems pretty extensive and complete guide. Thank you. Once I got time to try it, I’ll let you know the result. I’m still not decided whether I’m going to use hairpin or DNS way of doing it. Will try, will see. Thx

I don’t have my TO yet, and reviewing the solution from @protree above re using a local host entry seems to me to be the right and most simple solution.

It surely is and I have it up and running now. BUT… It’s not ultimate solution. It counts with users using DNS servers given by DHCP. Client using different DNS wouldn’t get the right IP. So my plan is to implement both. The hosts solution for the majority of users (phones, most of the notebooks at home) and hairpin NAT for guests with nondefault network settings. The hosts solution is more elegant and close to no-work for router. That’s why I want to use it even it’s not perfect