HostSEO Blog

Stories and News from IT Industry, Reviews & Tips | Technology Blog


Having a firewall in place and properly set up is an integral part of network security. There are many firewalls out there, both hardware and software based, but luckily, CentOS comes with a pretty powerful one already built in – iptables. CentOS 7 in particular (the environment we’ll use here) by default comes with firewalld – a dynamic firewall daemon, so we’ll disable it later on it this tutorial. But first, let’s explore how iptables actually manages the network traffic.


Iptables uses the concept of IP addresses, protocols (tcp, udp, icmp) and ports, meaning we can set up separate rules for specific combinations of those three. The code for filtering IPv4 packets is built into the kernel and is organized into a collection of tables, which consist of a set of predefined chainsand those chains finally contain the actual firewall rules that determine what will happen to the network packets. Each of those rules consist of potential matches and corresponding action – a target – which is executed if the packet matches a rule.

There are 5 tables in iptables: raw, filter, nat, mangle and security. We’ll generally have to use just the filter table, which is where most of the firewall’s work takes place. Nat table is used for port-forwarding, and the other three are usually used for complex configurations involving multiple routers.

These tables consist of chains, which are lists of rules that are followed in order. The default table filter contains three built-in chains:

INPUT – all packets destined for the host machine

OUTPUT – all packets originating from the host machine

FORWARD – all packets neither destined for nor originating from the host machine, but are passing through it. This chain is usually used if you use the machine as a router.

By default, none of the chains contain any rules, so it’s up to us to set them up. Chains do have a default policy however, which is generally set to ACCEPT, so all incoming and outgoing connections are allowed. This default policy can be changed to DROP, and it always applies at the end of a chain, meaning the packet has to pass through all existing rules in the chain (and not match any of them) before that default policy is applied.

This concept of default policies raises two possibilities that we want to consider before we decide how to set up our firewall rules.
We could set a default policy to ACCEPT and then add rules to specifically block or DROP all packets from specific IP addresses, or for certain ports, for example.
Alternatively, we could set a default policy to DROP all packets and then add rules to specifically ACCEPT packets from trusted IPs, or to and from certain ports.

Usually we’ll use the former for our OUTPUT chain (outbound traffic), where we trust the traffic that’s leaving our machine, and the latter for our INPUT chain when we want to control who or what is allowed to access it.

The actual packet filtering is based on rules, which are specified by one or more matches, that is, conditions the packet must satisfy so the rule can be applied, and one target – action taken if and when the packet matches all conditions.

There are a few more things that we need to mention here. Iptables will treat every packet that comes in on any network interface the same, so it’s up to us to define rules that treat the interfaces differently from one another. Adiitionally, iptables works only with IPv4 traffic – for IPv6 there’s a separate user utility called ip6tables, which has the same syntax as iptables, but some options are specific to either one of them.


Managing iptables requires root-level access so it’s best to either log in directly as root, or elevate to a root shell.

If you want to use iptables on CentOS 7, the first thing we need to do is disable firewalld . We can do that with the following commands:

To make sure it’s actually disabled, we can use:

If iptables isn’t installed on your system, we can use yum to install it:

And after it’s installed, we’ll want to set it to start on boot, and start up the service:

Now, to check the rules and default policies, we can use iptables -L :

We can see here our default policies for all three chains are set to ACCEPT, and that we do have some rules in place, mainly for the INPUT chain.

We’ll cover a basic iptables setup from here on, but it’s strongly advised to get acquainted will all the various options iptables has (man pages are your best friend!). We won’t get into too much detail on what the various options do, but the commands below will give you a good starting point which you can then further tweak to your specific needs.

First we’ll set the default policy of the INPUT chain to ACCEPT, so we don’t get locked out of the server, as we’ll flush (clear) the default ruleset:

Next, we’ll flush the ruleset with:

We’ll append (-A) a rule to the INPUT chain, for our localhost interface (-i lo), to allow all connections (-j ACCEPT), as that’s usually needed for many applications to work properly:

We can then add a rule that will load up a conntrack module (-m conntrack), which will inspect the state of the packet and determine if it’s NEW, ESTABLISHED or RELATED. NEW refers to incoming packets that are new incoming connections that weren’t initiated by the host system. ESTABLISHED and RELATED refers to incoming packets that are part of an already established connection or related to and already established connection.
This rule will allow only the latter 2:

Alternatively, we can use the state module:

We’ll then allow all traffic on our ssh, http and https ports:

Feel free to add any other rules such as these for any other ports you need.

As we now have our basic rules in place, that will allow all traffic on localhost interface, along with ssh and http/s traffic, we can set the default policy of the INPUT chain to DROP:

We’ll DROP all traffic on the FORWARD chain as we generally don’t want our server to act as a proxy, and will ALLOW all outbound traffic since we trust it’s source:

As it’s better to be safe than sorry, we can check our new rules at this point, with some additional verbosity:

The last thing to do is to actually save these rules, so they get loaded on every reboot. We can do so in a couple of ways:


And of course, we should restart the firewall at this point:

You should do these 2 steps each and every time you modify your ruleset!

At this point we have a pretty basic, but working, firewall setup. Since our default policy on INPUT chain is now set to DROP, if we want to allow (or whitelist) a specific IP, we can use something like:

Of, course, if your default policy is set to ACCEPT, and you want to block an IP, just replace ACCEPT with DROP in that rule.

Remember that rules are processed in order. If you have a DROP rule somewhere in your ruleset, and you want to ACCEPT some connection that would otherwise match the DROP rule, you’ll have to add it before that rule, so -A (append) won’t work. In that case, we can use -I (insert) option, like so:

We’d have to insert this particular rule if we didn’t already add it previously. Notice how the -I option needs two arguments, the first is for the chain (INPUT), the other is the position where the rule will be inserted (in this case it would be the first rule).


Hopefully, this article illustrated the power and flexibility iptables offers. You can mix and match all the various flags to set it up just the way you need it. There are many frontends to iptables on the market, both graphical and command-line (in my work I often use ConfigServer Firewall and have only positive experience with it so I highly recommend it), but few of them offer a granular approach to setting up your ruleset like iptables does.

Subscribe Now

10,000 successful online businessmen like to have our content directly delivered to their inbox. Subscribe to our newsletter!

Archive Calendar


Born in 2004 ... Trusted By Clients n' Experts

SEO Stars

They never made me feel silly for asking questions. Help me understand how to attract more people and improve my search engine ranking.

Read More

Emily Schneller Manager at Sabre Inc
SEO Stars

Took advantage of Hostseo's superb tech support and I must say, it is a very perfect one. It is very fast, servers reliability is incredible.

Read More

Leena Mäkinen Creative producer
SEO Stars

We're operating a worldwide network of servers with high quality standards requirements, we’ve choose hostseo to be our perfect partner.

Read More

Ziff Davis CEO at Mashable
SEO Stars

It’s very comfortable to know I can rely about all technical issues on Hostseo and mostly that my website and emails are safe and secured here.

Read More

Isaac H. Entrepreneur
SEO Stars

With hostseo as a hosting partner we are more flexible and save money due to the better packages with great pricing, free SEO n' free SSL too!

Read More

Madeline E. Internet Professional