Roll Your Own Firewall

Over the years I have learned how to roll my own firewall script and call it from /etc directory. Of course, my firewall is only INPUT based, instead of INPUT and OUTPUT based, but I find that building an INPUT/OUTPUT based firewall is tremendously difficult and not really all that necessary if you use good download practices on your Linux server or PC and/or if you're already behind a NAT router (such as a home-based DSL or cable router or wireless router) or other firewall.

If you're scratching your head on what I mean by INPUT and OUTPUT, then just think about you being inside a house that has a front door (INPUT), and a backdoor (OUTPUT). When you surf the web, you first start sending packets of data out your backdoor (OUTPUT). Then, packets return and come in your front door and then you see them. In some cases, some packets need to travel back out your backdoor (OUTPUT) in order to establish or continue a connection. To complicate things, imagine multiple front doors and backdoors, and your ability to direct traffic through these doorways through something called rules, which we explain in a moment.

On Linux, they have a module loaded into the core base of the operating system (the kernel) called NetFilter. It filters network traffic and can block out the bad stuff if you want. You can interface with it using a command-line tool called iptables. Using iptables, you can establish what holes you want to leave in your firewall, and block everything else. Usually the lingo we use is that when we use an iptables command that have the keywords INPUT, OUTPUT, or FORWARD on the line, we are establishing "rules".

Note also that a more advanced topic is a FORWARD connection in your firewall. That's another discussion on a different thread.

Remember that house model I used? Well, a FORWARD connection would be like a chute you install in your house that connects to another house. You can opt for certain packets to get sent out to your FORWARD connection, and you can set up multiple ones to various locations. This is often used for a concept called IP masquerading with a NAT router, which means that your workstation behind a NAT router can act as if it has the same address as the NAT router, or vice-versa. Anyway, that's a discussion for a different thread. It's an advanced topic and not very easy to set up.

Anyway, the combinations of these INPUT and OUTPUT doorways and your FORWARD chutes make up are the whole sum of your "firewall" on Linux.

- GETTING STARTED

Would you like to get started? Okay, great.

- DOING RESEARCH

1. Start by identifying the services your PC will need to either connect out for or host for connections in. Don't forget things like VPN, NTP, HTTP, FTP, DNS, DHCP (if you need it), etc. Normally you won't have to worry about things your PC connects out for EXCEPT in the case of VPN, NTP, and DHCP. There are rare cases that I have found beyond that. If you don't know what IP Address, intranet, TCP, UDP, VPN, NTP, HTTP, FTP, DNS, or DHCP are, then check a tech acronym directory on the web. You'll need to know what those concepts are before proceeding in this how to doc. I suggest using WikiPedia.org as your second choice, and keywords on Google as your first choice.

2. Using cat and grep on /etc/services, identify what the port numbers would be that you need to poke holes for. For instance:

cat /etc/services | grep -i "ntp"

...gives you 123. Write these numbers down. Note that in the case of VPN and DNS, you have to do things slightly different than this and I'll explain that in a moment.

3. Identify your DNS servers. DNS stands for Domain Name Server. When you surf the web and type in a name into your browser like nuxified.org, a DNS server receives this request and translates it to a physical address like 45.61.61.32 (not the actual one, of course, in this example). To find your DNS servers, you can usually do:

cat /etc/resolv.conf

...to get these, or look at perhaps your NAT router's settings, or perhaps your network control panel if your distro has this. Anyway, when you find these, write these down.

- STARTING YOUR FIRST SCRIPT

4. Now let's get started. Create a firewall script as /etc/firewall.sh for now. If you know the more advanced technique of building an entry in /etc/init.d (another article, another day), then so be it. But for now, let's stick with /etc/firewall.sh.

... in the above example, I flush any existing filter that may already be established and start a fresh one. I then permit you to do something called loopback connections, where your PC wants to talk back to itself which should normally be enabled. If you do "sudo /sbin/ifconfig", you'll find your interfaces by their short names on the left side of the output. The "lo" means loopback. You may also see "eth0", "eth1", etc. for each net card you have configured. I then permit reconnections from established connections and this is especially useful for Samba.

- PERMITTING DHCP CLIENT

6. Now, do you have a DHCP address or a static address? If your system depends on DHCP for an address, then add this line:

