LowEndBox

Hosting Websites on Bare Minimum VPS/Dedicated Servers

IPtables Tutorial on Inserting and Deleting Rules

Tags: Date/Time: August 6, 2013 @ 9:49 am, by Maarten Kossen

lowendtutorial

This tutorial is another part in a series of a security-related tutorials. This time, I’m going to talk about IPtables. IPtables is a software firewall that can filter out certain types of traffic. More specifically, it can filter based on source, packet type, protocol, port, connection status and more. It’s an extremely powerful tool to protect your server from unwanted access.

IPtables has two “versions”: iptables and ip6tables. The former is for IPv4 while the latter is for IPv6. The IPv4 and IPv6 packets are quite different from each other, thus each needing an own firewall. However, iptables functions mostly the same for both.

This is a bit of a theoretical tutorial, but understading how IPtables works helps a lot in working with it or in debugging problems with it. Let’s start with explaining what tables and chains are, as they are a fundamental concept in IPtables.

IPtables: tables and chains

IPtables contains four tables, each of which contains chains. A chain is a list of rules.

The four tables IPtables contains are:

  1. raw: this is the first place packets go through, unaltered
  2. filter: this is where packets may be filtered
  3. nat: this is where Network Address Translation is regulated/handled
  4. mangle: user for i.e. ToS or TTL alteration

I’m going to be focussing on the filter table this time. This is where most common filtering takes place. In a future guide (focusing on more advanced IPtables) I will be focussing on things like NAT. IPtables defaults to the filter table when adding rules without defining a table.

The filter table has three chains by default:

  • INPUT: for incoming packets
  • OUTPUT: for outgoing packets
  • FORWARD: for packets routed through the local server/for another device on the local server

In order to see current IPtables rules for the filter table, run:

sudo iptables -L

It should output something like this in case there are no rules:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

As you can see, no rules are defined. All three chains have a default policy, which is currently ACCEPT. ACCEPT is a target value. Other targets value that are valid are DROP, REJECT and LOG.

Each target value has a different response:

  • ACCEPT: packet is let through and processing rules in this chain is stopped
  • DROP: Ignore the packet and stop processing rules in this chain
  • REJECT: Reject the packet and inform the other end of doing so, then stop processing rules in this chain
  • LOG: Log the packet and continue processing rules in this chain

As you can see from the above, if you want to absolutely allow no traffic to your server at all, you could set all chains to default to DROP. In that case all packets are dropped, including SSH.

These target are also very important for rules. A chain contains one or more rules. When it is done processing rules and the packets has matched no rule, the default target is applied. In the above case, if there were any rules and no rules were matched, the packet would be allowed. Such a scenario allows for blocking certain ports or packets from certain IP addresses.

Let’s head on to adding rules to chains.

Inserting and Deleting Rules

Rules can be very complicated or very simple. Let’s dive into a simple example for this tutorial:

sudo iptables -A INPUT -s 198.51.100.51 -j DROP

The above command appends (-A) a rules to the INPUT chain. Any packet from source IP/subnet (-s) will be given DROP as a target (-j for jump). So any incoming packet coming from 198.51.100.51 will be dropped when this rule is matched. This command is something you should learn by heart, by the way, as it’s quite effective when you want to stop somebody attacking your server (i.e. password guessing or lots of requests).

It is important to note that rules are processed in the order that they have been added to a chain. So, for the above example, if the following rule would have been added before that one, the packets would not be dropped, but accepted:

sudo iptables -A INPUT -s 198.51.100.51 -j ACCEPT

But let’s stick with the first example and list the contents of the filter table:

mpkossen@gibbs:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  —  198.51.100.51        anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
mpkossen@gibbs:~$

As you can see, the rules has been added to the INPUT chain and is currently the first and only rule in there. If you add more rules with -A, they are appended to the chain. If you want to add a rule at a specific position in the chain, you can use the -I flag with the number of the position you want to add the rule to. Example:

sudo iptables -I INPUT 1 -s 198.51.100.50 -j DROP

This adds the rule to the first position in the chain and moves all other rules downwards. If you had changed the 1 to 2, it would have been added to the second position. This would have ensured the first rule to stay in place and the other rules to move downwards.

If you run the following command you get to see line numbers as well:

mpkossen@gibbs:~$ sudo iptables -L –line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       all  —  198.51.100.50        anywhere
2    DROP       all  —  198.51.100.51        anywhere

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
mpkossen@gibbs:~$

To delete rules, you have the -D flag. This has two options:

  • You specify the chain and the rule number (as defined in the above tables)
  • You specify the rule (if more than one rule matches the first is removed)

So, let’s say we want to remove rule number one, we have the following two options:

sudo iptables -D INPUT 1

Or:

sudo iptables -D INPUT -s 198.51.100.50 -j DROP

