Uncover the infinite in IT

Table of Contents
< All Topics

Setting up iptables-persistent

1. Purpose of the Script:

The purpose of this script is to simplify the deployment and initial configuration of iptables-persistent on a Debian-based system. It automates the process of installing iptables-persistent, creating rules based on user input for allowed hosts, ports, and protocols, and ensuring that the configured rules persist across reboots.

2. Creating the Script:

To create this script

#!/bin/bash

# Function to check if a command exists
command_exists() {
  command -v "$1" >/dev/null 2>&1
}

# Function to install iptables-persistent
install_iptables_persistent() {
    echo "Installing iptables-persistent..."
    apt update
    apt install -y iptables-persistent
}

# Function to enable iptables-persistent
enable_iptables_persistent() {
    echo "Enabling iptables-persistent..."
    systemctl enable netfilter-persistent
}

# Check if iptables-persistent is installed
if ! command_exists iptables-save; then
    install_iptables_persistent
fi

# Check if iptables-persistent is running
if ! /etc/init.d/netfilter-persistent status | grep -q "active"; then
    echo "Starting iptables-persistent service..."
    /etc/init.d/netfilter-persistent start
fi

# User Input - Choosing Host Type and Providing Details
echo "Choose the type of host input:"
echo "1) single"
echo "2) subnet"
echo "3) file"

read -p "Enter your choice: " host_type

case $host_type in
    1)
        read -p "Enter the IP of the host (e.g., 10.0.1.1/32): " host
        source_address="-s $host"
        ;;
    2)
        read -p "Enter the subnet (e.g., 10.0.1.0/24): " subnet
        source_address="-s $subnet"
        ;;
    3)
        read -p "Enter the full path to the hosts file: " hosts_file
        if [ -f "$hosts_file" ]; then
            source_address="-s $(cat "$hosts_file" | tr '\n' ',')"
        else
            echo "Error: File not found. Exiting."
            exit 1
        fi
        ;;
    *)
        echo "Invalid choice. Exiting."
        exit 1
        ;;
esac

# User Input - Ports and Protocol
read -p "Enter the port(s) you want to allow (comma-separated): " ports

echo "Choose the protocol:"
echo "1) tcp"
echo "2) udp"
echo "3) both"

read -p "Enter your choice: " protocol

# Proposed Rules
echo "Proposed rules:"
for p in $(echo $ports | tr ',' '\n'); do
    case $protocol in
        1)
            echo "iptables -A INPUT -p tcp --dport $p $source_address -j ACCEPT"
            ;;
        2)
            echo "iptables -A INPUT -p udp --dport $p $source_address -j ACCEPT"
            ;;
        3)
            echo "iptables -A INPUT -p tcp --dport $p $source_address -j ACCEPT"
            echo "iptables -A INPUT -p udp --dport $p $source_address -j ACCEPT"
            ;;
        *)
            echo "Invalid choice. Exiting."
            exit 1
            ;;
    esac
done

# User Confirmation
read -p "Is it OK to proceed? (y/n): " confirm

if [[ $confirm =~ ^[Yy]$ ]]; then
    # Flush the current rules
    iptables -F

    # Set INPUT to DROP as default
    iptables -P INPUT DROP

    # Allow loopback interface
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT

    # Allow established and related incoming connections
    iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

    # Add proposed rules to iptables
    for p in $(echo $ports | tr ',' '\n'); do
        case $protocol in
            1)
                iptables -A INPUT -p tcp --dport $p $source_address -j ACCEPT
                ;;
            2)
                iptables -A INPUT -p udp --dport $p $source_address -j ACCEPT
                ;;
            3)
                iptables -A INPUT -p tcp --dport $p $source_address -j ACCEPT
                iptables -A INPUT -p udp --dport $p $source_address -j ACCEPT
                ;;
            *)
                echo "Invalid choice. Exiting."
                exit 1
                ;;
        esac
    done

    # Save rules to /etc/iptables/rules.v4
    /etc/init.d/netfilter-persistent save

    echo "Firewall rules applied successfully."

    # Display current iptables rules
    echo "Current iptables rules:"
    iptables -nvL

else
    echo "Exiting without making changes."
fi

 follow these steps:

  1. Open a text editor on your Debian-based system (e.g., nano or vim).
  2. Copy and paste the script into the editor.
  3. Save the script with an appropriate name, such as firewall_setup.sh.
  4. Make the script executable by running: chmod +x firewall_setup.sh.

3. Script Overview:

The script performs the following steps:

  • Checks if iptables-persistent is installed, and installs it if not.
