OpenWrt Forum Archive

Topic: (with Luci) how to forward packets to wan IP that are coming from lan?

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

So, my setup is:
..........
lan IP 192.168.1.1
wan IP 71.246.215.8

config 'redirect'                     
        option 'src' 'wan'           
        option '_name' 'webserver'   
        option 'proto' 'tcp'         
        option 'src_dport' '80'       
        option 'dest_ip' '192.168.1.8'
..........

- http to 71.246.215.8 from wan works fine, forwards to 192.168.1.8
- http to 192.168.1.1 from lan works fine, goes to Luci admin console
- http to 71.246.215.8 from lan is wrong, SHOULD go to 192.168.1.8

So, I want to forward packets from the lan, addressed to the wan IP, as if they were external.

The desired behaviour from inside the lan is that I use 192.168.1.1 to get the Luci console, but that going via the DNS name (gogobeat.com) that resolves to 71.246.215.8 should forward as if it came from the wan.

How can I do this???  I know it can be done, just not sure how...

(Last edited by toehser on 3 Mar 2009, 15:26)

Maybe it would help if I understood what read the config file and what the format rules are?

I used to be OK with raw 'iptables' stuff, though it has been a long while.

It certainly doesn't look as though the Luci interface gives the kind of options to do what I want?

So I guess I would have to manually edit the /etc/config/firewall file?

But I'm not sure where documentation is for that thing, it certainly isn't iptables syntax.

Hi.

The rules generated by LuCI are indeed in /etc/config/firewall. However, LuCI covers everything this iptables abstraction layer provides, so you won't be able to achieve your desired behaviour by editing /etc/config/firewall. As an alternative solution, you can add this to /etc/config/firewall:

config include
  option path /etc/firewall.user

The file /etc/firewall.user is treated as a plain shell script then which is executed right after the default rules are built. Put manual iptables commands there to redirect traffic originating from lan and targeted at your wan ip to the correct chain.

~ JoW

(Last edited by jow on 3 Mar 2009, 18:46)

jow wrote:

The rules generated by LuCI are indeed in /etc/config/firewall. However, LuCI covers everything this iptables abstraction layer provides,

Are you sure?  I don't think so.

I'm looking at the docs now for the uci firewall stuff - http://dev.luci.freifunk-halle.net/docs … direct.xml -

... and I see docs, for example, for src-mac, for the source MAC address ...

... this is clearly an option covered by the /etc/config/firewall UCI stuff, but NOT supported by the Luci GUI interface ...

??? am I missing something

... It looks like I probably can do what I want with /etc/config/firewall, which would have the benefit of maybe showing up / being modifiable via future versions of Luci ...

From what I see, LuCI does _NOT_ cover everything the /etc/config/firewall provides, at least, not in 8.09.

Or am I missing some parts of LuCI?  Maybe there is a "third level" beyond "essentials" and "administration" (expert? advanced?)?

Or are things like "src-mac" not really supported, and I'm looking at the wrong web pages?

For UCI CLI:

root@OpenWrt:~# uci add firewall include
root@OpenWrt:~# uci set firewall.@include[0].path=/etc/firewall.user
root@OpenWrt:~# uci commit firewall

On the other hand, it seems to provide:
dest Destination zone
dest_ip Destination IP address
dest_port Destination port
proto Protocol
src Source zone
src_dport Source destination port
src_ip Source IP address
src_mac Option src_mac
src_port Source port

as options in /etc/config/firewall... more than the GUI provides... but...

... NOT including "src_dip Source destination IP address"...

The "dest" fields are where I'm redirecting to.

The "src" fields are about the packet as it came in.

I have 2 packets, one came in to 192.168.1.1, one came in to 71.246.215.8.

But both are zone "lan", both are src dport "80" ... what I really need is "src_dip" or "src_dest_ip".

Unless I'm missing something?

toehser wrote:
jow wrote:

The rules generated by LuCI are indeed in /etc/config/firewall. However, LuCI covers everything this iptables abstraction layer provides,

Are you sure?  I don't think so.

... this is clearly an option covered by the /etc/config/firewall UCI stuff, but NOT supported by the Luci GUI interface ...

??? am I missing something

You can find it in Administration -> Network -> Firewall -> Redirect if you click on the Edit-Button of a row (the one left of the delete button).

Jow is right, everything except the include-sections should be covered.

(Last edited by CyrusFF on 3 Mar 2009, 19:46)

Yanira wrote:

For UCI CLI:

root@OpenWrt:~# uci add firewall include
root@OpenWrt:~# uci set firewall.@include[0].path=/etc/firewall.user
root@OpenWrt:~# uci commit firewall

OK.  I guess I was hoping this would be a common enough configuration that it would have a UCI way.

Since I'm running the authoritative DNS, it is not simple to just give a different address to the hostname internally.

Since the webserver uses virtual domains, an to boot there are absolute references to the name in the pages, it isn't simple to use another name without the canonical one working.

So, to raw iptables it is...  I guess I have to crack out the 'man iptables'?

Or has anyone done something similar enough to point me to a snippet?

Being able to do this would be a nice feature to have...

But, if raw iptables it is, then raw iptables it is.

CyrusFF wrote:

You can find it in Administration -> Network -> Firewall -> Redirect if you click on the Edit-Button of a row (the one left of the delete button).

Jow is right, everything except the include-sections should be covered.

Got it.  So the expected current behaviour is that there is no way without the include to have requests from inside the lan to the wan-IP behave the same way they would if they originated from the wan?  I guess what I really want is a way to treat a packet from 192.168.1.x to 71.246.215.8 as if it was zone wan- as though it had looped out and back in.

What about the alternative- is it possible to have the router not even have the wan IP, to give that to a machine on the lan, and have all requests from the wan go to that machine?  Does the router have to have a wan IP?  I only get one static IP without paying way more than a few more static IPs should cost.  I would be fine if I could configure an internal machine with that IP, and only have NAT traffic go to the others...

Would enhancing this require change both to UCI (C) and LuCI (Lua)?  Or just to UCI and the Lua part will automatically pick up and bind GUI components?

Or is there a 3rd piece, with UCI managing config structures, LuCI as GUI for modifications, and then back-ends to do actual (i.e. iptables) work?

If I want to enhance it, could I get some feedback on whether this would be generally desired, or something I would just keep locally?

UCI comes from BSD or something, doesn't it?  Wish it was all just in Lua, I used to use Lua on tomsrtbt.

So, I'm clearly more ignorant than I thought, I thought:

iptables -t nat -I zone_lan_prerouting -p tcp --dport 80 -d 71.246.215.8 -j DNAT --to 192.168.1.8:80
iptables -t filter -I zone_lan_forward -d 192.168.1.8/32 -p tcp --dport 80 -j ACCEPT

would work, but, no, what am I missing?  Is there a better place to ask this question?

Hi.

If you want to change the default behaviour, you would have to change the uci firewall backend in /lib/firewall/uci_firewall.sh. You'll see a fw_redirect() procedure there which generates the actual port forwarding rules. I'm not sure whether it's solveable in a generic way, afaik you'd need to create appropriate iptables rules in each other zone when adding a portforward, so that it does not only match traffic from e.g. wan->lan but lan->lan or xyz->lan too.

If you extend the firewall uci (which happens indirectly by editing the shell backend) you'd have to add the appropriate optiosn to LuCI too which is not that hard, but one step at the time.

Afaik UCI is no BSD thing, iirc it was developed as successor of the old nvram based config system but I might be wrong.

HTH, JoW

So http://people.freebsd.org/~abial/UCI.html is just coincidence.

As far as my iptables example failing - any ideas?

I'll have to figure out how to get iptables to log on openwrt, operating blindly didn't work.

Ok, FWIW, what WORKS for this, which I'm going to be too lazy to submit a uci/luci patch to manage, was this, in the firewall.user:

iptables -t nat -A zone_lan_prerouting -p tcp -m tcp -s 192.168.1.0/24 -d 71.246.215.8 --dport 80 -j DNAT --to-destination 192.168.1.8:80
iptables -t nat -N toms_internal_nat
iptables -t nat -A POSTROUTING -j toms_internal_nat
iptables -t nat -A toms_internal_nat -p tcp -m tcp -d 192.168.1.8 --dport 80 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1

the one rule says that traffic from the internal lan to the wan IP gets d-natted to the internal webserver.
the other rule says that that traffics is s-natted to come from the router, so returns can match up right.

Personally, I think this should be the right way 99% of the time... And more likely shoudl be the _default_ than something that requires this much thinking...

Missed one thing and had it too complex:

iptables -t nat -A prerouting_lan -p tcp -m tcp -s 192.168.1.0/24 -d 71.246.215.8 --dport 80 -j DNAT --to-destination 192.168.1.8:80
iptables -t nat -A postrouting_rule -p tcp -m tcp -d 192.168.1.8 --dport 80 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1
iptables -t filter -A forwarding_lan -d 192.168.1.8 -s 192.168.1.0/24 -p tcp -m tcp --dport 80 -j ACCEPT

Thanks a lot, this has been of great help to me.

I needed to apply it to multiple ports: http, https and ssh (cause I want my laptop's Gnome sftp bookmarks to work when I'm in and out of the lan) also I have dynamic dns (with dyndns.com) in my domain, however the IP is rarely changed by the ISP (almost static) so I need to get it from the interface.

Here is what I put in /etc/firewall.user:

# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.

lan_src=10.1.52.0/24
wan_ip=$(ifconfig eth0.1 | awk  '/inet addr:/ {print $2}' | awk -F : '{print $2}')
lan_ip=10.1.52.1
server_ip=10.1.52.2
ports="80 443 22"

for p in $ports
do
    iptables -t nat -A prerouting_lan -p tcp -m tcp -s $lan_src -d $wan_ip --dport $p -j DNAT --to-destination ${server_ip}:$p
    iptables -t nat -A postrouting_rule -p tcp -m tcp -d $server_ip --dport $p -s $lan_src -j SNAT --to-source $lan_ip
    iptables -t filter -A forwarding_lan -d $server_ip -s $lan_src -p tcp -m tcp --dport $p -j ACCEPT
done

BTW I have a few questions:

- Is there an easier and/or shorter command to get an interface IP?
- How do I get the command '/etc/init.d/firewall reload' to be run each time my wan IP changes?
- Or, to avoid all the trouble, can I use the interface (eth0.1) in the rules instead of the IP? How?

jaimesilva wrote:

- Is there an easier and/or shorter command to get an interface IP?

IP=$(uci -P/var/state get network.wan.ipaddr)
jaimesilva wrote:

- How do I get the command '/etc/init.d/firewall reload' to be run each time my wan IP changes?

This is the wrong way, put your rules into a hotplug handler instead, e.g. /etc/hotplug.d/iface/90-my-ipt-rules with contents similar to this:

#!/bin/sh
if [ "$ACTION" = "ifup" ] && [ "$INTERFACE" = "wan" ]; then
  IP="$(uci -P/var/state get network.$INTERFACE.ipaddr)"
  iptables ...
fi

If you use trunk or really new 8.09 branch revisions you can also use the newly introduced firewall hotplug events: https://wiki.openwrt.org/doc/firewall#h … oks.8.09.2

jaimesilva wrote:

- Or, to avoid all the trouble, can I use the interface (eth0.1) in the rules instead of the IP? How?

You can get the eth-name of an openwrt interface with

uci -P/var/state get network.wan.ifname

.

~ JoW

(Last edited by jow on 3 Oct 2009, 17:39)

Also have a look at this HowTo it shows how to get the correct interface name for a network, e.g. wan via pppoe, bridged lan, etc.
The script there does not cover 100% of all cases yet, but it gives you a good insight how to do this very flexible in a script.
Could come in handy, otherwise ignore it.

(Last edited by maddes.b on 27 May 2010, 12:47)

The discussion might have continued from here.