By default, Kali Linux doesn’t use a firewall in its network interfaces. Although Kali is silent on the network on its default setting, nothing is stopping you from starting up services. And some of the most popular tools are starting up network services (and using default username/password combination)!

So just to play on the safe side, let’s configure one!

Basic Iptables rules

Basic rules allow everything out and nothing in. There are plenty of tutorials on the net how you can do this, but let’s recap it here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Run as root:
# Set OUTPUT chain default actions as ACCEPT (Should be default)
iptables -A OUTPUT -p ACCEPT
# Allow all already established TCP connection packets to pass
iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
# Allow all already established UDP connection packets to pass
iptables -A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT
# Allow all already established ICMP connection packets to pass
iptables -A INPUT -p icmp -m state --state ESTABLISHED -j ACCEPT
# Allow all localhost traffic to pass
iptables -A INPUT -i lo -j ACCEPT
# Create new chain "LOGGING"
iptables -N LOGGING
# Log everything that has not been accepted yet (and transfer packet to LOGGING chain)
iptables -A INPUT -j LOGGING
# Log all (soon to be) dropped packets
iptables -A LOGGING -m limit --limit 1/sec -j LOG --log-prefix "IPTables packet DROP: " --log-level 7
# Drop the packet
iptables -A LOGGING -j DROP

Now you can verify your configuration with

1
iptables -L

and it should list it as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere state ESTABLISHED
ACCEPT udp -- anywhere anywhere state ESTABLISHED
ACCEPT icmp -- anywhere anywhere state ESTABLISHED
ACCEPT all -- anywhere anywhere
LOGGING all -- anywhere anywhere

Chain FORWARD (policy DROP)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain LOGGING (1 references)
target prot opt source destination
LOG all -- anywhere anywhere limit: avg 1/sec burst 5 LOG level debug prefix "IPTables packet DROP: "
DROP all -- anywhere anywhere

Saving and loading iptables rules

Now, if you reboot your computer, your hardly created rules will vanish into the thin air. So we need to make iptables persistent to survive reboots and shutdowns. In some Linux distros, you can use

1
service iptables save

(RHEL / CENTOS) or

1
iptables-save > /etc/sysconfig/iptables.rules

to save iptables rules.

In Kali Linux, which is Debian based, there is no ready-made solution (or as far as I know).  First, we need to save the running configuration to a configuration file. Fortunately, iptables-save is available to us. iptables-save prints out the iptables configuration which another program, called iptables-restore will understand.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
iptables-save
# Generated by iptables-save v1.6.1 on Sun Dec 17 00:35:03 2017
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [38628:4592419]
:LOGGING - [0:0]
-A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p icmp -m state --state ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j LOGGING
-A LOGGING -m limit --limit 1/sec -j LOG --log-prefix "IPTables packet DROP: " --log-level 7
-A LOGGING -j DROP
COMMIT
# Completed on Sun Dec 17 00:35:03 2017

Now we can forward the output of iptables-save to the configuration file, ie. /etc/iptables/iptables.rules. You can create the /etc/iptables directory if it doesn’t yet exist.

1
iptables-save > /etc/iptables/iptables.rules

Now we can test the loading of the rules by first flushing the active rules:

1
iptables -F

Let’s verify that the iptables rules are empty:

1
2
3
4
5
6
7
8
9
10
11
12
13
iptables -L
# Output of the iptables -L command
Chain INPUT (policy DROP)
target     prot opt source               destination        

Chain FORWARD (policy DROP)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

Chain LOGGING (0 references)
target     prot opt source               destination

And reloading the rules with iptables-restore:

1
2
3
4
#Load the saved rules
iptables-restore < /etc/iptables/iptables.rules
#And let's verify that rules are loaded correctly
iptables -L

Making the iptables rules persistent

Now that we have the rules in the configuration file, we need to make Kali load these rules before taking the network up. You can add the following code to load the firewall in example /etc/network/if-pre-up.d/iptables file (create if does not exist).

1
2
3
4
5
6
7
8
#!/bin/bash
printf "%-50s" "Bringing up the iptables rules..."
/sbin/iptables-restore < /etc/iptables/iptables.rules
if [ $? -eq 0 ]; then
        printf "%s\n" "OK"
else
        printf "%s\n" "Fail"
fi

Make the script executable:

1
chmod +x /etc/network/if-pre-up.d/iptables

In order to clearly flush the rules (not necessary), we make the script to flush the rules. Create or edit /etc/network/if-post-down.d/iptables and make the file contents as following:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
printf "%-50s" "Flushing iptables rules..."
#Optionally save running config, to enable saving just uncomment following line
#iptables-save > /etc/iptables/iptables.rules
#And Flush the iptables rules
iptables -F
if [ $? -eq 0 ]; then
        printf "%s\n" "OK"
else
        printf "%s\n" "Fail"
fi

And remember to make script executable before testing:

1
chmod +x /etc/network/if-post-down.d/iptables

And finally test the loading and flushing:

1
2
3
4
service networking stop
iptables -L
service networking start
iptables -L

Stay safe out there!
-WreckedSec

5 Replies to “How to make Kali Linux Iptables Firewall Persistent”

  1. little refuse:

    in the BASIC IPTABLES RULE code you wrote: iptables -A OUTPUT -p ACCEPT, have to change in iptables -A OUTPUT -j ACCEPT.

    and in the script for persistent:
    #!/bin/bash
    printf “%-50s” “Bringing up the iptables rules…”
    /sbin/iptables-restore < /etc/iptables/rules.v4
    if [ $? -eq 0 ]; then
    printf "%s\n" "OK"
    else
    printf "%s\n" "Fail"
    fi

    have to change the restore file with the one you have created first

    #!/bin/bash
    printf "%-50s" "Bringing up the iptables rules…"
    /sbin/iptables-restore < /etc/iptables/iptables.rules
    if [ $? -eq 0 ]; then
    printf "%s\n" "OK"
    else
    printf "%s\n" "Fail"
    fi

    THank you for the post, it worked for me !

    1. Hi and thanks for pointing out that typo. I used the rules.v4 naming scheme on my personal Kali and I decided to use uptables.rules filename in the tutorial. Of course I forgot to renew the filename when I copy & pasted the script from my own computer to the blog. That typo should be fixed by now in the blog.

      I’m glad that I could help you out on this!

      Cheers,
      WreckedSec

  2. From a security perspective it would be wise to also add rules for IPv6. A default policy could look like that:

    ip6tables -P INPUT DROP
    ip6tables -P FORWARD DROP
    ip6tables -P OUTPUT ACCEPT

    1. Definitely! It’s good practice to prepare for the IPv6 even if your ISP / network does not yet support it! And also note that, even if your network doesn’t support it, your device will generate link local address which can be used to access devices in same local network (L2).

  3. What do you recommend in this rule:
    Which is better?
    iptables -A INPUT -p tcp -m state –state ESTABLISHED -j ACCEPT
    or
    iptables -A INPUT -m conntrack –ctstate ESTABLISHED,RELATED -j ACCEPT

    So which is better “-m state or -m conntrack”?
    Note: Sometimes I use a simple web server for file sharing on local network.

Leave a Reply to Istvan Vegh Cancel reply

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