./firewall.sh
Installing iptables-persistent...
Hit:1 http://deb.debian.org/debian bullseye InRelease
Hit:2 http://security.debian.org bullseye-security InRelease
Get:3 http://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]
Fetched 44.1 kB in 0s (94.4 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
55 packages can be upgraded. Run 'apt list --upgradable' to see them.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  iptables libip6tc2 libnetfilter-conntrack3 libnfnetlink0 netfilter-persistent
Suggested packages:
  firewalld
The following NEW packages will be installed:
  iptables iptables-persistent libip6tc2 libnetfilter-conntrack3 libnfnetlink0 netfilter-persistent
0 upgraded, 6 newly installed, 0 to remove and 55 not upgraded.
Need to get 0 B/495 kB of archives.
After this operation, 2941 kB of additional disk space will be used.
Preconfiguring packages ...
Selecting previously unselected package libip6tc2:amd64.
(Reading database ... 20875 files and directories currently installed.)
Preparing to unpack .../libip6tc2_1.8.7-1_amd64.deb ...
Unpacking libip6tc2:amd64 (1.8.7-1) ...
Selecting previously unselected package libnfnetlink0:amd64.
Preparing to unpack .../libnfnetlink0_1.0.1-3+b1_amd64.deb ...
Unpacking libnfnetlink0:amd64 (1.0.1-3+b1) ...
Selecting previously unselected package libnetfilter-conntrack3:amd64.
Preparing to unpack .../libnetfilter-conntrack3_1.0.8-3_amd64.deb ...
Unpacking libnetfilter-conntrack3:amd64 (1.0.8-3) ...
Selecting previously unselected package iptables.
Preparing to unpack .../iptables_1.8.7-1_amd64.deb ...
Unpacking iptables (1.8.7-1) ...
Selecting previously unselected package netfilter-persistent.
Preparing to unpack .../netfilter-persistent_1.0.15_all.deb ...
Unpacking netfilter-persistent (1.0.15) ...
Setting up libip6tc2:amd64 (1.8.7-1) ...
Setting up libnfnetlink0:amd64 (1.0.1-3+b1) ...
Setting up libnetfilter-conntrack3:amd64 (1.0.8-3) ...
Setting up iptables (1.8.7-1) ...
update-alternatives: using /usr/sbin/iptables-legacy to provide /usr/sbin/iptables (iptables) in auto mode
update-alternatives: using /usr/sbin/ip6tables-legacy to provide /usr/sbin/ip6tables (ip6tables) in auto mode
update-alternatives: using /usr/sbin/iptables-nft to provide /usr/sbin/iptables (iptables) in auto mode
update-alternatives: using /usr/sbin/ip6tables-nft to provide /usr/sbin/ip6tables (ip6tables) in auto mode
update-alternatives: using /usr/sbin/arptables-nft to provide /usr/sbin/arptables (arptables) in auto mode
update-alternatives: using /usr/sbin/ebtables-nft to provide /usr/sbin/ebtables (ebtables) in auto mode
Selecting previously unselected package iptables-persistent.
(Reading database ... 21104 files and directories currently installed.)
Preparing to unpack .../iptables-persistent_1.0.15_all.deb ...
Unpacking iptables-persistent (1.0.15) ...
Setting up netfilter-persistent (1.0.15) ...
Setting up iptables-persistent (1.0.15) ...
update-alternatives: using /lib/systemd/system/netfilter-persistent.service to provide /lib/systemd/system/iptables.service (iptables.service) in auto mode
Processing triggers for man-db (2.9.4-2) ...
Processing triggers for libc-bin (2.31-13+deb11u5) ...
  • Checks if iptables-persistent is running, and starts it if not.
  • Asks the user for the type of host input (single host, subnet, or file containing multiple hosts).
Choose the type of host input:
1) single
2) subnet
3) file
Enter your choice: 2
Enter the subnet (e.g., 10.0.1.0/24): 10.0.1.0/24
  • Based on user input, gathers information about the source addresses (IP or subnet).
Enter the subnet (e.g., 10.0.1.0/24): 10.0.1.0/24
  • Prompts the user for the ports and protocol type (TCP, UDP, or both).
Enter the port(s) you want to allow (comma-separated): 22,80,443
Choose the protocol:
1) tcp
2) udp
3) both
Enter your choice: 3
  • Displays proposed rules based on user input.
Proposed rules:
iptables -A INPUT -p tcp --dport 22 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p udp --dport 22 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p udp --dport 80 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p udp --dport 443 -s 10.0.1.0/24 -j ACCEPT
  • Asks the user for confirmation before applying the rules.
Is it OK to proceed? (y/n): y
  • Flushes existing rules and sets the default policy to DROP.
  • Allows loopback traffic, established, and related connections.
  • Adds user-specified rules to iptables.
  • Saves rules to /etc/iptables/rules.v4.
Saving netfilter rules...run-parts: executing /usr/share/netfilter-persistent/plugins.d/15-ip4tables save
run-parts: executing /usr/share/netfilter-persistent/plugins.d/25-ip6tables save
done.
Firewall rules applied successfully.
  • Displays the current iptables rules.
Current iptables rules:
Chain INPUT (policy DROP 1 packets, 40 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
    2    80 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       10.0.1.0/24          0.0.0.0/0            tcp dpt:22
    0     0 ACCEPT     udp  --  *      *       10.0.1.0/24          0.0.0.0/0            udp dpt:22
    0     0 ACCEPT     tcp  --  *      *       10.0.1.0/24          0.0.0.0/0            tcp dpt:80
    0     0 ACCEPT     udp  --  *      *       10.0.1.0/24          0.0.0.0/0            udp dpt:80
    0     0 ACCEPT     tcp  --  *      *       10.0.1.0/24          0.0.0.0/0            tcp dpt:443
    0     0 ACCEPT     udp  --  *      *       10.0.1.0/24          0.0.0.0/0            udp dpt:443

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0

This example demonstrates the user interaction, proposed rules, and the resulting iptables configuration.