On Tue, 2004-08-24 at 18:10, Aleksandar Milivojevic wrote: > Vincent Blondel wrote: > > Hi all, > > > > I a trying to initiate ftp connections to some of my servers but it > > doesn't work. You can find below a schema representing my three > > machines, client, firewall and ftp server. There is no NAT at the moment > > and the script I use on my firewall. > > OK, let's go through it line by line... > > > # Set the default policy to drop > > $fw --policy INPUT DROP > > $fw --policy OUTPUT DROP > > $fw --policy FORWARD DROP > > These are OK, and recommended setting for firewall. > > > $nat --policy PREROUTING DROP > > $nat --policy OUTPUT DROP > > $nat --policy POSTROUTING DROP > > > > $mangle --policy PREROUTING DROP > > $mangle --policy OUTPUT DROP > > With the above policies, you were dropping packets in PREROUTING chain > before they ever had a chance to reach INPUT or FORWARD chains (same > thing for POSTROUTING, packets are going there after (and if) they pass > FORWARD or OUTPUT chains). Also, make a note that packets will go > through only one of INPUT (just before packet is delivered to local > process), OUTPUT (as soon as packet is generated by local process), or > FORWARD chains (packets that are not generated or to be delivered > locally). They will never go through two or all three of them. > > Filter table is intended for general packet filtering, so that is the > only table where (generally) you would set default policy to DROP. (as > a sidenote, you could use nat table for filtering if you don't care if > origin and/or destination of packet is remote or local, but that isn't > something you would generally do). > > Nat table is intended for implementig NATed networks, and mangle is for > general purpuse packet mangling (strange things you might want to do to > packets). They are not intended for packet filtering (although you can > do it there too). So you would leave those two with ACCEPT policy, and > not implement any DROP rules there either. > > There's a logic behind why all chains do not exist in all tables, and > why you can't use all targets in all tables. And basically the logic is > based on for what the table was intended to be used. > > > if [ "$CONN_TRACK" = "1" ]; then > > $fw -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT > > $fw -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT > > $fw -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT > > fi > > I'd probably be more restrictive here, and allow only ESTABLISHED. Than > I would add separate generic rules for related ICMP packets (and you > really want to add those if you remove RELATED from above lines), and > then I would have rules for incoming related connections with helper > module match for each one of them. The ICMP thing would be something > like (for INPUT, add similar for OUTPUT and FORWARD): > > $fw -A INPUT -p icmp -m state --state RELATED -j ACCEPT > > > # Incoming FTP requests > > iptables -A FORWARD -i eth0 -o eth1 -p tcp -s 192.168.124.1 --sport > > $UNPRIVPORTS -d 192.168.125.1 --dport 21 -m state --state NEW -j ACCEPT > > This is OK. > > > # Port Mode Data Channel Responses > > iptables -A FORWARD -i eth1 -o eth0 -p tcp -d 192.168.124.1 --sport 20 > > --dport $UNPRIVPORTS -m state --state NEW -j ACCEPT > > This is wrong. The first packet of this connection will be in RELATED > state, and the rest will be in ESTABLISHED state (if you load ftp helper > module, as you should). However, your generic rules for > ESTABLISHED,RELATED will catch and accept this connection regardless of > this line (read below why they are not working). If you go with my > advice of removing generic RELATED rule, than you would write it > something like this (you'd need two lines): > > # This will handle active FTP data transfers > iptables -A FORWARD -i eth1 -o eth0 \ > -p tcp -s 192.168.125.1 -d 192.168.124.1 \ > --sport 20 --dport $UNPRIVPORTS \ > -m helper --helper ftp \ > -m state --state RELATED -j ACCEPT > > # This will handle passive FTP data transfers > iptables -A FORWARD -i eth0 -o eth1 > -p tcp -s 192.168.124.1 -d 192.168.125.1 \ > --sport $UNPRIVPORTS --dport $UNPRIVPORTS \ > -m helper --helper ftp \ > -m state --state RELATED -j ACCEPT > > If you are going to have your generic RELATED,ESTABLISHED match, than > you don't need any of those rules (you only need rule for allowing > connection to FTP port 21). Also, you can ommit specifying helper > module, it's just that this way you are matching which helper marked the > packet as related (security is paranoid by its nature ;-). > > Also, for the related match, you will need to load FTP helper module (it > doesn't get loaded automatically). Without it, it isn't going to work. > The one you need is ip_conntrack_ftp. You might also load ip_nat_ftp > (which will in turn load ip_conntrack_ftp automatically, since it > depends on it). Add a line like this to your firewall script (anywhere > in the script): > > modprobe ip_nat_ftp > > You can even type it manually on command line (before or after you load > the rules, doesn't matter). > > After that, when you do lsmod | grep '^ip' you should see ip_nat_ftp and > ip_conntrack_ftp loaded. Thanks a lot for all the details but I still get some problems. As I said it all the netfilter source code is compiled in a custom kernel without any modules. Concerning the little iptables script I have written, I updated it with your comments and now I get the next script #!/bin/sh # fw="/sbin/iptables" nat="$fw -t nat" mangle="$fw -t mangle" CONN_TRACK="1" # Connection Tracking UNPRIVPORTS="1024:65535" # unprivileged port range # Remove any existing rules from all chains $fw --flush $nat --flush $mangle --flush # Unlimited traffic on the loopback interface $fw -A INPUT -i lo -j ACCEPT $fw -A OUTPUT -o lo -j ACCEPT # Set the default policy to drop $fw --policy INPUT DROP $fw --policy OUTPUT DROP $fw --policy FORWARD DROP $nat --policy PREROUTING ACCEPT $nat --policy OUTPUT ACCEPT $nat --policy POSTROUTING ACCEPT $mangle --policy PREROUTING ACCEPT $mangle --policy OUTPUT ACCEPT # Remove any pre-existing user-defined chains $fw --delete-chain $nat --delete-chain $mangle --delete-chain if [ "$CONN_TRACK" = "1" ]; then $fw -A INPUT -m state --state ESTABLISHED -j ACCEPT $fw -A OUTPUT -m state --state ESTABLISHE -j ACCEPT $fw -A FORWARD -m state --state ESTABLISHED -j ACCEPT $fw -A INPUT -p icmp -m state --state RELATED -j ACCEPT fi # Incoming FTP requests iptables -A FORWARD -i eth0 -o eth1 -p tcp -s 192.168.124.1 --sport $UNPRIVPORTS -d 192.168.125.1 --dport 21 -m state --state NEW -j ACCEPT # This will handle active FTP data transfers iptables -A FORWARD -i eth1 -o eth0 \ -p tcp -s 192.168.125.1 -d 192.168.124.1 \ --sport 20 --dport $UNPRIVPORTS \ -m helper --helper ftp \ -m state --state RELATED -j ACCEPT # This will handle passive FTP data transfers iptables -A FORWARD -i eth0 -o eth1 -p tcp -s 192.168.124.1 -d 192.168.125.1 \ --sport $UNPRIVPORTS --dport $UNPRIVPORTS \ -m helper --helper ftp \ -m state --state RELATED -j ACCEPT ... but the connection takes a long time to terminate. If I disable all the rules, ftp connection goes directly but with iptables enabled it takes such 8 seconds to accomplish the annonymomus connection ( with data port and passive models ). What is this all about ??? Regards Vincent