I followed this tutorial to set up IP rules on ubuntu 12.04. Everything worked fine on setup -- but now I've made changes to the firewall that do not persist upon reboot. I do not understand why that is. Here is a demonstration of how I am using iptables-persistent. What am I doing wrong?

$ sudo service iptables-persistent start
 * Loading iptables rules...                                                                                             *  IPv4...                                                                                                              *  IPv6...   

$ sudo iptables -L   //shows a certain rule
$ iptables -D INPUT ... //command successfully drops the rule
$ sudo iptables -L   //shows rule has been deleted

 $ sudo service iptables-persistent restart
 * Loading iptables rules...                                                                                             *  IPv4...                                                                                                              *  IPv6...                                                                                                      [ OK ] 
 $ sudo iptables -L  //rule is back
  • I'm noticing the iptables -D INPUT rule isn't in sudo are you sure it's actually reporting a success? Does the behavior change if you do run it within sudo?
    – Bratchley
    Apr 21 '14 at 16:29

iptables-persistent does not work that way. Restarting the iptables-persistent "service" does not capture the current state of the iptables and save it; all it does is reinstate the iptables rules that were saved when the package was last configured.

To configure iptables-persistent, you need to tell it about your current iptables ruleset.

One way to accomplish that is as follows:

iptables-save >/etc/iptables/rules.v4
ip6tables-save >/etc/iptables/rules.v6

Or, equivalently, the iptables-persistent package also provides the following:

dpkg-reconfigure iptables-persistent

(You will need to answer yes to the questions about whether to save the rules.)

After that, the next time iptables-persistent is started/restarted, the iptables rulesets you expect will be loaded.

  • make sure you don't have anything like firewall-cmd which would block iptables-persistent changes and load its own rules ahead Jun 14 '20 at 5:42
  • PLEASE README! As @lvan Avdonin said above. YOU MUST DISABLE firewalld, or it will load its own iptables rules, and will override your own /etc/iptables/rules.v4
    – nuclear
    Jan 31 at 16:20

Very simple way to save the current iptables rules is to use the command:

sudo service netfilter-persistent save

Using the above, which works at least in Ubuntu after installing the netfilter-persistent (and iptables-persistent) package, there is no need to run manually the iptables commands or to reconfigure the package (as suggested by even the accepted Answer above).

  • Is it sudo service netfilter-persistent save or sudo service netfilter-persistent save . ? (Dot at the end.)
    – user147505
    Feb 27 '18 at 15:15
  • Thanks for noting that, the correct command is w/o the dot at the end of line. Corrected the Answer accordingly.
    – OpenITeX
    Nov 23 '18 at 22:26

Install iptables-persistent:

sudo apt install iptables-persistent

save rules after making desired changes:

sudo netfilter-persistent save
  • How can I stop the install of iptables-persistent to ask me question. Even with apt-get install -y --no-install-recommends iptables-persistent I still get questions that prevent any automated installation. Dec 21 '20 at 17:12
  • sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install iptables-persistent
    – Ajax
    Sep 27 at 13:29
$ iptables ... DROP //command successfully drops the rule
$ sudo iptables -L   //shows rule has been deleted

That's not what DROP means or does. From man iptables:

...the special values ACCEPT, DROP, QUEUE or RETURN. ACCEPT means to let the packet through. DROP means to drop the packet on the floor. QUEUE means...

So what you've done is add a new rule. It may effectively supersede any number of other rules, but those rules still exist.

When checking stuff like this (your iptables -L output), I would feed it though grep "string unique to this rule" rather than use your eyes. It's easier and faster to do, and less error prone.

iptables -L | grep "some unique string"

If you want to delete a rule, use the -D switch; the man page describes two forms of this:

-D, --delete chain rule-specification

-D, --delete chain rulenum

Delete one or more rules from the selected chain. There are two versions of this command: the rule can be specified as a number in the chain (starting at 1 for the first rule) or a rule to match.

  • sorry that was unclear. I am using the -D option to DROP a rule. See the change above
    – bernie2436
    Apr 21 '14 at 16:13
  • 4
    -D stands for "delete" not "DROP" Using the term "DROP" to mean anything other than a jump target when talking about iptables is confusing as hell.
    – Bratchley
    Apr 21 '14 at 16:27

As explained by @steven-monday, you can save your rule set by yourself in the proper directory (namely: /etc/iptables/rules.v{4,6}).

However, @OpenITeX is right: calling the save action of service netfilter-persistent is better.

As of today (in 18.10), iptables-save is builtin, but iptables-persistent is not installed. Hence, the plugin directory called by service netfilter-persistent is empty, and service prints out that the ruleset was saved, whereas it was not.

TLDR: install iptables-persistent and check that the plugin directory /usr/share/netfilter-persistent/plugins.d contains plugins.

Here is how I figured that out:

$ cat /etc/init.d/netfilter-persistent 
case "$1" in
    log_action_begin_msg "Saving netfilter rules"
    /usr/sbin/netfilter-persistent save
    log_action_end_msg $?

Then check the /usr/sbin/netfilter-persistent script, notice it invokes external scripts:

$ cat /usr/sbin/netfilter-persistent
run_plugins () {
    if [ -d ${PLUGINS} ]; then
        run-parts -v -a ${1} ${PLUGINS}

case $1 in
    run_plugins ${1}

Then I noticed that /usr/share/netfilter-persistent/plugins.d was empty.

Not the answer you're looking for? Browse other questions tagged or ask your own question.