[CLUG] *DSL, Firewalls, IPTables & more - a simple discussion.
adam beecher
lists at beecher.net
Wed Oct 22 15:23:33 IST 2003
Excellent post Ronan, although I'll prolly still go with Smoothwall. That
being said, I'm doing an office setup for a guy in the next week or two and
the setup will require a full distro, so you've won me over on that one. :)
This should really be published on Linux.ie, do you mind if I edit it and
post it under your name?
adam
_______________________________
M A K E T R A D E F A I R
http://www.maketradefair.org/
> -----Original Message-----
> From: cork-bounces at linux.ie [mailto:cork-bounces at linux.ie]On Behalf Of
> Ronan Kirby
> Sent: 22 October 2003 08:58
> To: cork at linux.ie
> Subject: [CLUG] *DSL, Firewalls, IPTables & more - a simple discussion.
>
>
> Folks,
>
> Adam's mail regarding which front-end to use for a firewall
> raises a topic
> which I'm sure we will see again and again on the list, especially as DSL
> becomes more widespread in Cork.
>
> So, what options are available to us Linux junkies? Well, there are many
> many front ends to the Linux firewalling system. Really all most of these
> do is try and make "iptables" (the front end to the Kernel's "netfilter")
> a little more friendly. Unfortunately its a slight catch 22 situation
> though - the more simple the interface usually is, the more functionality
> you tend to loose[1].
>
> In light of this, I discuss below the basics of setting up your own
> firewall on a gateway using iptables its self. It is by no means as
> advanced as some of us would use or as technically accurate as it could
> be, but it is a definite starting point, explaining in simple
> English what
> iptables means and does. It is also my little way of demonstrating that
> iptables is not the scary monster that some people[2] may tell you it is.
> In fact, it is a lot easier to use than its predecessors ipchains and
> ipfwadm[3], with one reason being that it is a stateful firewall (i.e. it
> can track connections properly). This makes rules a lot easier to write
> for services which you wish to allow.
>
> This is of course intended as a starting point and comes with no
> guarantees etcetera etcetera waffle waffle. It does however come with a
> desire to see this expanded on.
>
> So, first thing we want to do: Enable source address verification in the
> kernel. This goes a long way toward protecting you from spoofed packets,
> smurf attacks and other such fun things. So add the following line...
>
> net.ipv4.conf.default.rp_filter = 1
>
> ...in to /etc/sysctl.conf. This will make the change permanent and active
> after you reboot. This can be done on a boot by boot basis by echoing
> directly in to the underlying subsystem - but this much is easier.
>
> Now we want to enable forwarding, permanently. So in the same file as
> before, /etc/sysctl.conf, add the following line...
>
> net.ipv4.ip_forward = 1
>
> ...you can save and close the file for now. We will add more to it later.
>
> Lets start by clearing any rules that might be in memory already...
>
> # iptables -F
>
> ...and setting some defaults we will come back to later...
>
> # iptables --policy INPUT DROP
> # iptables --policy OUTPUT ACCEPT
> # iptables --policy FORWARD ACCEPT
>
> Now to the firewall itself. Being paranoid bunnies, by default we
> drop all
> traffic. It is important to note that I said "drop" and not reject. When
> you drop a packet, it literally does just that. No message or
> acknowledgment of any kind is sent back to the originator. Where as a
> reject will send back an error message to the originator. Now, while it
> might seem a little rude not to reply, if someone is flooding you with
> lots of traffic, you can use a lot of precious bandwidth by sending back
> errors. Better just to ignore it all. Also, this is part of being
> invisible to the world (so to speak). If someone is scanning your IP
> address, which does not reply in any way shape or form, people will
> generally assume there is simply nothing there. Thus not drawing any
> unwanted attention to one's self. So, in light of this, lets start by
> dropping ALL incoming traffic...
>
> # iptables -A INPUT -i eth0 -j DROP
>
> ...this discussion assumes that "eth0" is your connection to the Internet
> or outside world and that "eth1" is your internal facing interface. The
> internal network is assumed as being 192.168.1.0/24 a.k.a.
> 192.168.1.0/255.255.255.0 a.k.a 192.168.1.0 -> 192.168.1.255.
>
> For the sake of paranoia, lets drop all traffic from what should be
> loopback addresses on all interfaces except local...
>
> # iptables -A INPUT -s 127.0.0.0/255.0.0.0 -i ! lo -j DROP
>
> ...and while we're at it, lets drop ICMP traffic too, this means people
> won't be able to ping you (plus a little bit more)...
>
> # iptables -A INPUT -i eth0 -p icmp -j DROP
>
> At this stage, it should be becoming clear what the various flags mean.
> "-A" specifies the chain we're using. For the most part, we will
> deal with
> the INPUT chain, which is built in to iptables by default and deals with
> incoming traffic. "-i" specifies the incoming interface we're talking
> about. This could be anything - eth0 as above, or ppp0 if its a dialup or
> PPP based connection etcetera. "-p" specifies the protocol. You don't
> always have to specify this. But when you do it can be tcp, udp, icmp and
> so on. "-j" for all intents and purposes means "do what comes after me",
> i.e. the action comes next. The action we will mainly be dealing with is
> DROP. But it could be accept, log, reject - the list goes on. See the
> iptables man page for a full list.
>
> As it stands now, traffic from the Internet cannot get in to your
> network.
> Unfortunately at the moment, this also means that your requested
> information cannot get back in to you. i.e. if you try and check your
> mail, it can't get in. For this to work, we must enable whats called
> connection tracking, which put simply, watches any requests you make to
> the Internet (like for mail or a web page) and allows the replies back in
> to you. Thus greatly enhancing your Internet experience :o) This is done
> by the following...
>
> # iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
>
> ...this is fairly self explanatory. Now is also a good time to do some
> protection from the common tactics of a creature known as "El Script
> Kiddy"...
>
> # iptables -A INPUT -i eth0 -p tcp -m tcp ! --tcp-flags
> SYN,RST,ACK SYN -j
> ACCEPT
>
> ...the use of "!" is quite interesting and allows you a lot of
> flexibility. For all intents and purposes it means "the opposite of what
> comes after me". So in the case above its almost like inserting the words
> "ARE NOT" between "--tcp-flags" and "SYN,R...". To put it one final way,
> the "!" argument inverts the test or condition which it comes before.
>
> We are assuming here that all outbound traffic is allowed (actually, we
> set it to be so at the beginning), i.e. that there are no restrictions on
> what you can send to the Internet. That makes this an ingress
> firewall but
> not an egress. This may not necessarily be desirable in a corporate
> situation or on a sensitive network, but for this home scenario its fine.
> Now, while you don't need to explicitly tell the kernel that its ok to
> allow outbound traffic, lets do it anyway so we can see what it looks
> like...
>
> # iptables -A OUTPUT -o eth0 -j ACCEPT
>
> ...as you can see, we are now dealing with the OUTPUT chain which
> obviously is for outbound traffic. Now instead of "-i" which
> earlier meant
> "coming in on interface xyz" we now have "-o" which means "going out on
> interface xyz". I'll state the obvious and say that with the OUTPUT chain
> you couldn't use "-i" because the output chain will never have incoming
> traffic to deal with, its simply not possible. The visa versa also
> applies.
>
> Of course what we also don't want is any nasty broadcast traffic getting
> from your network to the gateway or outside world. Nor do we want it to
> activate a dialup or dial-on-demand (if you are using ISDN or
> PSTN instead
> of DSL). You may for some strange reason have a Windows workstation
> sitting on your network, which often blast out broadcast traffic and
> trigger dialups on gateways. So lets cater for this in a simple basic
> way...
>
> # iptables -A INPUT -i eth1 -d 192.168.1.255 -j DROP
>
> ...what we're doing here is dropping broadcast traffic. There are a few
> important things to note. First of all note the interface used in the
> rule, eth1 (the internal facing interface) not eth0 (the Internet facing
> interface). The reason for this is we don't want the gateway PC to ever
> see this evil broadcast traffic in case it brings up the line (if
> applicable). The IP address used is the broadcast address of the IP range
> used in this example.
>
> Right then, if this were just a workstation and not and gateway/firewall,
> we'd have an almost workable (albeit basic) firewall at this stage. But
> this is a gateway, more over, it probably has to do NAT (Network Address
> Translation) too. Most people will only have 1 public IP address given to
> them by their ISP, so NAT is pretty handy. Having just the 1 public IP
> does not mean you can't run publicly accessible servers - we'll come back
> to that later. For now, lets get NAT and forwarding going...
>
> # iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
>
> ...here "-t" tells iptables we are using the "nat" table, which here we
> are using for "postrouting". We can also do "prerouting", in fact we will
> use this toward the end. Basically postrouting is a chain (part
> of the nat
> table) which is for adjusting packets as they are about to go out
> or leave
> the network. No prizes for guessing that prerouting is for adjusting
> packets are they enter a network.
>
> If you like, you could leave it there. The above should work, but its
> still a bit lacking, even for a basic firewall. We could however go a
> little further and gain a lot more. So, lets continue with some likely
> scenarios.
>
> Lets say you want to be able to SSH back to your gateway from the outside
> world. Maybe so you can access your personal mail...
>
> # iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
>
> ...having said that, you really only want to collect it from work. So
> there is no point in risking leaving SSH open to the world, when you know
> the IP address your work network comes from. So instead of the
> above rule,
> lets use this one...
>
> # iptables -A INPUT -i eth0 -s 123.123.123.123 -p tcp --dport 22
> -j ACCEPT
>
> ...what we're saying here is that any traffic coming in on eth0, who's
> source IP address ("-s") is 123.123.123.123 coming in on TCP port 22
> (which is SSH's port) should be allowed. Obviously you should change the
> IP address to the appropriate one or network. In the same way the above
> rule uses "-s" to specify source address or network, we can also use "-d"
> to specify destination address if we needed to. The same applies to
> "--dport" which represents destination port, you can specify "--sport"
> which, you guessed it, means source port. The only point to note when
> specifying source or destination ports is that you have to state which
> protocol you mean. Thats why we have used "-p tcp", i.e. protocol tcp.
>
> Now, we still haven't discussed that clunky old 486 in the corner
> you want
> to use as your web server. Obviously if people are going to be able to
> browse to your sites, the box has to be accessible to the public
> Internet,
> or to be more precise, port 80 on it must be accessible to the public
> Internet. The simple way we do it in a nat situation like this is to
> forward port 80 from your gateway's external IP to port 80 on your
> internal clunky old 486. In other words, your website will be on the IP
> your ISP gave you at port 80 (where web servers normally listen, or 443
> for HTTPS). This is done with the following, where 192.168.1.3 is the IP
> private address you've given to the 486 and you will remember that we are
> calling 121.121.121.121 is real public IP that your ISP assigned you...
>
> # iptables -t nat -A PREROUTING -p tcp -d 121.121.121.121 --dport 80 -j
> DNAT --to 192.168.1.3:80
>
> ...the most interesting thing to note above this rule is that in fact, we
> can change the port we send it in to internally. As you can see, we
> specify the destination port "--dport" is 80, as that is where web
> requests will come in. But would could forward that to any port on the
> internal server if you wanted, just change the port which comes after the
> IP address, like ":80" in this case. A little food for though: you could
> take this rule a step further by specifying a source IP address too
> ("-s"), so the rule would only apply if traffic was coming from that
> address. This could be handy if you only wanted the web server to be
> available to your college network and not the whole Internet for example.
> You could reverse that and make it available to everyone except your
> college network by using "! -s" as mentioned earlier.
>
> Its time for one last iptables rule, just to make sure you have complete
> access to your gateway PC from your local network without restrictions.
> This is obviously not suitable for all situations.
>
> # iptables -A INPUT -i eth1 -s 192.168.1.0/24 -j ACCEPT
>
> Now, lets reopen /etc/sysctl.conf and add a little more protection. First
> of all add the following line...
>
> net.ipv4.conf.default.send_redirects = 0
>
> ...which will make sure we don't send any ICMP redirect messages. On that
> note, lets also make sure we don't act on any we receive either...
>
> net.ipv4.conf.default.accept_redirects = 0
>
> For pure pig iron, lets turn on the kernel's inbuilt syn cookie
> protection. This simply put affords you some protection against syn
> floods...
>
> net.ipv4.tcp_syncookies = 1
>
> The last thing we will add to this file as a little trick to make sure we
> ignore ICMP broadcast requests. If left enabled it is a way people could
> discover your existence. Block this by adding...
>
> net.ipv4.icmp_echo_ignore_broadcasts = 1
>
> ...now save and close the file. While we're at it, lets save the iptables
> rules too. We will do this in such a way that they will reload when the
> computer reboots...
>
> # iptables-save > /etc/sysconfig/iptables
>
> ...if you want to edit the rules in the future, you can do so using your
> favorite editor and attacking the file /etc/sysconfig/iptables, which is
> quite simple when you think it all through.
>
> When these rules are put in memory / active, your system should
> automatically load any related modules like ip_conntrack.
>
> This is quite a basic firewall, but it involves enough flags and
> attributes to allow you to make it in to something a lot more functional.
> Don't be afraid to play around. For example where we have used the INPUT
> and OUTPUT chains, you can apply many of the same rules to the FORWARD
> chain, i.e. the chain which passes the traffic back and forth for your
> network.
>
> A few things won't work so well, like FTP and Voice Over IP. They can be
> made to function properly though. You need to look in to ip_conntract_ftp
> (tldp.org and google.ie are your friends). You can also examine the state
> of traffic in considerably more detail than just ESTABLISHED or RELATED
> like we have used above. In fact its incredibly powerful. have a look in
> to the man page (man iptables) for more information. Depending on your
> kernel, you can mirror ports too! Also, using the "type of service" field
> in the packet headers, you can assign priority to packets and services as
> they go out (see TOS in iptables). This is great for giving priority to
> interactive traffic like web, ssh and so on.
>
> Once your comfortable with all this, you can start using logging too.
> Basically you would repeat each rule you want to log, but with the action
> set to log ("-j LOG ..."). Then someday when you have nothing to do, you
> can play with using Intrusion Detection Systems (IDS) like wonderfully
> named services such as SNORT :o)
>
> Anyway, the point of this is to try and demonstrate that IPTables is not
> some mean nasty beast thats hard to use and write rules for. Once you
> think things through logically, you can do pretty much anything you want!
> So don't bother with your fancy front-end. They can often be more
> confusing still!
>
> Linux is natively an incredibly powerful firewall system. You'd be amazed
> how many of the big commercial firewall appliances are actually just
> running embedded Linux! I have yet to come across anything more flexible
> and powerful.
>
> (I acknowledge and accept that there are probably mistakes in the above.
> This was done on a laptop, offline, in a lovely place called the Squirrel
> Inn[4]. A lot of it the descriptions given for various functions
> have been
> purposely simplified - so no grief please :o)
>
> If you have questions, just ask! We're a Linux User Group. We're here to
> help each other with Linux!
>
> Y'all take care now.
>
> - Ronan
>
> [1] I know, I know. You don't have to say it. But for the most part,
> alright?
>
> [2] ...daaa da daaa da Uber Alles... ;o)
>
> [3] Dear God, how did we survive having to use that?
>
> [4] Fantastic place to stay if your in Surrey -
> http://www.thesquirrelinn.co.uk/
>
> _______________________________________________
> Cork mailing list
> Cork at linux.ie
> http://www.linux.ie/mailman/listinfo/cork
More information about the Cork
mailing list