Iptables is a firewall that plays an essential role in network security for most Linux systems. While many iptables tutorials will teach you how to create firewall rules to secure your server, this one will focus on a different aspect of firewall management: listing and deleting rules.
In this tutorial, we will cover how to do the following iptables tasks:
Note: When working with firewalls, take care not to lock yourself out of your own server by blocking SSH traffic (port :22
, by default). If you lose access due to your firewall settings, you may need to connect to it via an out-of-band console to fix your access.
This tutorial assumes you are using a Linux server with the iptables
command installed, and that your user has sudo
privileges.
If you need help with this initial setup, please refer to our Initial Server Setup with Ubuntu 20.04 guide. It is also available for Debian and CentOS.
Let’s look at how to list rules first. There are two different ways to view your active iptables rules: in a table or as a list of rule specifications. Both methods provide roughly the same information in different formats.
To list out all of the active iptables rules by specification, run the iptables
command with the -S
option:
- sudo iptables -S
Output-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-N ICMP
-N TCP
-N UDP
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT
...
As you can see, the output looks just like the commands that were used to create them, without the preceding iptables
command. This will also look similar to the iptables rules configuration files, if you’ve ever used iptables-persistent
or iptables save
.
If you want to limit the output to a specific chain (INPUT
, OUTPUT
, TCP
, etc.), you can specify the chain name directly after the -S
option. For example, to show all of the rule specifications in the TCP
chain, you would run this command:
- sudo iptables -S TCP
Output-N TCP
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT
Now let’s take a look at the alternative way to view the active iptables rules: as a table of rules.
Listing the iptables rules in the table view can be useful for comparing different rules against each other. To output all of the active iptables rules in a table, run the iptables
command with the -L
option:
- sudo iptables -L
This will output all of the current rules sorted by chain.
If you want to limit the output to a specific chain (INPUT
, OUTPUT
, TCP
, etc.), you can specify the chain name directly after the -L
option.
Let’s take a look at an example INPUT
chain:
- sudo iptables -L INPUT
OutputChain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
DROP all -- anywhere anywhere ctstate INVALID
UDP udp -- anywhere anywhere ctstate NEW
TCP tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN ctstate NEW
ICMP icmp -- anywhere anywhere ctstate NEW
REJECT udp -- anywhere anywhere reject-with icmp-port-unreachable
REJECT tcp -- anywhere anywhere reject-with tcp-reset
REJECT all -- anywhere anywhere reject-with icmp-proto-unreachable
The first line of output indicates the chain name (INPUT
, in this case), followed by its default policy (DROP
). The next line consists of the headers of each column in the table, and is followed by the chain’s rules. Let’s go over what each header indicates:
target
: If a packet matches the rule, the target specifies what should be done with it. For example, a packet can be accepted, dropped, logged, or sent to another chain to be compared against more rulesprot
: The protocol, such as tcp
, udp
, icmp
, or all
opt
: Rarely used, this column indicates IP optionssource
: The source IP address or subnet of the traffic, or anywhere
destination
: The destination IP address or subnet of the traffic, or anywhere
The last column, which is not labeled, indicates the options of a rule. This is any part of the rule that isn’t indicated by the previous columns. This could be anything from source and destination ports to the connection state of the packet.
When listing iptables rules, it is also possible to show the number of packets, and the aggregate size of the packets in bytes, that matched each particular rule. This is often useful when trying to get a rough idea of which rules are matching against packets. To do so, use the -L
and -v
options together.
For example, let’s look at the INPUT
chain again, with the -v
option:
- sudo iptables -L INPUT -v
OutputChain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
284K 42M ACCEPT all -- any any anywhere anywhere ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 DROP all -- any any anywhere anywhere ctstate INVALID
396 63275 UDP udp -- any any anywhere anywhere ctstate NEW
17067 1005K TCP tcp -- any any anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN ctstate NEW
2410 154K ICMP icmp -- any any anywhere anywhere ctstate NEW
396 63275 REJECT udp -- any any anywhere anywhere reject-with icmp-port-unreachable
2916 179K REJECT all -- any any anywhere anywhere reject-with icmp-proto-unreachable
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:ssh ctstate NEW,ESTABLISHED
Note that the listing now has two additional columns, pkts
and bytes
.
Now that you know how to list the active firewall rules in a variety of ways, let’s look at how you can reset the packet and byte counters.
If you want to clear, or zero, the packet and byte counters for your rules, use the -Z
option. They also reset if a reboot occurs. This is useful if you want to see if your server is receiving new traffic that matches your existing rules.
To clear the counters for all chains and rules, use the -Z
option by itself:
- sudo iptables -Z
To clear the counters for all rules in a specific chain, use the -Z
option and specify the chain. For example, to clear the INPUT
chain counters run this command:
- sudo iptables -Z INPUT
If you want to clear the counters for a specific rule, specify the chain name and the rule number. For example, to zero the counters for the first rule in the INPUT
chain, run this:
- sudo iptables -Z INPUT 1
Now that you know how to reset the iptables packet and byte counters, let’s look at the two methods that can be used to delete them.
One of the ways to delete iptables rules is by rule specification. To do so, you can run the iptables
command with the -D
option followed by the rule specification. If you want to delete rules using this method, you can use the output of the rules list, iptables -S
, for some help.
For example, if you want to delete the rule that drops invalid incoming packets (-A INPUT -m conntrack --ctstate INVALID -j DROP
), you could run this command:
- sudo iptables -D INPUT -m conntrack --ctstate INVALID -j DROP
Note that the -A
option, which is used to indicate the rule position at creation time, should be excluded here.
The other way to delete iptables rules is by its chain and line number. To determine a rule’s line number, list the rules in the table format and add the --line-numbers
option:
- sudo iptables -L --line-numbers
OutputChain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
2 ACCEPT all -- anywhere anywhere
3 DROP all -- anywhere anywhere ctstate INVALID
4 UDP udp -- anywhere anywhere ctstate NEW
5 TCP tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN ctstate NEW
6 ICMP icmp -- anywhere anywhere ctstate NEW
7 REJECT udp -- anywhere anywhere reject-with icmp-port-unreachable
8 REJECT tcp -- anywhere anywhere reject-with tcp-reset
9 REJECT all -- anywhere anywhere reject-with icmp-proto-unreachable
10 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh ctstate NEW,ESTABLISHED
...
This adds the line number to each rule row, indicated by the num
header.
Once you know which rule you want to delete, note the chain and line number of the rule. Then run the iptables -D
command followed by the chain and rule number.
For example, if we want to delete the input rule that drops invalid packets, we can see that it’s rule 3
of the INPUT
chain. So we should run this command:
- sudo iptables -D INPUT 3
Now that you know how to delete individual firewall rules, let’s go over how you can flush chains of rules.
Iptables offers a way to delete all rules in a chain, or flush a chain. This section will cover the variety of ways to do this.
Warning: Be careful to not lock yourself out of your server via SSH by flushing a chain with a default policy of drop
or deny
. If you do, you may need to connect to it via the console to fix your access.
To flush a specific chain, which will delete all of the rules in the chain, you may use the -F
, or the equivalent --flush
, option and the name of the chain to flush.
For example, to delete all of the rules in the INPUT
chain, run this command:
- sudo iptables -F INPUT
To flush all chains, which will delete all of the firewall rules, you may use the -F
, or the equivalent --flush
, option by itself:
- sudo iptables -F
This section will show you how to flush all of your firewall rules, tables, and chains, and allow all network traffic.
Warning: This will effectively disable your firewall. You should only follow this section if you want to start over the configuration of your firewall.
First, set the default policies for each of the built-in chains to ACCEPT
. The main reason to do this is to ensure that you won’t be locked out from your server via SSH:
- sudo iptables -P INPUT ACCEPT
- sudo iptables -P FORWARD ACCEPT
- sudo iptables -P OUTPUT ACCEPT
Then flush the nat
and mangle
tables, flush all chains (-F
), and delete all non-default chains (-X
):
- sudo iptables -t nat -F
- sudo iptables -t mangle -F
- sudo iptables -F
- sudo iptables -X
Your firewall will now allow all network traffic. If you list your rules now, you will will see there are none, and only the three default chains (INPUT
, FORWARD
, and OUTPUT
) remain.
iptables -D
and iptables -F
Option | Description | Purpose | Example |
---|---|---|---|
-D |
Deletes a specific rule from a chain | Used to remove a single rule from a chain | sudo iptables -D INPUT 1 |
-F |
Flushes all rules from a chain | Used to delete all rules from a chain | sudo iptables -F INPUT |
iptables -D
is used to delete a specific rule from a chain. For example, to delete the first rule from the INPUT
chain, you would run sudo iptables -D INPUT 1
.
iptables -F
is used to flush all rules from a chain. For example, to delete all rules from the INPUT
chain, you would run sudo iptables -F INPUT
.
When managing your firewall rules, you may need to delete specific rules from custom chains. Custom chains are user-defined chains that allow for more complex and organized firewall rule configurations. To delete rules from these custom chains, you can use the -D
option followed by the name of the custom chain and the rule number you want to delete.
For example, let’s say you have a custom chain named custom_chain
and you want to delete the first rule from this chain. To do this, you would run the following command:
- sudo iptables -D custom_chain 1
This command will delete the first rule from the custom_chain
chain. Make sure to replace custom_chain
with the actual name of your custom chain and 1
with the actual rule number you want to delete.
Remember to exercise caution when deleting rules from your firewall configuration, as it can affect the security of your system. Always verify the rule you are about to delete to ensure it is the correct one.
This error occurs when the chain, target, or match name you specified does not exist. To fix this error, ensure that the chain, target, or match you are trying to use is correctly spelled and exists in your iptables configuration. You can list all existing chains using the following command:
- sudo iptables -L
This will display all chains, including the default chains (INPUT
, FORWARD
, and OUTPUT
). If the chain you are trying to use does not exist, you can create it using the -N
option:
- sudo iptables -N <chain_name>
Replace <chain_name>
with the name of the chain you want to create.
This error occurs when the rule you are trying to delete does not match the rule you want to delete. To fix this error, ensure that the rule you are trying to delete matches the rule you want to delete exactly. You can list all rules in a specific chain using the -S
option:
- sudo iptables -S <chain_name>
This will display all rules in the specified chain. Compare the output with the rule you are trying to delete to ensure they match exactly. If they do not match, adjust the rule you are trying to delete to match the rule you want to delete.
When deleting rules by line number, it is easy to accidentally delete the wrong rule. To avoid this, use the -n
option to list the rules with line numbers:
- sudo iptables -nL <chain_name>
This will display the rules with line numbers. Use the -D
option to delete a rule by its line number:
- sudo iptables -D <chain_name> <line_number>
Replace <chain_name>
with the name of the chain and <line_number>
with the line number of the rule you want to delete.
To view active iptables rules, you can use the iptables -L
command. This command will display all chains and their rules. For example:
- sudo iptables -L
This will display all chains and their rules. If you want to view the rules in a more detailed format, you can use the -S
option:
- sudo iptables -S
This will display the rules in a more detailed format, including the exact commands used to create them.
To delete a specific iptables rule, you can use the iptables -D
command. This command will delete a rule from a specific chain. For example, to delete a rule from the INPUT
chain, you would use:
- sudo iptables -D INPUT <rule_number>
Replace <rule_number>
with the actual number of the rule you want to delete. You can use the -n
option to view the rules with line numbers:
- sudo iptables -nL INPUT
This will display the rules in the INPUT
chain with line numbers, making it easier to identify the rule you want to delete.
Flushing a chain will delete all rules from that chain. Deleting a rule will delete a specific rule from a chain. For example, to flush all rules from the INPUT
chain, you would use:
- sudo iptables -F INPUT
This will delete all rules from the INPUT
chain. On the other hand, deleting a specific rule from the INPUT
chain would require using the -D
option as described in question 2.
To delete all rules in a chain, you can use the iptables -F
command. This command will flush all rules from a chain. For example, to flush all rules from the INPUT
chain, you would use:
- sudo iptables -F INPUT
This will delete all rules from the INPUT
chain. You can also use the -n
option to view the rules with line numbers before flushing them:
- sudo iptables -nL INPUT
This will display the rules in the INPUT
chain with line numbers, making it easier to verify the rules before flushing them.
Yes, you can undo a deleted iptables rule by using the iptables -A
command. This command will add a rule to a specific chain. For example, to add a rule to the INPUT
chain, you would use:
- sudo iptables -A INPUT <rule_specification>
Replace <rule_specification>
with the actual specification of the rule you want to add. You can also use the -n
option to view the rules with line numbers after adding a new rule:
- sudo iptables -nL INPUT
This will display the rules in the INPUT
chain with line numbers, making it easier to verify the new rule.
After going through this tutorial, you have seen how to list and delete your iptables firewall rules. Additionally, you have learned how to flush chains, delete all rules in a chain, and understand the differences between iptables -D
and iptables -F
.
Remember that any iptables changes via the iptables
command are ephemeral, and need to be saved to persist through server reboots. This is covered in the Saving Rules section of the Common Firewall Rules and Commands tutorial.
For further learning, we recommend referring to the following tutorials to enhance your firewall configuration skills:
These tutorials will provide you with a comprehensive understanding of iptables
and ufw
, enabling you to create robust firewall configurations for your servers.
Easily secure your infrastructure and define what services are visible on your servers using DigitalOcean Cloud Firewalls. Our Cloud Firewalls are free and perfect for staging and production deployments.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
This comment has been deleted
Another great tutorial I would like to add that is you want to reduce the number of SSH brute force attacks you can add this CHAIN to your iptables rules. Adjust accordingly to the seconds and hitcount and port for your server.
Create chain for ssh attacks
$ iptables -N SSH_CHECK
$ iptables -I INPUT -p tcp --dport 22 -m state --state NEW -j SSH_CHECK $ iptables -A SSH_CHECK -m recent --set --name SSH $ iptables -A SSH_CHECK -m recent --update --seconds 120 --hitcount 5 --name SSH -j DROP
I locked out myself from ssh ? How do i fix it?
wow… nice, concise, and useful… thank you very much
Great tutorial, it worth to add:
iptables -t nat -X
which will clean chains in nat table too.
Thank you!
I’m having issues deleting a specific rule from my iptables. I used iptables -t nat -S to list the rule: -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to-source 192.168.111.111
and tried to delete it with: $ sudo iptables -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to-source 192.168.111.111 iptables: Bad rule (does a matching rule exist in that chain?).
I’m sure it’s just a syntax issue but I’m having trouble finding a reference that clears it up for me. Any help would be greatly appreciated.