iptables NAT prerouting rule does not forward the traffic?
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.
worked to forward server's incoming traffic at mentioned port into the VPN tunnel where the VPN client network interface has IP 10.8.0.2. Port appeared as open.
Now when i tried the same rule on different server, the port appears closed, even i tried to disable client's firewall.
The ifconfig shows the server has only lo, eth0 and tun0 interfaces so eth0 should be correct.
Please what is the commands you would do to discover where the incoming traffic is stuck?
some details about the server:
Redhat based CentOS 7, kernel 3.10, iptables v1.4.21
Hello,
on one server, the iptables rule like:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 48280 -j DNAT --to 10.8.0.2:48280
worked to forward server's incoming traffic at mentioned port into the VPN tunnel where the VPN client network interface has IP 10.8.0.2. Port appeared as open. Now when i tried the same rule on different server, the port appears closed, even i tried to disable client's firewall. The ifconfig shows the server has only lo, eth0 and tun0 interfaces so eth0 should be correct. Please what is the commands you would do to discover where the incoming traffic is stuck?
some details about the server:
Redhat based CentOS 7, kernel 3.10, iptables v1.4.21
Again; we know nothing about your internal network, what IP addresses are in use on this server (past the one you posted), nor how you have determined the 'port appears closed'. Are you not able to look through the many, MANY threads you've opened in the past about iptables/firewalls/networking, and apply ANYTHING you've been told in the past???
Have you checked to see if IP forwarding is turned on???? And since you configured one server, why can't you use the EXACT SAME RULES (with small modifications, since the systems are obviously not the same), on the new system? You've been told several times in the past about how to backup and restore rule-sets, so that should be trivial for you to do.
Now when i tried the same rule on different server, the port appears closed, even i tried to disable client's firewall.
What do you mean by "appears closed"?
Quote:
Please what is the commands you would do to discover where the incoming traffic is stuck?
I would use commands like these:
Code:
tcpdump -v -i eth0 port 48280
tcpdump -v -i tun0
Or perhaps any instead of eth0 and tun0. If you have a GUI, wireshark is very comfortable for filtering and drilling down.
I would also use tcpdump or wireshark on the other side of the tunnel. Wireshark has a Windows edition, too, and tcpdump can be used on Windows via Cygwin if there is no native equivalent.
Other suggestions: Check your netfilter rules again. Is there a rule before the DNAT that might interfere? Also, add a logging rule to the netfilter ruleset (-j LOG).
Last edited by berndbausch; 04-16-2020 at 08:03 PM.
Sorry, forgot to mention this. It means the software on client has a tool that check its incoming port and report closed status. Also the web based third party port checker like https://www.yougetsignal.com/tools/open-ports/ reports the same.
Quote:
Originally Posted by berndbausch
I would use commands like these:
Code:
tcpdump -v -i eth0 port 48280
tcpdump -v -i tun0
...
wireshark is very comfortable for filtering and drilling down.
Thank you for this. I spent one hour trying to install Cygwin on Windows and npcap + windump.exe, but unable to find the tcpdump or no output. I am not interested to waste more of my time setting that. So i ran Wireshark. It seems to be pretty intuitive as you say. It has an flag/bookmark in the filtering field where i can define single port to filter and also in my case the tun0 interface to listen on. Then during capturing i click arrow at the end of the filtering field to apply the filter. It shows no captured output. So no traffic reaching client on that port. But on the server, Yours mentioned command shows alot of output. For just several seconds:
197 packets captured
1267 packets received by filter
915 packets dropped by kernel
So the traffic is not forwarded or is dropped/denied somehow? @berndbausch please what to do now?
/etc/sysctl.conf shows the forwarding is enabled. (net.ipv4.ip_forward = 1)
Firewall details i have shown in my first post.
And as mentioned, on the client i tried to disable firewall during the capture, so i expect the problem to be on the server.
Quote:
Originally Posted by berndbausch
Check your netfilter rules again. Is there a rule before the DNAT that might interfere?
I does not look like that right? Part of the "iptables -L -t nat" output:
Then this one started logging something: iptables -A INPUT -j LOG
tail -f /var/log/messages
Yet, it shows no traffic that match the port of my interest:
tail -f /var/log/messages|grep 48280
Despite the "tcpdump -v -i eth0 port 48280" has quite intensive traffic output. What would you suggest to try @berndbausch
Sorry, forgot to mention this. It means the software on client has a tool that check its incoming port and report closed status. Also the web based third party port checker like https://www.yougetsignal.com/tools/open-ports/ reports the same.
Thank you for this. I spent one hour trying to install Cygwin on Windows and npcap + windump.exe, but unable to find the tcpdump or no output. I am not interested to waste more of my time setting that.
And it didn't occur to you to run tcpdump on the LINUX system??? And since you spent an hour trying to install Cygwin (for some reason), it surprising you couldn't just put "install tcpdump on windows" into Google, and press ENTER...one of the first hit is a Windows version of it: https://www.microolap.com/products/network/tcpdump/
Quote:
So i ran Wireshark. It seems to be pretty intuitive as you say. It has an flag/bookmark in the filtering field where i can define single port to filter and also in my case the tun0 interface to listen on. Then during capturing i click arrow at the end of the filtering field to apply the filter. It shows no captured output. So no traffic reaching client on that port. But on the server, Yours mentioned command shows alot of output. For just several seconds:
197 packets captured
1267 packets received by filter
915 packets dropped by kernel
sample:
So the traffic is not forwarded or is dropped/denied somehow? @berndbausch please what to do now?
/etc/sysctl.conf shows the forwarding is enabled. (net.ipv4.ip_forward = 1)
Which is what I told you in my first reply...
Quote:
Firewall details i have shown in my first post. And as mentioned, on the client i tried to disable firewall during the capture, so i expect the problem to be on the server.
I does not look like that right? Part of the "iptables -L -t nat" output: I tried various commands, like but it logged no output into /var/log/messages Then this one started logging something: iptables -A INPUT -j LOG
tail -f /var/log/messages
Yet, it shows no traffic that match the port of my interest:
tail -f /var/log/messages|grep 48280
Despite the "tcpdump -v -i eth0 port 48280" has quite intensive traffic output. What would you suggest to try @berndbausch
Again, as you've been told many, MANY times over the years, we'd suggest you show some actual effort and thought of your own for a change. You literally have one server that WORKS, that you can look at.
COMPARE THE TWO...there has to be a difference somewhere. When you find it, MAKE IT MATCH. You also (AGAIN) don't tell us what environment you're in, tell us anything about your network topology, where these things run through, etc. Did you bother to check the DMZ? Hardware firewall??? You have to be running through those things in order to touch a public IP address. You were asked all of this in post #2, yet (as usual), don't supply any relevant information.
You've been working with iptables/ufw for SEVEN YEARS; you have been handed exact commands for NAT'ing and forwarding, but each time you need to change something, you don't seem to be able to apply anything you've been told or learned, and instead ask for a handout.
To find out where traffic disappears, you trace the interfaces through which traffic flows. Once you know where it disappears, you look at your netfilter rules once more.
I don't know which interface you traced when receiving this packet:
but in any case it's neither coming from nor going to port 48280, therefore irrelevant.
Quote:
Originally Posted by postcd
but it logged no output into /var/log/messages
Then this one started logging something: iptables -A INPUT -j LOG
tail -f /var/log/messages
Yet, it shows no traffic that match the port of my interest
tail -f /var/log/messages|grep 48280
This means that packets with port 48280 match an earlier rule and don't reach the LOG rule. You could analyze the rules and/or move the LOG rule to an earlier position.
You could analyze the rules and/or move the LOG rule to an earlier position.
So i tried "iptables -I INPUT -j LOG"
The client's Wireshark shows some TCP connections at that port 48280, but when the source is some unknown remote IP, then the connection is red with flags RST, ACK.
I found this tool can tell the port status: https://check-host.net/check-tcp https://check-host.net/check-udp
and it seems to properly report udp port status as "open or filtered" and the non-forwarded UDP port status as closed. But it always report closed in case of a TCP. So the problem looks to be in a TCP (forwarding on the server?), but i am really unsure why UDP yes and TCP no.
# iptables -L FORWARD
Quote:
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all -- 10.8.0.0/24 anywhere
DROP all -- anywhere anywhere ctstate INVALID
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- 192.168.42.0/24 192.168.42.0/24
ACCEPT all -- anywhere 192.168.43.0/24 ctstate RELATED,ESTABLISHED
ACCEPT all -- 192.168.43.0/24 anywhere
DROP all -- anywhere anywhere
You mean iptables -I INPUT -j log ?
Would it be helpful in case i discovered (using Wireshark) that the UDP traffic go through to the client, but TCP traffic somehow is not forwarded nor is visible in server's iptables log output but exist in server's tcpdump?
Or you can *AGAIN* use tcpdump for Windows, since you've been using it for some time. And since you want to trace what's going on in the logs for iptables, wouldn't it be obvious to look at that log file??
Quote:
I found this tool can tell the port status: https://check-host.net/check-tcp https://check-host.net/check-udp
and it seems to properly report udp port status as "open or filtered" and the non-forwarded UDP port status as closed. But it always report closed in case of a TCP. So the problem looks to be in a TCP (forwarding on the server?), but i am really unsure why UDP yes and TCP no.
**AGAIN**, since you don't seem to be understanding; PROVIDE DETAILS. You are looking at an ****EXTERNAL ADDRESS****....this most probably involves some sort of firewall/DMZ setup. Since you've been working with such things for at least SEVEN YEARS, you should already know that when you want a new server to be allowed to receive/send traffic externally, that you have to **CONFIGURE THE FIREWALL AND DMZ TO ALLOW IT**
Have you done this? Have you checked this???
Quote:
# iptables -L FORWARD
# iptables -L -t nat|grep DNAT
highlighted rule is the one responsible for the tcp port forwarding which results in port closed detection on online testers and in the app that using the port.. Thank you
Great; so AGAIN, as has been explained to you dozens of times over the past seven years: FIND THE DIFFERENCE BETWEEN THE WORKING AND NON WORKING SYSTEM. One works; the other doesn't. Since you set one up, you should easily be able to set another one up....you are familiar with EVERY PIECE of this, and it's been explained to you over and over again, on this site and many others.
You are not providing details about your network topology, just posting rulesets and asking us to diagnose them for you. After so many years, are you not able to do any sort of diagnostics on your own?? Are you unable to use the tools that people have told you about dozens of times??? Why can you not apply anything you've been told?
I have to admit that I know nothing about your architecture, about Windows, a client, virtual machines and so on. I know you have a Linux server with a NIC eth0 and a tunnel endpoint tun0. Traffic to port 48280 is supposed to enter via eth0 and get forwarded to the tunnel. Is that correct?
If so, first check if traffic arrives at eth0 at all. tcpdump can reveal that.
Next, check if those packets flow through tun0. If so, the problem is not your netfilter rules. If not, I would first check what the routing tables do with destination 10.8.0.2. Is it routed to tun0 at all? If not, fix this.
In case traffic does arrive at eth0, the routing rules are correct and traffic does NOT go through tun0, you rework your netfilter rules.
It seems solved now. The connections started going through (and recorded on server under tun0 interface - tcpdump -i tun0 tcp port 48280) when i removed the forwarding rule highlighted below:
Quote:
iptables -L FORWARD --line-numbers
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 10.8.0.0/24 anywhere
2 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
3 DROP all -- anywhere anywhere ctstate INVALID
4 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
5 ACCEPT all -- anywhere anywhere
6 ACCEPT all -- 192.168.42.0/24 192.168.42.0/24
7 ACCEPT all -- anywhere 192.168.43.0/24 ctstate RELATED,ESTABLISHED
8 ACCEPT all -- 192.168.43.0/24 anywhere 9 DROP all -- anywhere anywhere
Below are other details even the above mentioned action solved the issue of this forum topic, i am leaving it here if you are insterested to know:
Quote:
Originally Posted by berndbausch
Traffic to port 48280 is supposed to enter via eth0 and get forwarded to the tunnel. Is that correct?
Thank you for your reply. Yes, that is what i wanted to achieve.
Quote:
Originally Posted by berndbausch
If so, first check if traffic arrives at eth0 at all. tcpdump can reveal that.
yes, it does arrive, because on the server, i am seeing quite alot of connection from various IPs when running:
tcpdump tcp port 48280
tcpdump -i eth0 tcp port 48280
Sample:
but "tcpdump -i tun0 tcp port 48280" does not shown any TCP connections
Quote:
Originally Posted by berndbausch
Next, check if those packets flow through tun0.
How do i do it on the server? i mentioned a few lines above that i see the TCP traffic on eth0, but not on tun0.. + on the client i confirm that i received no TCP connections at that port, only UDP ones.
I think that here comes your suggestion:
Quote:
I would first check what the routing tables do with destination 10.8.0.2. Is it routed to tun0 at all?
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
POSTROUTING_direct all -- anywhere anywhere
POSTROUTING_ZONES_SOURCE all -- anywhere anywhere
POSTROUTING_ZONES all -- anywhere anywhere
SNAT all -- 10.8.0.0/24 !10.8.0.0/24 to:myserverpubliciphere
MASQUERADE all -- 192.168.42.0/24 anywhere
MASQUERADE all -- 192.168.43.0/24 anywhere policy match dir out pol none
MASQUERADE all -- anywhere anywhere
MASQUERADE all -- anywhere anywhere
I lso tried following but that NOT opened port on its own:
when i exported iptables (iptables-save > /etc/sysconfig/iptables_18.4.2020)
created copy (cp -p /etc/sysconfig/iptables_18.4.2020 /etc/sysconfig/iptables_18.4.2020_mod)
edited the copy (vi /etc/sysconfig/iptables_18.4.2020_mod)
append:
-A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source myserveriphere
after line:
-A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to-source myserveriphere
save and import into firewall (iptables-restore < /etc/sysconfig/iptables_18.4.2020_mod)
i then moved FORWARD rule:
FORWARD -s 10.8.0.0/24 -j ACCEPT
to the top
You did all the checks that I recommended. You confirmed that 48280 traffic arrives at eth0 and does not flow through tun0 (tcpdump -i tun0 confirms that). You checked that traffic to 10.8.0.0 is indeed routed to tun0. All this is fine.
So the only reason I can see is a problem with your netfilter rules. They are rather complex - I guess you have a firewall that creates all these rules. The problem is that you interfere with the firewall by adding a DNAT rule, and that it's hard to get a grip on that interference.
You seem to have the problem even when the firewall is off. But when it is off, the rules are simpler, I guess, which would make it easier to find out how packets are passed through netfilter.
As far as I know, the only ways to deal with it are, again, manually checking the rules, perhaps performing a netfilter simulation on paper. Or using LOG rules that you place at useful positions in the rule set. I am not aware of a netfilter analyzer (but by all means, don't believe me).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.