# HG changeset patch # User Michiel Broek # Date 1391089570 -3600 # Node ID d4d23e51be4ff30822b95c7805ac3b570b3b808f Initial import diff -r 000000000000 -r d4d23e51be4f Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Thu Jan 30 14:46:10 2014 +0100 @@ -0,0 +1,17 @@ +# Top level makefile for Slackware firewall. +# (C) 2013..2014 Michiel Broek +# + +all: + @echo "Nothing to do." + + +install: + @mkdir -p ${DESTDIR}/etc/mbse-firewall/conf.d + @mkdir -p ${DESTDIR}/usr/sbin + install -m 0644 etc/firewall.conf ${DESTDIR}/etc/mbse-firewall + install -m 0644 etc/*.example ${DESTDIR}/etc/mbse-firewall/conf.d + install -m 0755 sbin/mbse-firewall ${DESTDIR}/usr/sbin + @mkdir -p ${DESTDIR}/etc/rc.d + cd ${DESTDIR}/etc/rc.d ; ln -s /usr/sbin/mbse-firewall rc.firewall ; cd - + diff -r 000000000000 -r d4d23e51be4f etc/blocklist4.conf.example --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etc/blocklist4.conf.example Thu Jan 30 14:46:10 2014 +0100 @@ -0,0 +1,14 @@ +# /etc/mbse-firewall/conf.d/blocklist4.conf +# +# List with blocked IP's. Syntax can be networks in CIDR notation or plain +# IPv4 addresses. For example: +# +# 1.2.3.4 a plain IPv4 address +# 5.6.7.0/24 a IPv4 network. +# +# This file is loaded with the following commands: install or reload. +# Comments begin with a # and can be placed behind entries too. +# +1.2.3.4 +5.6.7.0/24 +3.4.5.0/17 # Real bad network diff -r 000000000000 -r d4d23e51be4f etc/blocklist6.conf.example --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etc/blocklist6.conf.example Thu Jan 30 14:46:10 2014 +0100 @@ -0,0 +1,15 @@ +# /etc/mbse-firewall/conf.d/blocklist6.conf +# +# List with blocked IPv6 networks. All entries must be in address/netmask +# format because blocking individual IPv6 addresses is useless. Block at +# least a /64 network. +# +# 2001:DB8:dead:beef::/64 +# +# This file is loaded with the following commands: install or reload. +# Comments begin with a # and can be placed behind entries too. +# +2001:DB8:dead:beef::/64 # comment +2001:DB8:c0:ffee::/64 +2001:db8:daed::/48 + diff -r 000000000000 -r d4d23e51be4f etc/eth0-input.conf.example --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etc/eth0-input.conf.example Thu Jan 30 14:46:10 2014 +0100 @@ -0,0 +1,59 @@ +# /etc/mbse-firewall/conf.d/eth0-input.conf +# +# This table is ; separated. From the data in the fields ip(6)tables commands +# are created by the main program. The filename of this file is +# -[forward|input|output|postrouting|prerouting].conf and from this name +# the initial part of the command is created. +# +# The first field is a 4 or 6 and defines if this is a IPv4 or IPv6 rule. +# +# The second field is tha -t table type. Values are nat, mangle ... or empty +# for the default filter type. +# +# The 3rd field is the protocol, tcp, udp, igmp, raw etc. +# +# The 4th field is the source address or source network. Valid notations +# are 10.126.150.2 10.1.1.0/24 2001:1af8:feb8:7e96::2 +# 2001:1af8:feb8:7e96::2/64 or 0/0 for any. +# +# The 5th field is the source port or ports. Ports may be command separated +# or ranges or a combination of that. See man iptables for the syntax. +# +# The 6th field is the destination address. +# +# The 7th field is the destination port or ports +# +# The 8th field is the action, can be any valid action like: +# DROP +# ACCEPT +# REJECT --reject-with tcp-reset +# +# The 9th field is special tests, for example: +# -m state --state NEW +# -m hashlimit --hashlimit 5/second --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-name torrent +# -m connlimit \! --connlimit-above 3 -m hashlimit --hashlimit 1/second --hashlimit-burst 2 --hashlimit-mode srcip --hashlimit-name openvpn +# -m connlimit --connlimit-above 35 +# If you want, write several conditions in the same field. + +# Maximum connections per source IP +4;;;;;;;DROP;-m connlimit --connlimit-above 35 + +# Allow SSH +4;;tcp;;;10.1.1.5;ssh;ACCEPT;-m state --state NEW +6;;tcp;;;2001:1af8:dead:beef::5;ssh;ACCEPT;-m state --state NEW + +# Allow CUPS +4;;tcp;10.1.1.0/24;631;10.1.1.255;631;ACCEPT; +4;;udp;10.1.1.0/24;631;10.1.1.255;631;ACCEPT; + +# Allow Samba +4;;udp;10.1.1.0/24;138;10.1.1.255;138;ACCEPT; +4;;udp;10.1.1.0/24;137;10.1.1.255;137;ACCEPT; + +# Rate limited web +4;;tcp;;;10.1.1.5;80,443;ACCEPT;-m state --state NEW -m hashlimit --hashlimit 15/second --hashlimit-burst 25 --hashlimit-name http-server +6;;tcp;;;2001:1af8:dead:beef::5;http,https;ACCEPT;-m state --state NEW -m hashlimit --hashlimit 15/second --hashlimit-burst 25 --hashlimit-name http-server + +# DHCP +4;;udp;;67;255.255.255.255;68;ACCEPT; +4;;udp;;68;255.255.255.255;67;ACCEPT; diff -r 000000000000 -r d4d23e51be4f etc/eth0-output.conf.example --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etc/eth0-output.conf.example Thu Jan 30 14:46:10 2014 +0100 @@ -0,0 +1,47 @@ +# /etc/mbse-firewall/conf.d/eth0-output.conf +# +# This table is ; separated. From the data in the fields ip(6)tables commands +# are created by the main program. The filename of this file is +# -[forward|input|output|postrouting|prerouting].conf and from this name +# the initial part of the command is created. +# +# The first field is a 4 or 6 and defines if this is a IPv4 or IPv6 rule. +# +# The second field is tha -t table type. Values are nat, mangle ... or empty +# for the default filter type. +# +# The 3rd field is the protocol, tcp, udp, igmp, raw etc. +# +# The 4th field is the source address or source network. Valid notations +# are 10.126.150.2 10.1.1.0/24 2001:1af8:feb8:7e96::2 +# 2001:1af8:feb8:7e96::2/64 or 0/0 for any. +# +# The 5th field is the source port or ports. Ports may be command separated +# or ranges or a combination of that. See man iptables for the syntax. +# +# The 6th field is the destination address. +# +# The 7th field is the destination port or ports +# +# The 8th field is the action, can be any valid action like: +# DROP +# ACCEPT +# REJECT --reject-with tcp-reset +# +# The 9th field is special tests, for example: +# -m state --state NEW +# -m hashlimit --hashlimit 5/second --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-name torrent +# -m connlimit \! --connlimit-above 3 -m hashlimit --hashlimit 1/second --hashlimit-burst 2 --hashlimit-mode srcip --hashlimit-name openvpn +# -m connlimit --connlimit-above 35 +# If you want, write several conditions in the same field. + +# Log all traffic +4;;;;;;;NFLOG --nflog-group 1 +6;;;;;;;NFLOG --nflog-group 1 + +# Allow all traffic out +4;;tcp;;;;;ACCEPT; +4;;udp;;;;;ACCEPT; +6;;tcp;;;;;ACCEPT; +6;;udp;;;;;ACCEPT; + diff -r 000000000000 -r d4d23e51be4f etc/firewall.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etc/firewall.conf Thu Jan 30 14:46:10 2014 +0100 @@ -0,0 +1,107 @@ +# /etc/mbse-firewall/firewall.conf + +# --------------------------------------------------------------------------- +# Copyright (C) 2013-2014 by Michiel Broek. +# Homepage http://www.mbse.eu +# Email mbse At mbse dOt eu +# +# This file is part of mbse-firewall. +# +# 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, 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; see the file COPYING. If not, write to the Free +# Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +# --------------------------------------------------------------------------- + + +# --------------------------------------------------------------------------- +# +# Interface settings +# +# --------------------------------------------------------------------------- + +# External interface that will be protected as internet connection. +# If this is a server on a DMZ network, use this too. +# +IF_EXT="eth0" + +# External IPv6 tunnel interface that will be protected as internet connection. +# Enable this if you use a tunnel broker for IPv6. +#IF_EXT6="six0" + +# If the external gateway is a border gateway, (your internet connection) then +# set the next option. Certain protocols are disabled in this case, and some +# are just enabled. +#IF_EXT_IS_BORDER_GW="1" + +# Enable automatic blacklisting of hosts that do any kind portscanning. +# This is tested by any rules not matched on the external interface(s) INPUT +# or FORWARD chain and is a repeated undefined port from the same IP. +# These hosts are blocked using ipset for one hour. +#IF_EXT_AUTO_BLOCK="1" + +# Block time in seconds when a host is blocked. Default is 3600. +#IF_EXT_AUTO_TO=172800 + +# Average detect limit, default 5/hour +#IF_EXT_AUTO_LIMIT="2/hour" + +# Burst detect limit, default 10 +#IF_EXT_AUTO_BURST="2" + +# Trunk networks. All other interfaces are set here. They should start +# with 0 and there should be no gaps. +# +#IF_TRUNK[0]="eth1" +#IF_TRUNK[1]="tap0" +#IF_TRUNK[2]="" +#IF_TRUNK[3]="" +#IF_TRUNK[4]="" +#IF_TRUNK[5]="" +#IF_TRUNK[6]="" +#IF_TRUNK[7]="" +#IF_TRUNK[8]="" +#IF_TRUNK[9]="" + + + +# --------------------------------------------------------------------------- +# +# Global settings +# +# --------------------------------------------------------------------------- + + +# On hosts leave this undefined or 0. On routers uncomment and set to 1 +FW_FORWARD="0" + +# Add rules to allow traceroute +FW_TRACEROUTE="1" + +# If you have a bridged interface like br0 with physical interfaces eth0 and +# tap0 for example, you need to add iptables rules to forward traffic between +# these interfaces. You can turn this off by setting the next variable. +# If this variable is set, then all bridged interfaces are seen as one physical +# interface. See http://ebtables.sourceforge.net/documentation/bridge-nf.html +# for more details. +#FW_NO_BRIDGE_NF_CALL="1" + +# Install a ssh backdoor from this IP. The examples show an exact IP address, +# but you can use networks if you like. Exact is better of course. +# for IPv4 use: 2.3.4.5/32 +#IPV4_BACKDOOR_SSH="10.1.1.231/32" +# for IPv6 use: 2001:dead:beef::1/128 +#IPV6_BACKDOOR_SSH="2001:1af8:dead:beef::e7/128" + +# Mangle, should be 1 on routers +#CLAMP_MSS_TO_PMTU="1" + diff -r 000000000000 -r d4d23e51be4f sbin/mbse-firewall --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbin/mbse-firewall Thu Jan 30 14:46:10 2014 +0100 @@ -0,0 +1,872 @@ +#!/bin/bash + +# --------------------------------------------------------------------------- +# Copyright (C) 2013-2014 by Michiel Broek. +# Homepage http://www.mbse.eu +# Email mbse At mbse dOt eu +# +# This file is part of mbse-firewall. +# +# 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, 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; see the file COPYING. If not, write to the Free +# Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +# --------------------------------------------------------------------------- + +MBSEFW_VERSION="0.0.12" + +# Sanity checks +if [ "$(id -u)" != "0" ]; then + echo "** You must be root to run this program" + exit 1 +fi + +# If possible, log events in /var/log/messages: +if [ -f /var/run/syslogd.pid -a -x /usr/bin/logger ]; then + LOGGER=/usr/bin/logger +else # output to stdout/stderr: + LOGGER=/bin/cat +fi + + +# IPv6 enabled? +USE_IPV6="0" +if [ -f /proc/sys/net/ipv6/conf/all/disable_ipv6 ] && [ "$(cat /proc/sys/net/ipv6/conf/all/disable_ipv6)" == "0" ]; then + USE_IPV6="1" +fi + +# Find programs +IPTABLES=$(which iptables 2>/dev/null) +IPTABLES_SAVE=$(which iptables-save 2>/dev/null) +IPTABLES_RESTORE=$(which iptables-restore 2>/dev/null) +LSMOD=$(which lsmod 2>/dev/null) +AWK=$(which awk 2>/dev/null) +GREP=$(which grep 2>/dev/null) +IPSET=$(which ipset 2>/dev/null) +SYSCTL=$(which sysctl 2>/dev/null) + +if [ "$USE_IPV6" = "1" ]; then + IP6TABLES=$(which ip6tables 2>/dev/null) + IP6TABLES_SAVE=$(which ip6tables-save 2>/dev/null) + IP6TABLES_RESTORE=$(which ip6tables-restore 2>/dev/null) +fi + + +# Load configuration +if [ ! -f /etc/mbse-firewall/firewall.conf ]; then + echo "** /etc/mbse-firewall/firewall.conf not found, abort" + exit 1 +fi +. /etc/mbse-firewall/firewall.conf + +# Some defaults, they are replaced when configured in +# /etc/mbse-firewall/firewall.conf + +IF_EXT_AUTO_TO=${IF_EXT_AUTO_TO:=3600} +IF_EXT_AUTO_LIMIT=${IF_EXT_AUTO_LIMIT:=5/hour} +IF_EXT_AUTO_BURST=${IF_EXT_AUTO_BURST:=10} + +# --------------------------------------------------------------------------- +# +# Functions +# +# --------------------------------------------------------------------------- + + +# Reset iptables back to Slackware default. +reset_iptables() { + + if [ -f /proc/net/ip_tables_names ]; then + cat /proc/net/ip_tables_names | while read table; do + $IPTABLES -t $table -L -n | while read c chain rest; do + if test "X$c" = "XChain" ; then + $IPTABLES -t $table -F $chain + fi + done + $IPTABLES -t $table -X + done + + $IPTABLES -P INPUT $1 + $IPTABLES -P OUTPUT $1 + $IPTABLES -P FORWARD $1 + echo "Reset iptables default policy $1" | $LOGGER + fi + + if [ "$USE_IPV6" == "1" ] && [ -f /proc/net/ip6_tables_names ]; then + cat /proc/net/ip6_tables_names | while read table; do + $IP6TABLES -t $table -L -n | while read c chain rest; do + if test "X$c" = "XChain" ; then + $IP6TABLES -t $table -F $chain + fi + done + $IP6TABLES -t $table -X + done + $IP6TABLES -P OUTPUT $1 + $IP6TABLES -P INPUT $1 + $IP6TABLES -P FORWARD $1 + echo "Reset ip6tables default policy $1" | $LOGGER + fi + + # Remove any ipset tables. + $IPSET flush + $IPSET destroy +} + + + +is_external_if4() { + [ "x${IF_EXT}" == "x$1" ] && return 1 + + return 0 +} + + + +is_external_if6() { + if [ "$USE_IPV6" == "1" ]; then + [ "x${IF_EXT6}" == "x$1" ] && return 1 + [ "x${IF_EXT}" == "x$1" -a -z "${IF_EXT6}" ] && return 1 + fi + + return 0 +} + + + +reload_blocklist4() { + + BLOCKLIST="/etc/mbse-firewall/conf.d/blocklist4.conf" + if [ -f $BLOCKLIST ]; then + echo "Reload $BLOCKLIST" | $LOGGER + $IPSET create new-mbsefw-blk4ip hash:ip counters -exist + $IPSET create new-mbsefw-blk4net hash:net counters -exist + $GREP -Ev '^#|^;|^\s*$' $BLOCKLIST | while read L ; do + set $L + if echo $1 | $GREP -q "/" ; then + $IPSET add new-mbsefw-blk4net $1 -exist + else + $IPSET add new-mbsefw-blk4ip $1 -exist + fi + done + $IPSET swap mbsefw-blk4net new-mbsefw-blk4net + $IPSET flush new-mbsefw-blk4net + $IPSET destroy new-mbsefw-blk4net + $IPSET swap mbsefw-blk4ip new-mbsefw-blk4ip + $IPSET flush new-mbsefw-blk4ip + $IPSET destroy new-mbsefw-blk4ip + fi +} + + + +reload_blocklist6() { + + BLOCKLIST="/etc/mbse-firewall/conf.d/blocklist6.conf" + if [ -f $BLOCKLIST ]; then + echo "Reload $BLOCKLIST" | $LOGGER + $IPSET create new-mbsefw-blk6 hash:net family inet6 counters -exist + $GREP -Ev '^#|^;|^\s*$' $BLOCKLIST | while read L ; do + set $L ; $IPSET add new-mbsefw-blk6 $1 -exist + done + $IPSET swap mbsefw-blk6 new-mbsefw-blk6 + $IPSET flush new-mbsefw-blk6 + $IPSET destroy new-mbsefw-blk6 + fi +} + + + +fw_init_sysctl() { + # If we have bridges and don't want iptables to work between + # the physical interfaces, turn it off. + if [ "$FW_NO_BRIDGE_NF_CALL" = "1" ]; then + $SYSCTL -e -q -w net.bridge.bridge-nf-call-arptables=0 + $SYSCTL -e -q -w net.bridge.bridge-nf-call-ip6tables=0 + $SYSCTL -e -q -w net.bridge.bridge-nf-call-iptables=0 + fi + + # No arp about internal interfaces across the border. + if [ "$IF_EXT_IS_BORDER_GW" = "1" ]; then + $SYSCTL -q -w net.ipv4.conf.${IF_EXT}.arp_ignore=1 + $SYSCTL -q -w net.ipv4.conf.${IF_EXT}.arp_announce=1 + fi +} + + + +fw_start_init() { + + echo "Init new firewall" | $LOGGER + + BLOCKLIST="/etc/mbse-firewall/conf.d/blocklist4.conf" + if [ -f $BLOCKLIST -a -n "$IF_EXT" ]; then + echo " Install $BLOCKLIST" | $LOGGER + $IPSET create mbsefw-blk4ip hash:ip counters -exist + $IPSET create mbsefw-blk4net hash:net counters -exist + $IPTABLES -A INPUT -i $IF_EXT -m set --match-set mbsefw-blk4ip src -j DROP + $IPTABLES -A INPUT -i $IF_EXT -m set --match-set mbsefw-blk4net src -j DROP + if [ "$FW_FORWARD" = "1" ]; then + $IPTABLES -A FORWARD -i $IF_EXT -m set --match-set mbsefw-blk4ip src -j DROP + $IPTABLES -A FORWARD -i $IF_EXT -m set --match-set mbsefw-blk4net src -j DROP + fi + $GREP -Ev '^#|^;|^\s*$' $BLOCKLIST | while read L ; do + set $L + if echo $1 | $GREP -q "/" ; then + $IPSET add mbsefw-blk4net $1 -exist + else + $IPSET add mbsefw-blk4ip $1 -exist + fi + done + echo -n "." + fi + + BLOCKLIST="/etc/mbse-firewall/conf.d/blocklist6.conf" + if [ -f $BLOCKLIST ]; then + echo " Install $BLOCKLIST" | $LOGGER + $IPSET create mbsefw-blk6 hash:net family inet6 counters -exist + if [ -n "$IF_EXT6" ]; then + IF6=$IF_EXT6 + else + IF6=$IF_EXT + fi + $IP6TABLES -A INPUT -i $IF6 -m set --match-set mbsefw-blk6 src -j DROP + if [ "$FW_FORWARD" = "1" ]; then + $IP6TABLES -A FORWARD -i $IF6 -m set --match-set mbsefw-blk6 src -j DROP + fi + $GREP -Ev '^#|^;|^\s*$' $BLOCKLIST | while read L ; do + set $L + $IPSET add mbsefw-blk6 $1 -exist + done + echo -n "." + fi + + # accept established and related connections + $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + [ "$FW_FORWARD" = "1" ] && $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT + if [ "$USE_IPV6" == "1" ]; then + $IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + $IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + [ "$FW_FORWARD" = "1" ] && $IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT + fi + + # drop packets that do not match any valid state. This also blocks invalid + # flag combinations that are used by portscans. + $IPTABLES -A OUTPUT -m state --state INVALID -j DROP + $IPTABLES -A INPUT -m state --state INVALID -j DROP + [ "$FW_FORWARD" = "1" ] && $IPTABLES -A FORWARD -m state --state INVALID -j DROP + if [ "$USE_IPV6" == "1" ]; then + $IP6TABLES -A OUTPUT -m state --state INVALID -j DROP + $IP6TABLES -A INPUT -m state --state INVALID -j DROP + [ "$FW_FORWARD" = "1" ] && $IP6TABLES -A FORWARD -m state --state INVALID -j DROP + fi + + # Allow everything on the loopback interface + $IPTABLES -A INPUT -i lo -j ACCEPT + $IPTABLES -A OUTPUT -o lo -j ACCEPT + if [ "$USE_IPV6" == "1" ]; then + $IP6TABLES -A INPUT -i lo -j ACCEPT + $IP6TABLES -A OUTPUT -o lo -j ACCEPT + fi + + # Anti spoofing on the external interface. Methods since the 3.3 kernel! + if [ -n "$IF_EXT" ]; then + for f in $(ls /proc/sys/net/ipv4/conf/*/rp_filter); do + echo 1 > $f + done + $IPTABLES -A PREROUTING -t raw -i $IF_EXT -m rpfilter --invert -j DROP + if [ "$USE_IPV6" == "1" ]; then + if [ -n "$IF_EXT6" ]; then + $IP6TABLES -A PREROUTING -t raw -i $IF_EXT6 -m rpfilter --invert -j DROP + else + $IP6TABLES -A PREROUTING -t raw -i $IF_EXT -m rpfilter --invert -j DROP + fi + fi + # Manual anti spoofing on the interfaces is configured using the + # interfaces configuration and only if the system is a router. + fi + + # IPv4 ssh backdoor + if [ -n "$IPV4_BACKDOOR_SSH" ]; then + $IPTABLES -A INPUT -p tcp -m tcp -s $IPV4_BACKDOOR_SSH --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT + $IPTABLES -A OUTPUT -p tcp -m tcp -d $IPV4_BACKDOOR_SSH --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT + fi + # IPv6 ssh backdoor + if [ "$USE_IPV6" == "1" ] && [ -n "$IPV6_BACKDOOR_SSH" ]; then + $IP6TABLES -A INPUT -p tcp -m tcp -s $IPV6_BACKDOOR_SSH --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT + $IP6TABLES -A OUTPUT -p tcp -m tcp -d $IPV6_BACKDOOR_SSH --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT + fi + + # Usefull ICMPv4 + $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 0/0 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 8/0 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 11/0 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A INPUT -p icmp -m icmp --icmp-type 11/1 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A INPUT -p icmp -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=ICMPv4_INPUT " + $IPTABLES -A INPUT -p icmp -j DROP + $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT + $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 0/0 -j ACCEPT + $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 8/0 -j ACCEPT + $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 11/0 -j ACCEPT + $IPTABLES -A OUTPUT -p icmp -m icmp --icmp-type 11/1 -j ACCEPT + $IPTABLES -A OUTPUT -p icmp -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=ICMPv4_OUTPUT " + $IPTABLES -A OUTPUT -p icmp -j DROP + if [ "$FW_FORWARD" = "1" ]; then + $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 3 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 0/0 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 8/0 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 11/0 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A FORWARD -p icmp -m icmp --icmp-type 11/1 -m hashlimit --hashlimit 15/second --hashlimit-mode srcip --hashlimit-name icmp -j ACCEPT + $IPTABLES -A FORWARD -p icmp -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=ICMPv4_FORWARD " + $IPTABLES -A FORWARD -p icmp -j DROP + fi + + # If this system has enabled IPv6 ... + if [ "$USE_IPV6" == "1" ]; then + # ICMPv6 + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type packet-too-big -j ACCEPT + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type time-exceeded -j ACCEPT + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type parameter-problem -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type packet-too-big -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type time-exceeded -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type parameter-problem -j ACCEPT + if [ "$FW_FORWARD" = "1" ]; then + $IP6TABLES -A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT + $IP6TABLES -A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type packet-too-big -j ACCEPT + $IP6TABLES -A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type time-exceeded -j ACCEPT + $IP6TABLES -A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type parameter-problem -j ACCEPT + fi + + # Rate limited icmpv6 + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -m limit --limit 15/second -j ACCEPT + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-reply -m limit --limit 15/second -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-reply -j ACCEPT + if [ "$FW_FORWARD" = "1" ]; then + $IP6TABLES -A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -m limit --limit 15/second -j ACCEPT + $IP6TABLES -A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type echo-reply -m limit --limit 15/second -j ACCEPT + fi + + # rules to permit IPv6 Neighbor discovery + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT + $IP6TABLES -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT + $IP6TABLES -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT + + # MLD messages. DROP on external interface, but ACCEPT on others. + if [ -n "$IF_EXT6" -a "$IF_EXT_IS_BORDER_GW" = "1" ]; then + $IP6TABLES -A OUTPUT -o $IF_EXT6 -p ipv6-icmp -d ff00::/8 -m icmp6 --icmpv6-type 143 -j DROP + elif [ -n "$IF_EXT" -a "$IF_EXT_IS_BORDER_GW" = "1" ]; then + $IP6TABLES -A OUTPUT -o $IF_EXT -p ipv6-icmp -d ff00::/8 -m icmp6 --icmpv6-type 143 -j DROP + fi + $IP6TABLES -A OUTPUT -p ipv6-icmp -d ff00::/8 -m icmp6 --icmpv6-type 143 -j ACCEPT + + # Drop unmatched icmpv6 but log them so we can debug + $IP6TABLES -A INPUT -p ipv6-icmp -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=ICMPv6_INPUT " + $IP6TABLES -A INPUT -p ipv6-icmp -j DROP + $IP6TABLES -A OUTPUT -p ipv6-icmp -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=ICMPv6_OUTPUT " + $IP6TABLES -A OUTPUT -p ipv6-icmp -j DROP + [ "$FW_FORWARD" = "1" ] && { + $IP6TABLES -A FORWARD -p ipv6-icmp -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=ICMPv6_FORWARD " + $IP6TABLES -A FORWARD -p ipv6-icmp -j DROP + } + fi + + if [ "$CLAMP_MSS_TO_PMTU" = "1" ]; then + # ================ Table 'mangle', automatic rules + [ "$FW_FORWARD" = "1" ] && $IPTABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + if [ "$USE_IPV6" == "1" ]; then + [ "$FW_FORWARD" = "1" ] && $IP6TABLES -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + fi + fi + + # Filter all packets that have RH0 header + if [ "$USE_IPV6" == "1" ]; then + # Filter all packets that have RH0 header + $IP6TABLES -A OUTPUT -m rt --rt-type 0 -j DROP + $IP6TABLES -A INPUT -m rt --rt-type 0 -j DROP + [ "$FW_FORWARD" = "1" ] && $IP6TABLES -A FORWARD -m rt --rt-type 0 -j DROP + + # Allow Link-Local sddresses + $IP6TABLES -A INPUT -s fe80::/10 -j ACCEPT + $IP6TABLES -A OUTPUT -s fe80::/10 -j ACCEPT + + # Allow Multicast + $IP6TABLES -A INPUT -d ff00::/8 -j ACCEPT + $IP6TABLES -A OUTPUT -d ff00::/8 -j ACCEPT + fi + + # Traceroute + if [ "$FW_TRACEROUTE" = "1" ]; then + $IPTABLES -A OUTPUT -p udp -m udp --dport 33434:33524 -m state --state NEW -j ACCEPT + $IPTABLES -A INPUT -p udp -m udp --dport 33434:33524 -m state --state NEW -j ACCEPT + [ "$FW_FORWARD" = "1" ] && $IPTABLES -A FORWARD -p udp -m udp --dport 33434:33524 -m state --state NEW -j ACCEPT + if [ "$USE_IPV6" == "1" ]; then + $IP6TABLES -A OUTPUT -p udp -m udp --dport 33434:33524 -m state --state NEW -j ACCEPT + $IP6TABLES -A INPUT -p udp -m udp --dport 33434:33524 -m state --state NEW -j ACCEPT + [ "$FW_FORWARD" = "1" ] && $IP6TABLES -A FORWARD -p udp -m udp --dport 33434:33524 -m state --state NEW -j ACCEPT + fi + fi + + echo -n "." +} + + + +fw_start_interface_chain() +{ + local multi iodir IFS=\; + + INTF=$1 + FCHAIN=$2 + NCHAIN=$3 + SCHAIN=$4 + CONFFILE="/etc/mbse-firewall/conf.d/${INTF}-${FCHAIN}.conf" + is_external_if4 $1 + EXTERN4=$? + is_external_if6 $1 + EXTERN6=$? + + # TODO: use subchains, but we need to do 2 passes on the config + # files to make it work. + + # Are there rules for this chain? + if [ -f $CONFFILE ]; then + echo " Start chain ${NCHAIN} on interface ${INTF} is external ipv4: ${EXTERN4} ipv6: ${EXTERN6}" | $LOGGER + + # Install auto blacklisting if set for this interface and this is the + # INPUT or FORWARD chain. In /etc/mbse-firewall/firewall.conf set then + # IF_EXT_AUTO_TO value for the block timeout. Default is 3600 seconds. + # See the end of this function for the actual test. + if [ "$NCHAIN" = "INPUT" -o "$NCHAIN" = "FORWARD" ]; then + if [ "$IF_EXT_AUTO_BLOCK" = "1" ]; then + if [ "$EXTERN4" = "1" ]; then + echo " Installing IPv4 auto blacklisting on interface ${INTF}" | $LOGGER + $IPSET create mbsefw-auto4 hash:ip timeout $IF_EXT_AUTO_TO counters -exist + $IPTABLES -I $NCHAIN -m set --match-set mbsefw-auto4 src -j DROP + fi + if [ "$EXTERN6" = "1" ]; then + echo " Installing IPv6 auto blacklisting on interface ${INTF}" | $LOGGER + $IPSET create mbsefw-auto6 hash:ip family inet6 timeout $IF_EXT_AUTO_TO counters -exist + $IP6TABLES -I $NCHAIN -m set --match-set mbsefw-auto6 src -j DROP + fi + fi + fi + + # Adjust for the direction of the chain + if [ "$NCHAIN" = "OUTPUT" -o "$NCHAIN" = "POSTROUTING" ]; then + iodir="-o" + else + iodir="-i" + fi + + # Read the configuration + $GREP -Ev '^#|^\s*$' $CONFFILE | while read L ; do + set $L + # Build command + if [ "$1" = "6" ]; then + CMD=$IP6TABLES + else + CMD=$IPTABLES + fi + + if [ -n "$2" ]; then + args=("-t" "$2" "-A" "$NCHAIN" "$iodir" "${INTF}") + else + args=("-A" "$NCHAIN" "$iodir" "${INTF}") + fi + + # Protocol + [ -n "$3" ] && args+=("-p" "$3" "-m" "$3") + + # Test for multiport + multi=0 + [ -n "$5$7" ] && { + [[ $5$7 == *","* ]] && multi=1 + [[ $5$7 == *":"* ]] && multi=1 + } + [ "$multi" = "1" ] && args+=("-m" "multiport") + + # Source address + [ -n "$4" ] && args+=("-s" "$4") + + # Source port(s) + [ -n "$5" ] && { + multi=0 + [[ $5 == *","* ]] && multi=1 + [[ $5 == *":"* ]] && multi=1 + if [ "$multi" = "1" ]; then + args+=("--sports" "$5") + else + args+=("--sport" "$5") + fi + } + + # Destination address + [ -n "$6" ] && args+=("-d" "$6") + + # Destination port(s) + [ -n "$7" ] && { + multi=0 + [[ $7 == *","* ]] && multi=1 + [[ $7 == *":"* ]] && multi=1 + if [ "$multi" = "1" ]; then + args+=("--dports" "$7") + else + args+=("--dport" "$7") + fi + } + + # Rule options + [ -n "$9" ] && { + IFS=' ' + for arg in $9; do + args+=("$arg") + done + IFS=\; + } + + # Rule action + [ -n "$8" ] && { + IFS=' ' + args+=("-j") + for arg in $8; do + args+=("$arg") + done + IFS=\; + } + + $CMD "${args[@]}" + rc=$? + echo " " $CMD "${args[@]}" | $LOGGER + if [ $rc -ne 0 ]; then + echo "Error in $CONFFILE" | $LOGGER + fi + done + + # In PREROUTING or POSTROUTING chains we are done here. + if [ "$NCHAIN" = "PREROUTING" -o "$NCHAIN" = "POSTROUTING" ]; then + return + fi + + # Ignore timing problems with old connections + $IPTABLES -A $NCHAIN $iodir ${INTF} -p tcp -m tcp --tcp-flags ACK,PSH ACK,PSH -j DROP + [ "$USE_IPV6" = "1" ] && $IP6TABLES -A $NCHAIN $iodir ${INTF} -p tcp -m tcp --tcp-flags ACK,PSH ACK,PSH -j DROP + + # Install the final autoblock rule if this is the INPUT or FORWARD chain. + # We allow upto 1 probe per minute or a burst of 3 probes. This should be + # a good balance to catch the real bad guys. Note that until the IP is + # blocked these systems are logged using the rule below this one. + if [ "$IF_EXT_AUTO_BLOCK" = "1" -a "$NCHAIN" != "OUTPUT" ]; then + if [ "${EXTERN4}" = "1" ]; then + $IPTABLES -A $NCHAIN $iodir ${INTF} \ + -m hashlimit --hashlimit-above ${IF_EXT_AUTO_LIMIT} --hashlimit-burst ${IF_EXT_AUTO_BURST} --hashlimit-mode srcip --hashlimit-name hash-auto4 \ + -j SET --add-set mbsefw-auto4 src + fi + if [ "${EXTERN6}" = "1" ]; then + $IP6TABLES -A $NCHAIN $iodir ${INTF} \ + -m hashlimit --hashlimit-above ${IF_EXT_AUTO_LIMIT} --hashlimit-burst ${IF_EXT_AUTO_BURST} --hashlimit-mode srcip --hashlimit-name hash-auto6 \ + -j SET --add-set mbsefw-auto6 src + fi + fi + # deny and log the rest + $IPTABLES -A $NCHAIN $iodir ${INTF} -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=$NCHAIN " + [ "$USE_IPV6" == "1" ] && $IP6TABLES -A $NCHAIN $iodir ${INTF} -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=$NCHAIN " + $IPTABLES -A $NCHAIN $iodir ${INTF} -j DROP + [ "$USE_IPV6" == "1" ] && $IP6TABLES -A $NCHAIN $iodir ${INTF} -j DROP + echo -n "." + fi +} + + + +fw_start_interface() +{ + fw_start_interface_chain $1 "prerouting" "PREROUTING" "pre" + fw_start_interface_chain $1 "input" "INPUT" "in" + fw_start_interface_chain $1 "output" "OUTPUT" "out" + fw_start_interface_chain $1 "forward" "FORWARD" "fwd" + fw_start_interface_chain $1 "postrouting" "POSTROUTING" "post" +} + + + +fw_start_main() { + i=0 + + [ -n "$IF_EXT" ] && fw_start_interface "$IF_EXT" + [ -n "$IF_EXT6" ] && fw_start_interface "$IF_EXT6" + + while [ $i -lt 50 ]; + do + [ -z "${IF_TRUNK[$i]}" ] && break + fw_start_interface "${IF_TRUNK[$i]}" + i=$(($i+1)) + done +} + + + +fw_start_final() { + # Deny and log everything else + $IPTABLES -N FINAL_RULE + $IPTABLES -A OUTPUT -j FINAL_RULE + $IPTABLES -A INPUT -j FINAL_RULE + [ "$FW_FORWARD" = "1" ] && $IPTABLES -A FORWARD -j FINAL_RULE + $IPTABLES -A FINAL_RULE -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=999 " + $IPTABLES -A FINAL_RULE -j DROP + if [ "$USE_IPV6" = "1" ]; then + $IP6TABLES -N FINAL_RULE + $IP6TABLES -A OUTPUT -j FINAL_RULE + $IP6TABLES -A INPUT -j FINAL_RULE + [ "$FW_FORWARD" = "1" ] && $IP6TABLES -A FORWARD -j FINAL_RULE + $IP6TABLES -A FINAL_RULE -m limit --limit 10/minute -j LOG --log-level info --log-prefix "DENY=999 " + $IP6TABLES -A FINAL_RULE -j DROP + fi + echo "Firewall installed" | $LOGGER +} + + + +fw_install() { + echo -n "Installing $(basename $0) $MBSEFW_VERSION: " + reset_iptables DROP + echo -n "." + fw_init_sysctl + echo -n "." + fw_start_init + fw_start_main + fw_start_final + echo " done." +} + + + +fw_start() { + if [ -f /etc/mbse-firewall/data/firewall-ipv4.data -a \ + -f /etc/mbse-firewall/data/firewall-ipv6.data -a \ + -f /etc/mbse-firewall/data/firewall-ipset.data ]; then + # Do a full restore of all saved data + echo -n "Starting $(basename $0) $MBSEFW_VERSION: " + echo "Start new firewall" | $LOGGER + reset_iptables DROP + echo -n "." + fw_init_sysctl + $IPSET restore < /etc/mbse-firewall/data/firewall-ipset.data + echo " Restored /etc/mbse-firewall/data/firewall-ipset.data" | $LOGGER + echo -n "." + $IPTABLES_RESTORE < /etc/mbse-firewall/data/firewall-ipv4.data + echo " Restored /etc/mbse-firewall/data/firewall-ipv4.data" | $LOGGER + echo -n "." + $IP6TABLES_RESTORE < /etc/mbse-firewall/data/firewall-ipv6.data + echo " Restored /etc/mbse-firewall/data/firewall-ipv6.data" | $LOGGER + echo " done." + echo -n "New firewall active" | $LOGGER + else + # If there is no saved firewall, install a new one and save it. + fw_install + fw_save + fi +} + + + +fw_stop() { + echo -n "Stopping $(basename $0) $MBSEFW_VERSION: " + # Slackware defaults to ACCEPT when no firewall is active. + reset_iptables ACCEPT + echo "done." +} + + + +# If there are blocklist tables, reload them. +fw_reload() { + echo -n "Reload $(basename $0) $MBSEFW_VERSION: " + reload_blocklist4 + reload_blocklist6 + echo done. +} + + + +fw_save() { + echo -n "Saving $(basename $0) $MBSEFW_VERSION: " + echo "Saving firewall" | $LOGGER + mkdir -p /etc/mbse-firewall/data + [ -n "$IPTABLES_SAVE" ] && $IPTABLES_SAVE > /etc/mbse-firewall/data/firewall-ipv4.data + echo -n "." + [ -n "$IP6TABLES_SAVE" ] && $IP6TABLES_SAVE > /etc/mbse-firewall/data/firewall-ipv6.data + echo -n "." + + rm -f /etc/mbse-firewall/data/firewall-ipset.data + touch /etc/mbse-firewall/data/firewall-ipset.data + SETS="$($IPSET list -n)" + for set in $SETS ; do + if [ "$set" = "mbsefw-auto4" -o "$set" = "mbsefw-auto6" ]; then + # Only save structure for auto blocklists + $IPSET save $set -t >> /etc/mbse-firewall/data/firewall-ipset.data + else + $IPSET save $set >> /etc/mbse-firewall/data/firewall-ipset.data + fi + echo -n "." + done + echo " done." + echo "Save firewall done in /etc/mbse-firewall/data" | $LOGGER +} + + + +fw_status() { + + echo -n "$(basename $0) $MBSEFW_VERSION" + + IP_MODULES=$($LSMOD | $AWK '{print $1}' | $GREP '^ip') + if [ "${IP_MODULES}x" = "x" ]; then + echo " - You do not have any iptables loaded." + return + else + echo " - You have the following ip modules loaded:" + echo -n " " + echo ${IP_MODULES} + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP iptable_filter )" ]; then + echo + echo ' FILTER TABLE IPv4' + echo + $IPTABLES -t filter -L -n -v --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP ip6table_filter )" ]; then + echo + echo ' FILTER TABLE IPv6' + echo + $IP6TABLES -t filter -L -n -v --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP iptable_nat )" ]; then + echo + echo ' NAT TABLE IPv4' + echo + $IPTABLES -t nat -L -v -n --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP ip6table_nat )" ]; then + echo + echo ' NAT TABLE IPv6' + echo + $IP6TABLES -t nat -L -v -n --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP iptable_raw )" ]; then + echo + echo ' RAW TABLE IPv4' + echo + $IPTABLES -t raw -L -v -n --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP ip6table_raw )" ]; then + echo + echo ' RAW TABLE IPv6' + echo + $IP6TABLES -t raw -L -v -n --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP iptable_mangle )" ]; then + echo + echo ' MANGLE TABLE IPv4' + echo + $IPTABLES -t mangle -L -v -n --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP ip6table_mangle )" ]; then + echo + echo ' MANGLE TABLE IPv6' + echo + $IP6TABLES -t mangle -L -v -n --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP iptable_security )" ]; then + echo + echo ' SECURITY TABLE IPv4' + echo + $IPTABLES -t security -L -v -n --line-numbers + fi + + if [ ! -z "$( echo $IP_MODULES | $GREP ip6table_security )" ]; then + echo + echo ' SECURITY TABLE IPv6' + echo + $IP6TABLES -t security -L -v -n --line-numbers + fi + + if [ -n "$IPSET" ] && [ ! -z "$($IPSET list)" ]; then + echo + echo ' IPSET listing' + echo + $IPSET list + fi +} + + + +# --------------------------------------------------------------------------- +# +# MAIN program part +# +# --------------------------------------------------------------------------- + + +# See how we were called +cmd=$1 + +case "$cmd" in + start) + fw_start + ;; + + stop) + fw_stop + ;; + + restart) + fw_stop + fw_start + ;; + + save) + fw_save + ;; + install) + fw_install + ;; + reload) + fw_reload + ;; + status) + fw_status + ;; + + *) + echo "Usage $0 [start|stop|restart|status]" + ;; +esac + +