Both will result in the following:

mpkossen@gibbs:~$ sudo iptables -L –line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       all  —  198.51.100.51        anywhere

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
mpkossen@gibbs:~$

The rules we have added above are not permanent, however. They are flushed as soon as iptables has been restarted or your server is rebooted. In a future tutorial, I will show how to persist these rules on both CentOS and Ubuntu.

Final notes on my introduction to IPtables

As you may have noticed, there is a lot to tell about IPtables. For example: you can also filter on source and destination IP address, source and destination port, protocol or even the state of a connection. But you can also log packets under certain circumstances.

For now, you know how to add rules to drop packets from a source address and how to delete rules. The iptables man-pages are a good starting point to find out more. In my next tutorial, I will focus on persisting rules and setting up some basic rules.

25 Comments

  1. moto:

    Come to learn~

    August 6, 2013 @ 10:54 am | Reply
  2. “you could set all chains to default to DROP”

    …and that is when you go to support with your tail between your legs!

    August 6, 2013 @ 11:44 am | Reply
    • Hy:

      lol, i remember doing something like that with my router, and i must hard reset it to be able to use it (and reconfigure everything)

      August 7, 2013 @ 1:10 pm | Reply
      • Everyone has locked themselves out of their own server at some point!

        August 7, 2013 @ 1:40 pm | Reply
        • Craig:

          Well this site is hardly known for it’s wise and experienced patrons. It’s mostly known as a hotbed of cheapskates and amateurs.

          August 10, 2013 @ 5:23 pm | Reply
    • EMG:

      True, but that is why it is helpful to test your console access before you make significant iptables changes. Many (most?) VPS providers include a special console through SSH or VNC so that you can connect to your VPS even if you make an iptables change where your VPS cuts off all network access.

      August 9, 2013 @ 3:53 pm | Reply
  3. budingyun:

    Nice tutorial. :D

    August 6, 2013 @ 12:20 pm | Reply
  4. Lucas:

    This tutorial must see and learn most OpenVZ providers!

    August 6, 2013 @ 1:01 pm | Reply
    • As a provider we should already know this :)

      August 6, 2013 @ 3:55 pm | Reply
      • Lucas:

        You are lucky :) most providers have no idea what is this and how to handle, as well I learn

        August 6, 2013 @ 4:50 pm | Reply
  5. GM:

    is it same for all virtualisation?

    August 6, 2013 @ 2:13 pm | Reply
    • Lucas:

      OpenVZ

      August 6, 2013 @ 4:51 pm | Reply
    • black:

      Fairly certain it’s for all virtualization.

      August 6, 2013 @ 10:11 pm | Reply
      • Yeah worse case operating system specific – shouldn’t be a virtualization thing.

        August 7, 2013 @ 8:32 am | Reply
        • GM:

          I saw openvpn tutorial.. they provide iptables rules for openvz and xen & kvm..

          August 7, 2013 @ 5:40 pm | Reply
    • Maarten Kossen:

      Yes. It’s the same for OpenVZ, Xen, KVM and probably others. The above is not OS-specific. The follow-up to this will have OS-specific stuff in it, but I’ll do a CentOS/Ubuntu hybrid.

      August 8, 2013 @ 6:43 am | Reply
  6. Mark:

    Very simple tutorial for a very useful operation, thank you.

    August 6, 2013 @ 11:24 pm | Reply
    • Maarten Kossen:

      Thank you and you’re welcome!

      August 8, 2013 @ 6:44 am | Reply
  7. good good study,day day up.←_←

    August 7, 2013 @ 6:43 am | Reply
  8. Terry Bush:

    Very good tutorials and bookmarked it.

    August 7, 2013 @ 2:45 pm | Reply
  9. Do you think there is benefit to using IPTABLES over Ubuntu’s ufw for simple, lightweight stuff? For example, locking a VPS down to just HTTP and SSH traffic? ufw seems pretty easy to get up and running with in a short space of time.

    August 7, 2013 @ 4:34 pm | Reply
    • Maarten Kossen:

      UFW is a simplified layer on top op IPTables, AFAIK. I read it’s a easier to use than plain IPTables.

      August 8, 2013 @ 6:46 am | Reply
      • Craig:

        It’s junk. Like everything that comes out of Ubuntu.

        August 10, 2013 @ 5:24 pm | Reply
  10. Mohammed:

    That’s a very good tutorial. Thank you.

    August 7, 2013 @ 9:26 pm | Reply

Leave a Reply

Some notes on commenting on LowEndBox:

  • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
  • Akismet is used for spam detection. Quoting webhostingtalk.com URL seems to get binned consistently here, but I do peek into the spam box frequently to publish those comments.
  • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

Your email address will not be published. Required fields are marked *