Skip to content

Instantly share code, notes, and snippets.

@ponceto
Last active February 6, 2023 17:27
Show Gist options
  • Save ponceto/1bdb7e2d0be58116be65ab9d0731ecd0 to your computer and use it in GitHub Desktop.
Save ponceto/1bdb7e2d0be58116be65ab9d0731ecd0 to your computer and use it in GitHub Desktop.
A KISS firewall script based on iptables

KISS firewall

Abstract

These scripts are written to help you harden your Linux server.

Description

The firewall.sh script supports up to 3 interfaces :

  • one wan interface connected to the internet.
  • two lan interfaces connected to different local networks.

For simplicity and performance reasons, the script will create some chains for each provided network interface.

  • WAN0_INPUT : input chain for the wan interface
  • LAN1_INPUT : input chain for the 1st lan interface
  • LAN2_INPUT : input chain for the 2nd lan interface

Architecture example:

   The Internet                    |      Your Private Networks            +--------> [Backend 1]
                                   |                                       |
  Wild Wild World                  |                                       +--------> [Backend 2]
                                   |                                       |
                                   |                                       +--------> [Backend 3]
                                   |                                       |
                        +--[ Reverse-Proxy ]--+           LAN 1            +--------> [Backend 4]
                        |                     |                            |
                        |                LAN1 +-->--[192.168.100.O/24]-->--+
                        |                     |                            
                        |                     |                            
O--<->--[x.x.x.x]--<->--+ WAN0                |                            
                        |                     |                            
                        |                     |                            
                        |                LAN2 +-->--[192.168.200.O/24]-->--+
                        |                     |                            |
                        +---------------------+           LAN 2            +--------> [Backend 5]
                                   |                                       |
                                   |                                       +--------> [Backend 6]
                                   |                                       |
                                   |                                       +--------> [Backend 7]
                                   |                                       |
                                   |                                       +--------> [Backend 8]

Dependencies

You should install iptables and iptable-persistent on your system.

Example for a Debian like operating system :

apt-get install iptables iptables-persistent

Apply the firewall rules

With the firewall.sh script you can play with the basic iptables rules to harden your server.

You can optionally edit the script and adjust the default rules.

./firewall.sh [OPTIONS]
Usage: firewall.sh [OPTIONS]

Options:

    --wan0={network-interface}    specifies the WAN0 network interface
    --lan1={network-interface}    specifies the LAN1 network interface
    --lan2={network-interface}    specifies the LAN2 network interface
    --wan0-icmp={target}          ACCEPT, REJECT or DROP
    --wan0-ssh={target}           ACCEPT, REJECT or DROP
    --wan0-smtp={target}          ACCEPT, REJECT or DROP
    --wan0-http={target}          ACCEPT, REJECT or DROP
    --wan0-https={target}         ACCEPT, REJECT or DROP
    --wan0-default={target}       ACCEPT, REJECT or DROP
    --lan1-icmp={target}          ACCEPT, REJECT or DROP
    --lan1-ssh={target}           ACCEPT, REJECT or DROP
    --lan1-default={target}       ACCEPT, REJECT or DROP
    --lan2-icmp={target}          ACCEPT, REJECT or DROP
    --lan2-ssh={target}           ACCEPT, REJECT or DROP
    --lan2-default={target}       ACCEPT, REJECT or DROP
    --ipv4                        apply only IPv4 rules
    --ipv6                        apply only IPv6 rules
    --list                        display the rules and exit
    --help                        display this help and exit

Environment variables:

    WAN0                          specifies the WAN0 interface
    LAN1                          specifies the LAN1 interface
    LAN2                          specifies the LAN2 interface

    IP4TABLES                     iptables for IPv4 rules (defaults to iptables)
    IP6TABLES                     iptables for IPv6 rules (defaults to ip6tables)

Examples:

./firewall.sh --wan0=ens18
./firewall.sh --wan0=ens18 --lan1=ens19
./firewall.sh --wan0=ens18 --lan1=ens19 --lan2=ens20

You can then print the rules applied with iptables for IPv4 or ip6tables for IPv6:

root@hostname:~# iptables -L -n -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 WAN0_INPUT  all  --  ens18  *       0.0.0.0/0            0.0.0.0/0           
    0     0 LAN1_INPUT  all  --  ens19  *       0.0.0.0/0            0.0.0.0/0           
    0     0 LAN2_INPUT  all  --  ens20  *       0.0.0.0/0            0.0.0.0/0           

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         

Chain LAN1_INPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  ens19  *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     icmp --  ens19  *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     tcp  --  ens19  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
    0     0 DROP       all  --  ens19  *       0.0.0.0/0            0.0.0.0/0           

Chain LAN2_INPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  ens20  *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     icmp --  ens20  *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     tcp  --  ens20  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
    0     0 DROP       all  --  ens20  *       0.0.0.0/0            0.0.0.0/0           

Chain WAN0_INPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  ens18  *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     icmp --  ens18  *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     tcp  --  ens18  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
    0     0 REJECT     tcp  --  ens18  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:25 reject-with icmp-port-unreachable
    0     0 ACCEPT     tcp  --  ens18  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    0     0 ACCEPT     tcp  --  ens18  *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443
    0     0 DROP       all  --  ens18  *       0.0.0.0/0            0.0.0.0/0           

Persist the firewall rules

If you are sufficiently confident, you can use netfilter-persistent save to persist your rules.

Alternatively, you can use the save-firewall-rules.sh script to :

  • clear the counters
  • persist the firewall rules
./save-firewall-rules.sh

After that, the rules are persisted into :

  • /etc/iptables/rules.v4 for IPv4 rules
  • /etc/iptables/rules.v6 for IPv6 rules
