Search This Blog

simple iptables firewall script

#!/bin/sh
### BEGIN INIT INFO
# Provides:          iptables
# Required-Start:    mountkernfs $local_fs
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Set up iptables rules
### END INIT INFO

#============================================================================#
# Settings                                                                   #
#============================================================================#

# iptables
IPT=/sbin/iptables

# set to 0 to disable logging drop
LOG_DROP=1

# set to 1 to enable logging accept
LOG_ACCEPT=0

# log prefix (do not change if you do not know what you are doing)
LOG_PREFIX="[IPTABLES "

# chain for logging drops
LOG_DROP_CHAIN="LOGDROP"

# chain for logging accepts
LOG_ACCEPT_CHAIN="LOGACCEPT"

# log_drop prefix (do not change if you do not know what you are doing)
LOG_DROP_PREFIX="${LOG_PREFIX}DROP"

# log_accept prefix (do not change if you do not know what you are doing)
LOG_ACCEPT_PREFIX="${LOG_PREFIX}ACCEPT"

#============================================================================#
# Functions                                                                  #
#============================================================================#

reset() {

    # Reset the default policies to accept everything
    $IPT --policy INPUT   ACCEPT
    $IPT --policy OUTPUT  ACCEPT
    $IPT --policy FORWARD ACCEPT

    # Flush/Remove all rules
    $IPT --flush

    # Delete all custom chains
    $IPT --delete-chain

    # Zero counters
    $IPT --zero

    # Reset all built-in tables (nat, mangle and filter)
    for table in filter nat mangle; do
        $IPT -t $table -F
        $IPT -t $table -X
        $IPT -t $table -Z
    done

}

status() {

    echo "============================================================"
    echo "= Filter Rules:                                            ="
    echo "============================================================"
    $IPT -L -v
    echo ""

    echo "============================================================"
    echo "= NAT Rules:                                               ="
    echo "============================================================"
    $IPT -t nat -L -v
    echo ""

    echo "============================================================"
    echo "= Mangle Rules:                                            ="
    echo "============================================================"
    $IPT -t mangle -L -v
    echo ""

}

start() {

    # Reset iptables (remove all rules & chains; reset default policies to accept everything)
    reset

    # Set default policies for all three default chains
    $IPT -P INPUT DROP
    $IPT -P FORWARD DROP
    $IPT -P OUTPUT ACCEPT

    # create LOGDROP chain
    $IPT -N ${LOG_DROP_CHAIN}
    $IPT -A ${LOG_DROP_CHAIN} -m limit --limit 3/m --limit-burst 10 -j LOG --log-level 4 --log-prefix "${LOG_DROP_PREFIX}"
    $IPT -A ${LOG_DROP_CHAIN} -j DROP

    # create LOGACCEPT chain
    $IPT -N ${LOG_ACCEPT_CHAIN}
    $IPT -A ${LOG_ACCEPT_CHAIN} -m limit --limit 3/m --limit-burst 10 -j LOG --log-level 6 --log-prefix "${LOG_ACCEPT_PREFIX}"
    $IPT -A ${LOG_ACCEPT_CHAIN} -j ACCEPT

    # Log or not drops
    DROP_TARGET=${LOG_DROP_CHAIN}
    if [ "${LOG_DROP}" -eq 0 ]; then
        DROP_TARGET=DROP
    fi

    # Log or not accepts
    ACCEPT_TARGET=ACCEPT
    if [ "${LOG_ACCEPT}" -eq 1 ]; then
        ACCEPT_TARGET=${LOG_ACCEPT_CHAIN}
    fi

    # Accept loopback interfaces
    $IPT -A INPUT -i lo -j ACCEPT
    $IPT -A OUTPUT -o lo -j ACCEPT

    # Log & drop packets do not begin with SYN
    $IPT -A INPUT -p tcp ! --syn -m state --state NEW -s 0.0.0.0/0 -j ${DROP_TARGET}

    # Accept inbound TCP packets
    $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

####### CUSTOM RULES BEGIN

    # Accept ssh connections from subnet 192.168.2.0/24
    $IPT -A INPUT -p tcp --dport 22 -m state --state NEW -s 192.168.2.0/24 -j ${ACCEPT_TARGET}

    # Accept ssh connections from remote ip 172.23.65.1
    $IPT -A INPUT -p tcp --dport 22 -m state --state NEW -s 172.23.65.1/32 -j ${ACCEPT_TARGET}

    # Accept ssh connections from subnet 192.168.1.0/24 and mac address is 11:22:33:44:55:66
    $IPT -A INPUT -p tcp --dport 22 -m state --state NEW -m mac --mac-source 11:22:33:44:55:66 -s 192.168.1.0/24 -j ${ACCEPT_TARGET}

    # Accept http connections from anywhere
    $IPT -A INPUT -p tcp --dport 80 -m state --state NEW -s 0.0.0.0/0 -j ${ACCEPT_TARGET}

####### CUSTOM RULES END

    # Accept inbound ICMP messages
    $IPT -A INPUT -p ICMP --icmp-type 8 -s 0.0.0.0/0 -j ACCEPT

    # Drop all other traffic
    $IPT -A INPUT -j ${DROP_TARGET}
}

#============================================================================#
# Main                                                                       #
#============================================================================#

case "$1" in
  start|restart)
    start
    echo "iptables firewall enabled."
    ;;
  stop)
    reset
    echo "iptables firewall disabled."
    ;;
  status)
    status
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}" >&2
    exit 1
    ;;
esac

exit 0

NOTE:

  • Click here to download the script;
  • You can add your rules between ####### CUSTOM RULES BEGIN and ####### CUSTOM RULES END section by modifying the script.
  • To install the script as startup script on Ubuntu/Debian Linux:
    sudo cp iptables.sh /etc/init.d/
    sudo update-rc.d iptables.sh defaults
    
  • To start the iptables firewall:
    sudo /etc/init.d/iptables.sh start
  • To enable logging on Ubuntu Linux, you also need to do this.

No comments:

Post a Comment