[SOLVED] Firewalld - forwarding traffic received on eth1:0 to different IP than eth1
Linux - NetworkingThis forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
What I need is to be able to see the website on 192.168.0.1 when I hit 172.16.1.1 with a web browser, and the website on 192.168.0.2 when I hit 172.16.1.2 with a web browser.
E. g. I want to forward the traffic through ports 80 and 443 to 192.168.0.1 on eth1 (172.16.1.1) and 192.168.0.2 on eth1:0 (172.16.1.2).
With the above config, firewalld / iptables IGNORES eth1:0 - e. g. if I hit 172.16.1.1 I get the website on 192.168.0.1. BUT if I hit 172.16.1.2 I -still- get the website on 192.168.0.1, NOT 192.168.0.2
E. g. the virtual NIC eth1:0 appears to be equivalent to firewalld as eth1 - HTTP traffic on port 80 to either 172.16.1.1 (eth1) or 172.16.1.2 (eth1:0) all gets sent to 192.168.0.1, ignoring the forward rules set on eth1:0.
How can I get firewalld / iptables to
forward traffic received on :80 and :443 on 172.16.1.1 (eth1) to 192.168.0.1
forward traffic received on :80 and :443 on 172.16.1.2 (eth1:0) to 192.168.0.2
and not just forward all traffic on both 172.16.1.1 and 172.16.1.2 to 192.168.0.1?
Why don't you use the ip address as a criterium instead of the interface
iptables -A PREROUTING -d 172.16.1.1/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.1:80
iptables -A PREROUTING -d 172.16.1.2/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.2:80
Why don't you use the ip address as a criterium instead of the interface
iptables -A PREROUTING -d 172.16.1.1/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.1:80
iptables -A PREROUTING -d 172.16.1.2/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.2:80
Hi
Thanks for the reply!
Ok, I will try the above and see what happens. I was looking for a firewalld based approach, hoping to avoid iptables itself but that doesn't appear possible then.
I'm certainly no expert with firewalld, but I do know that:
Quote:
firewall-cmd is the command line client of the firewalld daemon. It provides interface to manage runtime and permanent configuration.
So, start with man firewall-cmd -- there's a LOT of documentation there, but one of the listed options will provide what KatrinAlec suggested -- sorry, I don't know which one.
I'm certainly no expert with firewalld, but I do know that:
So, start with man firewall-cmd -- there's a LOT of documentation there, but one of the listed options will provide what KatrinAlec suggested -- sorry, I don't know which one.
Hi!
Thanks for the reply.
I've gone through the documentation as advised, but no luck. In fact, following the documentation is what got me into the situation where all HTTP / HTTPS traffic sent to 172.16.1.1 or 172.16.1.2 still gets forwarded to 192.168.0.1 - instead of 172.16.1.1 on eth1 forwarding to 192.168.0.1 and 172.16.1.2 on eth1:0 forwarding to 192.168.0.2.
I used this syntax found in the manpage you mention to setup the port forwards in my original post:
Code:
[--permanent] [--zone=zone] --add-forward-port=port=portid[-portid]:proto=protocol[:toport=portid[-portid]][:toaddr=address[/mask]]
[--timeout=timeval]
Add the IPv4 forward port for zone. If zone is omitted, default zone will be used. This option can be specified multiple times. If a timeout is
supplied, the rule will be active for the specified amount of time and will be removed automatically afterwards. timeval is either a number
(of seconds) or number followed by one of characters s (seconds), m (minutes), h (hours), for example 20m or 1h.
The port can either be a single port number portid or a port range portid-portid. The protocol can either be tcp, udp, sctp or dccp. The
destination address is a simple IP address.
The --timeout option is not combinable with the --permanent option.
For IPv6 forward ports, please use the rich language.
In this configuration, curl-ing 172.16.1.1 hits apache at 192.168.0.1 as it should.
BUT in this configuration, curl-ing 172.16.1.2 hits apache at 192.168.0.1 as it should not - instead of forwarding traffic to 192.168.0.2 from 172.16.1.2, it still sends all traffic to 192.168.0.1 - irrespective from if you do a curl to 172.16.1.1 or 172.16.1.2, firewalld / iptables controlled by firewalld sends all HTTP and HTTPS traffic ONLY to 192.168.0.1, never to 192.168.0.2.
What I'm trying to do appears quite unique, I can find numerous examples of just forwarding traffic in firewalld, but none anywhere about forwarding traffic to a certain IP given on which interface the traffic arrives at initially.
I can also find no guidance in the documentation on how I can somehow with firewalld "know" that traffic has arrived to a certain IP address, and use that as a rule to know what to with the traffic (send to 192.168.0.1 or 192.168.0.2 based on whether 172.16.1.1 or 172.16.1.2 was hit, instead of trying to use the zone bound to a certain interface - eth1 or eth1:0?)
E. g. from that, the above - to attempt to get firewalld to do this by assigning a certain interface to a zone, and then setting up a distinct forward rule in that zone, to get the effect that curl-ing / HTTP browsing that IP bound to that zone, through the interface set in that zone, will send traffic through the forward rule defined for that zone, and traffic received in a different zone on a different interface bound to that different zone, through the forward rule defined in THAT completely separate zone.
This does not work. The second virtual interface for zone 2 - eth1:0 - is ignored and the distinct zone "zone 2" behaves as if its forward rule to 192.168.0.2 does not exist, instead behaving as if the distinct forward rule set in the zone 1 zone, bound to interface eth1, is the only forward rule that exists and is then universally applied.
Even though it is two seperate zones, bound to two seperate ethernet interfaces, one physical - eth1 - and one virtual, eth1:0.
What's in the logs? Any hints there about what's not working?
Hi!
Thanks for taking the time to reply.
I tailed /var/log/firewalld, and no errors are emitted at all when curl-ing 172.16.1.1 and 172.16.1.2, while both these IPs forward the traffic only to 192.168.0.1, and 192.168.0.2 never receives any HTTP requests, if 172.16.1.2 is curl-ed.
and curling 172.16.1.1 and 172.16.1.2 all traffic still simply gets forwarded to 192.168.0.1 with no errors evident in /var/log/firewalld at all - if deleted and touched, it just stays completely empty.
Firewalld in my Centos 7 setup DOES log, if I delete and touch it and restart firewalld, re-create the above setup, and then try to create a zone that already exists it logs in the log file
in the newly-empty /var/log/firewalld, so firewalld logging is working fine as far as I can see.
Any other logs I can check or some way to turn up verbosity?
The problem is that there is no distinct error per se, it is just that no HTTP/HTTPS traffic requested from 172.16.1.2, is ever forwarded to 192.168.0.2, everything always goes only to 192.168.0.1, if either 172.16.1.1 or 172.16.1.2 (eth1 and eth1:0 on the same box) receives HTTP/HTTPS requests from curl or a web browser. So there is no "error" per se, it is just that HTTP/HTTPS requests to 172.16.1.2 (virtual eth1:0) are treated as if they were made to 172.16.1.1 ("real" eth1). No traffic is rejected and nothing is blocked, HTTP requests to 172.16.1.2 are just forwarded to the wrong host (192.168.0.1), always, instead of 172.16.1.1 (on eth1) forwarding to 192.168.0.1, and 172.16.1.2 (on eth1:0) forwarding to 172.16.1.2.
---
It appears that firewalld / iptables cannot distinguish for forward rules between a "real" physical NIC, and a -virtual- NIC, with a different IP, defined on that physical NIC? And that any forward rules applied can only be applied to one physical NIC with one "physical NIC" IP, and the logic that a virtual NIC can exist on that physical NIC with a different "virtual NIC IP" and must be treated differently for having a different IP from the main physical NIC's IP (and being in a different firewalld zone), does not exist. All virtual NICs and their IPs and forward rules appear to all be the same as the one physical NIC's IP and the physical NIC's zone forward rules in firewalld.
---
Just a further note, I repeated the above but not with one physical and one virtual NIC, but two physical NICs in a Centos 7 machine.
The results are exactly the same e. g.
IP A on 172.16.1.1 -> IP A 192.168.0.1 - SUCCESS
IP B on 172.16.1.2 -> IP A 192.168.0.1 - STILL FAILS
So firewalld, as used above, is incapable of detecting that an IP which in one zone, should be forwarded according to the forward rules in that zone, and an IP which is in another zone, should be forwarded according to the forward rules in that other zone.
Even if the IPs are on two physical, real NICs plugged into the machine's motherboard, vs. one physical NIC and one virtual NIC.
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -I INPUT 1 -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -j DROP
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A PREROUTING -d 172.16.1.1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.1:80
But this just results in the webserver on 172.16.1.1 receiving the traffic to 172.16.1.1, instead of the traffic to port 80 on 172.16.1.1 being forwarded to 192.168.0.1:80
Any other ideas?
E. g. with firewalld, everything gets forwarded to the whatever IP is first in the forward rules created.
With iptables with the above, everything gets redirected to the local physical port 80, instead of being forwarded.
The above code allows me to hit my "proxy" server on either its 172.16.1.1 or 172.16.1.2 NICs' IP addresses, and get the HTTP requests forwarded to 192.168.0.1 if 172.16.1.1 is hit, or to 192.168.0.2 if 172.16.1.2 is hit.
This is exactly what the ticket was for, so this is solved.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.