iptables and vsftpd on firewall box - can't connect
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.
iptables and vsftpd on firewall box - can't connect
Hi Gurus!
I've been running iptables on my Linux firewall for several years and have a good basic understanding of its implementation and IP networks in general, however recently I decided to run an ftp server on my firewall to accomodate various anonymous downloads and I am struggling with getting a login prompt when connecting from the Internet. I have narrowed this problem down to a firewall issue, b/c if I unload iptables, I can connect just fine to my vsftpd server on the f/w from both internal and external interfaces. This validates my vsftpd configuration accordingly.
I can also ssh to this f/w box from the Internet just fine.
My config is as follows:
eth0 - internal interface
eth1 - external interface ( ... to DSL 300i using DHCP on external i/f )
Filter Table:
#
# Allow FTP to this firewall from internal addresses only
#
-A INPUT -p tcp -m tcp -i eth0 -s 192.168.1.0/24 --sport 1024: --dport 20:21 -j ACCEPT
-A OUTPUT -p tcp -m tcp -o eth0 --sport 20:21 -d 192.168.1.0/24 --dport 1024: -j ACCEPT
# Allow FTP to firewall from Internet
-A INPUT -p tcp -m tcp -i eth1 --sport 1024: --dport 20:21 -j ACCEPT
-A OUTPUT -p tcp -m tcp -o eth1 --sport 20:21 --dport 1024: -j ACCEPT
-A FORWARD -i eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
I suspect it has something to do with the state configuration for INPUT and OUTPUT rules on the firewall box. So I did try:
Filter table:
-A OUTPUT -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
But I suspect its something to do with the NAT table ... ???
Essentially, the Internet ftp client attempts to connect and times out:
So, from the trace, you can see the SYN-ACK being logged yet the Internet client never sees the SYN-ACK so it never responds with an ACK back to the firewall to complete the 3-way handshaking.
Now, for the record, this client internet node is my desktop PC within my employers network and it supports internally initiated active and passive FTP sessions. I have also tried it from a box that's sitting on the outside of the firewall altogether and it doesn't see the SYN-ACK as well.
Linux kernel being used is: 2.4.20-8
iptables-1.2.7a-2
Any ideas? Please help! :-)
Also, when loading the ip_conntrack_ftp and ip_nat_ftp modules, do I need to have an explicit rule to account for active sessions using an arbitrarily high port? Or will one of these modules handle that. I thought I read something somewhere that indicated these modules would handle it and its a better approach than putting an explicit rule to allow highport TCP track to/from the box. Please confirm.
Connecting to FTP is quite a complicated matter. Have a look here http://slacksite.com/other/ftp.html. In fact, as you probably know, not only 20 and 21 ports are involved by also other random ports aswell on server or client side depending on type of connection (passive, active).
You need module connection tracking to be on.
# modprobe ip_conntrack_ftp
First open port 21, it is used for active and passive
iptables -A INPUT -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
Certainly you simply dont want ports >1024 open on server, unless they are related to to previous connection on port 21 so you have to use state RELATED. According to man, RELATED means that the packet is starting a new connection, but is associated with an existing connection. This lines are for active
iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT
these for passive:
iptables -A INPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT
Notice that both server and client operate on ports >1024.
I am totally stumped on this. I can't even get a login prompt. tcpdump on the fw indicates the reception of the SYN pkt from the client ftp station, and the subsequent SYN-ACK yet the client never sees it! How can this be??? If tcpdumps the SYN-ACK on the outside interface, doesn't than unambiguously indicate the packet has passed through the kernel/netfilter/iptables framework?
What's completely bizarre is that if i open my firewall up completely with the following rules right at the beginning of the filter table:
eth0 - internal i/f
eth1 - external i/f
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp -m tcp -i eth0 -j ACCEPT
-A OUTPUT -p tcp -m tcp -o eth0 -j ACCEPT
-A INPUT -p udp -m udp -i eth0 -j ACCEPT
-A OUTPUT -p udp -m udp -o eth0 -j ACCEPT
-A INPUT -p tcp -m tcp -i eth1 -j ACCEPT
-A OUTPUT -p tcp -m tcp -o eth1 -j ACCEPT
-A INPUT -p udp -m udp -i eth1 -j ACCEPT
-A OUTPUT -p udp -m udp -o eth1 -j ACCEPT
This is as wide open as it can get ...
I don't see the SYN-ACK response on the client station and as a result, I can't even get a login prompt all.
Can anyone explain what's going on here?
I am at a total loss here as I should at the very least see a successfull TCP handshake here. Is there some obscure kernel parameter that makes even attempting to connect to an ftp service fail to complete the 3-way connection handshake??? With the rules above, I can easily get a telnet prompt and obviously 3-way handshaking on port 23 succeed. What's going on here? It can't be tcp_wrappers nor PAM at this level.
I've also tried running vsftpd standalone on this f/w box and I get the same behavior.
The ip_conntrack_ftp ip_ nat_ip etc should not prevent the 3-way TCP connection handshaking on port 21 and to prevent the login prompt correct???
Please help ... I've invested so much time into something that should be somewhat trivial!
If i change /etc/services ftp to use port 29 instead of 21 and use the following rules I can login !!!
eth1 - external
eth0 - internal
-A INPUT -i eth1 -p tcp --dport 29 -j ACCEPT
-A OUTPUT -o eth1 -p tcp --sport 29 -j ACCEPT
-A INPUT -i eth1 -p tcp --dport 20 -j ACCEPT
-A OUTPUT -o eth1 -p tcp --sport 20 -j ACCEPT
-A INPUT -i eth1 -p tcp --dport 29 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -o eth1 -p tcp --sport 29 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -i eth1 -p tcp --dport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -o eth1 -p tcp --sport 20 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -i eth1 -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -o eth1 -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT
and use windoze ftp cmd using open <host> 29
If I change back to port 21 in services as well as the rules above, I return to the same symptoms as before ... no login prompt
Why???? This is completely bizzare. hardcoded constant in one of the netfilter modules????
I can't ls / dir and now .. but its a step in the right direction. In vsftpd, i've got "connect_from_port_20=YES" so I would have thought I would have seen an outbound SYN packet requesting a connection to my ftp client using src port 20 when doing an ls / dir.
I'm no guru, but I'm gonna offer up and observation or two:
Quote:
-A OUTPUT -o eth1 -p tcp --sport 29 -m state --state NEW,ESTABLISHED -j ACCEPT
You're locking down the source ports at the firewall, but you really don't know that the output traffic is originating from a specific port. For FTP, if you are in active mode, I believe that the server responds on specific ports (21 and 20) but if you are in passive mode, you don' know what ports besides 21 are being used.
Rather than lock down the output, for now I would just use a general OUTPUT statement:
iptables -A OUTPUT -o eth1 -p tcp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
The other observation is that I don't see where you have allowed/disallowed passive mode from the server. If passive mode is used, you need to lock down a port range for passive mode to use in your vsftpd.conf file and then open up that range in your firewall as well. In passive mode I believe that the incoming connection to ports are NEW, so you may have to abandon state matching for the passive port range.
Now the one bit I can't help with is how your box is routing the FTP traffic. I don't use linux as a router so I'm out of my depth, but you do need to be sure that the FTP traffic is getting directed to the right place. So that would include port 21 and and passive port range.
Hi. I'm far from an expert on iptables, but I have found a possible fix for this problem as it is the same problem I was having on my web server. I had the following line way down in the bottom of my iptables rules:
-A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j DROP
If I comment it out, I can connect to the server. I found it just looking through the rules trying to make sense of everything. It was the only thing I saw dropping packets that aren't tied to a specific port. From the discussion above I got the impression that ACK is possibly a packet type that is important to the FTP session. The rule looks like it drops ACK packets irrespective of what port they arrive on. Perhaps you have something similar elsewhere in your rules which is dropping packets that you need.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.