ftp connection and --state RELATED

Brian Wainscott brian@lstc.com
Mon, 01 Nov 1999 15:01:57 -0800

This is a multi-part message in MIME format.
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I'm trying to set up a firewall/masquerade setup, and can't get part of
the ftp service to work.

My setup:

RedHat 6.1
Kernel 2.3.24
netfilter 0.1.11
(a simple script that I think should work but doesn't is attached)

internet -- network 1  -- LINUX FIREWALL -- network 2

I want to be able to get from network 1 to network 2, but not back.  But
network 2 should be able to get to the internet.

Eventually, I want to set up:

network 2 masqueraded to the internet using ipnatctl (this works fine).
nameserver on network 1 can be reached from network 2 via masquerade
[network 2 will eventually have its own nameserver]

network 1 cannot be reached from network 2 (using iptables -- works)
network 2 CAN be reached from network 1 -- here's the rub!

I can telnet from network 1 to network 2 just fine, but ftp hangs.

I expected that adding a iptables rule like this:

iptables -A FORWARD -m state --state RELATED -j ACCEPT

should do it -- afterall, the data FTP connection is related to the ftp
session -- isn't this what the ip_conntrack_ftp module is for?  But the
above rule doesn't seem to match ANYTHING!

I've created as simple a setup as I can that demonstrates my problem,
and attached it below.

Things I've tried:

I have a "WATCH" chain that logs ALL packets, without limits.

With the rule:

iptables -A FORWARD -j WATCH

I can ftp the direction I want (with a lot of print outs)

If I insert this rule before the above one:

iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT

then I can ftp, with only three print outs (1 to the name server)

but if I have these two rules:

iptables -A FORWARD -m state --state RELATED -j WATCH
iptables -A FORWARD -j ACCEPT

I can ftp but get NO print outs!
I need to match the RELATED statement since in my real application the
rules following it would deny tcp traffic back to network 1 from network

Suggestions please!

Brian Wainscott |  Read the BIBLE:
brian@lstc.com  |  Basic Instructions Before Leaving Earth
Content-Type: text/plain; charset=us-ascii; name="masqt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="masqt"

# First insert the required modules
echo Loading iptables module
/sbin/modprobe iptables
/sbin/modprobe ipt_state
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe netfilter_dev
echo Flush Standard Tables
$iptables --flush INPUT
$iptables --flush OUTPUT
$iptables --flush FORWARD
echo Deny everything until firewall setup is complete
$iptables --policy INPUT	DROP
$iptables --policy OUTPUT	DROP
$iptables --policy FORWARD	DROP
# Flush and delete any and all other chains
CHAINS=`/usr/local/bin/iptables -n -L | perl -n -e '/Chain\s+(\S+)/ && !($1 =~ /^(INPUT|FORWARD|OUTPUT)$/) && print "$1 "'`
echo Remove remaining chains:
echo $CHAINS
for chain in $CHAINS; do
  $iptables --flush $chain
# 2nd step in case of dependencies
for chain in $CHAINS; do
  $iptables --delete-chain $chain
echo Loading ip_defrag module
/sbin/modprobe ip_defrag
echo Turn off rp_filter for all interfaces
echo 1 > /proc/sys/net/ipv4/ip_forward
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
  echo 1 > $f

# Simple chain for watching packets
$iptables --new WATCH 2>/dev/null
$iptables -A WATCH -j LOG --log-level warn --log-prefix "ACCEPT "
# Here's the stuff...
# Accept all ESTABLISHED and RELATED packets without logging
$iptables -A FORWARD --match state --state RELATED -j WATCH
# Allow other packets, but log them all, so I can see which ones don't
# match the above
# $iptables -A FORWARD -s -d -j WATCH
# $iptables -A FORWARD -d -s -j WATCH
$iptables -A FORWARD -j	ACCEPT

# $iptables -A FORWARD -i $CLASSROOM_DEV -d $LSTC_IP --proto tcp --syn -j LDROP

$iptables --policy INPUT	ACCEPT
$iptables --policy OUTPUT	ACCEPT
$iptables --policy FORWARD	ACCEPT

/sbin/modprobe ip_nat
# /sbin/modprobe ip_nat_ftp

$ipnatctl -D -s $CLASSROOM_IP -b source -d -m masquerade 2> /dev/null
$ipnatctl -I -s $CLASSROOM_IP -b source -d -m masquerade