At Negative's instruction, I'm reposting this iptables script / tutorial in the correct forum. Sorry for the duplication.

I wrote a simple little firewall tutorial/script that builds the firewall set as it teaches you about how to write rules. I know it's simple, but it's my first attempt at a tutorial. My own ruleset is much more complex and wouldn't make for good teaching material. Let me know if you have any suggestions or comments. Thanks.
Note: This is my third attempt. Something went wrong with the file transfer the first and second time so I'll just paste in the text...



# A quick guide to iptables by str34m3r

# This firewall ruleset is designed for a simple linux box. This ruleset will
# probably work for most home users with little editing. If you use things like
# IRC or MSN Messenger, then you'll need to add your own rules. I added an AIM
# rule that you can copy for simplicity. This is all about learning, right?

# The first thing you'll want to do is set your default policies with -P.
# Your basic target options are ACCEPT, DROP, LOG, and REJECT. ACCEPT means that
# you are allowing the packet. DROP means that the system will silently drop the
# packet. No response at all will be given to the computer that sent the packet.
# While this isn't standard TCP practice, it is often considered to be good
# security practice because your system becomes indistinguishable from a
# machine that is turned off. The LOG option sends a line of data about the
# packet to your system logs. If you use this as your policy, the system will
# log the packet and then accept it. The REJECT target will send some sort of
# error message to the computer that sent the packet, and then drop the packet.
# The default error message default is an ICMP port unreachable, but the
# response is largely customizable.

iptables -P INPUT DROP # I generally choose the drop policy for packets
iptables -P OUTPUT DROP # that are not explicitly allowed so my system
iptables -P FORWARD DROP # will appear to be off when I get scanned.

# After that, you'll want to make sure that all old rules have been cleared.

iptables -F # Flush all tables
iptables -X # Delete all tables except the defaults

# Now for some good generic rules - I generally allow all traffic through the
# loopback interface. Technically, you're supposed to use the IP 127.0.0.1 for
# loopback traffic, but you'll find that the world is often imperfect.

iptables -A INPUT -j ACCEPT -i lo
iptables -A OUTPUT -j ACCEPT -o lo

# I'll leave an example of how the loopback rules would look in a perfect world.
# Try them out if you're feeling brave, but it occasionally breaks Xwindows.

#iptables -A INPUT -j ACCEPT -i lo -s 127.0.0.1 -d 127.0.0.1
#iptables -A OUTPUT -j ACCEPT -o lo -s 127.0.0.1 -d 127.0.0.1

# Before proceeding, you'll need to set the IF variable to point to the
# external interface that you're using to connect to the internet.

EXT='eth0'
# or EXT='ppp0'

# IPtables claim to fame is that it's a stateful packet filter. There are four
# possible states for a packet: NEW, ESTABLISHED, RELATED, or INVALID.
# Surprisingly enough, NEW refers to the first packet in a new connection.
# ESTABLISHED refers to packets that are part of a conection that is already in
# progress. RELATED refers to packets that are not part of, but are related to
# another connection. This includes ICMP error packets and FTP data connections
# among others. In order to use state, you must use -m state to match the
# packet's state and then --state to specify which state to match. We'll start
# with the most obvious - packets that are in an INVALID state. What are we
# gonna do? Drop em. You also may want to note a policy I try to maintain in my
# firewall rules - when dropping packets, I try to be as vague as possible so
# I drop as many unfriendly packets as possible. Then when I accept packets, I
# try to be as specific as possible so that I don't let in any stray packets.

iptables -A INPUT -j DROP -m state --state INVALID
iptables -A OUTPUT -j DROP -m state --state INVALID

# If you're careful about you're NEW connections, all of your ESTABLISHED
# connections should be fine.

iptables -A INPUT -j ACCEPT -i $EXT -m state --state ESTABLISHED
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state ESTABLISHED

# Now I'll drop everything else ESTABLISHED. Nothing should ever get flagged by
# this rule since we've alread covered the loopback and the external interface.
# If something does get flagged here, then you either have another interface
# (which I may cover in a later guide) or something weird is going on.

