Score:0

iptables -t nat seems not working properly

ph flag

I'm working on Ubuntu 20.04. I set the following iptables rules:

sudo iptables -t nat -A POSTROUTING -d 192.168.10.162 -j MASQUERADE
sudo iptables -t nat -A PREROUTING -p tcp --dport 445 -j DNAT --to-destination 192.168.10.162:445

There 192.168.10.162 is another Ubuntu server of 18.04 running some smb server also.

When I run $sudo iptables -t nat -L -v, it shows the following:

Chain PREROUTING (policy ACCEPT 3 packets, 249 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  any    any     anywhere             anywhere             tcp dpt:microsoft-ds to:192.168.10.162:445

Chain INPUT (policy ACCEPT 1 packets, 149 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  any    any     anywhere             192.168.10.162

It means my nat commands has taken effects, right? And it means the packets to 445 (smb) port will be forwarded to 192.168.10.162:445, right?

I enabled ip forward by $sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward. I installed a smb server on the Ubuntu 20.04 machine and use another Win10 PC to access the shared directory of it. Then I found my visits, delete of files under the directory, or copy of files to the directory, shows no signs of records on the two nat rules I added.

And then after I mount the smb shared directory of 192.168.10.162 on the Ubuntu 20.04 machine, and visit its own smb shared directory as above, it still shows no sign of records in the PREROUTING rule but some in the POSTROUTING rule.

Chain PREROUTING (policy ACCEPT 176 packets, 16007 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  any    any     anywhere             anywhere             tcp dpt:microsoft-ds to:192.168.10.162:445

Chain INPUT (policy ACCEPT 74 packets, 10704 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 19 packets, 1620 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 18 packets, 1560 bytes)
 pkts bytes target     prot opt in     out     source               destination
    1    60 MASQUERADE  all  --  any    any     anywhere             192.168.10.162

It seems maybe the mount command triggered the record on my POSTROUTING rule. And I also tested that ping to 192.168.10.162 triggered records on this rule. But why there is no pkts or bytes captured on my PREROUTING rule? Even I copy a large file to the smb shared directory of the Ubuntu 20.04 machine.

[Update] I tried forwarding all packets with dport of 8080 to 192:168.10.162:80 running a web server. Then I use a Win10 PC to visit the machine (Ubuntu 20.04) via http://[ip address]:8080, it redirects to the web server. And iptables nat PREROUTING and POSTROUTING shows records.

Chain PREROUTING (policy ACCEPT 551 packets, 41812 bytes)
 pkts bytes target     prot opt in     out     source               destination
    5   260 DNAT       tcp  --  any    any     anywhere             anywhere             tcp dpt:http-alt to:192.168.10.162:80

Chain INPUT (policy ACCEPT 77 packets, 10563 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 12 packets, 922 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 12 packets, 922 bytes)
 pkts bytes target     prot opt in     out     source               destination
    5   260 MASQUERADE  tcp  --  any    any     anywhere             192.168.10.162       tcp dpt:http

[Update] I use $tcptrack to confirm that the packets did sent to the 445 port of Ubuntu 20.04. Again no packets were shown captured by nat PREROUTING.

Score:1
bv flag

You're trying SMB server, but you didn't DNAT all the SMB-replated ports. You also need these ports as well: 137,138,139

You can see a nice table on the ports and their corresponding TCP/UDP protocol here.

sudo iptables -t nat -A POSTROUTING -d 192.168.10.162 -j MASQUERADE
sudo iptables -t nat -A PREROUTING -m multiport --dports 137,138,139,445 -j DNAT --to-destination 192.168.10.162

Of course the second rule doesn't chek the correct TCP/UDP protocol for each port.

If you want your tables to work for this machine as well as the ones that this machine routes, then you have to do the same for the OUTPUT chain as well as the PREROUTING chain:

sudo iptables -t nat -A OUTPUT -m multiport --dports 137,138,139,445 -j DNAT --to-destination 192.168.10.162

This is because the packets that are generated from your own machine, don't go through the PREROUTING and go straight to the OUTPUT and then to the POSTROUTING.

Here's a diagram from nftables' hooks than can help you out in understanding this:

description

li_jessen avatar
ph flag
Even so, why only one pkt of 60 bytes shown on the second rule?
li_jessen avatar
ph flag
I tried, still the same. I found that smbd is listening on both 445 and 139 on the machine by $sudo netstat -tulpn | grep LISTEN.
moisrex avatar
bv flag
If you're trying smb from your the machine that you're setting these firewall rules, then your request won't go into PREROUTING. You'll have to do the same for the OUTPUT too if you want your system's request to be DNATed as well. The reason for the POSTROUTING working might be because you're testing SMB from this machine, or it could be because you're connection to that machine with unrelated-to-smb protocols (even pings to that machine will make POSTROUTING counts go up)
li_jessen avatar
ph flag
Now let's focus on PREROUTING. Why I can't find any hit in it after I visited the smb directory from a Win10 PC?
moisrex avatar
bv flag
It should get hit unless you have some other rules in other tables. Is this the scenario that you're testing right?: Win10 -----(smb to)-----> Ubuntu20 ------(but opens up smb from)-----> Ubuntu18(192.168.10.162)
li_jessen avatar
ph flag
Ubuntu20 mounts the shared SMB directory of Ubuntu 18 (192.168.10.162) on its local directory, say, /mnt/smb
moisrex avatar
bv flag
Ubuntu20 is the one doing the NATing which directly sends every SMB request to Ubuntu18 without any knowledge of it being mounted locally. So in the scenario that Win10 asks Ubuntu20 for SMB, Ubuntu20 gives back Ubuntu18's SMB. But if you run SMB from Ubuntu20 to Ubuntu18, PREROUTING should not get any hits because self-generated packets don't go to the PRETOUGING, they go to OUTPUT.
li_jessen avatar
ph flag
Win10 asks Ubuntu 20 for SMB, Ubuntu 20 gives back Ubuntu 18's SMB. What exactly does Win10 get in your view?
moisrex avatar
bv flag
"Win10 asks Ubuntu 20 for SMB, Ubuntu 20 gives back Ubuntu 18's SMB"; that's exactly what I think Win10 should get, Ubuntu 18's SMB. Is this not what you wanted?
li_jessen avatar
ph flag
How could it work? The Ubuntu 20 and Ubuntu 18 each has its own distict username , password, and shared name.
moisrex avatar
bv flag
If you provide the ubuntu18's user/pass to ubuntu20 (from Win10) then you'll get ubuntu18. If you provide ubuntu20's credentials to ubuntu20 from Win10, then it won't work because it's ubuntu18 is the machine's that responding to that request really not ubuntu20. Ubuntu20 is routing every SMB requests to Ubuntu18 doesn't matter if Ubuntu20 is running smb on its own or not. What are you actually trying to pull anyway?
li_jessen avatar
ph flag
I did what you told me to do. There are hits in PREROUTING now but no hits in POSTROUTING yet.
li_jessen avatar
ph flag
I also tried with another Linux machine to try to mount the smb of Ubuntu 18 by typing the ip address of Ubuntu 20, it failed, saying "mount: /mnt/smb: mount(2) system call failed: Operation now in progress". And only hits in PREROUTING but no POSTROUTING.
moisrex avatar
bv flag
What do you want to actually do here? I'm getting confused by your scenario now.
li_jessen avatar
ph flag
I want to foward all packets targeting port 445 of Ubuntu 20 to another machine of Ubuntu 18 running a smb server.
moisrex avatar
bv flag
It's already doing that. Does it work?
li_jessen avatar
ph flag
No. No hits on POSTROUTING. Only on PREROUTING.
moisrex avatar
bv flag
What if you removed the `-d 192.168.10.162` in the POSTROUTING rule and masquerade everything?
Score:0
ph flag

I'm sorry to tell you all that I made a low-level mistake. I forgot to enable IPFORWARD in the Linux machine. After I run

sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

It works.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.