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
Maintained by the ILUG website team. The aim of Linux.ie is to
support and help commercial and private users of Linux in Ireland. You can
display ILUG news in your own webpages, read backend
information to find out how. Networking services kindly provided by HEAnet, server kindly donated by
Dell. Linux is a trademark of Linus Torvalds,
used with permission. No penguins were harmed in the production or maintenance
of this highly praised website. Looking for the
Indian Linux Users' Group? Try here. If you've read all this and aren't a lawyer: you should be!