What is iptables?
iptables is a fairly flexible firewall system developed for Linux/Unix operating systems and used commonly for web server administrators to block access to servers by IP address or groups of IP addresses. It can also be used to white-list IP addresses as well. It is a command line tool that allows server administrators to enter simply one line commands to add, edit or delete rules for accessing the web server from the outside world.
Understanding iptables Infrastructure
Understanding the infrastructure of iptables in an important component to learning how to use iptables. Basically there are tables, chains and rules. Tables contain chains and chains contain rules. Here is a simple graphic to illustrate my point:
There are four default tables in iptables and you can add others if you want to get deep into config options. However, I recommend using the default tables to keep things simple. In fact, the filter table is the only one we will be messing with for now. The four default tables are filter, nat, mangle and raw.
- Filter Table - default table for iptables. If you do not define a table, you’ll be using the filter table. The filter table has the following built-in chains:
- Input Chain - handles incoming connections.
- Output Chain - handles outgoing connections.
- Forward Chain - handles routing of connections like a router.
- Nat Table - Consists of prerouting, postrouting and output chains. The prerouting chain helps translate destination ip address of the packets to match the routing on the local server. The postrouting chain translates packets as they leave the system and alters packets after routing. The output chain is NAT(Network Address Translation) for locally generated packets on the firewall.
- Mangle Table - for specialized packet alteration. We will leave this table alone for now as it it outside the scope of this tutorial, but just know it is there.
- Raw Table - for configuration exemptions. Raw table has a prerouting chain and an output chain.
Chain? WTF does my server need Chains for? Is it winter already?
When using iptables, there are basically three types of chains that we are mainly interested in. They are input chains, output chains and forward chains, the three chains from the filter table described above.
- Input Chain - used to control the behavior of incoming connections. For example, if a user attempts to SSH into your server, iptables will attempt to match the IP address and port to a rule in the input chain.
- Output Chain - used with outgoing connections. For example, if you try to ping jafty.com, iptables will check its output chain to see what the rules are regarding ping and jafty.com before making a decision to allow or deny the attempt to connect.
- Forward Chain - used for incoming connections that aren’t delivered locally. It is something like a router where data is always being sent to it but is not destined for the actual router. Data is forwarded to its target. Unless you’re doing some type of routing or NATing that requires forwarding, you probably won't use a forward chain much if at all.
Understanding iptables Commands
In order to use iptables in Linux, you need to know the basic commands, so I'll go over some of the more common iptables commands here for your learning pleasure!
Note that after you make any change, it is important to save iptables with the following command on Debian/Ubuntu servers:
or in some cases
The save command is a little different for other servers, so take note of the one that applies to your server as noted below:
- Centos / Redhat:
service iptables save or sudo service iptables save if you are not root user.
- If that didn't work, try:
/etc/init.d/iptables save with and without sudo first.
If you don't save after a change by typing the above at your command prompt and hitting enter, you will most likely lose your changes and/or they will never take effect.
iptables Command to Block a Single Simple IP address
If you wish to simply block an IP such as 184.108.40.206 from accessing your server in any way and from any port, type this at your command prompt and press enter, then save:
iptables -A INPUT -s 220.127.116.11 -j DROP
Whenever possible, always test to be sure your iptables rules work after adding then to be safe. Be sure to save using the appropriate iptables save command as mentioned above after you successfully enter your new rule.
Blocking all IP addresses but your own with iptables
If your server is getting throttled and you want to lock it down immediately or you are simply under construction and don't want anyone but you to be able to access your server, here is how you can block all IP addresses from accessing your server and white-list just one or more IP addresses that will be able to access your server:
iptables -A INPUT -s 0.0.0.0 -j ACCEPT
iptables -A OUTPUT -d 0.0.0.0 -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
First, you should flush your current rules(see below). Then simply replace 0.0.0.0 with your own IP address in the commands above and enter each of the four commands one at a time from the command line, pressing enter after each, then save iptables.
Flushing iptables rules
To get rid of all active rules in iptables, enter the following command at the Linux command prompt:
Deleting Single iptables Rules
If you entered one or more iptables rules you want to delete without deleting the entire configuration, here is how to do it:
- List numbered rules using this command: sudo
iptables -L INPUT -n --line-numbers
- To delete the first rule enter: sudo iptables -D INPUT 1(where 1 is the line number you want to delete)
- Confirm deletion took place by running the first command again and verify the rule is no longer present: sudo
iptables -L INPUT -n --line-numbers
- Save iptables to be safe: sudo iptables-save
Restrict Number of Connections Per IP
Use connlimit to place restrictions on the number of connections allowed per IP address. To allow 4 ssh connections per client host, enter:
# iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 4 -j REJECT
Set HTTP requests to 20:
# iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j DROP
- --connlimit-above 3 : Match if the number of existing connections is above 3.
- --connlimit-mask 24 : Group hosts using the prefix length. For IPv4, this must be a number between (including) 0 and 32.
What is this nonsense after the slash in iptables ip addresses?
This is what I need to touch on before we go much further because you've no doubt seen existing rules in your iptables with IP addresses listed similar to:
...and have surely wondered why there is a slash followed by a number after the ip addresses listed in your iptables rules. Well I'll explain as best as I can in the next section as it is a little complicated to explain...
Knowing how to read and write more complex iptables rules with CIDR notation.
Learning to write iptables rules can get very frustrating if you don't understand how the notation works. CIDR, Classless Inter Domain Routing notation, is often confused with network masks which are similar but not the same. I will offer my best explanation of CIDR notation here which I've gathered from several different sources to put together an explanation I feel comfortable with:
Imagine an IP address something like xxx.yyy.zzz.www/N, where N is the number of bits from 0 to 32. Each of the other numbers represents one byte out of the 4 bytes that make up an IP address. N says how many BITS of those 4 bytes matter. So any address that looks like 10.X.Y.Z/8 refers to ANY IP starting with "10.": 8 bits = 1 byte, meaning everything after the first byte is ignored. The convention is to use zeroes in the ignored positions, so the canonical name for that subnet is 10.0.0.0/8. Most of the time, N is a multiple of 8, so it says to ignore a certain number of bytes.
Once in a while, you'll see something other than that, like a /29. This means that PART of one of the bytes is ignored. For simplicity's sake however, we will stick to multiples of 8 in this guide.
It's also important to note that if the N is omitted, then it's usually assumed to be 32, i.e. a single IP address specification.
So, taking what I've just explained above regarding CIDR notation, Here are some general examples of how netmasks work in conjunction with iptables rules:
10.0.0.0/8 - A CIDR of 8 bits means that only 1 of 4 possible bytes of the IP address is noted as represented by the "10" here. so this would cover the IP range from 10.0.0.0 to 10.255.255.255. In other words any IP address starting with "10.".
18.104.22.168/16 - A CIDR of 16 means that 2 of 4 possible bytes of the IP address are noted as represented here by "100.50.". In this case, a range from 22.214.171.124 to 126.96.36.199 is covered.
188.8.131.52/24 - A CIDR of 24 means that 3 of the 4 IP address bytes are noted as seen here with "92.50.8." This time a range from 184.108.40.206 to 220.127.116.11 is represented.
Those should be the three most common types of CIDR notations. Following the above pattern of incrementing the number of bits by 8, the next logical example would be something like 18.104.22.168/32. While that is a perfectly good notation and will work, it is also moot because 32 bits would represent the entire IP address, so you might as well enter it without the CIDR notation(with no slash and number after the IP). In iptables rules, 22.214.171.124/32 means the exact same thing as simply putting 126.96.36.199.
What do Bytes and Bits have to do with IP Addresses?
Good question, glad I asked myself! To properly understand how CIDR notation works you have to understand the math behind it. A Byte is made up of 8 bits(that's why we increment by 8 in our previous examples). An IP address is made up of 4 Bytes or 32 Bits(4x8=32).
As you probably know, an IP address is made of of four numbers separated by dots or periods(.) like this: N.N.N.N where N can be any number from 0 to 255. This raised a question in my mind: In an IP address byte, how does a range from 0 to 255 have 8 bits? Well my question just goes to show I don't fully understand how Bytes and Bits correspond with numbers because I googled around and discovered that indeed Eight binary bits can represent any whole number from zero to 255, so the segments of a dotted decimal address are decimal numbers with a range from 0 to 255. I think it's enough for now to understand that it is correct without getting into exactly how Bytes and Bits work with IP addresses because I don't want this tutorial to confuse you even more. Let's just know for now that 1 Byte = 8 Bits and that a Byte can be any number from 0 to 255 in an IP address which is made up of 4 Bytes and/or 32 Bits. If anyone would like to explain how this works in more detail, feel free to make a comment on this post and I'll make sure it gets published.