#!/bin/sh
#
# firewall.sh - Copyright (c) 2019-2021 - Olivier Poncet
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
# ----------------------------------------------------------------------------
# program options
# ----------------------------------------------------------------------------
opt_script="${0}"
opt_error='no'
opt_usage='no'
opt_proto='all'
opt_list='no'
# ----------------------------------------------------------------------------
# the network interfaces : eth0, eno1, ens18, enp3s0, etc ...
# ----------------------------------------------------------------------------
wan0="${WAN0:-not-set}"
lan1="${LAN1:-not-set}"
lan2="${LAN2:-not-set}"
# ----------------------------------------------------------------------------
# ip4tables & ip6tables
# ----------------------------------------------------------------------------
ip4tables="${IP4TABLES:-not-found}"
ip6tables="${IP6TABLES:-not-found}"
# ----------------------------------------------------------------------------
# IPv4 rules (ACCEPT, REJECT or DROP)
# ----------------------------------------------------------------------------
DFLT_IPV4_INPUT_____TARGET='ACCEPT'
DFLT_IPV4_FORWARD___TARGET='ACCEPT'
DFLT_IPV4_OUTPUT____TARGET='ACCEPT'
WAN0_IPV4_CONNTRACK_TARGET='ACCEPT'
WAN0_IPV4_ICMP______TARGET='ACCEPT'
WAN0_IPV4_SSH_______TARGET='ACCEPT'
WAN0_IPV4_SMTP______TARGET='REJECT'
WAN0_IPV4_HTTP______TARGET='REJECT'
WAN0_IPV4_HTTPS_____TARGET='REJECT'
WAN0_IPV4_DEFAULT___TARGET='DROP'
LAN1_IPV4_CONNTRACK_TARGET='ACCEPT'
LAN1_IPV4_ICMP______TARGET='ACCEPT'
LAN1_IPV4_SSH_______TARGET='ACCEPT'
LAN1_IPV4_DEFAULT___TARGET='DROP'
LAN2_IPV4_CONNTRACK_TARGET='ACCEPT'
LAN2_IPV4_ICMP______TARGET='ACCEPT'
LAN2_IPV4_SSH_______TARGET='ACCEPT'
LAN2_IPV4_DEFAULT___TARGET='DROP'
# ----------------------------------------------------------------------------
# IPv6 rules (ACCEPT, REJECT or DROP)
# ----------------------------------------------------------------------------
DFLT_IPV6_INPUT_____TARGET='ACCEPT'
DFLT_IPV6_FORWARD___TARGET='ACCEPT'
DFLT_IPV6_OUTPUT____TARGET='ACCEPT'
WAN0_IPV6_CONNTRACK_TARGET='ACCEPT'
WAN0_IPV6_ICMP______TARGET='ACCEPT'
WAN0_IPV6_SSH_______TARGET='ACCEPT'
WAN0_IPV6_SMTP______TARGET='REJECT'
WAN0_IPV6_HTTP______TARGET='REJECT'
WAN0_IPV6_HTTPS_____TARGET='REJECT'
WAN0_IPV6_DEFAULT___TARGET='DROP'
LAN1_IPV6_CONNTRACK_TARGET='ACCEPT'
LAN1_IPV6_ICMP______TARGET='ACCEPT'
LAN1_IPV6_SSH_______TARGET='ACCEPT'
LAN1_IPV6_DEFAULT___TARGET='DROP'
LAN2_IPV6_CONNTRACK_TARGET='ACCEPT'
LAN2_IPV6_ICMP______TARGET='ACCEPT'
LAN2_IPV6_SSH_______TARGET='ACCEPT'
LAN2_IPV6_DEFAULT___TARGET='DROP'
# ----------------------------------------------------------------------------
# parse the command-line
# ----------------------------------------------------------------------------
while [ "${#}" -gt '0' ] && [ "${opt_error}+${opt_usage}" = 'no+no' ]
do
case "${1}" in
*=*)
arg_value="$(expr "${1}" : '[^=]*=\(.*\)')"
;;
*)
arg_value=""
;;
esac
case "${1}" in
--wan0=*)
wan0="${arg_value}"
;;
--lan1=*)
lan1="${arg_value}"
;;
--lan2=*)
lan2="${arg_value}"
;;
--wan0-icmp=*)
WAN0_IPV4_ICMP______TARGET="${arg_value}"
WAN0_IPV6_ICMP______TARGET="${arg_value}"
;;
--wan0-ssh=*)
WAN0_IPV4_SSH_______TARGET="${arg_value}"
WAN0_IPV6_SSH_______TARGET="${arg_value}"
;;
--wan0-smtp=*)
WAN0_IPV4_SMTP______TARGET="${arg_value}"
WAN0_IPV6_SMTP______TARGET="${arg_value}"
;;
--wan0-http=*)
WAN0_IPV4_HTTP______TARGET="${arg_value}"
WAN0_IPV6_HTTP______TARGET="${arg_value}"
;;
--wan0-https=*)
WAN0_IPV4_HTTPS_____TARGET="${arg_value}"
WAN0_IPV6_HTTPS_____TARGET="${arg_value}"
;;
--wan0-default=*)
WAN0_IPV4_DEFAULT___TARGET="${arg_value}"
WAN0_IPV6_DEFAULT___TARGET="${arg_value}"
;;
--lan1-icmp=*)
LAN1_IPV4_ICMP______TARGET="${arg_value}"
LAN1_IPV6_ICMP______TARGET="${arg_value}"
;;
--lan1-ssh=*)
LAN1_IPV4_SSH_______TARGET="${arg_value}"
LAN1_IPV6_SSH_______TARGET="${arg_value}"
;;
--lan1-default=*)
LAN1_IPV4_DEFAULT___TARGET="${arg_value}"
LAN1_IPV6_DEFAULT___TARGET="${arg_value}"
;;
--lan2-icmp=*)
LAN2_IPV4_ICMP______TARGET="${arg_value}"
LAN2_IPV6_ICMP______TARGET="${arg_value}"
;;
--lan2-ssh=*)
LAN2_IPV4_SSH_______TARGET="${arg_value}"
LAN2_IPV6_SSH_______TARGET="${arg_value}"
;;
--lan2-default=*)
LAN2_IPV4_DEFAULT___TARGET="${arg_value}"
LAN2_IPV6_DEFAULT___TARGET="${arg_value}"
;;
--ipv4)
opt_proto='ipv4'
;;
--ipv6)
opt_proto='ipv6'
;;
--list)
opt_list='yes'
;;
--help)
opt_usage='yes'
;;
*)
opt_error='yes'
echo "Error: invalid argument ${1}"
;;
esac
shift
done
# ----------------------------------------------------------------------------
# display usage if needed
# ----------------------------------------------------------------------------
if [ "${opt_error}+${opt_usage}" != 'no+no' ]
then
cat << ____EOF
Usage: $(basename "${opt_script}") [OPTIONS]
Options:
--wan0={network-interface} specifies the WAN0 network interface
--lan1={network-interface} specifies the LAN1 network interface
--lan2={network-interface} specifies the LAN2 network interface
--wan0-icmp={target} ACCEPT, REJECT or DROP
--wan0-ssh={target} ACCEPT, REJECT or DROP
--wan0-smtp={target} ACCEPT, REJECT or DROP
--wan0-http={target} ACCEPT, REJECT or DROP
--wan0-https={target} ACCEPT, REJECT or DROP
--wan0-default={target} ACCEPT, REJECT or DROP
--lan1-icmp={target} ACCEPT, REJECT or DROP
--lan1-ssh={target} ACCEPT, REJECT or DROP
--lan1-default={target} ACCEPT, REJECT or DROP
--lan2-icmp={target} ACCEPT, REJECT or DROP
--lan2-ssh={target} ACCEPT, REJECT or DROP
--lan2-default={target} ACCEPT, REJECT or DROP
--ipv4 apply only IPv4 rules
--ipv6 apply only IPv6 rules
--list display the rules and exit
--help display this help and exit
Environment variables:
WAN0 specifies the WAN0 interface
LAN1 specifies the LAN1 interface
LAN2 specifies the LAN2 interface
IP4TABLES iptables for IPv4 rules (defaults to iptables)
IP6TABLES iptables for IPv6 rules (defaults to ip6tables)
____EOF
exit 1
fi
# ----------------------------------------------------------------------------
# display list if needed
# ----------------------------------------------------------------------------
if [ "${opt_list}" != 'no' ]
then
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv4' ]
then
cat << ________EOF
DFLT_IPV4_INPUT = ${DFLT_IPV4_INPUT_____TARGET}
DFLT_IPV4_FORWARD = ${DFLT_IPV4_FORWARD___TARGET}
DFLT_IPV4_OUTPUT = ${DFLT_IPV4_OUTPUT____TARGET}
________EOF
if [ "${wan0:-not-set}" != 'not-set' ]
then
cat << ____________EOF
WAN0_IPV4_CONNTRACK = ${WAN0_IPV4_CONNTRACK_TARGET}
WAN0_IPV4_ICMP = ${WAN0_IPV4_ICMP______TARGET}
WAN0_IPV4_SSH = ${WAN0_IPV4_SSH_______TARGET}
WAN0_IPV4_SMTP = ${WAN0_IPV4_SMTP______TARGET}
WAN0_IPV4_HTTP = ${WAN0_IPV4_HTTP______TARGET}
WAN0_IPV4_HTTPS = ${WAN0_IPV4_HTTPS_____TARGET}
WAN0_IPV4_DEFAULT = ${WAN0_IPV4_DEFAULT___TARGET}
____________EOF
fi
if [ "${lan1:-not-set}" != 'not-set' ]
then
cat << ____________EOF
LAN1_IPV4_CONNTRACK = ${LAN1_IPV4_CONNTRACK_TARGET}
LAN1_IPV4_ICMP = ${LAN1_IPV4_ICMP______TARGET}
LAN1_IPV4_SSH = ${LAN1_IPV4_SSH_______TARGET}
LAN1_IPV4_DEFAULT = ${LAN1_IPV4_DEFAULT___TARGET}
____________EOF
fi
if [ "${lan2:-not-set}" != 'not-set' ]
then
cat << ____________EOF
LAN2_IPV4_CONNTRACK = ${LAN2_IPV4_CONNTRACK_TARGET}
LAN2_IPV4_ICMP = ${LAN2_IPV4_ICMP______TARGET}
LAN2_IPV4_SSH = ${LAN2_IPV4_SSH_______TARGET}
LAN2_IPV4_DEFAULT = ${LAN2_IPV4_DEFAULT___TARGET}
____________EOF
fi
fi
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv6' ]
then
cat << ________EOF
DFLT_IPV6_INPUT = ${DFLT_IPV6_INPUT_____TARGET}
DFLT_IPV6_FORWARD = ${DFLT_IPV6_FORWARD___TARGET}
DFLT_IPV6_OUTPUT = ${DFLT_IPV6_OUTPUT____TARGET}
________EOF
if [ "${wan0:-not-set}" != 'not-set' ]
then
cat << ____________EOF
WAN0_IPV6_CONNTRACK = ${WAN0_IPV6_CONNTRACK_TARGET}
WAN0_IPV6_ICMP = ${WAN0_IPV6_ICMP______TARGET}
WAN0_IPV6_SSH = ${WAN0_IPV6_SSH_______TARGET}
WAN0_IPV6_SMTP = ${WAN0_IPV6_SMTP______TARGET}
WAN0_IPV6_HTTP = ${WAN0_IPV6_HTTP______TARGET}
WAN0_IPV6_HTTPS = ${WAN0_IPV6_HTTPS_____TARGET}
WAN0_IPV6_DEFAULT = ${WAN0_IPV6_DEFAULT___TARGET}
____________EOF
fi
if [ "${lan1:-not-set}" != 'not-set' ]
then
cat << ____________EOF
LAN1_IPV6_CONNTRACK = ${LAN1_IPV6_CONNTRACK_TARGET}
LAN1_IPV6_ICMP = ${LAN1_IPV6_ICMP______TARGET}
LAN1_IPV6_SSH = ${LAN1_IPV6_SSH_______TARGET}
LAN1_IPV6_DEFAULT = ${LAN1_IPV6_DEFAULT___TARGET}
____________EOF
fi
if [ "${lan2:-not-set}" != 'not-set' ]
then
cat << ____________EOF
LAN2_IPV6_CONNTRACK = ${LAN2_IPV6_CONNTRACK_TARGET}
LAN2_IPV6_ICMP = ${LAN2_IPV6_ICMP______TARGET}
LAN2_IPV6_SSH = ${LAN2_IPV6_SSH_______TARGET}
LAN2_IPV6_DEFAULT = ${LAN2_IPV6_DEFAULT___TARGET}
____________EOF
fi
fi
exit 0
fi
# ----------------------------------------------------------------------------
# looking for iptables and ip6tables if needed
# ----------------------------------------------------------------------------
if [ "${ip4tables:-not-found}" = 'not-found' ]
then
ip4tables="$(which iptables || echo 'not-found')"
fi
if [ "${ip6tables:-not-found}" = 'not-found' ]
then
ip6tables="$(which ip6tables || echo 'not-found')"
fi
# ----------------------------------------------------------------------------
# sanity checks
# ----------------------------------------------------------------------------
if [ "${ip4tables}" = 'not-found' ]
then
echo "*** iptables was not found ***"
exit 1
fi
if [ "${ip6tables}" = 'not-found' ]
then
echo "*** ip6tables was not found ***"
exit 1
fi
# ----------------------------------------------------------------------------
# interfaces checks
# ----------------------------------------------------------------------------
if [ "${wan0:-not-set}" != 'not-set' ] && [ ! -d "/sys/class/net/${wan0}" ]
then
echo "*** ${wan0} does not exists ***"
exit 1
fi
if [ "${lan1:-not-set}" != 'not-set' ] && [ ! -d "/sys/class/net/${lan1}" ]
then
echo "*** ${lan1} does not exists ***"
exit 1
fi
if [ "${lan2:-not-set}" != 'not-set' ] && [ ! -d "/sys/class/net/${lan2}" ]
then
echo "*** ${lan2} does not exists ***"
exit 1
fi
# ----------------------------------------------------------------------------
# IPv4 default policies
# ----------------------------------------------------------------------------
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv4' ]
then
${ip4tables} -t filter -F
${ip4tables} -t filter -P INPUT "${DFLT_IPV4_INPUT_____TARGET}"
${ip4tables} -t filter -P FORWARD "${DFLT_IPV4_FORWARD___TARGET}"
${ip4tables} -t filter -P OUTPUT "${DFLT_IPV4_OUTPUT____TARGET}"
fi
# ----------------------------------------------------------------------------
# IPv6 default policies
# ----------------------------------------------------------------------------
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv6' ]
then
${ip6tables} -t filter -F
${ip6tables} -t filter -P INPUT "${DFLT_IPV6_INPUT_____TARGET}"
${ip6tables} -t filter -P FORWARD "${DFLT_IPV6_FORWARD___TARGET}"
${ip6tables} -t filter -P OUTPUT "${DFLT_IPV6_OUTPUT____TARGET}"
fi
# ----------------------------------------------------------------------------
# IPv4 wan0 rules
# ----------------------------------------------------------------------------
if [ "${wan0}" != 'not-set' ]
then
${ip4tables} -X WAN0_INPUT > /dev/null 2>&1
${ip4tables} -N WAN0_INPUT > /dev/null 2>&1
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv4' ]
then
${ip4tables} -t filter -A INPUT -i "${wan0}" -j WAN0_INPUT
${ip4tables} -t filter -A WAN0_INPUT -i "${wan0}" -p all -m state --state RELATED,ESTABLISHED -j "${WAN0_IPV4_CONNTRACK_TARGET}"
${ip4tables} -t filter -A WAN0_INPUT -i "${wan0}" -p icmp -j "${WAN0_IPV4_ICMP______TARGET}"
${ip4tables} -t filter -A WAN0_INPUT -i "${wan0}" -p tcp --dport ssh -j "${WAN0_IPV4_SSH_______TARGET}"
${ip4tables} -t filter -A WAN0_INPUT -i "${wan0}" -p tcp --dport smtp -j "${WAN0_IPV4_SMTP______TARGET}"
${ip4tables} -t filter -A WAN0_INPUT -i "${wan0}" -p tcp --dport http -j "${WAN0_IPV4_HTTP______TARGET}"
${ip4tables} -t filter -A WAN0_INPUT -i "${wan0}" -p tcp --dport https -j "${WAN0_IPV4_HTTPS_____TARGET}"
${ip4tables} -t filter -A WAN0_INPUT -i "${wan0}" -j "${WAN0_IPV4_DEFAULT___TARGET}"
fi
fi
# ----------------------------------------------------------------------------
# IPv6 wan0 rules
# ----------------------------------------------------------------------------
if [ "${wan0}" != 'not-set' ]
then
${ip6tables} -X WAN0_INPUT > /dev/null 2>&1
${ip6tables} -N WAN0_INPUT > /dev/null 2>&1
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv6' ]
then
${ip6tables} -t filter -A INPUT -i "${wan0}" -j WAN0_INPUT
${ip6tables} -t filter -A WAN0_INPUT -i "${wan0}" -p all -m state --state RELATED,ESTABLISHED -j "${WAN0_IPV6_CONNTRACK_TARGET}"
${ip6tables} -t filter -A WAN0_INPUT -i "${wan0}" -p icmp -j "${WAN0_IPV6_ICMP______TARGET}"
${ip6tables} -t filter -A WAN0_INPUT -i "${wan0}" -p tcp --dport ssh -j "${WAN0_IPV6_SSH_______TARGET}"
${ip6tables} -t filter -A WAN0_INPUT -i "${wan0}" -p tcp --dport smtp -j "${WAN0_IPV6_SMTP______TARGET}"
${ip6tables} -t filter -A WAN0_INPUT -i "${wan0}" -p tcp --dport http -j "${WAN0_IPV6_HTTP______TARGET}"
${ip6tables} -t filter -A WAN0_INPUT -i "${wan0}" -p tcp --dport https -j "${WAN0_IPV6_HTTPS_____TARGET}"
${ip6tables} -t filter -A WAN0_INPUT -i "${wan0}" -j "${WAN0_IPV6_DEFAULT___TARGET}"
fi
fi
# ----------------------------------------------------------------------------
# IPv4 lan1 rules
# ----------------------------------------------------------------------------
if [ "${lan1}" != 'not-set' ]
then
${ip4tables} -X LAN1_INPUT > /dev/null 2>&1
${ip4tables} -N LAN1_INPUT > /dev/null 2>&1
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv4' ]
then
${ip4tables} -t filter -A INPUT -i "${lan1}" -j LAN1_INPUT
${ip4tables} -t filter -A LAN1_INPUT -i "${lan1}" -p all -m state --state RELATED,ESTABLISHED -j "${LAN1_IPV4_CONNTRACK_TARGET}"
${ip4tables} -t filter -A LAN1_INPUT -i "${lan1}" -p icmp -j "${LAN1_IPV4_ICMP______TARGET}"
${ip4tables} -t filter -A LAN1_INPUT -i "${lan1}" -p tcp --dport ssh -j "${LAN1_IPV4_SSH_______TARGET}"
${ip4tables} -t filter -A LAN1_INPUT -i "${lan1}" -j "${LAN1_IPV4_DEFAULT___TARGET}"
fi
fi
# ----------------------------------------------------------------------------
# IPv6 lan1 rules
# ----------------------------------------------------------------------------
if [ "${lan1}" != 'not-set' ]
then
${ip6tables} -X LAN1_INPUT > /dev/null 2>&1
${ip6tables} -N LAN1_INPUT > /dev/null 2>&1
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv6' ]
then
${ip6tables} -t filter -A INPUT -i "${lan1}" -j LAN1_INPUT
${ip6tables} -t filter -A LAN1_INPUT -i "${lan1}" -p all -m state --state RELATED,ESTABLISHED -j "${LAN1_IPV6_CONNTRACK_TARGET}"
${ip6tables} -t filter -A LAN1_INPUT -i "${lan1}" -p icmp -j "${LAN1_IPV6_ICMP______TARGET}"
${ip6tables} -t filter -A LAN1_INPUT -i "${lan1}" -p tcp --dport ssh -j "${LAN1_IPV6_SSH_______TARGET}"
${ip6tables} -t filter -A LAN1_INPUT -i "${lan1}" -j "${LAN1_IPV6_DEFAULT___TARGET}"
fi
fi
# ----------------------------------------------------------------------------
# IPv4 lan2 rules
# ----------------------------------------------------------------------------
if [ "${lan2}" != 'not-set' ]
then
${ip4tables} -X LAN2_INPUT > /dev/null 2>&1
${ip4tables} -N LAN2_INPUT > /dev/null 2>&1
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv4' ]
then
${ip4tables} -t filter -A INPUT -i "${lan2}" -j LAN2_INPUT
${ip4tables} -t filter -A LAN2_INPUT -i "${lan2}" -p all -m state --state RELATED,ESTABLISHED -j "${LAN2_IPV4_CONNTRACK_TARGET}"
${ip4tables} -t filter -A LAN2_INPUT -i "${lan2}" -p icmp -j "${LAN2_IPV4_ICMP______TARGET}"
${ip4tables} -t filter -A LAN2_INPUT -i "${lan2}" -p tcp --dport ssh -j "${LAN2_IPV4_SSH_______TARGET}"
${ip4tables} -t filter -A LAN2_INPUT -i "${lan2}" -j "${LAN2_IPV4_DEFAULT___TARGET}"
fi
fi
# ----------------------------------------------------------------------------
# IPv6 lan2 rules
# ----------------------------------------------------------------------------
if [ "${lan2}" != 'not-set' ]
then
${ip6tables} -X LAN2_INPUT > /dev/null 2>&1
${ip6tables} -N LAN2_INPUT > /dev/null 2>&1
if [ "${opt_proto}" = 'all' ] || [ "${opt_proto}" = 'ipv6' ]
then
${ip6tables} -t filter -A INPUT -i "${lan2}" -j LAN2_INPUT
${ip6tables} -t filter -A LAN2_INPUT -i "${lan2}" -p all -m state --state RELATED,ESTABLISHED -j "${LAN2_IPV6_CONNTRACK_TARGET}"
${ip6tables} -t filter -A LAN2_INPUT -i "${lan2}" -p icmp -j "${LAN2_IPV6_ICMP______TARGET}"
${ip6tables} -t filter -A LAN2_INPUT -i "${lan2}" -p tcp --dport ssh -j "${LAN2_IPV6_SSH_______TARGET}"
${ip6tables} -t filter -A LAN2_INPUT -i "${lan2}" -j "${LAN2_IPV6_DEFAULT___TARGET}"
fi
fi
# ----------------------------------------------------------------------------
# End-Of-File
# ----------------------------------------------------------------------------
#!/bin/sh
#
# save-firewall-rules.sh - Copyright (c) 2019-2021 - Olivier Poncet
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
# ----------------------------------------------------------------------------
# iptables dir and rules files
# ----------------------------------------------------------------------------
IPTABLES_DIR="/etc/iptables"
IPV4_RULES="${IPTABLES_DIR}/rules.v4"
IPV6_RULES="${IPTABLES_DIR}/rules.v6"
# ----------------------------------------------------------------------------
# looking for iptables & ip6tables
# ----------------------------------------------------------------------------
IP4TABLES="$(which iptables || echo 'not-found')"
IP6TABLES="$(which ip6tables || echo 'not-found')"
# ----------------------------------------------------------------------------
# looking for iptables-save & ip6tables-save
# ----------------------------------------------------------------------------
IP4TABLES_SAVE="$(which iptables-save || echo 'not-found')"
IP6TABLES_SAVE="$(which ip6tables-save || echo 'not-found')"
# ----------------------------------------------------------------------------
# sanity checks
# ----------------------------------------------------------------------------
if [ "${IP4TABLES}" = "not-found" ]
then
echo "*** iptables was not found ***"
exit 1
fi
if [ "${IP6TABLES}" = "not-found" ]
then
echo "*** ip6tables was not found ***"
exit 1
fi
if [ "${IP4TABLES_SAVE}" = "not-found" ]
then
echo "*** iptables-save was not found ***"
exit 1
fi
if [ "${IP6TABLES_SAVE}" = "not-found" ]
then
echo "*** ip6tables-save was not found ***"
exit 1
fi
# ----------------------------------------------------------------------------
# reset counters and save IPv4 rules
# ----------------------------------------------------------------------------
if [ -d "${IPTABLES_DIR}" ]
then
${IP4TABLES} -Z INPUT
${IP4TABLES} -Z FORWARD
${IP4TABLES} -Z OUTPUT
${IP4TABLES_SAVE} > "${IPV4_RULES}"
else
echo "*** ${IPTABLES_DIR} was not found ***"
fi
# ----------------------------------------------------------------------------
# reset counters and save IPv6 rules
# ----------------------------------------------------------------------------
if [ -d "${IPTABLES_DIR}" ]
then
${IP6TABLES} -Z INPUT
${IP6TABLES} -Z FORWARD
${IP6TABLES} -Z OUTPUT
${IP6TABLES_SAVE} > "${IPV6_RULES}"
else
echo "*** ${IPTABLES_DIR} was not found ***"
fi
# ----------------------------------------------------------------------------
# End-Of-File
# ----------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment