Forward external request IP behind reverse proxy behind OpenWRT


With the help of tommie from the #linuxger channel, I’ve finally been able to configure my port forwarding to my web server in a way that I see the actual source request IPs in the web server’s access log. So here’s the overall picture:

  1. A request from an external IP like comes to my external, static IP address, which is the eth1 WAN interface of my OpenWRT router.
  2. The router should do a port forward of incoming requests on port 80, via its internal LAN  interface br-lan,, to my reverse proxy,
  3. The reverse proxy shall, depending on the URL that was actually called, forward the request to one of the actual web servers, say,
  4. In that web server’s access log, I want to see as originating IP

Here’s what’s needed to set it up.

Configure the target Web Server to understand the X-Forwarded-For header

On, I had to install the rpaf module for the Apache web server that I’m using:

I then added three lines to the web sites VirtualHost section:

Configure the Reverse Proxy to add the X-Forwarded-For header

On, I switched from off to on the ProxyPreserveHost directive that was already there:

Make sure, OpenWRT does not do NAT outside-in

This was the real bummer which finally tommie spotted. Until here, everything should just have worked, but didn’t: I still saw only in the web server logs of both the reverse proxy and the final web server. It turned out that masquerading was switched on outside-in:


This amounts to setting to 1 or 0 in the line option masq ‘0’ (where unchecked, i.e., 0, is what you want to have), the following in /etc/config/firewall of the router:

If that’s switched on, then you get masquerading inwards, which will essentially hide the incoming IP address.

Finally, very simply configure the port forward either through the UI:


or, which is equivalent, adding the following to /etc/config/firewall:

If you want to do these forwards by hand, you can for example add the following to /etc/firewall.user:

Which is what actually happens when you add those entries to the UI and then restart the firewall saying “Save & Apply” (which runs /etc/init.d/firewall restart).

Thanks again tommie from #linuxger for that awesome help spotting the surplus masquerading in the iptables -t nat -v -L dump.


So empty here ... leave a comment!

Leave a Reply

Your email address will not be published. Required fields are marked *