...Note it says eth0 above. That's because I assume here you are wanting to play with eth0, or the first network card your PC recognizes. If you want to apply this to more than one net card, you'll have to use something like "eth1", "eth2", etc. in addition to using "eth0". It all depends on which net cards you want to set up on static IP address or which ones you want to set up on DHCP.

- POKING HOLES FOR SERVICES AND CERTAIN KINDS OF CONNECTIONS THAT REQUIRE SPECIAL HOLES

7. Now follow this with port numbers that you wrote down that you think you want to permit through. Do this for all except VPN and NTP, which you have to do a little differently. The format is:

...but replace ZZZ with the port number. Now, note that in doing this you are enabling both tcp protocol and udp protocol. If you don't know what those are, then just enable both for now because we'll come back to this later in a moment.

Another important thing to note here is that I do not specify the interface with "-i". This means it applies to all net cards. You may not wish to have that kind of configuration and may want to start inserting "-i YYY" in ALL your iptables commands where YYY is the eth0, eth1, etc. of network cards you want to manipulate.

8. Repeat the previous step for each port number that you wrote down, appending lines, changing ZZZ to the port number. However, below are a few steps to help you shortcut this a bit.

10. Do you want to host SSH connections into your PC? SSH stands for Secure Session Host. It's used for when you want to enable remote command-line connections to your PC or server. If so, then append these lines:

11. Do you want to host POP connections into your PC? POP stands for Post Office Protocol. It's used for hosting a mail server where other workstations can download mail from you. If so, then append these lines:

12. Do you want to host SMTP connections into your PC? SMTP stands for Simple Mail Transport Protocol. It's for hosting a server that permits you to send out mail to another host on the Internet or on an intranet. If so, then append these lines:

13. Do you want to host FTP connections into your PC? FTP is for File Transfer Protocol. It's for when you want to host files in a very common way so that they may be easily accessed by other workstations. If so, then append these lines:

14. Do you want to host LDAP connections into your PC? LDAP is a way to centralize your login accounts in your Linux, Unix, Mac, Mainframe, and Windows systems into a central database. If so, then append these lines:

17. Remember what I said about holding off on VPN? Okay, if you want to enable your workstation to establish VPN connections to a remote PC, such as making a connection from your home to office, enable it by adding this:

Note that this VPN connection isn't perfect. You may have special needs that require other ports. For that discussion, try using this forum as a discussion item as well as on Usenet (groups.google.com is an option for you).

- POKING A SPECIAL HOLE FOR NTP

18. Now do you need NTP access? This is for time server synchronization to keep your time up to date. Note that usually you can use the formula in step 7 to set this up, but I found that you have to do something special in Debian with the GNOME time control panel when you check off time server synchronization. Use these two lines instead:

...and note that instead of "dport", we use "sport". Going into why this is necessary is beyond this discussion. I'm trying to keep you from getting a major headache. At a later date you can dig on the web and find out how all these iptables commands actually work.

- POKING A SPECIAL HOLE FOR DNS QUERIES BY YOUR PC

19. Now, remember that DNS stuff you wrote down? You need to ping those addresses if you only have names, and get their physical IP address. Then, put them below, replacing MYDNS1 and MYDNS2 with those addresses.

...and append this to the /etc/firewall.sh file that we've been building. Note that in some cases you may have DNS problems because the addresses have changed, so you might in that case, if this happens frequently, use the name version instead of the IP address.

Note, however, that this causes a speed hit for every time you want to surf the web or do something on the Internet.

...Note that we use the keyword REJECT here instead of DROP. Later on, we may test with DROP to see if this is possible in your case.

Anyway, the first two statements block everything else that we haven't poked a hole for already and which we did not initiate the transaction. The last line simply lists out the existing iptables because I like it that way.

- TESTING -- THIS IS KEY!

21. Now save this /etc/firewall.sh file and let's run it to see what happens. Do this at command line:

sudo chmod u+x /etc/firewall.sh
sudo /etc/firewall.sh

You should see on your screen the firewall script begin. If you typed something wrong, you'll probably get a nasty note, so go back and edit the file until you see your blunder and change that to what it should properly be. Note also that when it gets to the DNS part in your script, it may take about 2-3 seconds to re-establish this connection before continuing. Therefore, you may see a pause on the screen as it is doing this.

22. Now start testing things that you poked holes for. Here's what you do when it still doesn't work:

a. Check your syntax.
b. Research on the web some port choices you could use to enable that special gizmo you want to poke a hole for. Consider using those.
c. Try using sport instead of dport on the tcp or udp lines.
d. Try commenting it out with #, re-running the script, and seeing if at least the rest of your script works.
e. Post a note to this forum or USENET (groups.google.com is a choice for that) to ask for help.
f. After about 24 hours and no help, start looking on Google for other docs or web-based forums that may have an answer for you. Note also that there are some IRC chats you can hop in for working out firewall issues.

23. Now we need to restrict this firewall even more. I recommend backing up your firewall script with:

sudo cp /etc/firewall.sh /etc/firewall.TEST

24. Now remember those lines where we had a tcp version and a udp version? You may not need to enable both. Therefore, with one port number at a time, comment out one of these, test connections, and then switch to comment out the other other and uncomment the other one out, and test again. This will let you know whether you need both tcp and udp, or just udp, or just tcp poked through. Don't forget that after commenting this out, you must re-run the script with:

sudo /etc/firewall.sh

25. Now, in any case above where I provided more than one set of port numbers, you may not need all those port numbers enabled. Therefore, comment out the tcp/udp set beneath the first one and see if that breaks your connection. For example, here's an option:

In this case, I have enabled only 21 on tcp and udp. I could then test my FTP service to see if remote users can connect on my intranet. Again, don't forget to re-run your script -- simply editing this file won't help you without running it.

...and see if this works by re-running your script. If it does, great. If not, then stick with REJECT. With DROP, your net card doesn't send a message back to the originator saying, "I am not letting you in." Instead, it drops this and acts more stealth. With REJECT, it says, "I'm here on the network, but I'm blocking you from getting in on that port. Try some other ports to hack on." Can you see the difference in messages and why you would want DROP instead of REJECT? However, in some cases, with some kinds of port traffic, this won't work and you have to use REJECT, unfortunately. Only your test will determine this.

27. Now you need to get this script to fire up when everything else on your PC has concluded loading. The way I do that, instead of /etc/init.d, which is a slightly more complicated discussion, is to call the script from this file:

/etc/X11/gdm/Init/Default

...right after the PATH statement. However, this works in my chosen distro, Ubuntu, and may not work for you in yours. Essentially this script is called when my Ubuntu login screen loads up. All I had to do was add after the PATH statement this line:

/bin/bash /etc/firewall.sh

...and when I reboot and do "iptables -L" at command line, I see it is loaded properly with all my rules.

CONCLUSION

By now, you have built your first firewall script. You should feel happy that you're a little more secure. However, I would suggest you read some other things on the Internet to take this to the next level:

* How do I implement this as a service in /etc/init.d?
* Visit Shields-Up at grc.com (Gibson Research) and use that feature to see if you have exposed ports that you didn't want.
* Use nmap and another Linux workstation on your intranet to see if you have exposed ports that you didn't want. (Never ask a buddy to do this.)
* How do these iptables commands work? man iptables
* What is a FORWARD rule and how do I build one?
* What is IP masquerading?
* How do I block a SYN flood?
* How do I block IP spoofing?
* How do I block the ping of death?
* How do I block a particular IP address range from reaching certain ports?
* How do I share my home workstation's web server over the Internet if I'm behind a DSL/Cable Modem router?
* What are the licensing agreements with NetFilter? (Note, this was a recent problem in the news in late 2005 where someone tried to build a product for sale and bundle it with NetFilter without permission, and they got busted at a technology conference!)
* How do I host VPN connections and build a firewall script to support it?
* How do I build OUTPUT-based firewall rules in combination or in replace of INPUT-based firewall rules, and still keep things from breaking?
* What does lokkit and shorewall do that my script doesn't do? Where do these programs store their iptables scripts?
* Are there people out there on the Internet who can give you totally bogus information about building firewall rules just to hack you, make your life miserable, or tell you stupid stuff because they don't know what they're talking about? Unfortunately, yes, I believe so. I'm not one of them, though. I use this same set of rules for my own systems and I am triple safe because my ISP implements special rules, my firewall/router device has more rules, and then my workstation has the iptables firewall script for even more security. And how did I get my information to teach you this here? I reverse-engineered how lokkit worked by asking a lot of questions and checking the results, then testing how strong my firewall was.

Hey, thanks for commenting! :smt045 Yeah, it's long, so it's more of a sticky suggestion or perhaps a doc to place somewhere on the site. It's just so hard to describe firewalls in a way that noobs can understand.

This is a great article. I think you did a great job at explaining it to less experienced users.

I'm sorry there were no replies earlier. We still need more people here. If it's OK with you I'll submit this to some news sites (like LXer.com and digg.com) so it gets more views and possibly comments.

After we have an articles system set up this should be posted there and we'll always then propagate that to other sites for more views.

Thanks alot for writing this.

You might consider officially joining our writers team that is to be set up, since you already wrote a few good articles anyway and are obviously very good at it.

You might consider officially joining our writers team that is to be set up, since you already wrote a few good articles anyway and are obviously very good at it.

I can join and help if it makes a difference, although I have bad time constraints from time to time. You can list me, but perhaps the best thing to do would be to have the list out there for anyone on the group to look at and tackle. Then, each of us can pick from the list when we have the time, write it, and submit it to you. I don't know what you would do to reconcile two or more people writing about the same thing. I guess you could ask them to take a moment to get together and merge it all into a single doc, or someone willing to do that if the members agree. It's just with my family and all, my time comes and goes. I love writing as a great way to release frustrations. For instance, I was often frustrated about firewalls and the docs on the web for noobs, and I wanted to make a difference with that.

hey thanks for writing this article!
just a couple of days ago, I was wondering about setting up a firewall but am afraid it will be very complicated for me.
I followed the link from digg & for sure I will use your guide.
thanks again! :-)

I can join and help if it makes a difference, although I have bad time constraints from time to time. You can list me, but perhaps the best thing to do would be to have the list out there for anyone on the group to look at and tackle.

I'm not sure I get what you mean by the list. The basic difference between team members and other members is that writer team members would be more dedicated to writing articles as well as possibly help finish drafts that may be submit by other members, while other members would just submit when they have something, not necessarily frequently..

Still, the team wouldn't be so strict, so if you don't have time at any point that would be OK, as long as you write something good every once in a while (with reasonable frequency).. or even write it cooperatively with other team members.. The ultimate purpose of the team is to always have some new content to publish, but since there's more of us in, not everyone has to be writing at the same time.

Anyway, I don't mind either way. You can be a "freelancer" or you can be in a team. You're articles are great either way.

That said, congratulations on this one. It is excellent work, and diggers confirm that. (it got on digg.com homepage).

Thanks for this great wiki Its been a long time since I wanted to set up an iptables firewall, but since I use DHCP behind a router I have never found a wiki or howto that deals with such situation. However, I did encountere a minor problem after installing, my gaim IM did not work but after some tweaking it did.

Furtheron I think it's not necessary to open TCP- and UDP-Ports for all services you need, since usually the server just uses one of these. For example, I've never seen a Web-server listening on UDP/80.

It's good trying to write a firewall-tut for people who are not so much into all that networking-stuff, but it's hard. I did one a while ago on another forum, so I know that a firewall-tut can quickly become the monster of your most horrifying nightmares.
And it's never possible to just keep it short and simple, that's why I think a certain level of knowledge should be okay to be assumed when you present a firewall-tut. Anyway, if your reader doesn't have that knowledge, he most propably won't know what he's doing when he's configuring his rules and have more holes than necessary or not enough for daily operation.
But, as I said before, overall it's really good work and will hopefully help a few people securing their boxes a little.

The answer to that is that I was trying to conceive of optional things like SMTP over SSL (port 465) and POP3 over SSL (port 995).

"reptiler" wrote:

Furtheron I think it's not necessary to open TCP- and UDP-Ports for all services you need, since usually the server just uses one of these. For example, I've never seen a Web-server listening on UDP/80.

The answer to that is that I was trying to teach users that it's okay to poke holes for both and then start commenting out items and testing. I know it's a lot of words to read unfortunately because of the nature of the topic, but I state this step in my howto if you doublecheck. Let me give you an example. I found that in a couple different implementations of Network Time Protocol, one only needs UDP, while another needs both TCP and UDP. Another thing to note is that unfortunately many TCP/IP services do not easily document what ports they use and whether they require TCP, UDP, or both to be enabled. The safest advice that I thought noobs could benefit from was to not care about looking for that documentation -- just investigate your /etc/services file and start experimenting, opening both TCP and UDP up, and then start disabling one or the other and testing to see if it still works. And if that fails, then you probably don't know the right set of port numbers and could benefit from looking on USENET or in forums like this.

