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.
-- Aleksandar Milivojevic <amilivojevic@xxxxxx> Pollard Banknote Limited Systems Administrator 1499 Buffalo Place Tel: (204) 474-2323 ext 276 Winnipeg, MB R3T 1L7