≡ Menu

Linux IPTables: How to Add Firewall Rules (With Allow SSH Example)

This article explains how to add iptables firewall rules using the “iptables -A” (append) command.

“-A” is for append. If it makes it easier for you to remember “-A” as add-rule (instead of append-rule), it is OK. But, keep in mind that “-A” adds the rule at the end of the chain.

Again, it is very important to remember that -A adds the rule at the end.

Typically the last rule will be to drop all packets. If you already have a rule to drop all packets, and if you try to use “-A” from the command-line to create new rule, you will end-up adding the new rule after the current “drop all packets” rule, which will make your new rule pretty much useless.

Once you’ve mastered the iptables, and when you are implementing it on production, you should use a shell script, where you use -A command to add all the rules. In that shell script, your last line should always be “drop all packets” rule. When you want to add any new rules, modify that shell script and add your new rules above the “drop all packets” rule.


iptables -A chain firewall-rule
  • -A chain – Specify the chain where the rule should be appended. For example, use INPUT chain for incoming packets, and OUTPUT for outgoing packets.
  • firewall-rule – Various parameters makes up the firewall rule.

If you don’t know what chain means, you better read about iptables fundamentals first.

Firewall Rule Parameters

The following parameters are available for all kinds of firewall rules.

-p is for protocol

  • Indicates the protocol for the rule.
  • Possible values are tcp, udp, icmp
  • Use “all” to allow all protocols. When you don’t specify -p, by default “all” protocols will be used. It is not a good practice to use “all”, and always specify a protocol.
  • Use either the name (for example: tcp), or the number (for example: 6 for tcp) for protocol.
  • /etc/protocols file contains all allowed protocol name and number.
  • You an also use –protocol

-s is for source

  • Indicates the source of the packet.
  • This can be ip address, or network address, or hostname
  • For example: -s indicates a specific ip address
  • For network mask use /mask. For example: “-s” represents a network mask of for that network. This matches 192.168.1.x network.
  • When you don’t specify a source, it matches all source.
  • You can also use –src or –source

-d is for destination

  • Indicates the destination of the packet.
  • This is same as “-s” (except this represents destination host, or ip-address, or network)
  • You can also use –dst or –destination

-j is target

  • j stands for “jump to target”
  • This specifies what needs to happen to the packet that matches this firewall rule.
  • Possible values are ACCEPT, DROP, QUEUE, RETURN
  • You can also specify other user defined chain as target value.

-i is for in interface

  • i stands for “input interface”
  • You might over look this and assume that “-i” is for interface. Please note that both -i and -o are for interfaces. However, -i for input interface and -o for output interface.
  • Indicates the interface through which the incoming packets are coming through the INPUT, FORWARD, and PREROUTING chain.
  • For example: -i eth0 indicates that this rule should consider the incoming packets coming through the interface eth0.
  • If you don’t specify -i option, all available interfaces on the system will be considered for input packets.
  • You can also use –in-interface

-o is for out interface

  • o stands for “output interface”
  • Indicates the interface through which the outgoing packets are sent through the INPUT, FORWARD, and PREROUTING chain.
  • If you don’t specify -o option, all available interfaces on the system will be considered for output packets.
  • You can also use –out-interface

Additional Options for Firewall Parameters

Some of the above firewall parameters in turn has it’s own options that can be passed along with them. Following are some of the most common options.

To use these parameter options, you should specify the corresponding parameter in the firewall rule. For example, to use “–sport” option, you should’ve specified “-p tcp” (or “-p udp”) parameter in your firewall rule.

Note: All of these options have two dashes in front of them. For example, there are two hyphens in front of sport.

–sport is for source port (for -p tcp, or -p udp)

  • By default all source ports are matched.
  • You can specify either the port number or the name. For example, to use SSH port in your firewall rule, use either “–sport 22” or “–sport ssh”.
  • /etc/services file contains all allowed port name and number.
  • Using port number in the rule is better (for performance) than using port name.
  • To match range of ports, use colon. For example, 22:100 matches port number from 22 until 100.
  • You can also use –source-port

–dport is for destination port (for -p tcp, or -p udp)

  • Everything is same as –sport, except this is for destination ports.
  • You can also use –destination-port

–tcp-flags is for TCP flags (for -p tcp)

  • This can contain multiple values separated by comma.
  • Possible values are: SYN, ACK, FIN, RST, URG, PSH. You can also use ALL or NONE

–icmp-type is for ICMP Type (for -p icmp)

  • When you use icmp protocol “-p icmp”, you can also specify the ICMP type using “–icmp-type” parameter.
  • For example: use “–icmp-type 0” for “Echo Reply”, and “–icmp-type 8” for “Echo”.

Example Firewall Rule to Allow Incoming SSH Connections

Now that you understand various parameters (and it’s options) of firewall rule, let us build a sample firewall rule.

In this example, let us allow only the incoming SSH connection to the server. All other connections will be blocked (including ping).

WARNING: Playing with firewall rules might render your system inaccessible. If you don’t know what you are doing, you might lock yourself (and everybody else) out of the system. So, do all your learning only on a test system that is not used by anybody, and you have access to the console to restart the iptables, if you get locked out.

1. Delete Existing Rules

If you already have some iptables rules, take a backup before delete the existing rules.

Delete all the existing rules and allow the firewall to accept everything. Use iptables flush as we discussed earlier to clean-up all your existing rules and start from scratch.

Test to make sure you are able to ssh and ping this server from outside.

When we are done with this example, you’ll only be able to SSH to this server. You’ll not be able to ping this server from outside.

2. Allow only SSH

Allow only the incoming SSH connection to this server. You can ssh to this server from anywhere.

iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT

The above iptables command has the following 4 components.

  • “-A INPUT” – This indicates that we are appending a new rule (or adding) to the INPUT chain. So, this rule is for incoming traffic.
  • “-i eth0” – Incoming packets through the interface eth0 will be checked against this rule.
  • “-p tcp –dport 22” – This rule is for TCP packets. This has one tcp option called “–dport 22”, which indicates that the destination port for this rule on the server is 22 (which is ssh).
  • “-j ACCEPT” – Jump to accept, which just ACCEPTS the packet.

In simple terms the above rule can be stated as: All incoming packets through eth0 for ssh will be accepted.

3. Drop all Other Packets

Once you’ve specified your custom rules to accept packets, you should also have a default rule to drop any other packets.

This should be your last rule in the INPUT chain.

To drop all incoming packets, do the following.

iptables -A INPUT -j DROP

4. View the SSH rule and Test

To view the current iptables firewall rules, use “iptables -L” command.

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
DROP       all  --  anywhere             anywhere

As you see from the above output, it has the following two rules in sequence.

  • Accept all incoming ssh connections
  • Drop all other packets.

Instead of adding the firewall rules from the command line, it might be better to create a shell script that contains your rules as shown below.

# vi iptables.sh
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP

# sh -x iptables.sh
+ iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
+ iptables -A INPUT -j DROP

# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
DROP       all  --  anywhere             anywhere

Similar to iptables append/add command, there are few other commands available for iptables. I’ll cover them in the upcoming articles in the iptables series. I’ll also provide several practical firewall rule examples that will be helpful in real life scenarios.

Previous articles in the iptables series:

Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • Karn Chandra February 14, 2011, 4:41 am

    Hi Ramesh,

    Thanks for your lucid explanation! Could you also please link your past IPTables posts (those are part of this ongoing tutorial) within this post? It would be really helpful to view them in context and move around them swiftly. Presently one has to use the search box.

    Once again thanks and keep up the good work!

  • Karn Chandra February 14, 2011, 4:43 am

    Sorry just noticed they are already linked at the end of the post. Please ignore the comment above.

  • Kuldeep February 14, 2011, 6:11 am

    very gud !!!!!

    Thanx alot for very informative article…..

  • kgas February 14, 2011, 7:39 am

    good one. I keep reading your articles.

  • manish February 14, 2011, 8:33 am


  • mky February 14, 2011, 1:07 pm

    many thanks!

  • Zoly February 15, 2011, 3:46 am

    simple and clear example/explanation, thanks

  • ranjith February 15, 2011, 7:57 am

    dear rameshji,
    please add securetty, only sysadmin from remotely with the help of ssh can only manage and monitor. I kept this firewall running with messages displayed in the terminal mode(cui). If any user trying to login in the terminal will be denied access and moreover running messages will disturb him. Instead i sitting in my remote place with the help of SSH can monitor and route logs to log server.

  • jackd February 16, 2011, 5:21 am

    Thanks for the very clear explanation. Well done.

  • jhun bacala March 10, 2011, 9:21 pm

    this is a good article for starters. nice job

  • lesca March 21, 2012, 11:48 pm

    One mistake found:
    -o is for out interface Section
    Indicates the interface through which the outgoing packets are sent through the INPUT, FORWARD, and PREROUTING chain.


  • siraj May 15, 2012, 6:57 am

    rule 4 and rule 8 doesnot work together , when i apply rule 4 alone it works fine , when applied both 4 and 8 rule 8 is not working that means i cannot have an outgoing ssh , please advise — thanks siraj sharjah uae

  • Tigist May 17, 2012, 12:06 pm

    it really helps me, many thanks

  • Kanhaiya Singh Patel August 28, 2012, 8:26 pm

    Very good article…….

  • subash August 30, 2012, 12:29 am

    Really simple and neat…!!

  • Conrad November 5, 2012, 12:27 am

    Another good article, with very clear explanation. Keep up the good work. Thank you so much for sharing this tutorial.

    Best regards to you !

  • Sher December 17, 2012, 6:20 am

    Really nice tutorials. I have now bookmarked it.

    However I think you might be missing “-m” for match.

    Thanks again.

  • ehsan ghasisin November 22, 2013, 9:01 am

    hi .

    I have question a bout anti IP-Spoofing packet ,

    This Rules is correct or not


    if put negation(!) before input interface IPTABLES -A INPUT ! -i $INT_INTF -s $INT_NET -j DROP is correct or not

  • Joe mont January 15, 2014, 3:52 pm

    It would be nice if you did something on custom chains, appending to input and then saying “all incoming packets” makes it confusing how custom chains work in all this.

  • sujith February 4, 2014, 4:30 am

    Very informative and it is very easy to understand with your part 1 ,2 & 3.

    Thanks a lot Remeshji .

  • anand February 12, 2014, 1:22 pm

    nice tutorial……

  • Seth Greenburg March 17, 2014, 1:13 pm

    Nice clear writing! I’ve been looking for a “one-pager” like this for years. Too many tutorials go into way too much detail.

    One request: if you have time, explain why using a shell script to setup iptables is better than the other options (modifying via an iptables config tool). Even if the explanation is simply, “it’ll work on all Unices.”

  • Amit June 22, 2014, 11:35 pm

    Thanks, Could you explain the line
    -A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 9999 -j ACCEPT

    What is -A RH-Firewall-1-INPUT, -m state –state NEW -m tcp

  • Yogesh Choudhary August 28, 2014, 2:32 am

    Hi Sir

  • Anonymous March 21, 2016, 4:22 pm

    Why are you using elan0 rather than wlan0 in the chain?