iptables -A INPUT -j DROP -m state --state ESTABLISHED
iptables -A OUTPUT -j DROP -m state --state ESTABLISHED

# Related packets are a little bit more tricky. If you just blindly open up all
# related traffic without checking any rules, you could get into trouble. I
# generally take a more cautious route. To make things easier, I split up the
# related traffic by protocol.

# I certainly want any ICMP error messages from any of the computers I'm trying
# to connect to, but I don't necessarily want any error messages going back to
# them. If you're not as picky as I am, you can uncomment the output rules.

iptables -A INPUT -j ACCEPT -i $EXT -m state --state RELATED -p icmp
#iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state RELATED -p icmp

# I haven't run across much in the way of UDP related traffic, so I'll leave it
# commented out for now.

#iptables -A INPUT -j ACCEPT -i $EXT -m state --state RELATED -p udp
#iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state RELATED -p udp

# The main TCP related traffic I've seen is in FTP connections. These come in
# active and passive FTP varieties. First passive, then active. Note that the
# 65535 isn't technically needed, it's just easier to read than 1024: is. Also
# I'm not a big fan of active FTP, so I'll leave it commented out as well.

iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state RELATED -p tcp \
--sport 1024:65535 --dport 1024:65535
#iptables -A INPUT -j ACCEPT -i $EXT -m state --state RELATED -p tcp \
# --sport 20 --dport 1024:65535

# Now I'll drop everything else RELATED since we obviously didn't like it.

iptables -A INPUT -j DROP -m state --state RELATED
iptables -A OUTPUT -j DROP -m state --state RELATED

# Ok, so we've finished INVALID, ESTABLISHED, and RELATED. Everything else
# should be NEW, but as I said before, keep being specific, just in case.

# I don't actually allow any NEW inbound packets, but I thought I'd write some
# examples for them anyway. Here's an example for allowing inbound ping,
# inbound HTTP, and inbound SSH from one subnet. The notation for defining
# subnets is tough at first, but simple once you figure it out. The sample
# below allows all ssh traffic from 10.10.220.* because the /24 at the end
# tells iptables to only pay attention to the first 24 bits (or three octets) of
# the IP address. Another way to write this would be 10.10.220.0/255.255.255.0
# which may be a little more familiar to you.

#iptables -A INPUT -j ACCEPT -i $EXT -m state --state NEW -p icmp \
# --icmp-type ping
#iptables -A INPUT -j ACCEPT -i $EXT -m state --state NEW -p tcp \
# --sport 1024:65535 -dport 80
#iptables -A INPUT -j ACCEPT -i $EXT -m state --state NEW -p tcp \
# --sport 1024:65535 -dport 22 \
# -s 10.10.220.0/24

# Outbound rules can be a touchy subject. Some people like to just allow all
# outbound traffic because it's simpler to manage. As you may have guessed, I
# am not one of those people. I like to be able to control exactly what traffic
# leaves my system, or at least which ports it's allowed to use. For those of you in the former category, here's your (commented) rule.

#iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW

# For those that are little more pciky, here are some sample rules. There are a
# lot of different services out there. I can't write a rule for all of them,
# but I've given you some of the more popular ports and now you can write the
# rest.

iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p icmp \
--icmp-type ping # Ping
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p udp \
--dport 53 # DNS
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p tcp \
--sport 1024:65535 --dport 21 # FTP
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p tcp \
--sport 1024:65535 --dport 22 # SSH
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p tcp \
--sport 1024:65535 --dport 23 # Telnet
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p tcp \
--sport 1024:65535 --dport 25 # SMTP (Mail)
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p tcp \
--sport 1024:65535 --dport 80 # HTTP
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p tcp \
--sport 1024:65535 --dport 110 # Pop3
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p tcp \
--sport 1024:65535 --dport 443 # HTTPS
iptables -A OUTPUT -j ACCEPT -o $EXT -m state --state NEW -p tcp \
--sport 1024:65535 --dport 5190 # AIM

# And finally, drop all other NEW packets. Since the default policy is to drop
# packets anyway, this really isn't needed, but I try to be thorough.

iptables -A INPUT -j DROP -m state --state NEW
iptables -A OUTPUT -j DROP -m state --state NEW