"reptiler" wrote:

It's good trying to write a firewall-tut for people who are not so much into all that networking-stuff, but it's hard. I did one a while ago on another forum, so I know that a firewall-tut can quickly become the monster of your most horrifying nightmares.<SNIP> But, as I said before, overall it's really good work and will hopefully help a few people securing their boxes a little.

Yes indeed, it was hard. But my frustration in getting started was thwarted by people giving up on noobs and not sharing enough easy documentation for them. I once was a noob once in this area, and I continue to be a noob in various other areas. I swore that once I figured it out, I wouldn't give up on them, and I continue to do that today as I grow my Linux skills.

Thanks for this great wiki Its been a long time since I wanted to set up an iptables firewall, but since I use DHCP behind a router I have never found a wiki or howto that deals with such situation. However, I did encountere a minor problem after installing, my gaim IM did not work but after some tweaking it did.

Okay, welcome and thanks. Here's your answer if you have not really got this working yet.

I'd encourage you to make certain your firewall is running. Do "sudo iptables -L" to see if it dumps out the rules that you wrote. If it does not, then you'll need to find a place where you can get it to start automatically, such as putting inside some Bash file that only usually runs once on your system. In my case, I use the easy way by looking for the Bash script that loaded my GDM login screen. If I wanted to be really sophisticated, however, I could put it in /etc/init.d as a daemon script, but that's a conversation for another thread.

Next, it depends on where you were trying to go with Gaim. If you were connecting to AOL IM, then I think that's assignable. I chose 443 on my system and poked a hole for that. The reason I reassigned it to this number is because my employer has Byzantine rules and blocks most other ports. Luckily AOL IM can work over almost any port. In your case, you'll want to check your GAIM settings and identify not only what services you are connecting with, but what ports you have assigned for that. If you recall step # 7 in the howto, you can stick those port numbers in the middle of your firewall script before you put in your DNS settings on step # 18.

If that fails, then reply with a little more detail and we'll tackle it. That's what this forum is for -- free software and GNU/Linux support.

I know it's a lot of words to read unfortunately because of the nature of the topic, but I state this step in my howto if you doublecheck.

I'm sorry. Must have been a case of selective blindness.

I think a good way to determine which ports are actually open is nmap. I love this tool. And in my oppinion it's also not too hard to use for noobs.
Just use nmap -sT -sU localhost to get the open TCP- and UDP-ports.

Shouldn't be more than 5 minutes to explain the output of nmap, even to a noob.

I'm sure we all have been total noobs in the beginning, nobody was born connected to a computer already knowing all the stuff.
And nobody can know everything, for that all that IT-stuff is too widely spread. That's why in IT you really have to specialize, one of the things a friend of mine doesn't seem to understand.

Personally, I spent a lot of time with IPTables, reading about it, trying around and things like that. So I pretty much got the point, but I also don't know all the things it can do. And I know it can be a tricky thing.
Also with the philosophy of using REJECT or DROP.
The advantage of DROP clearly is that it can really slow down a port-scan since for all dropped ports the scanner has to wait for the timeout. But it's clear that there's a packet-filter running.
REJECT doesn't slow down the port-scan, but using the right options you can hide that you're using a packet-filter.
There everybody has to decide what he/she/it prefers. Slowing down the port-scan, clearly revealing the existence of a port-filter, or hiding the port-filter without doing "any harm" (it's not a real harm if the scan get's slowed down, is it?) to the port-scan.
Funny things could be done by having most ports rejected so that they look like really closed and some dropped, so that they're marked filtered. An attacker might think that only these ports have been closed since something's running there that shouldn't be publicly available. For example SQL or SMB.
Sure, this should only be used if you want to get stupid people's attention but for a honeypot it might be a nice thing.

Thanks for encouraging me to do that.
I think I'll use my german HowTo as a base for that, since that already pretty much explains the most important options of IPTables and shows some examples. So I'm going to translate that first and then check how to implement the nmap-section properly and maybe add some thoughts about building these mentioned traps with honeypots. Right now I have to say that that honeypot-part will propably be pretty short since I never played with that yet. But I'm interested so maybe I'll have a look into it and then add a cool section about that.