📄 iptables connection tracking.htm
字号:
connection state now becomes ESTABLISHED and the state table entry is marked
ASSURED (ASSURED connections are not dropped from the state table when the
connection is under load). Here we see the ESTABLISHED connection:
<P><FONT color=#000066>tcp 6 431995 ESTABLISHED
src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 src=207.46.230.218
dst=140.208.5.62 sport=80 dport=1311 [ASSURED] use=1</FONT>
<P><U>Connection tracking's perspective on the state table</U>
<P>We just talked a lot about tcp connection states. Now let's think about this
from the perspective of the connection tracking:
<P>Connection tracking only knows about <FONT color=#33cc00>NEW</FONT>, <FONT
color=#33cc00>ESTABLISHED</FONT>, <FONT color=#33cc00>RELATED</FONT> and <FONT
color=#33cc00>INVALID</FONT>, classified as described above and in the iptables
<A
href="http://www.sns.ias.edu/~jns/security/iptables/iptables_manpage.txt">manpage</A>.
To quote Joszef Kadlecsik, who helped me out with a confusion I had initially
about this very subject:
<P><I>When a packet with the SYN+ACK flags set arrrives in response to a packet
with SYN set the connection tracking thinks: "I have been just seeing a packet
with SYN+ACK which answers a SYN I had previously seen, so this is an <FONT
color=#33cc00>ESTABLISHED</FONT> connection."</I>
<P>The important point here is that the conntrack states are<I> not
</I>equivalent to tcp states<I>. </I>We have already seen that a connection
doesn't achieve the tcp connection status of ESTABLISHED until the ACK after the
SYN+ACK has been seen by the connection tracking module.
<P>The representation of the tcp connection states in the state table is purely
for timeouts. You can prove this to yourself by sending an ACK packet through
your firewall to a non-existent machine (so that you don't get the RST back). It
will create a state table entry no problem because it it is the first packet of
a connection and so is treated as <FONT color=#33cc00>NEW</FONT> (the entry will
not be marked as ASSURED though). <FONT color=#000000>Checkpoint's
Firewall-1 version 4.1 SP1 allows connection initiation by ACK packets too (see
Lance Spitzner's <A href="http://www.spitzner.net/fwtable.html">whitepaper</A>
for details).</FONT>
<P>In the light of the fact that ACK packets can create state table entries, the
following contribution from Henrik Nordstrum is insightful: To make sure that
<FONT color=#33cc00>NEW</FONT> tcp connections are packets with SYN set, use the
following rule:
<P><FONT color=#cc0000>iptables -A </FONT><FONT color=#3333ff>INPUT</FONT><FONT
color=#cc0000> -p tcp ! --syn -m state --state </FONT><FONT
color=#33cc00>NEW</FONT><FONT color=#cc0000> -j DROP</FONT>
<P><FONT color=#000000>Note that doing this will prevent idle sessions from
continuing once they have expired from the conntrack table. In the normal
"relaxed" view such connections initiated from the correct direction (i.e. the
direction you allow NEW packets through) can normally continue even if expired
from conntrack, provided that the first data/ack packet that resumes the
connection comes from the correct direction.</FONT>
<P>If you want real stateful filtering that requires correct connection
initiation and tracks sequence numbers, apply the <A
href="http://www.netfilter.org/documentation/pomlist/pom-extra.html#tcp-window-tracking">tcp-window-tracking</A>
patch from <A
href="http://www.netfilter.org/documentation/pomlist/pom-summary.html">patch-o-matic</A>.
<P><U>Timeouts</U>
<P><FONT color=#000000>Something to note is that timeouts are reset to the
maximum each time a connection sees traffic. Timeouts are set in
<I>/usr/src/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c</I> at compile
time. </FONT>Here is the relevant section of code:
<P><I><FONT color=#000000>static unsigned long tcp_timeouts[]</FONT></I>
<BR><I><FONT color=#000000>= { 30 MINS,
/* TCP_CONNTRACK_NONE,
*/</FONT></I> <BR><I><FONT color=#000000> 5
DAYS, /*
TCP_CONNTRACK_ESTABLISHED, */</FONT></I>
<BR><I><FONT color=#000000> 2 MINS,
/* TCP_CONNTRACK_SYN_SENT, */</FONT></I>
<BR><I><FONT color=#000000> 60 SECS,
/* TCP_CONNTRACK_SYN_RECV, */</FONT></I>
<BR><I><FONT color=#000000> 2 MINS,
/* TCP_CONNTRACK_FIN_WAIT, */</FONT></I>
<BR><I><FONT color=#000000> 2 MINS,
/*
TCP_CONNTRACK_TIME_WAIT, */</FONT></I>
<BR><I><FONT color=#000000> 10 SECS,
/* TCP_CONNTRACK_CLOSE,
*/</FONT></I> <BR><I><FONT color=#000000> 60
SECS, /*
TCP_CONNTRACK_CLOSE_WAIT, */</FONT></I>
<BR><I><FONT color=#000000> 30 SECS,
/* TCP_CONNTRACK_LAST_ACK, */</FONT></I>
<BR><I><FONT color=#000000> 2 MINS,
/* TCP_CONNTRACK_LISTEN, */</FONT></I>
<BR><I><FONT color=#000000>};</FONT></I>
<P>There is no absolute timeout for a connection.
<P><U>Connection termination</U>
<P>Connection termination occurs in two ways. Natural termination at the end of
a session occurs when the client sends a packet with the FIN and ACK flags set.
The closure proceeds as follows:
<P>
<U>Client</U>
<U>Server</U>
<BR>
.........
<BR>
......... <BR> FIN+ACK --->
<BR>
<--- ACK
<BR>
<--- FIN+ACK
<BR>
ACK --->
<P>Sometime during, or at the end of this sequence the state table connection
status changes to TIME_WAIT and the entry is removed after 2 minutes by default.
<P>Another way for connection termination to occur is if either party sends a
packet with the RST (reset) flag set. RST's are not acknowledged. In this case
the state table connection status changes to CLOSE and times out from the state
table after 10 seconds. This often happens with http entries, where the server
sends an RST after a period of inactivity. <BR>
<P><A name=ICMP></A><B>ICMP</B>
<P>In iptables parlance, there are only four types of icmp that can be
categorized as <FONT color=#33cc00>NEW</FONT>, or <FONT
color=#33cc00>ESTABLISHED</FONT>:
<P>1) Echo request (ping, 8) and echo reply (pong, 0). <BR>2) Timestamp request
(13)and reply (14). <BR>3) Information request (15) and reply (16). <BR>4)
Address mask request (17) and reply (18).
<P>The request in each case is classified as <FONT color=#33cc00>NEW</FONT> and
the reply as <FONT color=#33cc00>ESTABLISHED</FONT>. <BR>Other types of icmp are
not request-reply based and can only be <FONT color=#33cc00>RELATED</FONT> to
other connections.
<P>Let us consider a sample ruleset and a few examples:
<P><FONT color=#cc0000>iptables -A </FONT><FONT color=#3333ff>OUTPUT</FONT><FONT
color=#cc0000> -p icmp -m state --state </FONT><FONT
color=#33cc00>NEW,ESTABLISHED,RELATED</FONT><FONT color=#cc0000> -j
ACCEPT</FONT> <BR><FONT color=#cc0000>iptables -A </FONT><FONT
color=#3333ff>INPUT</FONT><FONT color=#cc0000> -p icmp
-m state --state </FONT><FONT color=#33cc00>ESTABLISHED,RELATED</FONT><FONT
color=#cc0000> -j ACCEPT</FONT>
<P>1) An icmp echo request is <FONT color=#33cc00>NEW</FONT> and so is allowed
in the OUTPUT chain.
<P>2) An icmp echo reply, provided it is in response to an echo request, is
<FONT color=#33cc00>ESTABLISHED</FONT> and so is allowed in the INPUT chain. An
echo reply cannot be allowed in the OUTPUT chain for the rules above because
there is no <FONT color=#33cc00>NEW</FONT> in the INPUT chain to allow echo
requests and a reply has to be in response to a request.
<P>3) An icmp redirect, because it is not request-reply based, is <FONT
color=#33cc00>RELATED</FONT> and so can be allowed in both the INPUT and the
OUTPUT chains provided there is already a tcp or udp connection in the state
table already that it can be matched against. <BR>
<P><A name=FTP></A><B><U><FONT size=+1>Connection tracking and
ftp</FONT></U></B>
<P><FONT color=#000000>Firstly, you need to load the ip_conntrack_ftp
module.</FONT>
<P><FONT color=#000000>Assuming you have a single-homed box, a simple ruleset to
allow an ftp connection would be:</FONT>
<P><FONT color=#cc0000>iptables -A </FONT><FONT color=#3333ff>INPUT</FONT><FONT
color=#cc0000> -p tcp --sport 21 -m state --state
</FONT><FONT color=#33cc00>ESTABLISHED</FONT><FONT color=#cc0000> -j
ACCEPT</FONT> <BR><FONT color=#cc0000>iptables -A </FONT><FONT
color=#3333ff>OUTPUT</FONT><FONT color=#cc0000> -p tcp --dport 21 -m state
--state </FONT><FONT color=#33cc00>NEW,ESTABLISHED</FONT><FONT color=#cc0000> -j
ACCEPT</FONT>
<P><FONT color=#000000>(Please note, I am assuming here you have a separate
ruleset to allow any icmp </FONT><FONT color=#33cc00>RELATED</FONT><FONT
color=#000000> to the conection. Please see my <A
href="http://www.sns.ias.edu/~jns/security/iptables/index.html#CONFIG">example
ruleset</A> for this).</FONT>
<P><FONT color=#000000>This is not the whole story. An ftp connection also needs
a data-channel, which can be provided in one of two ways:</FONT>
<P><B><FONT color=#000000>1) Active ftp</FONT></B>
<P><FONT color=#000000>The ftp client sends a port number over the ftp channel
via a PORT command to the ftp server. The ftp server then connects from port 20
to this port to send data, such as a file, or the output from an ls command. The
ftp-data connection is in the <I>opposite sense</I> from the original ftp
connection.</FONT>
<P><FONT color=#000000>To allow active ftp without knowing the port number that
has been passed we need a general rule which allows connections from port 20 on
remote ftp servers to high ports (port numbers > 1023) on ftp clients. This
is simply too general to ever be secure.</FONT>
<P><FONT color=#000000>Enter the <I>ip_conntrack_ftp</I> module. This module is
able to recognize the PORT command and pick-out the port number. As such, the
ftp-data connection can be classified as </FONT><FONT
color=#33cc00>RELATED</FONT><FONT color=#000000> to the original outgoing
connection to port 21 so we don't need </FONT><FONT
color=#33cc00>NEW</FONT><FONT color=#000000> as a state match for the connection
in the INPUT chain. The following rules will serve our purposes grandly:</FONT>
<P><FONT color=#cc0000>iptables -A </FONT><FONT color=#3333ff>INPUT</FONT><FONT
color=#cc0000> -p tcp --sport 20 -m state --state
</FONT><FONT color=#33cc00>ESTABLISHED,RELATED</FONT><FONT color=#cc0000> -j
ACCEPT</FONT> <BR><FONT color=#cc0000>iptables -A </FONT><FONT
color=#3333ff>OUTPUT</FONT><FONT color=#cc0000> -p tcp --dport 20 -m state
--state </FONT><FONT color=#33cc00>ESTABLISHED</FONT><FONT color=#cc0000> -j
ACCEPT</FONT>
<P><B><FONT color=#000000>2) Passive ftp</FONT></B>
<P><FONT color=#000000>A PORT command is again issued, but this time it is from
the server to the client. The client connects to the server for data transfer.
Since the connection is in the <I>same sense</I> as the original ftp
connection, passive ftp is inherently more secure than active ftp, but
note that this time we know even less about the port numbers. Now we have a
connection between almost arbitrary port numbers.</FONT>
<P><FONT color=#000000>Enter the <I>ip_conntrack_ftp</I> module once more.
Again, this module is able to recognize the PORT command and pick-out the port
number. Instead of </FONT><FONT color=#33cc00>NEW</FONT><FONT color=#000000> in
the state match for the OUTPUT chain, we can use </FONT><FONT
color=#33cc00>RELATED</FONT><FONT color=#000000>. The following rules will
suffice:</FONT>
<P><FONT color=#cc0000>iptables -A </FONT><FONT color=#3333ff>INPUT</FONT><FONT
color=#cc0000> -p tcp --sport 1024: --dport 1024:
-m state --state </FONT><FONT color=#33cc00>ESTABLISHED</FONT><FONT
color=#cc0000> -j ACCEPT</FONT> <BR><FONT color=#cc0000>iptables -A </FONT><FONT
color=#3333ff>OUTPUT</FONT><FONT color=#cc0000> -p tcp --sport 1024: --dport
1024: -m state --state </FONT><FONT
color=#33cc00>ESTABLISHED,RELATED</FONT><FONT color=#cc0000> -j ACCEPT</FONT>
<BR> <BR> <BR>
<CENTER>
<P><IMG height=10 src="IPtables Connection tracking.files/blue_marble.gif"
width=556 align=center></CENTER>
<P><I>Prepared by James C. Stephens</I> <BR><I>(jns@ias.edu)</I> <BR><I>Last
updated: Wed Oct 2nd 2002</I> </P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -