If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Iptables Script / Tutorial

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.

# 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.

# 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.

# 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.

# 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.

# 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.

# 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.

# 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.

Well Str34m3r,
I guess your tutorial must work! Here's a quote from the Sygate on line security scan.
////We have determined that you have a firewall blocking UDP ports!
\\\\We are unable to scan any more UDP ports on IP: xx.xxx.xx.xxx . . .

You have blocked all of our probes! We still recommend running this test both with
and without Sygate Personal Firewall enabled... so turn it off and try the test again.

Thanks preacherman, I'm glad you liked it. I've been slowly working on my next installment, which sets up a firewall for a dual (triple?) homed box that acts primarily as a firewall/router with the rest of their boxes behind it. It's taking a while though because I'm trying to be meticulous about it.

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.

This is actually false. Depending on your version of iptables, it will reply with icmp destination-port-unreachable. If you get this kind of reply, you know the box is up and running and there.
Granted, most people wouldn't know how to obtain that info, but there is a very subtle difference between icmp destination-port-unreachable and icmp destination-host-unreachable.

Your system can still be determined to be up during this scan, and this is a rather fruitless effort if your system has even one open port. Not to mention that this can cause problems with various services (Ident, etc). It's much better to set the policy to drop, but to append a final statement on your rules that reads:

iptables -A INPUT -j REJECT

All in all a good tutorial. I'd like to see what you have to say about NAT and etc, as I was thinking of writing a tutorial on that myself, as the only tutorials I'd found on NAT were inexact at best.

Chris Shepherd
The Nelson-Shepherd cutoff: The point at which you realise someone is an idiot while trying to help them.
\"Well as far as the spelling, I speak fluently both your native languages. Do you even can try spell mine ?\" -- Failed Insult
Is your whole family retarded, or did they just catch it from you?

After reading your post, I went back through some of my machines' traffic to look for any of the ICMP replies you're referring to. Since I'm paranoid by nature, I keep tcpdump running on all of my firewall's interfaces 24-7 so I had plenty of traffic to go through, but I still can't find a single ICMP unreachable reply (of any kind) from my machine. So it would appear that the drop target does exactly what it's supposed to do: drop the packet. If you read the man page for iptables, you'll note the following section:

ACCEPT means to let the packet through. DROP means to drop the packet on the floor. QUEUE means to pass the packet to userspace ... blah, blah, blah ...

Now I'm not saying that you're entirely incorrect. There may be some old (interpret that as broken) versions of iptables that do not drop packets correctly. But any up-to-date system with patches applied should drop the packets as expected, thus appearing to be off. The REJECT target gives the attacker a reply, and in certain situations, gives him/her a different response than he/she would have recieved from a port that was simply closed, so I've never been fond of it. I would prefer the attacker think my machine is off and move on to his/her next victim.

That being said... your statement about an attacker being able to determine that the machine is up if one port is open is of course correct. But if you have some services that you're offering to the world, then of course you're not really trying to make your machine look like it's off, so it doesn't really matter. Your computer will still appear to be off for 99.999% of the ports, and that's not bad.

Hopefully, my tutorial on NAT will be finished by the end of the week. I only work on it during my train rides, so it's slow going.

However, if you just receive NO reply, then you know the host is there, because the router that sits in front of the host should return the ICMP-HOST-UNREACHEABLE if the IP has not been configured.

At least IIRC.

At any rate, I still disagree. This is the internet, a vast public network. There is no reason to make an effort to hide your machine.

BTW, REJECT does the exact same thing as a CLOSED port does -- the differences you may notice depend on the differences between Windows and Linux. When Windows says a port is closed, it replies with TCP-RST. When Linux says a port is closed, it replies with ICMP-PORT-UNREACHABLE, unless configured otherwise by iptables...

If the thing doesn't exist, I believe the router should forward back an ICMP-HOST-UNREACHABLE.
Here's some TCPdump for you from my internal network. I'm trying to telnet to 10.0.0.2:85 from 10.0.0.1, while 10.0.0.2 doesn't exist:

I don't think this packet will translate past a router, but it does indeed get sent.

Chris Shepherd
The Nelson-Shepherd cutoff: The point at which you realise someone is an idiot while trying to help them.
\"Well as far as the spelling, I speak fluently both your native languages. Do you even can try spell mine ?\" -- Failed Insult
Is your whole family retarded, or did they just catch it from you?

However, if you just receive NO reply, then you know the host is there, because the router that sits in front of the host should return the ICMP-HOST-UNREACHEABLE if the IP has not been configured.

You are partially correct. In some cases, the router will return host unreachable packets. Most well administered routers, however, do now give away this kind of information because it violates security best practice of giving away too much information about your network structure. Of course, very few ISP's have ever been accused of following security best practices. At any rate, I think every little bit helps, and if I at least avoid showing up on the skiddies scopes, then I've avoided the vast majority of the threat.

At any rate, I still disagree. This is the internet, a vast public network. There is no reason to make an effort to hide your machine.

I guess we'll have to agree to disagree on this one. I do agree that the internet is a vast public network - full of malicious hackers, worms, and random skiddies on my subnet who just downloaded a new hacker tool. I do my best to make them think I don't exist.

BTW, REJECT does the exact same thing as a CLOSED port does -- the differences you may notice depend on the differences between Windows and Linux. When Windows says a port is closed, it replies with TCP-RST. When Linux says a port is closed, it replies with ICMP-PORT-UNREACHABLE, unless configured otherwise by iptables...

Perhaps now I'm the one that's confusing ipchains and iptables. I'll have to look into it again.

By the way chsh, thanks for keeping me in check. I had a few people say good job, but it's nice to know someone went through it with a fine tooth comb.

Originally posted here by str34m3r You are partially correct. In some cases, the router will return host unreachable packets. Most well administered routers, however, do now give away this kind of information because it violates security best practice of giving away too much information about your network structure. Of course, very few ISP's have ever been accused of following security best practices. At any rate, I think every little bit helps, and if I at least avoid showing up on the skiddies scopes, then I've avoided the vast majority of the threat.

This is the problem, I don't know of very many well-administered routers. Especially at broadband ISPs.

I guess we'll have to agree to disagree on this one. I do agree that the internet is a vast public network - full of malicious hackers, worms, and random skiddies on my subnet who just downloaded a new hacker tool. I do my best to make them think I don't exist.

Yep, to each his own.

Perhaps now I'm the one that's confusing ipchains and iptables. I'll have to look into it again.

By the way chsh, thanks for keeping me in check. I had a few people say good job, but it's nice to know someone went through it with a fine tooth comb.

Accuracy is everything. I'm contemplating writing an iptables-NAT-HOWTO because of how I got caught up with forward table policies. The current howto doesn't do a very good job of letting you know that for each DNAT routed packet, you need a FORWARD rule to allow the packet through. It wasn't explained very well in the version I read at any rate.

Chris Shepherd
The Nelson-Shepherd cutoff: The point at which you realise someone is an idiot while trying to help them.
\"Well as far as the spelling, I speak fluently both your native languages. Do you even can try spell mine ?\" -- Failed Insult
Is your whole family retarded, or did they just catch it from you?