/sbin/iptables -N HTTP /sbin/iptables -N HTTP-FINAL /sbin/iptables -N HTTP-FINAL-1 /sbin/iptables -N HTTP-FINAL-2 /sbin/iptables -A INPUT -p tcp --dport 80 -j HTTP /sbin/iptables -A HTTP-FINAL -p tcp -m recent --name HTTP-LIST -j HTTP-FINAL-1 /sbin/iptables -A HTTP-FINAL -p tcp -m recent --name HTTP-FINAL -j HTTP-FINAL-2 /sbin/iptables -A HTTP-FINAL-1 -p tcp --tcp-flags SYN,ACK,FIN FIN,ACK -m recent --name HTTP-LIST --close -j ACCEPT /sbin/iptables -A HTTP-FINAL-1 -p tcp --tcp-flags SYN,ACK,FIN FIN,ACK -m recent --name HTTP-FINAL --set -j ACCEPT /sbin/iptables -A HTTP-FINAL-2 -p tcp --tcp-flags SYN,ACK NONE -m recent --name HTTP-FINAL --update -j ACCEPT /sbin/iptables -A HTTP-FINAL-2 -p tcp --tcp-flags SYN,ACK ACK -m recent --name HTTP-FINAL --update -j ACCEPT /sbin/iptables -A HTTP-FINAL-2 -p tcp --tcp-flags SYN,ACK,FIN FIN -m recent --name HTTP-FINAL --update -j ACCEPT /sbin/iptables -A HTTP-FINAL-2 -p tcp --tcp-flags SYN,ACK,FIN FIN,ACK -m recent --name HTTP-FINAL --close -j ACCEPT /sbin/iptables -A HTTP -p tcp --tcp-flags SYN,ACK,FIN,RST SYN -m recent --name HTTP-LIST --set -j ACCEPT /sbin/iptables -A HTTP -p tcp --tcp-flags SYN,ACK,FIN,RST SYN,ACK -m recent --name HTTP-LIST --update -j ACCEPT /sbin/iptables -A HTTP -p tcp --tcp-flags SYN,ACK,FIN ACK -m recent --name HTTP-LIST --update -j ACCEPT /sbin/iptables -A HTTP -p tcp --tcp-flags SYN,ACK NONE -m recent --name HTTP-LIST --update -j ACCEPT /sbin/iptables -A HTTP -p tcp --tcp-flags SYN,ACK ACK -m recent --name HTTP-LIST --update -j ACCEPT /sbin/iptables -A HTTP -p tcp --tcp-flags SYN,FIN,ACK FIN -m recent --name HTTP-LIST --update -j ACCEPT /sbin/iptables -A HTTP -p tcp --tcp-flags SYN,FIN,ACK FIN,ACK -m recent --name HTTP-LIST -j HTTP-FINAL /sbin/iptables -A HTTP -p tcp --tcp-flags SYN,FIN,ACK,RST RST -m recent --name HTTP-LIST --remove -j ACCEPT # Note: The first packet should be a SYN packet, and should not have the ACK,FIN # or RST bits set. Hence it is matched using the --tcp-flags SYN,ACK,FIN,RST # SYN line. At this point we add the connection to the HTTP-LIST using -m # recent --name HTTP-LIST --set line. Finally we accept the packet. # After the first packet we should receive a SYN/ACK packet to acknowledge # that the SYN packet was received. This can be matched using the # --tcp-flags SYN,ACK,FIN,RST SYN,ACK line. FIN and RST should be illegal at # this point as well. At this point we update the entry in the HTTP-LIST # using -m recent --name HTTP-LIST --update and finally we ACCEPT the # packet. # By now we should get a final ACK packet, from the original creater of the # connection, to acknowledge the SYN/ACK sent by the server. SYN, FIN and # RST are illegal at this point of the connection, so the line should look # like --tcp-flags SYN,ACK,FIN,RST ACK. We update the list in exactly the # same way as in the previous step, and ACCEPT it. # At this point the data tranmission can start. The connection should never # contain any SYN packet now, but it will contain ACK packets to acknowledge # the data packets that are sent. Each time we see any packet like this, we # update the list and ACCEPT the packets. # The transmission can be ended in two ways, the simplest is the RST packet. # RST will simply reset the connection and it will die. With FIN, the other # endpoint answers with a FIN,ACK, and this closes down the connection so # that the original source of the FIN can no longer send any data. The # receiver of the FIN, will still be able to send data, hence we send the # connection to a "final" stage chain to handle the rest. # In the HTTP-FINAL chain we check if the packet is still in the # HTTP-LIST, and if so, we send it to the HTTP-FINAL-1 chain. In that # chain we remove the connection from the HTTP-LIST and add it to the # HTTP-FINAL list instead. If the connection has already been removed # and moved over to the HTTP-FINAL list, we send te packet to the # HTTP-FINAL-2 chain.