OpenWrt Forum Archive

Topic: Access LAN from... LAN as if you accessed from WAN

The content of this topic has been archived on 20 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi everybody,

I'm using KAMIKAZE (8.09.2, r18961).

I have a router which is configured to forward some specific ports to the outside, via a public adress (let's say my public adress is myprivateserver.com, and that I installed port forwarding for port 443 to allow access to 192.168.1.10:443 and for port 444 to allow access to 192.168.1.11:443).

If I connect to myprivateserver.com:443 from anywhere, I can connect without problem.
If I connect to myprivateserver.com:443 from inside the LAN, I get the message that no connection is possible.

How do I configure my router to allow "WAN-like" connection from the LAN ? The question is important for me: if I connect from the LAN using the LAN adress of my router, I can't check if I've correctly set the port forwarding.

Thanks in advance for any help

Olivier Subilia

User mbm gives the answer in posting:

https://forum.openwrt.org/viewtopic.php?id=4030

I recently used his /etc/firewall.user rules to allow printing to port 9100 from inside the LAN:

iptables -t nat -A prerouting_rule -d x.x.x.x -p tcp --dport 80 \
        -j DNAT --to 10.0.0.2
iptables -A forwarding_rule -p tcp --dport 80 -d 10.0.0.2 -j ACCEPT
iptables -t nat -A postrouting_rule -s 10.0.0.0/24 -p tcp --dport 80 \
        -d 10.0.0.2 -j MASQUERADE

As he explains:

"x.x.x.x is my external IP address; I want it so when I connect to that IP
address that it gets forwarded to my internal webserver which is 10.0.0.2.
The problem is this:

request: 10.0.0.x (some random lan machine) -> x.x.x.x (external ip)
-> 10.0.0.2 (websever)
response: 10.0.0.2 -> 10.0.0.x

I've connected to x.x.x.x but the response came from 10.0.0.2 .. oops. To
correct this, a masquerade is done using the third rule. This has the
unfortunate side effect of hiding the original source address, but it does
correct the issue with the response. Since this only applies to machines on
the lan subnet, I've added a -s; this allows proper logging of requests
from outside the lan."

Hope this helps.

I would suggest to try and make "myprivateserver.com" resolv different on the inside (LAN) than on the outside (WAN).

The simplest way to go is to add an entry in your local host file. This however applies only to non-roaming devices. For laptops/mobiles, which sometimes connect from both sides, you could setup a dns server on the router. Make it resolv "myprivateserver.com" and point it to your internal ip address of your server. I don't know if dnsmasq can do this...

Main advantage of this sollution is that traffic isn't routed/natted and therefor give much better performance results.


Edit: looks like dnsmasq can do this for you by adding "myprivateserver.com" to /etc/hosts: http://www.thekelleys.org.uk/dnsmasq/doc.html .

Edit2: A snip form /etc/dnsmasq.conf

# Add domains which you want to force to an IP address here.
# The example below send any host in doubleclick.net to a local
# webserver.
#address=/doubleclick.net/127.0.0.1

(Last edited by Adze on 10 Aug 2010, 14:47)

Thanks for the advice. I didn't notice this post.

But I still see two problems (if I've understood correctly, I'm almost everything but a network expert...)

1. As nbm said:

nbm wrote:

The problem is this means that your ip can nolonger change; any time you get a new ip address you'd have to rerun the firewall

And that's a serious problem: I've a dynamic IP (yes, maybe I could change this, but if I want a fixed address, I MUST have a SLOWER connection to the internet. Yeah, administration, you know, ...) so my rule will not last forever...

2 If my comprehension is good: you have to define ONE rule for EACH port you want to forward (and --dport should have been 9100 in your example, and not 80. Is it correct ?). If it's true, well, it's not really easy. I've a bunch of https webservers inside my network, so I must define one port for each server (with a different IP lan address). If the goal is to check why this f*** connection doesn't work, and if that for I must create three rules for each connection, the risk that the connection doesn't work because of the iptables rules rather than the port forwarding is really high.

Anyhow, thank you for the explanation. I'll try asap.

Olivier Subilia

@ Adze: No this (clearly better from a technical point of view) solution is not the one I want. If myprivateserver.com resolves as 192.168.1.10, and is consequently not routed, I can't check how routing functions... I want the traffic from inside to (myprivateserver.com, so )inside to be routed to chek how routing functions.

This function was basically installed in my Linksys before I installed OpenWRT. The configuration of OpenWRT is great, the possibilities are great, too, but this function (routing as from WAN communications that physically come from LAN port) lacks from my point of view.

Olivier Subilia

If you want to test routing from the outside, then test from the outside. The loopback nat workarounds are just fakes and do not the same as a real wan->lan connection.

I had a similar problem, maybe my solution can help anyone in the future.

I have four networks: lan, wan, wlan, dmz
The dmz includes two servers, thus I couldnt just add a dns entry to make the services available for lan and wlan.
So, I want all traffic that has my wan ip as destination to be NATed as if it comes from the wan interface.

On backfire, I added this rule:

iptables -t nat -A PREROUTING -d xx.xx.xx.xx -j zone_wan_prerouting

where xx.xx.xx.xx is the ip of the wan interface. This way I just have to setup port forwarding once and exactly the same rules are applied, no matter where the traffic comes from (lan or wan or wlan).
Only disadvantage: The rule has to updated every time the wan ip changes.

Hi, I'm trying to implement this in Backfire 10.03.1 (rc3), my firewall.user file is as follows:

# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.
LAN=$(uci get network.lan.ipaddr)
WAN=$(ifconfig eth1 | grep inet | awk '{print $2}' | awk -F 'addr:' '{print $2}')

iptables -t nat -A PREROUTING -d $WAN -j zone_wan_prerouting

I've set this up to get the LAN and WAN addresses automatically, so anytime the firewall rules get reloaded, it will always use the current addresses.  But this command isn't giving the desired effect.

For example, let's say my WAN address is 10.0.0.1, and my router's LAN address is 192.168.1.1.  Right now, my firewall does not allow any connection on port 22 to pass from the WAN side, but with this firewall rule, if I ssh to 10.0.0.1, I can connect to my router, instead of this being blocked.

Also, I have a web server on another machine, if I'm elsewhere on the net, I can http://10.0.0.1, and pull up my web server correctly.  If I use the same address from the LAN, I cannot access this server.

Doing a portscan of 10.0.0.1 from a machine on the LAN, I only see ports 22 & 53 being open, neither of these should be visible on the WAN side, and other ports that the firewall has open for the WAN side are not seen.

I'm guessing that the above command still has the packets as appearing to come from the LAN side and not the WAN, so the firewall rules aren't showing the correct ports?  Further up this thread was a quote from mbm's posting showing three separate rules to do this, for each port needed.  I'm guessing some additional logic is still needed here?

(Last edited by JimWright on 28 Sep 2010, 20:17)

Hi JimWright,

I think the problem is that you forward the web server ports to the LAN subnet. If you do so, you will have to add a MASQUERADE rule like this:

iptables -t nat -A postrouting_rule -d $WEBSERVER_LANIP -p tcp --dport 80 -s 192.168.1.0/24 -j MASQUERADE

If you forward the web server ports to a different subnet (e.g. DMZ), you won't need masquerading but you will have to activate forwarding from LAN to DMZ at least for the web server ports.

By the way: You seem to have a dynamic wan ip address. Do you restart the firewall on reconnects?

So, I'll need to have a separate rule for each port then?  I can live with that, I was just hoping there might have been some way to avoid specifically listing each port.  I'll try that this evening when I'm home and can get the new router online again for testing.

Yes, I have a dynamic IP.  My current WhiteRussian config is set up to reload the firewall when the WAN IP changes, I haven't spent enough time with the Backfire setup yet, but I believe that these rules are reloaded when the IP changes there as well, as long as I can pick up the WAN address inside the firewall.user script like I did above, this should all update automatically.

JimWright wrote:

So, I'll need to have a separate rule for each port then?  I can live with that, I was just hoping there might have been some way to avoid specifically listing each port.  I'll try that this evening when I'm home and can get the new router online again for testing.

You can add a rule to masquerade all traffic to your web server instead of setting up single ports..just leave away the --dport parameter.

I waged an epic battle with iptables last night, and though the battle was again lost, I've not given up hope...

So far, nothing I've tried has allowed me to access services using my external DNS name from the LAN side.  Either I'm blocked outright and get an immediate error, or the connection just hangs and eventually times out.  The packets just aren't getting where they need to be.

My working theory is that Backfire is setting up the tables and chains in such a way that the rules I'm trying aren't taking effect where they need to be.  I'm using the Luci interface to set up all my port forwarding, which is working correctly, but have to to the masquerade part in /etc/firewall.user.  Even taking working code from my WhiteRussian setup last night didn't help.

I'm going to try adding some logging this evening and test again, and see if I can determine exactly where things are failing.

I've added some logging, but this hasn't helped.  So far I've not been able to log anything on the output_rule, the command I used should have logged anything hitting that point?  I'm only logging on port 80 since I only want to see web traffic at this point.

For reference, here are the rules that iptables is working with:

root@OpenWrt:/# iptables --list-rules -t nat

-P PREROUTING ACCEPT
-P POSTROUTING ACCEPT
-P OUTPUT ACCEPT
-N postrouting_rule
-N prerouting_lan
-N prerouting_rule
-N prerouting_wan
-N zone_lan_nat
-N zone_lan_prerouting
-N zone_wan_nat
-N zone_wan_prerouting
-A PREROUTING -i eth1 -j zone_wan_prerouting
-A PREROUTING -i br-lan -j zone_lan_prerouting
-A PREROUTING -j prerouting_rule
-A POSTROUTING -j postrouting_rule
-A POSTROUTING -j zone_wan_nat
-A postrouting_rule -j LOG --log-prefix "postroute: "
-A postrouting_rule -s 192.168.1.0/24 -d 192.168.1.10/32 -o eth0 -p tcp -m multiport --dports 80 -j SNAT --to-source 70.116.91.238
-A zone_lan_nat -o br-lan -j MASQUERADE
-A zone_lan_prerouting -j prerouting_lan
-A zone_wan_nat -o eth1 -j MASQUERADE
-A zone_wan_prerouting -j prerouting_wan
-A zone_wan_prerouting -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.10

root@OpenWrt:/# iptables --list-rules

-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT
-N forward
-N forwarding_lan
-N forwarding_rule
-N forwarding_wan
-N input
-N input_lan
-N input_rule
-N input_wan
-N output
-N output_rule
-N reject
-N syn_flood
-N zone_lan
-N zone_lan_ACCEPT
-N zone_lan_DROP
-N zone_lan_MSSFIX
-N zone_lan_REJECT
-N zone_lan_forward
-N zone_wan
-N zone_wan_ACCEPT
-N zone_wan_DROP
-N zone_wan_MSSFIX
-N zone_wan_REJECT
-N zone_wan_forward
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn_flood
-A INPUT -j input_rule
-A INPUT -j input
-A FORWARD -j zone_wan_MSSFIX
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j forwarding_rule
-A FORWARD -j forward
-A FORWARD -j reject
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -j output_rule
-A OUTPUT -j output
-A forward -i br-lan -j zone_lan_forward
-A forward -i eth1 -j zone_wan_forward
-A forwarding_rule -o eth1 -p tcp -m tcp --dport 80 -j LOG --log-prefix "forward: "
-A input -i br-lan -j zone_lan
-A input -i eth1 -j zone_wan
-A input_rule -i eth1 -p tcp -m tcp --dport 80 -j LOG --log-prefix "input: "
-A output -j zone_lan_ACCEPT
-A output -j zone_wan_ACCEPT
-A output_rule -p tcp -m tcp --dport 80 -j LOG --log-prefix "output: "
-A reject -p tcp -j REJECT --reject-with tcp-reset
-A reject -j REJECT --reject-with icmp-port-unreachable
-A syn_flood -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m limit --limit 25/sec --limit-burst 50 -j RETURN
-A syn_flood -j DROP
-A zone_lan -j input_lan
-A zone_lan -j zone_lan_ACCEPT
-A zone_lan_ACCEPT -i br-lan -j ACCEPT
-A zone_lan_ACCEPT -o br-lan -j ACCEPT
-A zone_lan_DROP -i br-lan -j DROP
-A zone_lan_DROP -o br-lan -j DROP
-A zone_lan_MSSFIX -o br-lan -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A zone_lan_REJECT -i br-lan -j reject
-A zone_lan_REJECT -o br-lan -j reject
-A zone_lan_forward -j zone_wan_ACCEPT
-A zone_lan_forward -j forwarding_lan
-A zone_lan_forward -j zone_lan_REJECT
-A zone_wan -p udp -m udp --dport 68 -j ACCEPT
-A zone_wan -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A zone_wan -j input_wan
-A zone_wan -j zone_wan_REJECT
-A zone_wan_ACCEPT -i eth1 -j ACCEPT
-A zone_wan_ACCEPT -o eth1 -j ACCEPT
-A zone_wan_DROP -i eth1 -j DROP
-A zone_wan_DROP -o eth1 -j DROP
-A zone_wan_MSSFIX -o eth1 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A zone_wan_REJECT -i eth1 -j reject
-A zone_wan_REJECT -o eth1 -j reject
-A zone_wan_forward -d 192.168.1.10/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A zone_wan_forward -j forwarding_wan
-A zone_wan_forward -j zone_wan_REJECT

I've finally googled the message that comes back in my browser, it wasn't something I had seen before when a page didn't load, but didn't think anything of it.  Here's the text:
Rejected request from RFC1918 IP to public server address

Imagine my surprise when I googled this and found that this was coming from OpenWrt!

https://dev.openwrt.org/changeset/22589
https://dev.openwrt.org/changeset/22590

This is part of OpenWrt's uhttpd package, and I suppose seeing this error might make sense if I were attempting to hit the web service on the router itself, but I don't see where this would be happening?

So, you already found the problem: You are trying to forward port 80 to your webserver, but this traffic is handled by the uhttpd of the openwrt device.
This is due to the facts that uhttp listens on all subnets and the traffic that comes from br_lan is accepted in the INPUT chain which means that it will be processed locally.

I think you have to options:
* edit /etc/config/uhttpd so that uhttpd only listens on the local subnet
* modify the iptables for zone_lan so that packets to port 80 are dropped, hence they won't be processed locally and never reach the uhttpd

Apparently anything hitting the router's WAN address from the LAN is getting directed to the router itself, not just port 80.  Port 22 and others are being directed there as well, so what you're suggestion wouldn't help.  What I need to do at this point if determine why anything going to the WAN IP is being directed to the router itself and not routed.

My logging right now stops after the zone_lan_prerouting rule.  Next up should have been the POSTROUTING chain, but nothing ever gets logged there.

I'm missing the rule

iptables -t nat -A PREROUTING -d $WAN -j zone_wan_prerouting

or something similar that would forward some ports to your (web)server.

vali wrote:

I'm missing the rule

iptables -t nat -A PREROUTING -d $WAN -j zone_wan_prerouting

or something similar that would forward some ports to your (web)server.

In my iptables --list-rules above, you'll see this line:
-A PREROUTING -i eth1 -j zone_wan_prerouting

That's what OpenWRT automatically added when I added the ports on the Traffic Redirection page.  From the WAN side, this works correctly.  It looks like the difference between this line and the one you posted is that the default rule routes when packets are coming in via the WAN interface (eth1), and your line would route packets destined for the WAN IP, is that right?  If that's the case, I'd want this to jump to a new chain that would specifically handle the routing on the LAN side, but I'm not sure how I can mangle the packets correctly at that point, since SNAT or MASQUERADE can't be done during prerouting, only postrouting.

I was referring to post #8 and assuming you want the router to act as if you accessed from WAN when you actually access the WAN IP from LAN. In order to guard against misunderstandings: could you please specify what you are trying to set up?!

On my LAN, I run a web server, and an email server, both on the same box.  Assume that my DNS name is example.com, I need http://example.com to correctly route to my web server, and I need users to be able to check their mail accounts (user1@example.com, etc) both internally and externally.  At a minimum ports 25, 80, 110, and 443 need to route to this server.  There is also the web interface on the router itself, which on the LAN is accessed on port 80, and via the wan via port 81  (http://example.com:81).  I also have several other devices accessed via non-standard ports from the WAN (including several using port 22), but these can all be accessed normally via the LAN, and do not need the DNS name mapping used externally.

I want to use as much of the Luci web interface to set this up as possible, Firewall/Traffic Control & Firewall/Traffic Redirection are set correctly for these ports to route correctly for external connections.  As there doesn't appear to be anything in the Luci interface to handle what I need done on the LAN side.  Some common terms I've read for this setup are Hairpin NAT and NAT Reflection.

OK, success!  Some more googling and searching the forums here revealed a solution:
https://forum.openwrt.org/viewtopic.php … 59#p109259

I had found that script a few days ago, but thought it was doing more than what I wanted done (thanks to my misreading it, I thought it was handling opening ports on the WAN side as well), but after studying it a bit closer I figured out what it was doing, and saw that I only needed the do_hairpin routine.  I set up a test for ports 25, 80, 110, and I'm now able to get Mail and view my web server using my DNS name correctly.

I never tried this with ports 80 and 443, which are actually handled by the router device itself, but here is what does work for me when I want to forward e.g. port 25 to 192.168.1.10:

iptables -t nat -A zone_lan_prerouting -p tcp --dport 25 -j DNAT --to-destination 192.168.1.10:25
iptables -t nat -A postrouting_rule -d 192.168.1.10 -p tcp --dport 25 -s 192.168.1.0/24 -j MASQUERADE

The first rule can be set with LuCI.
Could you try this?

The easiest way to solve the issue with port 80 and 443 is to setup uhttpd to use non-standard ports.

OK, tested that by itself without the hairpin script, using port 80 since that was easier to quickly test.  Failed totally.  Not only could I not reach my web server by DNS name, I could no longer connect to the router's web page on the LAN.

Sorry to necro this thread, but I found a simple solution for me.
I use a domain name for my DynDNS and some of the services I use have webpages that I routed from subdomains in apache. I have 1178.us as a webserver and media.1178.us as a media server.

This allows me to visit these URLs from my LAN:
In LuCI, Network > DHCP and DNS > Server Settings
uncheck "Discard upstream RFC1918 responses"
Save and Apply.

Edit: using  OpenWrt Backfire 10.03.1

(Last edited by eagleapex on 4 Feb 2013, 18:05)

Thanks vali for the iptables rule. Short and effective. It works great on my mr3420 running Barrier Breaker.

vali wrote:

I had a similar problem, maybe my solution can help anyone in the future.

I have four networks: lan, wan, wlan, dmz
The dmz includes two servers, thus I couldnt just add a dns entry to make the services available for lan and wlan.
So, I want all traffic that has my wan ip as destination to be NATed as if it comes from the wan interface.

On backfire, I added this rule:

iptables -t nat -A PREROUTING -d xx.xx.xx.xx -j zone_wan_prerouting

where xx.xx.xx.xx is the ip of the wan interface. This way I just have to setup port forwarding once and exactly the same rules are applied, no matter where the traffic comes from (lan or wan or wlan).
Only disadvantage: The rule has to updated every time the wan ip changes.

Visit the file

vi /etc/config/uhttpd


and "change option rfc1918_filter '1' "from 1 to 0

/etc/init.d/uhttpd restart

this did the trick for me, apparently the option in LUCI does not work....

The discussion might have continued from here.