From c48534146a4ab6265990952e4c52fb3ab689bbb1 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 09:11:49 +0200 Subject: [PATCH 01/42] Source files in /etc/default/minifirewall.d --- minifirewall | 26 +++++++++++++++------ minifirewall.conf | 25 ++++---------------- minifirewall.d/default-input-v6 | 7 ++++++ minifirewall.d/dhcp-v6.example | 4 ++++ minifirewall.d/dns-output-v6 | 3 +++ minifirewall.d/ntp-output-v6 | 3 +++ minifirewall.d/traceroute-output-v6.example | 3 +++ 7 files changed, 43 insertions(+), 28 deletions(-) create mode 100644 minifirewall.d/default-input-v6 create mode 100644 minifirewall.d/dhcp-v6.example create mode 100644 minifirewall.d/dns-output-v6 create mode 100644 minifirewall.d/ntp-output-v6 create mode 100644 minifirewall.d/traceroute-output-v6.example diff --git a/minifirewall b/minifirewall index c1a7251..9a64dff 100755 --- a/minifirewall +++ b/minifirewall @@ -61,6 +61,7 @@ chain_exists() # Configuration oldconfigfile="/etc/firewall.rc" configfile="/etc/default/minifirewall" +includesdir="/etc/default/minifirewall.d" IPV6=$(grep "IPV6=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') DOCKER=$(grep "DOCKER=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') @@ -133,14 +134,25 @@ if ! test -f $configfile; then exit 1 fi -tmpfile=`mktemp` -. $configfile 2>$tmpfile >&2 -if [ -s $tmpfile ]; then - echo "$configfile returns standard or error output (see below). Stopping." >&2 - cat $tmpfile - exit 1 +source_file_or_error() { + file=$1 + echo "...sourcing '${file}\`" + tmpfile=$(mktemp --tmpdir=/tmp minifirewall.XXX) + . ${file} 2>${tmpfile} >&2 + if [ -s ${tmpfile} ]; then + echo "${file} returns standard or error output (see below). Stopping." >&2 + cat ${tmpfile} + exit 1 + fi + rm ${tmpfile} +} +source_file_or_error ${configfile} +if [ -d "${includesdir}" ]; then + includefiles=$(find ${includesdir} -type f -readable -not -name '*.*') + for includefile in ${includefiles}; do + source_file_or_error "${includefile}" + done fi -rm $tmpfile # Trusted ip addresses $IPT -N ONLYTRUSTED diff --git a/minifirewall.conf b/minifirewall.conf index f5548fc..8230854 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -1,5 +1,6 @@ # Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall # Version 20.12 — 2020-12-01 22:55:35 +# shellcheck shell=sh disable=SC2034 # Main interface INT='eth0' @@ -77,26 +78,8 @@ SMTPSECUREOK='' NTPOK='0.0.0.0/0' -# IPv6 Specific rules +# Includes ##################### -# Example: allow input HTTP/HTTPS/SMTP/DNS traffic -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT - -# Example: allow output DNS, NTP and traceroute traffic -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 53 --match state --state NEW -j ACCEPT -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 123 --match state --state NEW -j ACCEPT -#/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT - -# Example: allow DHCPv6 -/sbin/ip6tables -A INPUT -i $INT -p udp --dport 546 -d fe80::/64 -j ACCEPT -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 547 -j ACCEPT - -# IPv4 Specific rules -##################### - -# /sbin/iptables ... +# Files in /etc/default/minifirewall.d/* (without "." in name) +# are automatically included in alphanumerical order. \ No newline at end of file diff --git a/minifirewall.d/default-input-v6 b/minifirewall.d/default-input-v6 new file mode 100644 index 0000000..38cfe3f --- /dev/null +++ b/minifirewall.d/default-input-v6 @@ -0,0 +1,7 @@ +# shellcheck shell=sh disable=SC2034 +# allow input HTTP/HTTPS/SMTP/DNS traffic +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT diff --git a/minifirewall.d/dhcp-v6.example b/minifirewall.d/dhcp-v6.example new file mode 100644 index 0000000..f2a60df --- /dev/null +++ b/minifirewall.d/dhcp-v6.example @@ -0,0 +1,4 @@ +# shellcheck shell=sh disable=SC2034 +# allow DHCPv6 +/sbin/ip6tables -A INPUT -i $INT -p udp --dport 546 -d fe80::/64 -j ACCEPT +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 547 -j ACCEPT \ No newline at end of file diff --git a/minifirewall.d/dns-output-v6 b/minifirewall.d/dns-output-v6 new file mode 100644 index 0000000..ac966ff --- /dev/null +++ b/minifirewall.d/dns-output-v6 @@ -0,0 +1,3 @@ +# shellcheck shell=sh disable=SC2034 +# allow DNS output +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 53 --match state --state NEW -j ACCEPT \ No newline at end of file diff --git a/minifirewall.d/ntp-output-v6 b/minifirewall.d/ntp-output-v6 new file mode 100644 index 0000000..e1a27e1 --- /dev/null +++ b/minifirewall.d/ntp-output-v6 @@ -0,0 +1,3 @@ +# shellcheck shell=sh disable=SC2034 +# allow NTP output +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 123 --match state --state NEW -j ACCEPT \ No newline at end of file diff --git a/minifirewall.d/traceroute-output-v6.example b/minifirewall.d/traceroute-output-v6.example new file mode 100644 index 0000000..786f352 --- /dev/null +++ b/minifirewall.d/traceroute-output-v6.example @@ -0,0 +1,3 @@ +# shellcheck shell=sh disable=SC2034 +# allow traceroute output +#/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT \ No newline at end of file From 72e3729a78e21fd2a54de9b492ad413b20a1da93 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 09:23:14 +0200 Subject: [PATCH 02/42] Extract main functions --- minifirewall | 636 ++++++++++++++++++++++++++------------------------- 1 file changed, 325 insertions(+), 311 deletions(-) diff --git a/minifirewall b/minifirewall index 9a64dff..acd5065 100755 --- a/minifirewall +++ b/minifirewall @@ -51,13 +51,6 @@ BROAD='255.255.255.255' PORTSROOT='0:1023' PORTSUSER='1024:65535' -chain_exists() -{ - local chain_name="$1" ; shift - [ $# -eq 1 ] && local intable="--table $1" - iptables $intable -nL "$chain_name" >/dev/null 2>&1 -} - # Configuration oldconfigfile="/etc/firewall.rc" configfile="/etc/default/minifirewall" @@ -67,76 +60,17 @@ IPV6=$(grep "IPV6=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') DOCKER=$(grep "DOCKER=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') INT=$(grep "INT=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') -case "$1" in - start) - - echo "Start IPTables rules..." - -# Stop and warn if error! -set -e -trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT - - -# sysctl network security settings -################################## - -# Don't answer to broadcast pings -echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts - -# Ignore bogus ICMP responses -echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses - -# Disable Source Routing -for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do -echo 0 > $i -done - -# Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks -# cf http://cr.yp.to/syncookies.html -echo 1 > /proc/sys/net/ipv4/tcp_syncookies - -# Disable ICMP redirects -for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do -echo 0 > $i -done - -for i in /proc/sys/net/ipv4/conf/*/send_redirects; do -echo 0 > $i -done - -# Enable Reverse Path filtering : verify if responses use same network interface -for i in /proc/sys/net/ipv4/conf/*/rp_filter; do -echo 1 > $i -done - -# log des paquets avec adresse incoherente -for i in /proc/sys/net/ipv4/conf/*/log_martians; do -echo 1 > $i -done - -# IPTables configuration -######################## - -$IPT -N LOG_DROP -$IPT -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' -$IPT -A LOG_DROP -j DROP -$IPT -N LOG_ACCEPT -$IPT -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' -$IPT -A LOG_ACCEPT -j ACCEPT - -if test -f $oldconfigfile; then - echo "$oldconfigfile is deprecated, rename to $configfile" >&2 - exit 1 -fi - -if ! test -f $configfile; then - echo "$configfile does not exist" >&2 - exit 1 -fi +chain_exists() +{ + local chain_name="$1" ; shift + [ $# -eq 1 ] && local intable="--table $1" + iptables $intable -nL "$chain_name" >/dev/null 2>&1 +} source_file_or_error() { file=$1 echo "...sourcing '${file}\`" + tmpfile=$(mktemp --tmpdir=/tmp minifirewall.XXX) . ${file} 2>${tmpfile} >&2 if [ -s ${tmpfile} ]; then @@ -146,280 +80,346 @@ source_file_or_error() { fi rm ${tmpfile} } -source_file_or_error ${configfile} -if [ -d "${includesdir}" ]; then - includefiles=$(find ${includesdir} -type f -readable -not -name '*.*') - for includefile in ${includefiles}; do - source_file_or_error "${includefile}" - done -fi -# Trusted ip addresses -$IPT -N ONLYTRUSTED -$IPT -A ONLYTRUSTED -j LOG_DROP -for x in $TRUSTEDIPS - do - $IPT -I ONLYTRUSTED -s $x -j ACCEPT +start() { + echo "Start IPTables rules..." + + # Stop and warn if error! + set -e + trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT + + + # sysctl network security settings + ################################## + + # Don't answer to broadcast pings + echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts + + # Ignore bogus ICMP responses + echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses + + # Disable Source Routing + for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do + echo 0 > $i done -# Privilegied ip addresses -# (trusted ip addresses *are* privilegied) -$IPT -N ONLYPRIVILEGIED -$IPT -A ONLYPRIVILEGIED -j ONLYTRUSTED -for x in $PRIVILEGIEDIPS - do - $IPT -I ONLYPRIVILEGIED -s $x -j ACCEPT + # Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks + # cf http://cr.yp.to/syncookies.html + echo 1 > /proc/sys/net/ipv4/tcp_syncookies + + # Disable ICMP redirects + for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do + echo 0 > $i done -# Chain for restrictions (blacklist IPs/ranges) -$IPT -N NEEDRESTRICT - -# We allow all on loopback interface -$IPT -A INPUT -i lo -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A INPUT -i lo -j ACCEPT -# if OUTPUTDROP -$IPT -A OUTPUT -o lo -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o lo -j ACCEPT - -# We avoid "martians" packets, typical when W32/Blaster virus -# attacked windowsupdate.com and DNS was changed to 127.0.0.1 -# $IPT -t NAT -I PREROUTING -s $LOOPBACK -i ! lo -j DROP -$IPT -A INPUT -s $LOOPBACK ! -i lo -j DROP - - -if [ "$DOCKER" = "on" ]; then - - $IPT -N MINIFW-DOCKER-TRUSTED - $IPT -A MINIFW-DOCKER-TRUSTED -j DROP - - $IPT -N MINIFW-DOCKER-PRIVILEGED - $IPT -A MINIFW-DOCKER-PRIVILEGED -j MINIFW-DOCKER-TRUSTED - $IPT -A MINIFW-DOCKER-PRIVILEGED -j RETURN - - $IPT -N MINIFW-DOCKER-PUB - $IPT -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED - $IPT -A MINIFW-DOCKER-PUB -j RETURN - - # Flush DOCKER-USER if exist, create it if absent - if chain_exists 'DOCKER-USER'; then - $IPT -F DOCKER-USER - else - $IPT -N DOCKER-USER - fi; - - # Pipe new connection through MINIFW-DOCKER-PUB - $IPT -A DOCKER-USER -i $INT -m state --state NEW -j MINIFW-DOCKER-PUB - $IPT -A DOCKER-USER -j RETURN - -fi - - -# Local services restrictions -############################# - -# Allow services for $INTLAN (local server or local network) -$IPT -A INPUT -s $INTLAN -j ACCEPT - -# Enable protection chain for sensible services -for x in $SERVICESTCP1p - do - $IPT -A INPUT -p tcp --dport $x -j NEEDRESTRICT + for i in /proc/sys/net/ipv4/conf/*/send_redirects; do + echo 0 > $i done -for x in $SERVICESUDP1p - do - $IPT -A INPUT -p udp --dport $x -j NEEDRESTRICT + # Enable Reverse Path filtering : verify if responses use same network interface + for i in /proc/sys/net/ipv4/conf/*/rp_filter; do + echo 1 > $i done -# Public service -for x in $SERVICESTCP1 - do - $IPT -A INPUT -p tcp --dport $x -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p tcp --dport $x -j ACCEPT + # log des paquets avec adresse incoherente + for i in /proc/sys/net/ipv4/conf/*/log_martians; do + echo 1 > $i done -for x in $SERVICESUDP1 - do - $IPT -A INPUT -p udp --dport $x -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p udp --dport $x -j ACCEPT - done + # IPTables configuration + ######################## -# Privilegied services -for x in $SERVICESTCP2 - do - $IPT -A INPUT -p tcp --dport $x -j ONLYPRIVILEGIED - done + $IPT -N LOG_DROP + $IPT -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' + $IPT -A LOG_DROP -j DROP + $IPT -N LOG_ACCEPT + $IPT -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' + $IPT -A LOG_ACCEPT -j ACCEPT -for x in $SERVICESUDP2 - do - $IPT -A INPUT -p udp --dport $x -j ONLYPRIVILEGIED - done + if test -f $oldconfigfile; then + echo "$oldconfigfile is deprecated, rename to $configfile" >&2 + exit 1 + fi -# Private services -for x in $SERVICESTCP3 - do - $IPT -A INPUT -p tcp --dport $x -j ONLYTRUSTED - done + if ! test -f $configfile; then + echo "$configfile does not exist" >&2 + exit 1 + fi -for x in $SERVICESUDP3 - do - $IPT -A INPUT -p udp --dport $x -j ONLYTRUSTED - done + source_file_or_error ${configfile} + if [ -d "${includesdir}" ]; then + includefiles=$(find ${includesdir} -type f -readable -not -name '*.*') + for includefile in ${includefiles}; do + source_file_or_error "${includefile}" + done + fi -if [ "$DOCKER" = "on" ]; then - - # Public services defined in SERVICESTCP1 & SERVICESUDP1 - for dstport in $SERVICESTCP1 + # Trusted ip addresses + $IPT -N ONLYTRUSTED + $IPT -A ONLYTRUSTED -j LOG_DROP + for x in $TRUSTEDIPS do - $IPT -I MINIFW-DOCKER-PUB -p tcp --dport "$dstport" -j RETURN + $IPT -I ONLYTRUSTED -s $x -j ACCEPT done - for dstport in $SERVICESUDP1 + # Privilegied ip addresses + # (trusted ip addresses *are* privilegied) + $IPT -N ONLYPRIVILEGIED + $IPT -A ONLYPRIVILEGIED -j ONLYTRUSTED + for x in $PRIVILEGIEDIPS do - $IPT -I MINIFW-DOCKER-PUB -p udp --dport "$dstport" -j RETURN + $IPT -I ONLYPRIVILEGIED -s $x -j ACCEPT done - # Privileged services (accessible from privileged & trusted IPs) - for dstport in $SERVICESTCP2 - do - for srcip in $PRIVILEGIEDIPS - do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN - done + # Chain for restrictions (blacklist IPs/ranges) + $IPT -N NEEDRESTRICT - for srcip in $TRUSTEDIPS - do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN - done + # We allow all on loopback interface + $IPT -A INPUT -i lo -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -i lo -j ACCEPT + # if OUTPUTDROP + $IPT -A OUTPUT -o lo -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o lo -j ACCEPT + + # We avoid "martians" packets, typical when W32/Blaster virus + # attacked windowsupdate.com and DNS was changed to 127.0.0.1 + # $IPT -t NAT -I PREROUTING -s $LOOPBACK -i ! lo -j DROP + $IPT -A INPUT -s $LOOPBACK ! -i lo -j DROP + + + if [ "$DOCKER" = "on" ]; then + + $IPT -N MINIFW-DOCKER-TRUSTED + $IPT -A MINIFW-DOCKER-TRUSTED -j DROP + + $IPT -N MINIFW-DOCKER-PRIVILEGED + $IPT -A MINIFW-DOCKER-PRIVILEGED -j MINIFW-DOCKER-TRUSTED + $IPT -A MINIFW-DOCKER-PRIVILEGED -j RETURN + + $IPT -N MINIFW-DOCKER-PUB + $IPT -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED + $IPT -A MINIFW-DOCKER-PUB -j RETURN + + # Flush DOCKER-USER if exist, create it if absent + if chain_exists 'DOCKER-USER'; then + $IPT -F DOCKER-USER + else + $IPT -N DOCKER-USER + fi; + + # Pipe new connection through MINIFW-DOCKER-PUB + $IPT -A DOCKER-USER -i $INT -m state --state NEW -j MINIFW-DOCKER-PUB + $IPT -A DOCKER-USER -j RETURN + + fi + + + # Local services restrictions + ############################# + + # Allow services for $INTLAN (local server or local network) + $IPT -A INPUT -s $INTLAN -j ACCEPT + + # Enable protection chain for sensible services + for x in $SERVICESTCP1p + do + $IPT -A INPUT -p tcp --dport $x -j NEEDRESTRICT done - for dstport in $SERVICESUDP2 + for x in $SERVICESUDP1p do - for srcip in $PRIVILEGIEDIPS - do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN - done - - for srcip in $TRUSTEDIPS - do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN - done + $IPT -A INPUT -p udp --dport $x -j NEEDRESTRICT done - # Trusted services (accessible from trusted IPs) - for dstport in $SERVICESTCP3 + # Public service + for x in $SERVICESTCP1 do - for srcip in $TRUSTEDIPS - do - $IPT -I MINIFW-DOCKER-TRUSTED -p tcp -s "$srcip" --dport "$dstport" -j RETURN - done + $IPT -A INPUT -p tcp --dport $x -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p tcp --dport $x -j ACCEPT done - for dstport in $SERVICESUDP3 + for x in $SERVICESUDP1 do - for srcip in $TRUSTEDIPS - do - $IPT -I MINIFW-DOCKER-TRUSTED -p udp -s "$srcip" --dport "$dstport" -j RETURN - done - done -fi - -# External services -################### - -# DNS authorizations -for x in $DNSSERVEURS - do - $IPT -A INPUT -p tcp ! --syn --sport 53 --dport $PORTSUSER -s $x -j ACCEPT - $IPT -A INPUT -p udp --sport 53 --dport $PORTSUSER -s $x -m state --state ESTABLISHED,RELATED -j ACCEPT - $IPT -A OUTPUT -o $INT -p udp -d $x --dport 53 --match state --state NEW -j ACCEPT - done - -# HTTP (TCP/80) authorizations -for x in $HTTPSITES - do - $IPT -A INPUT -p tcp ! --syn --sport 80 --dport $PORTSUSER -s $x -j ACCEPT - done - -# HTTPS (TCP/443) authorizations -for x in $HTTPSSITES - do - $IPT -A INPUT -p tcp ! --syn --sport 443 --dport $PORTSUSER -s $x -j ACCEPT - done - -# FTP (so complex protocol...) authorizations -for x in $FTPSITES - do - # requests on Control connection - $IPT -A INPUT -p tcp ! --syn --sport 21 --dport $PORTSUSER -s $x -j ACCEPT - # FTP port-mode on Data Connection - $IPT -A INPUT -p tcp --sport 20 --dport $PORTSUSER -s $x -j ACCEPT - # FTP passive-mode on Data Connection - # WARNING, this allow all connections on TCP ports > 1024 - $IPT -A INPUT -p tcp ! --syn --sport $PORTSUSER --dport $PORTSUSER -s $x -j ACCEPT - done - -# SSH authorizations -for x in $SSHOK - do - $IPT -A INPUT -p tcp ! --syn --sport 22 -s $x -j ACCEPT + $IPT -A INPUT -p udp --dport $x -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p udp --dport $x -j ACCEPT done -# SMTP authorizations -for x in $SMTPOK - do - $IPT -A INPUT -p tcp ! --syn --sport 25 --dport $PORTSUSER -s $x -j ACCEPT - done - -# secure SMTP (TCP/465 et TCP/587) authorizations -for x in $SMTPSECUREOK - do - $IPT -A INPUT -p tcp ! --syn --sport 465 --dport $PORTSUSER -s $x -j ACCEPT - $IPT -A INPUT -p tcp ! --syn --sport 587 --dport $PORTSUSER -s $x -j ACCEPT - done - -# NTP authorizations -for x in $NTPOK + # Privilegied services + for x in $SERVICESTCP2 do - $IPT -A INPUT -p udp --sport 123 -s $x -j ACCEPT - $IPT -A OUTPUT -o $INT -p udp -d $x --dport 123 --match state --state NEW -j ACCEPT + $IPT -A INPUT -p tcp --dport $x -j ONLYPRIVILEGIED done -# Always allow ICMP -$IPT -A INPUT -p icmp -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A INPUT -p icmpv6 -j ACCEPT + for x in $SERVICESUDP2 + do + $IPT -A INPUT -p udp --dport $x -j ONLYPRIVILEGIED + done + + # Private services + for x in $SERVICESTCP3 + do + $IPT -A INPUT -p tcp --dport $x -j ONLYTRUSTED + done + + for x in $SERVICESUDP3 + do + $IPT -A INPUT -p udp --dport $x -j ONLYTRUSTED + done -# IPTables policy -################# + if [ "$DOCKER" = "on" ]; then -# by default DROP INPUT packets -$IPT -P INPUT DROP -[ "$IPV6" != "off" ] && $IPT6 -P INPUT DROP + # Public services defined in SERVICESTCP1 & SERVICESUDP1 + for dstport in $SERVICESTCP1 + do + $IPT -I MINIFW-DOCKER-PUB -p tcp --dport "$dstport" -j RETURN + done -# by default, no FORWARING (deprecated for Virtual Machines) -#echo 0 > /proc/sys/net/ipv4/ip_forward -#$IPT -P FORWARD DROP -#$IPT6 -P FORWARD DROP + for dstport in $SERVICESUDP1 + do + $IPT -I MINIFW-DOCKER-PUB -p udp --dport "$dstport" -j RETURN + done -# by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) -$IPT -P OUTPUT ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT -$IPT -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT -$IPT -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT -$IPT -A OUTPUT -p udp -j DROP -[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT -[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp -j DROP + # Privileged services (accessible from privileged & trusted IPs) + for dstport in $SERVICESTCP2 + do + for srcip in $PRIVILEGIEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done -trap - INT TERM EXIT + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + for dstport in $SERVICESUDP2 + do + for srcip in $PRIVILEGIEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + # Trusted services (accessible from trusted IPs) + for dstport in $SERVICESTCP3 + do + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-TRUSTED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + for dstport in $SERVICESUDP3 + do + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-TRUSTED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + done + fi + + # External services + ################### + + # DNS authorizations + for x in $DNSSERVEURS + do + $IPT -A INPUT -p tcp ! --syn --sport 53 --dport $PORTSUSER -s $x -j ACCEPT + $IPT -A INPUT -p udp --sport 53 --dport $PORTSUSER -s $x -m state --state ESTABLISHED,RELATED -j ACCEPT + $IPT -A OUTPUT -o $INT -p udp -d $x --dport 53 --match state --state NEW -j ACCEPT + done + + # HTTP (TCP/80) authorizations + for x in $HTTPSITES + do + $IPT -A INPUT -p tcp ! --syn --sport 80 --dport $PORTSUSER -s $x -j ACCEPT + done + + # HTTPS (TCP/443) authorizations + for x in $HTTPSSITES + do + $IPT -A INPUT -p tcp ! --syn --sport 443 --dport $PORTSUSER -s $x -j ACCEPT + done + + # FTP (so complex protocol...) authorizations + for x in $FTPSITES + do + # requests on Control connection + $IPT -A INPUT -p tcp ! --syn --sport 21 --dport $PORTSUSER -s $x -j ACCEPT + # FTP port-mode on Data Connection + $IPT -A INPUT -p tcp --sport 20 --dport $PORTSUSER -s $x -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + $IPT -A INPUT -p tcp ! --syn --sport $PORTSUSER --dport $PORTSUSER -s $x -j ACCEPT + done + + # SSH authorizations + for x in $SSHOK + do + $IPT -A INPUT -p tcp ! --syn --sport 22 -s $x -j ACCEPT + done + + # SMTP authorizations + for x in $SMTPOK + do + $IPT -A INPUT -p tcp ! --syn --sport 25 --dport $PORTSUSER -s $x -j ACCEPT + done + + # secure SMTP (TCP/465 et TCP/587) authorizations + for x in $SMTPSECUREOK + do + $IPT -A INPUT -p tcp ! --syn --sport 465 --dport $PORTSUSER -s $x -j ACCEPT + $IPT -A INPUT -p tcp ! --syn --sport 587 --dport $PORTSUSER -s $x -j ACCEPT + done + + # NTP authorizations + for x in $NTPOK + do + $IPT -A INPUT -p udp --sport 123 -s $x -j ACCEPT + $IPT -A OUTPUT -o $INT -p udp -d $x --dport 123 --match state --state NEW -j ACCEPT + done + + # Always allow ICMP + $IPT -A INPUT -p icmp -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p icmpv6 -j ACCEPT + + + # IPTables policy + ################# + + # by default DROP INPUT packets + $IPT -P INPUT DROP + [ "$IPV6" != "off" ] && $IPT6 -P INPUT DROP + + # by default, no FORWARING (deprecated for Virtual Machines) + #echo 0 > /proc/sys/net/ipv4/ip_forward + #$IPT -P FORWARD DROP + #$IPT6 -P FORWARD DROP + + # by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) + $IPT -P OUTPUT ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT + $IPT -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + $IPT -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT + $IPT -A OUTPUT -p udp -j DROP + [ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp -j DROP + + trap - INT TERM EXIT echo "...starting IPTables rules is now finish : OK" - ;; - - stop) +} +stop() { echo "Flush all rules and accept everything..." # Delete all rules @@ -465,19 +465,17 @@ trap - INT TERM EXIT $IPT -X NEEDRESTRICT echo "...flushing IPTables rules is now finish : OK" - ;; - - status) +} +status() { $IPT -L -n -v --line-numbers $IPT -t nat -L -n -v --line-numbers $IPT -t mangle -L -n -v --line-numbers $IPT6 -L -n -v --line-numbers $IPT6 -t mangle -L -n -v --line-numbers - ;; - - reset) +} +reset() { echo "Reset all IPTables counters..." $IPT -Z @@ -487,13 +485,29 @@ trap - INT TERM EXIT [ "$IPV6" != "off" ] && $IPT6 -t mangle -Z echo "...reseting IPTables counters is now finish : OK" - ;; +} - restart) +case "$1" in + start) + start + ;; - $0 stop - $0 start - ;; + stop) + stop + ;; + + status) + status + ;; + + reset) + reset + ;; + + restart) + stop + start + ;; *) From 9a9fc7fd440f21d80d54bc20bdf904ac2c2d4172 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 09:23:31 +0200 Subject: [PATCH 03/42] squid command seems obsolete --- minifirewall | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/minifirewall b/minifirewall index acd5065..52869d9 100755 --- a/minifirewall +++ b/minifirewall @@ -70,7 +70,7 @@ chain_exists() source_file_or_error() { file=$1 echo "...sourcing '${file}\`" - + tmpfile=$(mktemp --tmpdir=/tmp minifirewall.XXX) . ${file} 2>${tmpfile} >&2 if [ -s ${tmpfile} ]; then @@ -511,7 +511,7 @@ case "$1" in *) - echo "Usage: $0 {start|stop|restart|status|reset|squid}" + echo "Usage: $0 {start|stop|restart|status|reset}" exit 1 esac From e02be5b852464ddf67878ed204ea16bd99a34c27 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 09:34:35 +0200 Subject: [PATCH 04/42] Surround variable names with curly braces --- minifirewall | 335 ++++++++++++++++++++++++++------------------------- 1 file changed, 168 insertions(+), 167 deletions(-) diff --git a/minifirewall b/minifirewall index 52869d9..14b97fa 100755 --- a/minifirewall +++ b/minifirewall @@ -64,7 +64,8 @@ chain_exists() { local chain_name="$1" ; shift [ $# -eq 1 ] && local intable="--table $1" - iptables $intable -nL "$chain_name" >/dev/null 2>&1 + # shellcheck disable=SC2086 + iptables ${intable} -nL "${chain_name}" >/dev/null 2>&1 } source_file_or_error() { @@ -72,13 +73,13 @@ source_file_or_error() { echo "...sourcing '${file}\`" tmpfile=$(mktemp --tmpdir=/tmp minifirewall.XXX) - . ${file} 2>${tmpfile} >&2 - if [ -s ${tmpfile} ]; then + . "${file}" 2>"${tmpfile}" >&2 + if [ -s "${tmpfile}" ]; then echo "${file} returns standard or error output (see below). Stopping." >&2 - cat ${tmpfile} + cat "${tmpfile}" exit 1 fi - rm ${tmpfile} + rm "${tmpfile}" } start() { @@ -100,7 +101,7 @@ start() { # Disable Source Routing for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do - echo 0 > $i + echo 0 > "${i}" done # Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks @@ -109,40 +110,40 @@ start() { # Disable ICMP redirects for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do - echo 0 > $i + echo 0 > "${i}" done for i in /proc/sys/net/ipv4/conf/*/send_redirects; do - echo 0 > $i + echo 0 > "${i}" done # Enable Reverse Path filtering : verify if responses use same network interface for i in /proc/sys/net/ipv4/conf/*/rp_filter; do - echo 1 > $i + echo 1 > "${i}" done # log des paquets avec adresse incoherente for i in /proc/sys/net/ipv4/conf/*/log_martians; do - echo 1 > $i + echo 1 > "${i}" done # IPTables configuration ######################## - $IPT -N LOG_DROP - $IPT -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' - $IPT -A LOG_DROP -j DROP - $IPT -N LOG_ACCEPT - $IPT -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' - $IPT -A LOG_ACCEPT -j ACCEPT + ${IPT} -N LOG_DROP + ${IPT} -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' + ${IPT} -A LOG_DROP -j DROP + ${IPT} -N LOG_ACCEPT + ${IPT} -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' + ${IPT} -A LOG_ACCEPT -j ACCEPT - if test -f $oldconfigfile; then - echo "$oldconfigfile is deprecated, rename to $configfile" >&2 + if test -f ${oldconfigfile}; then + echo "${oldconfigfile} is deprecated, rename to ${configfile}" >&2 exit 1 fi - if ! test -f $configfile; then - echo "$configfile does not exist" >&2 + if ! test -f ${configfile}; then + echo "${configfile} does not exist" >&2 exit 1 fi @@ -156,61 +157,61 @@ start() { fi # Trusted ip addresses - $IPT -N ONLYTRUSTED - $IPT -A ONLYTRUSTED -j LOG_DROP - for x in $TRUSTEDIPS + ${IPT} -N ONLYTRUSTED + ${IPT} -A ONLYTRUSTED -j LOG_DROP + for x in ${TRUSTEDIPS} do - $IPT -I ONLYTRUSTED -s $x -j ACCEPT + ${IPT} -I ONLYTRUSTED -s ${x} -j ACCEPT done # Privilegied ip addresses # (trusted ip addresses *are* privilegied) - $IPT -N ONLYPRIVILEGIED - $IPT -A ONLYPRIVILEGIED -j ONLYTRUSTED - for x in $PRIVILEGIEDIPS + ${IPT} -N ONLYPRIVILEGIED + ${IPT} -A ONLYPRIVILEGIED -j ONLYTRUSTED + for x in ${PRIVILEGIEDIPS} do - $IPT -I ONLYPRIVILEGIED -s $x -j ACCEPT + ${IPT} -I ONLYPRIVILEGIED -s ${x} -j ACCEPT done # Chain for restrictions (blacklist IPs/ranges) - $IPT -N NEEDRESTRICT + ${IPT} -N NEEDRESTRICT # We allow all on loopback interface - $IPT -A INPUT -i lo -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A INPUT -i lo -j ACCEPT + ${IPT} -A INPUT -i lo -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -i lo -j ACCEPT # if OUTPUTDROP - $IPT -A OUTPUT -o lo -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o lo -j ACCEPT + ${IPT} -A OUTPUT -o lo -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A OUTPUT -o lo -j ACCEPT # We avoid "martians" packets, typical when W32/Blaster virus # attacked windowsupdate.com and DNS was changed to 127.0.0.1 - # $IPT -t NAT -I PREROUTING -s $LOOPBACK -i ! lo -j DROP - $IPT -A INPUT -s $LOOPBACK ! -i lo -j DROP + # ${IPT} -t NAT -I PREROUTING -s ${LOOPBACK} -i ! lo -j DROP + ${IPT} -A INPUT -s ${LOOPBACK} ! -i lo -j DROP - if [ "$DOCKER" = "on" ]; then + if [ "${DOCKER}" = "on" ]; then - $IPT -N MINIFW-DOCKER-TRUSTED - $IPT -A MINIFW-DOCKER-TRUSTED -j DROP + ${IPT} -N MINIFW-DOCKER-TRUSTED + ${IPT} -A MINIFW-DOCKER-TRUSTED -j DROP - $IPT -N MINIFW-DOCKER-PRIVILEGED - $IPT -A MINIFW-DOCKER-PRIVILEGED -j MINIFW-DOCKER-TRUSTED - $IPT -A MINIFW-DOCKER-PRIVILEGED -j RETURN + ${IPT} -N MINIFW-DOCKER-PRIVILEGED + ${IPT} -A MINIFW-DOCKER-PRIVILEGED -j MINIFW-DOCKER-TRUSTED + ${IPT} -A MINIFW-DOCKER-PRIVILEGED -j RETURN - $IPT -N MINIFW-DOCKER-PUB - $IPT -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED - $IPT -A MINIFW-DOCKER-PUB -j RETURN + ${IPT} -N MINIFW-DOCKER-PUB + ${IPT} -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED + ${IPT} -A MINIFW-DOCKER-PUB -j RETURN # Flush DOCKER-USER if exist, create it if absent if chain_exists 'DOCKER-USER'; then - $IPT -F DOCKER-USER + ${IPT} -F DOCKER-USER else - $IPT -N DOCKER-USER + ${IPT} -N DOCKER-USER fi; # Pipe new connection through MINIFW-DOCKER-PUB - $IPT -A DOCKER-USER -i $INT -m state --state NEW -j MINIFW-DOCKER-PUB - $IPT -A DOCKER-USER -j RETURN + ${IPT} -A DOCKER-USER -i ${INT} -m state --state NEW -j MINIFW-DOCKER-PUB + ${IPT} -A DOCKER-USER -j RETURN fi @@ -218,110 +219,110 @@ start() { # Local services restrictions ############################# - # Allow services for $INTLAN (local server or local network) - $IPT -A INPUT -s $INTLAN -j ACCEPT + # Allow services for ${INTLAN} (local server or local network) + ${IPT} -A INPUT -s ${INTLAN} -j ACCEPT # Enable protection chain for sensible services - for x in $SERVICESTCP1p + for x in ${SERVICESTCP1p} do - $IPT -A INPUT -p tcp --dport $x -j NEEDRESTRICT + ${IPT} -A INPUT -p tcp --dport ${x} -j NEEDRESTRICT done - for x in $SERVICESUDP1p + for x in ${SERVICESUDP1p} do - $IPT -A INPUT -p udp --dport $x -j NEEDRESTRICT + ${IPT} -A INPUT -p udp --dport ${x} -j NEEDRESTRICT done # Public service - for x in $SERVICESTCP1 + for x in ${SERVICESTCP1} do - $IPT -A INPUT -p tcp --dport $x -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p tcp --dport $x -j ACCEPT + ${IPT} -A INPUT -p tcp --dport ${x} -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p tcp --dport ${x} -j ACCEPT done - for x in $SERVICESUDP1 + for x in ${SERVICESUDP1} do - $IPT -A INPUT -p udp --dport $x -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p udp --dport $x -j ACCEPT + ${IPT} -A INPUT -p udp --dport ${x} -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p udp --dport ${x} -j ACCEPT done # Privilegied services - for x in $SERVICESTCP2 + for x in ${SERVICESTCP2} do - $IPT -A INPUT -p tcp --dport $x -j ONLYPRIVILEGIED + ${IPT} -A INPUT -p tcp --dport ${x} -j ONLYPRIVILEGIED done - for x in $SERVICESUDP2 + for x in ${SERVICESUDP2} do - $IPT -A INPUT -p udp --dport $x -j ONLYPRIVILEGIED + ${IPT} -A INPUT -p udp --dport ${x} -j ONLYPRIVILEGIED done # Private services - for x in $SERVICESTCP3 + for x in ${SERVICESTCP3} do - $IPT -A INPUT -p tcp --dport $x -j ONLYTRUSTED + ${IPT} -A INPUT -p tcp --dport ${x} -j ONLYTRUSTED done - for x in $SERVICESUDP3 + for x in ${SERVICESUDP3} do - $IPT -A INPUT -p udp --dport $x -j ONLYTRUSTED + ${IPT} -A INPUT -p udp --dport ${x} -j ONLYTRUSTED done - if [ "$DOCKER" = "on" ]; then + if [ "${DOCKER}" = "on" ]; then # Public services defined in SERVICESTCP1 & SERVICESUDP1 - for dstport in $SERVICESTCP1 + for dstport in ${SERVICESTCP1} do - $IPT -I MINIFW-DOCKER-PUB -p tcp --dport "$dstport" -j RETURN + ${IPT} -I MINIFW-DOCKER-PUB -p tcp --dport "${dstport}" -j RETURN done - for dstport in $SERVICESUDP1 + for dstport in ${SERVICESUDP1} do - $IPT -I MINIFW-DOCKER-PUB -p udp --dport "$dstport" -j RETURN + ${IPT} -I MINIFW-DOCKER-PUB -p udp --dport "${dstport}" -j RETURN done # Privileged services (accessible from privileged & trusted IPs) - for dstport in $SERVICESTCP2 + for dstport in ${SERVICESTCP2} do - for srcip in $PRIVILEGIEDIPS + for srcip in ${PRIVILEGIEDIPS} do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN done - for srcip in $TRUSTEDIPS + for srcip in ${TRUSTEDIPS} do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN done done - for dstport in $SERVICESUDP2 + for dstport in ${SERVICESUDP2} do - for srcip in $PRIVILEGIEDIPS + for srcip in ${PRIVILEGIEDIPS} do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN done - for srcip in $TRUSTEDIPS + for srcip in ${TRUSTEDIPS} do - $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN done done # Trusted services (accessible from trusted IPs) - for dstport in $SERVICESTCP3 + for dstport in ${SERVICESTCP3} do - for srcip in $TRUSTEDIPS + for srcip in ${TRUSTEDIPS} do - $IPT -I MINIFW-DOCKER-TRUSTED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + ${IPT} -I MINIFW-DOCKER-TRUSTED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN done done - for dstport in $SERVICESUDP3 + for dstport in ${SERVICESUDP3} do - for srcip in $TRUSTEDIPS + for srcip in ${TRUSTEDIPS} do - $IPT -I MINIFW-DOCKER-TRUSTED -p udp -s "$srcip" --dport "$dstport" -j RETURN + ${IPT} -I MINIFW-DOCKER-TRUSTED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN done done fi @@ -330,89 +331,89 @@ start() { ################### # DNS authorizations - for x in $DNSSERVEURS + for x in ${DNSSERVEURS} do - $IPT -A INPUT -p tcp ! --syn --sport 53 --dport $PORTSUSER -s $x -j ACCEPT - $IPT -A INPUT -p udp --sport 53 --dport $PORTSUSER -s $x -m state --state ESTABLISHED,RELATED -j ACCEPT - $IPT -A OUTPUT -o $INT -p udp -d $x --dport 53 --match state --state NEW -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${x} -j ACCEPT + ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${x} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${x} --dport 53 --match state --state NEW -j ACCEPT done # HTTP (TCP/80) authorizations - for x in $HTTPSITES + for x in ${HTTPSITES} do - $IPT -A INPUT -p tcp ! --syn --sport 80 --dport $PORTSUSER -s $x -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${x} -j ACCEPT done # HTTPS (TCP/443) authorizations - for x in $HTTPSSITES + for x in ${HTTPSSITES} do - $IPT -A INPUT -p tcp ! --syn --sport 443 --dport $PORTSUSER -s $x -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${x} -j ACCEPT done # FTP (so complex protocol...) authorizations - for x in $FTPSITES + for x in ${FTPSITES} do # requests on Control connection - $IPT -A INPUT -p tcp ! --syn --sport 21 --dport $PORTSUSER -s $x -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${x} -j ACCEPT # FTP port-mode on Data Connection - $IPT -A INPUT -p tcp --sport 20 --dport $PORTSUSER -s $x -j ACCEPT + ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${x} -j ACCEPT # FTP passive-mode on Data Connection # WARNING, this allow all connections on TCP ports > 1024 - $IPT -A INPUT -p tcp ! --syn --sport $PORTSUSER --dport $PORTSUSER -s $x -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${x} -j ACCEPT done # SSH authorizations - for x in $SSHOK + for x in ${SSHOK} do - $IPT -A INPUT -p tcp ! --syn --sport 22 -s $x -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 22 -s ${x} -j ACCEPT done # SMTP authorizations - for x in $SMTPOK + for x in ${SMTPOK} do - $IPT -A INPUT -p tcp ! --syn --sport 25 --dport $PORTSUSER -s $x -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${x} -j ACCEPT done # secure SMTP (TCP/465 et TCP/587) authorizations - for x in $SMTPSECUREOK + for x in ${SMTPSECUREOK} do - $IPT -A INPUT -p tcp ! --syn --sport 465 --dport $PORTSUSER -s $x -j ACCEPT - $IPT -A INPUT -p tcp ! --syn --sport 587 --dport $PORTSUSER -s $x -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${x} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${x} -j ACCEPT done # NTP authorizations - for x in $NTPOK + for x in ${NTPOK} do - $IPT -A INPUT -p udp --sport 123 -s $x -j ACCEPT - $IPT -A OUTPUT -o $INT -p udp -d $x --dport 123 --match state --state NEW -j ACCEPT + ${IPT} -A INPUT -p udp --sport 123 -s ${x} -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${x} --dport 123 --match state --state NEW -j ACCEPT done # Always allow ICMP - $IPT -A INPUT -p icmp -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p icmpv6 -j ACCEPT + ${IPT} -A INPUT -p icmp -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p icmpv6 -j ACCEPT # IPTables policy ################# # by default DROP INPUT packets - $IPT -P INPUT DROP - [ "$IPV6" != "off" ] && $IPT6 -P INPUT DROP + ${IPT} -P INPUT DROP + [ "${IPV6}" != "off" ] && ${IPT6} -P INPUT DROP # by default, no FORWARING (deprecated for Virtual Machines) #echo 0 > /proc/sys/net/ipv4/ip_forward - #$IPT -P FORWARD DROP - #$IPT6 -P FORWARD DROP + #${IPT} -P FORWARD DROP + #${IPT6} -P FORWARD DROP # by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) - $IPT -P OUTPUT ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT - $IPT -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT - $IPT -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT - $IPT -A OUTPUT -p udp -j DROP - [ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp -j DROP + ${IPT} -P OUTPUT ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -P OUTPUT ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + ${IPT} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT} -A OUTPUT -p udp -j DROP + [ "${IPV6}" != "off" ] && ${IPT6} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A OUTPUT -p udp -j DROP trap - INT TERM EXIT @@ -423,66 +424,66 @@ stop() { echo "Flush all rules and accept everything..." # Delete all rules - $IPT -F INPUT - $IPT -F OUTPUT - $IPT -F LOG_DROP - $IPT -F LOG_ACCEPT - $IPT -F ONLYTRUSTED - $IPT -F ONLYPRIVILEGIED - $IPT -F NEEDRESTRICT - [ "$DOCKER" = "off" ] && $IPT -t nat -F - $IPT -t mangle -F - [ "$IPV6" != "off" ] && $IPT6 -F INPUT - [ "$IPV6" != "off" ] && $IPT6 -F OUTPUT + ${IPT} -F INPUT + ${IPT} -F OUTPUT + ${IPT} -F LOG_DROP + ${IPT} -F LOG_ACCEPT + ${IPT} -F ONLYTRUSTED + ${IPT} -F ONLYPRIVILEGIED + ${IPT} -F NEEDRESTRICT + [ "${DOCKER}" = "off" ] && ${IPT} -t nat -F + ${IPT} -t mangle -F + [ "${IPV6}" != "off" ] && ${IPT6} -F INPUT + [ "${IPV6}" != "off" ] && ${IPT6} -F OUTPUT - if [ "$DOCKER" = "on" ]; then - $IPT -F DOCKER-USER - $IPT -A DOCKER-USER -j RETURN + if [ "${DOCKER}" = "on" ]; then + ${IPT} -F DOCKER-USER + ${IPT} -A DOCKER-USER -j RETURN - $IPT -F MINIFW-DOCKER-PUB - $IPT -X MINIFW-DOCKER-PUB - $IPT -F MINIFW-DOCKER-PRIVILEGED - $IPT -X MINIFW-DOCKER-PRIVILEGED - $IPT -F MINIFW-DOCKER-TRUSTED - $IPT -X MINIFW-DOCKER-TRUSTED + ${IPT} -F MINIFW-DOCKER-PUB + ${IPT} -X MINIFW-DOCKER-PUB + ${IPT} -F MINIFW-DOCKER-PRIVILEGED + ${IPT} -X MINIFW-DOCKER-PRIVILEGED + ${IPT} -F MINIFW-DOCKER-TRUSTED + ${IPT} -X MINIFW-DOCKER-TRUSTED fi # Accept all - $IPT -P INPUT ACCEPT - $IPT -P OUTPUT ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -P INPUT ACCEPT - [ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT - #$IPT -P FORWARD ACCEPT - #$IPT -t nat -P PREROUTING ACCEPT - #$IPT -t nat -P POSTROUTING ACCEPT + ${IPT} -P INPUT ACCEPT + ${IPT} -P OUTPUT ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -P INPUT ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -P OUTPUT ACCEPT + #${IPT} -P FORWARD ACCEPT + #${IPT} -t nat -P PREROUTING ACCEPT + #${IPT} -t nat -P POSTROUTING ACCEPT # Delete non-standard chains - $IPT -X LOG_DROP - $IPT -X LOG_ACCEPT - $IPT -X ONLYPRIVILEGIED - $IPT -X ONLYTRUSTED - $IPT -X NEEDRESTRICT + ${IPT} -X LOG_DROP + ${IPT} -X LOG_ACCEPT + ${IPT} -X ONLYPRIVILEGIED + ${IPT} -X ONLYTRUSTED + ${IPT} -X NEEDRESTRICT echo "...flushing IPTables rules is now finish : OK" } status() { - $IPT -L -n -v --line-numbers - $IPT -t nat -L -n -v --line-numbers - $IPT -t mangle -L -n -v --line-numbers - $IPT6 -L -n -v --line-numbers - $IPT6 -t mangle -L -n -v --line-numbers + ${IPT} -L -n -v --line-numbers + ${IPT} -t nat -L -n -v --line-numbers + ${IPT} -t mangle -L -n -v --line-numbers + ${IPT6} -L -n -v --line-numbers + ${IPT6} -t mangle -L -n -v --line-numbers } reset() { echo "Reset all IPTables counters..." - $IPT -Z - $IPT -t nat -Z - $IPT -t mangle -Z - [ "$IPV6" != "off" ] && $IPT6 -Z - [ "$IPV6" != "off" ] && $IPT6 -t mangle -Z + ${IPT} -Z + ${IPT} -t nat -Z + ${IPT} -t mangle -Z + [ "${IPV6}" != "off" ] && ${IPT6} -Z + [ "${IPV6}" != "off" ] && ${IPT6} -t mangle -Z echo "...reseting IPTables counters is now finish : OK" } From a3ab1a4f2eb66938192d1f84eedb63c5ce3414fa Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 09:35:51 +0200 Subject: [PATCH 05/42] variables with better names --- minifirewall | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/minifirewall b/minifirewall index 14b97fa..47f20ed 100755 --- a/minifirewall +++ b/minifirewall @@ -223,49 +223,49 @@ start() { ${IPT} -A INPUT -s ${INTLAN} -j ACCEPT # Enable protection chain for sensible services - for x in ${SERVICESTCP1p} + for port in ${SERVICESTCP1p} do - ${IPT} -A INPUT -p tcp --dport ${x} -j NEEDRESTRICT + ${IPT} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT done - for x in ${SERVICESUDP1p} + for port in ${SERVICESUDP1p} do - ${IPT} -A INPUT -p udp --dport ${x} -j NEEDRESTRICT + ${IPT} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT done # Public service - for x in ${SERVICESTCP1} + for port in ${SERVICESTCP1} do - ${IPT} -A INPUT -p tcp --dport ${x} -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p tcp --dport ${x} -j ACCEPT + ${IPT} -A INPUT -p tcp --dport ${port} -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p tcp --dport ${port} -j ACCEPT done - for x in ${SERVICESUDP1} + for port in ${SERVICESUDP1} do - ${IPT} -A INPUT -p udp --dport ${x} -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p udp --dport ${x} -j ACCEPT + ${IPT} -A INPUT -p udp --dport ${port} -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p udp --dport ${port} -j ACCEPT done # Privilegied services - for x in ${SERVICESTCP2} + for port in ${SERVICESTCP2} do - ${IPT} -A INPUT -p tcp --dport ${x} -j ONLYPRIVILEGIED + ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED done - for x in ${SERVICESUDP2} + for port in ${SERVICESUDP2} do - ${IPT} -A INPUT -p udp --dport ${x} -j ONLYPRIVILEGIED + ${IPT} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED done # Private services - for x in ${SERVICESTCP3} + for port in ${SERVICESTCP3} do - ${IPT} -A INPUT -p tcp --dport ${x} -j ONLYTRUSTED + ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED done - for x in ${SERVICESUDP3} + for port in ${SERVICESUDP3} do - ${IPT} -A INPUT -p udp --dport ${x} -j ONLYTRUSTED + ${IPT} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED done From 8eb0180b5165bd6519edda909b0629494af00af4 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 09:41:29 +0200 Subject: [PATCH 06/42] compact syntax for loops --- minifirewall | 222 ++++++++++++++++++++++----------------------------- 1 file changed, 96 insertions(+), 126 deletions(-) diff --git a/minifirewall b/minifirewall index 47f20ed..c63f744 100755 --- a/minifirewall +++ b/minifirewall @@ -159,19 +159,17 @@ start() { # Trusted ip addresses ${IPT} -N ONLYTRUSTED ${IPT} -A ONLYTRUSTED -j LOG_DROP - for x in ${TRUSTEDIPS} - do - ${IPT} -I ONLYTRUSTED -s ${x} -j ACCEPT - done + for ip in ${TRUSTEDIPS}; do + ${IPT} -I ONLYTRUSTED -s ${ip} -j ACCEPT + done # Privilegied ip addresses # (trusted ip addresses *are* privilegied) ${IPT} -N ONLYPRIVILEGIED ${IPT} -A ONLYPRIVILEGIED -j ONLYTRUSTED - for x in ${PRIVILEGIEDIPS} - do - ${IPT} -I ONLYPRIVILEGIED -s ${x} -j ACCEPT - done + for ip in ${PRIVILEGIEDIPS}; do + ${IPT} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT + done # Chain for restrictions (blacklist IPs/ranges) ${IPT} -N NEEDRESTRICT @@ -223,170 +221,142 @@ start() { ${IPT} -A INPUT -s ${INTLAN} -j ACCEPT # Enable protection chain for sensible services - for port in ${SERVICESTCP1p} - do - ${IPT} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT - done + for port in ${SERVICESTCP1p}; do + ${IPT} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT + done - for port in ${SERVICESUDP1p} - do - ${IPT} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT - done + for port in ${SERVICESUDP1p}; do + ${IPT} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT + done # Public service - for port in ${SERVICESTCP1} - do - ${IPT} -A INPUT -p tcp --dport ${port} -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p tcp --dport ${port} -j ACCEPT - done + for port in ${SERVICESTCP1}; do + ${IPT} -A INPUT -p tcp --dport ${port} -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p tcp --dport ${port} -j ACCEPT + done - for port in ${SERVICESUDP1} - do - ${IPT} -A INPUT -p udp --dport ${port} -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p udp --dport ${port} -j ACCEPT - done + for port in ${SERVICESUDP1}; do + ${IPT} -A INPUT -p udp --dport ${port} -j ACCEPT + [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p udp --dport ${port} -j ACCEPT + done # Privilegied services - for port in ${SERVICESTCP2} - do - ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED - done + for port in ${SERVICESTCP2}; do + ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED + done - for port in ${SERVICESUDP2} - do - ${IPT} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED - done + for port in ${SERVICESUDP2}; do + ${IPT} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED + done # Private services - for port in ${SERVICESTCP3} - do - ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED - done + for port in ${SERVICESTCP3}; do + ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED + done - for port in ${SERVICESUDP3} - do - ${IPT} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED - done + for port in ${SERVICESUDP3}; do + ${IPT} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED + done if [ "${DOCKER}" = "on" ]; then # Public services defined in SERVICESTCP1 & SERVICESUDP1 - for dstport in ${SERVICESTCP1} - do - ${IPT} -I MINIFW-DOCKER-PUB -p tcp --dport "${dstport}" -j RETURN - done + for dstport in ${SERVICESTCP1}; do + ${IPT} -I MINIFW-DOCKER-PUB -p tcp --dport "${dstport}" -j RETURN + done - for dstport in ${SERVICESUDP1} - do - ${IPT} -I MINIFW-DOCKER-PUB -p udp --dport "${dstport}" -j RETURN - done + for dstport in ${SERVICESUDP1}; do + ${IPT} -I MINIFW-DOCKER-PUB -p udp --dport "${dstport}" -j RETURN + done # Privileged services (accessible from privileged & trusted IPs) - for dstport in ${SERVICESTCP2} - do - for srcip in ${PRIVILEGIEDIPS} - do - ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN - done - - for srcip in ${TRUSTEDIPS} - do - ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN - done + for dstport in ${SERVICESTCP2}; do + for srcip in ${PRIVILEGIEDIPS}; do + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN done - for dstport in ${SERVICESUDP2} - do - for srcip in ${PRIVILEGIEDIPS} - do - ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN - done - - for srcip in ${TRUSTEDIPS} - do - ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN - done + for srcip in ${TRUSTEDIPS}; do + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN done + done + + for dstport in ${SERVICESUDP2}; do + for srcip in ${PRIVILEGIEDIPS}; do + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + done + + for srcip in ${TRUSTEDIPS}; do + ${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN + done + done # Trusted services (accessible from trusted IPs) - for dstport in ${SERVICESTCP3} - do - for srcip in ${TRUSTEDIPS} - do - ${IPT} -I MINIFW-DOCKER-TRUSTED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN - done + for dstport in ${SERVICESTCP3}; do + for srcip in ${TRUSTEDIPS}; do + ${IPT} -I MINIFW-DOCKER-TRUSTED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN done + done - for dstport in ${SERVICESUDP3} - do - for srcip in ${TRUSTEDIPS} - do - ${IPT} -I MINIFW-DOCKER-TRUSTED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN - done + for dstport in ${SERVICESUDP3}; do + for srcip in ${TRUSTEDIPS}; do + ${IPT} -I MINIFW-DOCKER-TRUSTED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN done + done fi # External services ################### # DNS authorizations - for x in ${DNSSERVEURS} - do - ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${x} -j ACCEPT - ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${x} -m state --state ESTABLISHED,RELATED -j ACCEPT - ${IPT} -A OUTPUT -o ${INT} -p udp -d ${x} --dport 53 --match state --state NEW -j ACCEPT - done + for x in ${DNSSERVEURS}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${x} -j ACCEPT + ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${x} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${x} --dport 53 --match state --state NEW -j ACCEPT + done # HTTP (TCP/80) authorizations - for x in ${HTTPSITES} - do - ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${x} -j ACCEPT - done + for x in ${HTTPSITES}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${x} -j ACCEPT + done # HTTPS (TCP/443) authorizations - for x in ${HTTPSSITES} - do - ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${x} -j ACCEPT - done + for x in ${HTTPSSITES}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${x} -j ACCEPT + done # FTP (so complex protocol...) authorizations - for x in ${FTPSITES} - do - # requests on Control connection - ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${x} -j ACCEPT - # FTP port-mode on Data Connection - ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${x} -j ACCEPT - # FTP passive-mode on Data Connection - # WARNING, this allow all connections on TCP ports > 1024 - ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${x} -j ACCEPT - done + for x in ${FTPSITES}; do + # requests on Control connection + ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${x} -j ACCEPT + # FTP port-mode on Data Connection + ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${x} -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${x} -j ACCEPT + done # SSH authorizations - for x in ${SSHOK} - do - ${IPT} -A INPUT -p tcp ! --syn --sport 22 -s ${x} -j ACCEPT - done + for x in ${SSHOK}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 22 -s ${x} -j ACCEPT + done # SMTP authorizations - for x in ${SMTPOK} - do - ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${x} -j ACCEPT - done + for x in ${SMTPOK}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${x} -j ACCEPT + done # secure SMTP (TCP/465 et TCP/587) authorizations - for x in ${SMTPSECUREOK} - do - ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${x} -j ACCEPT - ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${x} -j ACCEPT - done + for x in ${SMTPSECUREOK}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${x} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${x} -j ACCEPT + done # NTP authorizations - for x in ${NTPOK} - do - ${IPT} -A INPUT -p udp --sport 123 -s ${x} -j ACCEPT - ${IPT} -A OUTPUT -o ${INT} -p udp -d ${x} --dport 123 --match state --state NEW -j ACCEPT - done + for x in ${NTPOK}; do + ${IPT} -A INPUT -p udp --sport 123 -s ${x} -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${x} --dport 123 --match state --state NEW -j ACCEPT + done # Always allow ICMP ${IPT} -A INPUT -p icmp -j ACCEPT From 372ad8f1d1a2bea1886731349459717ba06ff5e9 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 09:46:22 +0200 Subject: [PATCH 07/42] whitespaces --- minifirewall | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/minifirewall b/minifirewall index c63f744..24b019e 100755 --- a/minifirewall +++ b/minifirewall @@ -60,8 +60,7 @@ IPV6=$(grep "IPV6=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') DOCKER=$(grep "DOCKER=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') INT=$(grep "INT=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') -chain_exists() -{ +chain_exists() { local chain_name="$1" ; shift [ $# -eq 1 ] && local intable="--table $1" # shellcheck disable=SC2086 @@ -188,7 +187,6 @@ start() { if [ "${DOCKER}" = "on" ]; then - ${IPT} -N MINIFW-DOCKER-TRUSTED ${IPT} -A MINIFW-DOCKER-TRUSTED -j DROP @@ -210,7 +208,6 @@ start() { # Pipe new connection through MINIFW-DOCKER-PUB ${IPT} -A DOCKER-USER -i ${INT} -m state --state NEW -j MINIFW-DOCKER-PUB ${IPT} -A DOCKER-USER -j RETURN - fi @@ -260,7 +257,6 @@ start() { if [ "${DOCKER}" = "on" ]; then - # Public services defined in SERVICESTCP1 & SERVICESUDP1 for dstport in ${SERVICESTCP1}; do ${IPT} -I MINIFW-DOCKER-PUB -p tcp --dport "${dstport}" -j RETURN @@ -416,7 +412,6 @@ stop() { ${IPT} -X MINIFW-DOCKER-PRIVILEGED ${IPT} -F MINIFW-DOCKER-TRUSTED ${IPT} -X MINIFW-DOCKER-TRUSTED - fi # Accept all From c4f9e7867709d9a9ecc5cd4c9091cb218edf9eac Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 22:44:47 +0200 Subject: [PATCH 08/42] all variables must be defined --- minifirewall | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/minifirewall b/minifirewall index 24b019e..458aaa7 100755 --- a/minifirewall +++ b/minifirewall @@ -31,6 +31,8 @@ DESC="minifirewall" NAME="minifirewall" +set -u + # Variables configuration ######################### @@ -52,6 +54,30 @@ PORTSROOT='0:1023' PORTSUSER='1024:65535' # Configuration + +INT='' +IPV6='' +DOCKER='' +INTLAN='' +TRUSTEDIPS='' +PRIVILEGIEDIPS='' +SERVICESTCP1p='' +SERVICESUDP1p='' +SERVICESTCP1='' +SERVICESUDP1='' +SERVICESTCP2='' +SERVICESUDP2='' +SERVICESTCP3='' +SERVICESUDP3='' +DNSSERVEURS='' +HTTPSITES='' +HTTPSSITES='' +FTPSITES='' +SSHOK='' +SMTPOK='' +SMTPSECUREOK='' +NTPOK='' + oldconfigfile="/etc/firewall.rc" configfile="/etc/default/minifirewall" includesdir="/etc/default/minifirewall.d" From 597042ebf7ab0f62a41d2c4f35eab3473de3d0cb Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 22:45:48 +0200 Subject: [PATCH 09/42] more expressive variable names --- minifirewall | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/minifirewall b/minifirewall index 458aaa7..b78cd42 100755 --- a/minifirewall +++ b/minifirewall @@ -331,53 +331,53 @@ start() { ################### # DNS authorizations - for x in ${DNSSERVEURS}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${x} -j ACCEPT - ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${x} -m state --state ESTABLISHED,RELATED -j ACCEPT - ${IPT} -A OUTPUT -o ${INT} -p udp -d ${x} --dport 53 --match state --state NEW -j ACCEPT + for src in ${DNSSERVEURS}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${src} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 53 --match state --state NEW -j ACCEPT done # HTTP (TCP/80) authorizations - for x in ${HTTPSITES}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${x} -j ACCEPT + for src in ${HTTPSITES}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${src} -j ACCEPT done # HTTPS (TCP/443) authorizations - for x in ${HTTPSSITES}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${x} -j ACCEPT + for src in ${HTTPSSITES}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${src} -j ACCEPT done # FTP (so complex protocol...) authorizations - for x in ${FTPSITES}; do + for src in ${FTPSITES}; do # requests on Control connection - ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${x} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${src} -j ACCEPT # FTP port-mode on Data Connection - ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${x} -j ACCEPT + ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${src} -j ACCEPT # FTP passive-mode on Data Connection # WARNING, this allow all connections on TCP ports > 1024 - ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${x} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${src} -j ACCEPT done # SSH authorizations - for x in ${SSHOK}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 22 -s ${x} -j ACCEPT + for src in ${SSHOK}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 22 -s ${src} -j ACCEPT done # SMTP authorizations - for x in ${SMTPOK}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${x} -j ACCEPT + for src in ${SMTPOK}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${src} -j ACCEPT done # secure SMTP (TCP/465 et TCP/587) authorizations - for x in ${SMTPSECUREOK}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${x} -j ACCEPT - ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${x} -j ACCEPT + for src in ${SMTPSECUREOK}; do + ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${src} -j ACCEPT done # NTP authorizations - for x in ${NTPOK}; do - ${IPT} -A INPUT -p udp --sport 123 -s ${x} -j ACCEPT - ${IPT} -A OUTPUT -o ${INT} -p udp -d ${x} --dport 123 --match state --state NEW -j ACCEPT + for src in ${NTPOK}; do + ${IPT} -A INPUT -p udp --sport 123 -s ${src} -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 123 --match state --state NEW -j ACCEPT done # Always allow ICMP From 9477d47938ec3a61ca43c4f84bcadad291a8a6e2 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 22:46:02 +0200 Subject: [PATCH 10/42] Use function to tets ipv6 and docker --- minifirewall | 91 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 21 deletions(-) diff --git a/minifirewall b/minifirewall index b78cd42..f579a6e 100755 --- a/minifirewall +++ b/minifirewall @@ -86,6 +86,13 @@ IPV6=$(grep "IPV6=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') DOCKER=$(grep "DOCKER=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') INT=$(grep "INT=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') +is_ipv6_enabled() { + test "${IPV6}" != "off" +} +is_docker_enabled() { + test "${DOCKER}" = "on" +} + chain_exists() { local chain_name="$1" ; shift [ $# -eq 1 ] && local intable="--table $1" @@ -201,10 +208,14 @@ start() { # We allow all on loopback interface ${IPT} -A INPUT -i lo -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -i lo -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -i lo -j ACCEPT + fi # if OUTPUTDROP ${IPT} -A OUTPUT -o lo -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A OUTPUT -o lo -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A OUTPUT -o lo -j ACCEPT + fi # We avoid "martians" packets, typical when W32/Blaster virus # attacked windowsupdate.com and DNS was changed to 127.0.0.1 @@ -212,7 +223,7 @@ start() { ${IPT} -A INPUT -s ${LOOPBACK} ! -i lo -j DROP - if [ "${DOCKER}" = "on" ]; then + if is_docker_enabled; then ${IPT} -N MINIFW-DOCKER-TRUSTED ${IPT} -A MINIFW-DOCKER-TRUSTED -j DROP @@ -255,12 +266,16 @@ start() { # Public service for port in ${SERVICESTCP1}; do ${IPT} -A INPUT -p tcp --dport ${port} -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p tcp --dport ${port} -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --dport ${port} -j ACCEPT + fi done for port in ${SERVICESUDP1}; do ${IPT} -A INPUT -p udp --dport ${port} -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p udp --dport ${port} -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --dport ${port} -j ACCEPT + fi done # Privilegied services @@ -282,7 +297,7 @@ start() { done - if [ "${DOCKER}" = "on" ]; then + if is_docker_enabled; then # Public services defined in SERVICESTCP1 & SERVICESUDP1 for dstport in ${SERVICESTCP1}; do ${IPT} -I MINIFW-DOCKER-PUB -p tcp --dport "${dstport}" -j RETURN @@ -382,7 +397,9 @@ start() { # Always allow ICMP ${IPT} -A INPUT -p icmp -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A INPUT -p icmpv6 -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p icmpv6 -j ACCEPT + fi # IPTables policy @@ -390,22 +407,35 @@ start() { # by default DROP INPUT packets ${IPT} -P INPUT DROP - [ "${IPV6}" != "off" ] && ${IPT6} -P INPUT DROP + if is_ipv6_enabled; then + ${IPT6} -P INPUT DROP + fi - # by default, no FORWARING (deprecated for Virtual Machines) + # by default, no FORWARDING (deprecated for Virtual Machines) #echo 0 > /proc/sys/net/ipv4/ip_forward #${IPT} -P FORWARD DROP #${IPT6} -P FORWARD DROP # by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) ${IPT} -P OUTPUT ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -P OUTPUT ACCEPT + if is_ipv6_enabled; then + ${IPT6} -P OUTPUT ACCEPT + fi + ${IPT} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + fi + ${IPT} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT + fi + ${IPT} -A OUTPUT -p udp -j DROP - [ "${IPV6}" != "off" ] && ${IPT6} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -A OUTPUT -p udp -j DROP + if is_ipv6_enabled; then + ${IPT6} -A OUTPUT -p udp -j DROP + fi trap - INT TERM EXIT @@ -417,18 +447,24 @@ stop() { # Delete all rules ${IPT} -F INPUT + if is_ipv6_enabled; then + ${IPT6} -F INPUT + fi + ${IPT} -F OUTPUT + if is_ipv6_enabled; then + ${IPT6} -F OUTPUT + fi + ${IPT} -F LOG_DROP ${IPT} -F LOG_ACCEPT ${IPT} -F ONLYTRUSTED ${IPT} -F ONLYPRIVILEGIED ${IPT} -F NEEDRESTRICT - [ "${DOCKER}" = "off" ] && ${IPT} -t nat -F + ${IPT} -t mangle -F - [ "${IPV6}" != "off" ] && ${IPT6} -F INPUT - [ "${IPV6}" != "off" ] && ${IPT6} -F OUTPUT - if [ "${DOCKER}" = "on" ]; then + if is_docker_enabled; then ${IPT} -F DOCKER-USER ${IPT} -A DOCKER-USER -j RETURN @@ -438,13 +474,20 @@ stop() { ${IPT} -X MINIFW-DOCKER-PRIVILEGED ${IPT} -F MINIFW-DOCKER-TRUSTED ${IPT} -X MINIFW-DOCKER-TRUSTED + else + ${IPT} -t nat -F fi # Accept all ${IPT} -P INPUT ACCEPT + if is_ipv6_enabled; then + ${IPT6} -P INPUT ACCEPT + fi + ${IPT} -P OUTPUT ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -P INPUT ACCEPT - [ "${IPV6}" != "off" ] && ${IPT6} -P OUTPUT ACCEPT + if is_ipv6_enabled; then + ${IPT6} -P OUTPUT ACCEPT + fi #${IPT} -P FORWARD ACCEPT #${IPT} -t nat -P PREROUTING ACCEPT #${IPT} -t nat -P POSTROUTING ACCEPT @@ -471,10 +514,16 @@ reset() { echo "Reset all IPTables counters..." ${IPT} -Z + if is_ipv6_enabled; then + ${IPT6} -Z + fi + ${IPT} -t nat -Z + ${IPT} -t mangle -Z - [ "${IPV6}" != "off" ] && ${IPT6} -Z - [ "${IPV6}" != "off" ] && ${IPT6} -t mangle -Z + if is_ipv6_enabled; then + ${IPT6} -t mangle -Z + fi echo "...reseting IPTables counters is now finish : OK" } From e071610a37bbb487c7468dfdc4b183f3c2fef10c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 23:12:09 +0200 Subject: [PATCH 11/42] check for commands --- minifirewall | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/minifirewall b/minifirewall index f579a6e..fc027c0 100755 --- a/minifirewall +++ b/minifirewall @@ -38,8 +38,16 @@ set -u ######################### # iptables paths -IPT=/sbin/iptables -IPT6=/sbin/ip6tables +IPT=$(command -v iptables) +if [ -z "${IPT}" ]; then + echo "Unable to find 'iptables\` command in PATH." >&2 + exit 1 +fi +IPT6=$(command -v ip6tables) +if [ -z "${IPT6}" ]; then + echo "Unable to find 'ip6tables\` command in PATH." >&2 + exit 1 +fi # TCP/IP variables LOOPBACK='127.0.0.0/8' From c9eecabdf8d3fa9602ee09dd01a45d64de6994d8 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 23:13:00 +0200 Subject: [PATCH 12/42] more expressive variable names --- minifirewall | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/minifirewall b/minifirewall index fc027c0..698e522 100755 --- a/minifirewall +++ b/minifirewall @@ -140,8 +140,8 @@ start() { echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses # Disable Source Routing - for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do - echo 0 > "${i}" + for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_source_route; do + echo 0 > "${proc_sys_file}" done # Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks @@ -149,22 +149,22 @@ start() { echo 1 > /proc/sys/net/ipv4/tcp_syncookies # Disable ICMP redirects - for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do - echo 0 > "${i}" + for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_redirects; do + echo 0 > "${proc_sys_file}" done - for i in /proc/sys/net/ipv4/conf/*/send_redirects; do - echo 0 > "${i}" + for proc_sys_file in /proc/sys/net/ipv4/conf/*/send_redirects; do + echo 0 > "${proc_sys_file}" done # Enable Reverse Path filtering : verify if responses use same network interface - for i in /proc/sys/net/ipv4/conf/*/rp_filter; do - echo 1 > "${i}" + for proc_sys_file in /proc/sys/net/ipv4/conf/*/rp_filter; do + echo 1 > "${proc_sys_file}" done # log des paquets avec adresse incoherente - for i in /proc/sys/net/ipv4/conf/*/log_martians; do - echo 1 > "${i}" + for proc_sys_file in /proc/sys/net/ipv4/conf/*/log_martians; do + echo 1 > "${proc_sys_file}" done # IPTables configuration From 773d7086fc137af562c96e3ee2a1607be832a160 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 23:14:27 +0200 Subject: [PATCH 13/42] source configuration with functions --- minifirewall | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/minifirewall b/minifirewall index 698e522..19e7341 100755 --- a/minifirewall +++ b/minifirewall @@ -86,13 +86,13 @@ SMTPOK='' SMTPSECUREOK='' NTPOK='' -oldconfigfile="/etc/firewall.rc" -configfile="/etc/default/minifirewall" -includesdir="/etc/default/minifirewall.d" +legacy_config_file="/etc/firewall.rc" +config_file="/etc/default/minifirewall" +includes_dir="/etc/default/minifirewall.d" -IPV6=$(grep "IPV6=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') -DOCKER=$(grep "DOCKER=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') -INT=$(grep "INT=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') +IPV6=$(grep "IPV6=" "${config_file}" | awk -F '=' -F "'" '{print $2}') +DOCKER=$(grep "DOCKER=" "${config_file}" | awk -F '=' -F "'" '{print $2}') +INT=$(grep "INT=" "${config_file}" | awk -F '=' -F "'" '{print $2}') is_ipv6_enabled() { test "${IPV6}" != "off" @@ -121,6 +121,26 @@ source_file_or_error() { fi rm "${tmpfile}" } +source_configuration() { + if test -f ${legacy_config_file}; then + echo "${legacy_config_file} is deprecated, rename to ${config_file}" >&2 + exit 1 + fi + + if ! test -f ${config_file}; then + echo "${config_file} does not exist" >&2 + exit 1 + fi + + source_file_or_error ${config_file} + + if [ -d "${includes_dir}" ]; then + include_files=$(find ${includes_dir} -type f -readable -not -name '*.*') + for include_file in ${include_files}; do + source_file_or_error "${include_file}" + done + fi +} start() { echo "Start IPTables rules..." @@ -177,24 +197,7 @@ start() { ${IPT} -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' ${IPT} -A LOG_ACCEPT -j ACCEPT - if test -f ${oldconfigfile}; then - echo "${oldconfigfile} is deprecated, rename to ${configfile}" >&2 - exit 1 - fi - - if ! test -f ${configfile}; then - echo "${configfile} does not exist" >&2 - exit 1 - fi - - source_file_or_error ${configfile} - - if [ -d "${includesdir}" ]; then - includefiles=$(find ${includesdir} -type f -readable -not -name '*.*') - for includefile in ${includefiles}; do - source_file_or_error "${includefile}" - done - fi + source_configuration # Trusted ip addresses ${IPT} -N ONLYTRUSTED From dfc91a068997e847b612a31dac7bfa2de67a7bf3 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 23:14:40 +0200 Subject: [PATCH 14/42] syntax and readability --- minifirewall | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/minifirewall b/minifirewall index 19e7341..d9e0201 100755 --- a/minifirewall +++ b/minifirewall @@ -100,14 +100,14 @@ is_ipv6_enabled() { is_docker_enabled() { test "${DOCKER}" = "on" } - chain_exists() { - local chain_name="$1" ; shift - [ $# -eq 1 ] && local intable="--table $1" + chain_name="$1" + if [ $# -ge 2 ]; then + intable="--table $2" + fi # shellcheck disable=SC2086 iptables ${intable} -nL "${chain_name}" >/dev/null 2>&1 } - source_file_or_error() { file=$1 echo "...sourcing '${file}\`" @@ -233,7 +233,6 @@ start() { # ${IPT} -t NAT -I PREROUTING -s ${LOOPBACK} -i ! lo -j DROP ${IPT} -A INPUT -s ${LOOPBACK} ! -i lo -j DROP - if is_docker_enabled; then ${IPT} -N MINIFW-DOCKER-TRUSTED ${IPT} -A MINIFW-DOCKER-TRUSTED -j DROP From 800448ff9723f39616581bcb34c8ff49223b41a3 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 22 May 2021 23:22:31 +0200 Subject: [PATCH 15/42] update verison --- minifirewall | 2 +- minifirewall.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/minifirewall b/minifirewall index d9e0201..115b843 100755 --- a/minifirewall +++ b/minifirewall @@ -4,7 +4,7 @@ # we used netfilter/iptables http://netfilter.org/ designed for recent Linux kernel # See https://gitea.evolix.org/evolix/minifirewall -# Copyright (c) 2007-2020 Evolix +# Copyright (c) 2007-2021 Evolix # 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 3 diff --git a/minifirewall.conf b/minifirewall.conf index 8230854..d192e08 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -1,5 +1,5 @@ # Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall -# Version 20.12 — 2020-12-01 22:55:35 +# Version 21.05 — 2021-05-22 23:22:10 # shellcheck shell=sh disable=SC2034 # Main interface From 9be97b2436e26a8fe2086d093fe598d392ec8ac3 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 26 May 2021 13:09:50 +0200 Subject: [PATCH 16/42] store includes in /etc/minifirewall.d --- minifirewall | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minifirewall b/minifirewall index 115b843..c0028f8 100755 --- a/minifirewall +++ b/minifirewall @@ -88,7 +88,7 @@ NTPOK='' legacy_config_file="/etc/firewall.rc" config_file="/etc/default/minifirewall" -includes_dir="/etc/default/minifirewall.d" +includes_dir="/etc/minifirewall.d" IPV6=$(grep "IPV6=" "${config_file}" | awk -F '=' -F "'" '{print $2}') DOCKER=$(grep "DOCKER=" "${config_file}" | awk -F '=' -F "'" '{print $2}') From 275a4c5bab55f2af14eaad96415c8c70cedea750 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 26 May 2021 13:12:15 +0200 Subject: [PATCH 17/42] Add macro for backup servers --- minifirewall | 13 +++++++++++++ minifirewall.conf | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/minifirewall b/minifirewall index c0028f8..ddfcba9 100755 --- a/minifirewall +++ b/minifirewall @@ -85,6 +85,7 @@ SSHOK='' SMTPOK='' SMTPSECUREOK='' NTPOK='' +BACKUPSERVERS='' legacy_config_file="/etc/firewall.rc" config_file="/etc/default/minifirewall" @@ -405,6 +406,18 @@ start() { ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 123 --match state --state NEW -j ACCEPT done + # Output for backup servers + for server in ${BACKUPSERVERS}; do + server_ip=$(echo "${server}" | cut -d ':' -f1) + server_port=$(echo "${server}" | cut -d ':' -f2) + if [ -n "${server_ip}" ] && [ -n "${server_port}" ]; then + ${IPT} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT + else + echo "Unrecognized syntax for BACKUPSERVERS '${server}\`. Use space-separated IP:PORT tuples." >&2 + exit 1 + fi + done + # Always allow ICMP ${IPT} -A INPUT -p icmp -j ACCEPT if is_ipv6_enabled; then diff --git a/minifirewall.conf b/minifirewall.conf index d192e08..0fc27d1 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -78,6 +78,10 @@ SMTPSECUREOK='' NTPOK='0.0.0.0/0' +# Backup servers +# (add IP:PORT for each one, example: '192.168.10.1:1234 192.168.10.2:5678') +BACKUPSERVERS='' + # Includes ##################### From 0f93e8e75e114908c4b9ec38291bbe8821408133 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 26 May 2021 13:13:26 +0200 Subject: [PATCH 18/42] fixup! store includes in /etc/minifirewall.d --- minifirewall.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minifirewall.conf b/minifirewall.conf index 0fc27d1..f067f6b 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -85,5 +85,5 @@ BACKUPSERVERS='' # Includes ##################### -# Files in /etc/default/minifirewall.d/* (without "." in name) +# Files in /etc/minifirewall.d/* (without "." in name) # are automatically included in alphanumerical order. \ No newline at end of file From f87bbe544222fe84c661ad50cd8bfb5b6ae4fa5d Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 26 May 2021 13:20:12 +0200 Subject: [PATCH 19/42] add macro for proxy --- minifirewall | 19 +++++++++++++++++++ minifirewall.conf | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/minifirewall b/minifirewall index ddfcba9..67b2c52 100755 --- a/minifirewall +++ b/minifirewall @@ -85,6 +85,9 @@ SSHOK='' SMTPOK='' SMTPSECUREOK='' NTPOK='' +PROXY='' +PROXYBYPASS='' +PROXYPORT='' BACKUPSERVERS='' legacy_config_file="/etc/firewall.rc" @@ -101,6 +104,9 @@ is_ipv6_enabled() { is_docker_enabled() { test "${DOCKER}" = "on" } +is_proxy_enabled() { + test "${PROXY}" = "on" +} chain_exists() { chain_name="$1" if [ $# -ge 2 ]; then @@ -406,6 +412,19 @@ start() { ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 123 --match state --state NEW -j ACCEPT done + # Proxy (Squid) + if is_proxy_enabled; then + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT + if [ -n "${INTLAN}" ]; then + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "${INTLAN}" -j ACCEPT + fi + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "127.0.0.0/8" -j ACCEPT + for dstip in ${PROXYBYPASS}; do + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "${dstip}" -j ACCEPT + done + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port "${PROXYPORT:-'8888'}" + fi + # Output for backup servers for server in ${BACKUPSERVERS}; do server_ip=$(echo "${server}" | cut -d ':' -f1) diff --git a/minifirewall.conf b/minifirewall.conf index f067f6b..b73910f 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -77,6 +77,12 @@ SMTPSECUREOK='' # NTP authorizations NTPOK='0.0.0.0/0' +# Proxy (Squid) +PROXY='off' +# (destinations that bypass the proxy. ${INTLAN} and '127.0.0.0/8' are always added to the list) +PROXYBYPASS='' +# (proxy port, default if missing: '8888') +PROXYPORT='' # Backup servers # (add IP:PORT for each one, example: '192.168.10.1:1234 192.168.10.2:5678') From 9ae2a03955e480f0bd29d77b13ab93d4bb79b0ba Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 4 Jun 2021 14:06:37 +0200 Subject: [PATCH 20/42] proxy: simplification de la boucle --- minifirewall | 4 ---- minifirewall.conf | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/minifirewall b/minifirewall index 67b2c52..349833f 100755 --- a/minifirewall +++ b/minifirewall @@ -415,10 +415,6 @@ start() { # Proxy (Squid) if is_proxy_enabled; then ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT - if [ -n "${INTLAN}" ]; then - ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "${INTLAN}" -j ACCEPT - fi - ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "127.0.0.0/8" -j ACCEPT for dstip in ${PROXYBYPASS}; do ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "${dstip}" -j ACCEPT done diff --git a/minifirewall.conf b/minifirewall.conf index b73910f..6a1f180 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -79,10 +79,10 @@ NTPOK='0.0.0.0/0' # Proxy (Squid) PROXY='off' -# (destinations that bypass the proxy. ${INTLAN} and '127.0.0.0/8' are always added to the list) -PROXYBYPASS='' -# (proxy port, default if missing: '8888') -PROXYPORT='' +# (proxy port) +PROXYPORT='8888' +# (destinations that bypass the proxy) +PROXYBYPASS="${INTLAN} 127.0.0.0/8" # Backup servers # (add IP:PORT for each one, example: '192.168.10.1:1234 192.168.10.2:5678') From aa678944385af32574b6c846bc2ba52cb12e97cb Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 4 Jun 2021 14:07:21 +0200 Subject: [PATCH 21/42] =?UTF-8?q?Ouverture=20totale=20de=20HTTPSITES=20par?= =?UTF-8?q?=20d=C3=A9faut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- minifirewall.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minifirewall.conf b/minifirewall.conf index 6a1f180..b6c357c 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -57,7 +57,7 @@ DNSSERVEURS='0.0.0.0/0' # HTTP authorizations # (you can use DNS names but set cron to reload minifirewall regularly) # (if you have HTTP proxy, set 0.0.0.0/0) -HTTPSITES='security.debian.org pub.evolix.net security-cdn.debian.org mirror.evolix.org backports.debian.org hwraid.le-vert.net antispam00.evolix.org spamassassin.apache.org sa-update.space-pro.be sa-update.secnap.net www.sa-update.pccc.com sa-update.dnswl.org ocsp.int-x3.letsencrypt.org' +HTTPSITES='0.0.0.0/0' # HTTPS authorizations HTTPSSITES='0.0.0.0/0' From ad024bac8f862f52a58daa79f39439589a799074 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 4 Jun 2021 14:08:04 +0200 Subject: [PATCH 22/42] valeur de IPV6 avec simples quotes --- minifirewall.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minifirewall.conf b/minifirewall.conf index b6c357c..92ad55b 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -6,7 +6,7 @@ INT='eth0' # IPv6 -IPV6=on +IPV6='on' # Docker Mode # Changes the behaviour of minifirewall to not break the containers' network From ef18fccc96a842de0e60b42bdd7097f3948f685f Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 6 Sep 2021 14:02:03 +0200 Subject: [PATCH 23/42] Add version --- minifirewall | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/minifirewall b/minifirewall index 349833f..b949c3c 100755 --- a/minifirewall +++ b/minifirewall @@ -28,6 +28,8 @@ # Description: Firewall designed for standalone server ### END INIT INFO +VERSION="21.09" + DESC="minifirewall" NAME="minifirewall" @@ -150,7 +152,8 @@ source_configuration() { } start() { - echo "Start IPTables rules..." + echo "${NAME} version ${VERSION}" + echo "Start IPTables rules..." # Stop and warn if error! set -e @@ -481,6 +484,7 @@ start() { } stop() { + echo "${NAME} version ${VERSION}" echo "Flush all rules and accept everything..." # Delete all rules @@ -541,6 +545,7 @@ stop() { } status() { + echo "${NAME} version ${VERSION}" ${IPT} -L -n -v --line-numbers ${IPT} -t nat -L -n -v --line-numbers ${IPT} -t mangle -L -n -v --line-numbers @@ -549,6 +554,7 @@ status() { } reset() { + echo "${NAME} version ${VERSION}" echo "Reset all IPTables counters..." ${IPT} -Z @@ -588,10 +594,9 @@ case "$1" in start ;; - *) - - echo "Usage: $0 {start|stop|restart|status|reset}" - exit 1 + *) + echo "Usage: $0 {start|stop|restart|status|reset}" + exit 1 esac exit 0 From 08182dd606828e956d3597f57db5211adae965c4 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 6 Sep 2021 14:03:44 +0200 Subject: [PATCH 24/42] Conditionals in IPv6 includes --- minifirewall.d/default-input-v6 | 12 +++++++----- minifirewall.d/dhcp-v6.example | 6 ++++-- minifirewall.d/dns-output-v6 | 4 +++- minifirewall.d/ntp-output-v6 | 4 +++- minifirewall.d/traceroute-output-v6.example | 4 +++- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/minifirewall.d/default-input-v6 b/minifirewall.d/default-input-v6 index 38cfe3f..6ec4fd4 100644 --- a/minifirewall.d/default-input-v6 +++ b/minifirewall.d/default-input-v6 @@ -1,7 +1,9 @@ # shellcheck shell=sh disable=SC2034 # allow input HTTP/HTTPS/SMTP/DNS traffic -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT -/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT +if [ "${IPV6}" != "off" ]; then + /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT + /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT + /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT + /sbin/ip6tables -A INPUT -i ${INT} -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT + /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT +fi \ No newline at end of file diff --git a/minifirewall.d/dhcp-v6.example b/minifirewall.d/dhcp-v6.example index f2a60df..84e0438 100644 --- a/minifirewall.d/dhcp-v6.example +++ b/minifirewall.d/dhcp-v6.example @@ -1,4 +1,6 @@ # shellcheck shell=sh disable=SC2034 # allow DHCPv6 -/sbin/ip6tables -A INPUT -i $INT -p udp --dport 546 -d fe80::/64 -j ACCEPT -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 547 -j ACCEPT \ No newline at end of file +if [ "${IPV6}" != "off" ]; then + /sbin/ip6tables -A INPUT -i ${INT} -p udp --dport 546 -d fe80::/64 -j ACCEPT + /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 547 -j ACCEPT +fi \ No newline at end of file diff --git a/minifirewall.d/dns-output-v6 b/minifirewall.d/dns-output-v6 index ac966ff..6711eb5 100644 --- a/minifirewall.d/dns-output-v6 +++ b/minifirewall.d/dns-output-v6 @@ -1,3 +1,5 @@ # shellcheck shell=sh disable=SC2034 # allow DNS output -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 53 --match state --state NEW -j ACCEPT \ No newline at end of file +if [ "${IPV6}" != "off" ]; then + /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 53 --match state --state NEW -j ACCEPT +fi \ No newline at end of file diff --git a/minifirewall.d/ntp-output-v6 b/minifirewall.d/ntp-output-v6 index e1a27e1..dc7b1c4 100644 --- a/minifirewall.d/ntp-output-v6 +++ b/minifirewall.d/ntp-output-v6 @@ -1,3 +1,5 @@ # shellcheck shell=sh disable=SC2034 # allow NTP output -/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 123 --match state --state NEW -j ACCEPT \ No newline at end of file +if [ "${IPV6}" != "off" ]; then + /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 123 --match state --state NEW -j ACCEPT +fi \ No newline at end of file diff --git a/minifirewall.d/traceroute-output-v6.example b/minifirewall.d/traceroute-output-v6.example index 786f352..73696ae 100644 --- a/minifirewall.d/traceroute-output-v6.example +++ b/minifirewall.d/traceroute-output-v6.example @@ -1,3 +1,5 @@ # shellcheck shell=sh disable=SC2034 # allow traceroute output -#/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT \ No newline at end of file +if [ "${IPV6}" != "off" ]; then + /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +fi \ No newline at end of file From d811e5647dff3db883d69c16c4f819289c53ea81 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 6 Sep 2021 14:33:22 +0200 Subject: [PATCH 25/42] Show version once for each action --- minifirewall | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/minifirewall b/minifirewall index b949c3c..64002e8 100755 --- a/minifirewall +++ b/minifirewall @@ -109,6 +109,9 @@ is_docker_enabled() { is_proxy_enabled() { test "${PROXY}" = "on" } +is_ipv6() { + grep -q ':' "$1" +} chain_exists() { chain_name="$1" if [ $# -ge 2 ]; then @@ -152,7 +155,6 @@ source_configuration() { } start() { - echo "${NAME} version ${VERSION}" echo "Start IPTables rules..." # Stop and warn if error! @@ -484,7 +486,6 @@ start() { } stop() { - echo "${NAME} version ${VERSION}" echo "Flush all rules and accept everything..." # Delete all rules @@ -545,7 +546,6 @@ stop() { } status() { - echo "${NAME} version ${VERSION}" ${IPT} -L -n -v --line-numbers ${IPT} -t nat -L -n -v --line-numbers ${IPT} -t mangle -L -n -v --line-numbers @@ -554,7 +554,6 @@ status() { } reset() { - echo "${NAME} version ${VERSION}" echo "Reset all IPTables counters..." ${IPT} -Z @@ -574,27 +573,33 @@ reset() { case "$1" in start) + echo "${NAME} version ${VERSION}" start ;; stop) + echo "${NAME} version ${VERSION}" stop ;; status) + echo "${NAME} version ${VERSION}" status ;; reset) + echo "${NAME} version ${VERSION}" reset ;; restart) + echo "${NAME} version ${VERSION}" stop start ;; *) + echo "${NAME} version ${VERSION}" echo "Usage: $0 {start|stop|restart|status|reset}" exit 1 esac From 5f0de36216815aa843348c89e01d7f9194860270 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 6 Sep 2021 14:33:33 +0200 Subject: [PATCH 26/42] Combine all IPv6 rules --- minifirewall.d/default-input-v6 | 9 ------- minifirewall.d/dhcp-v6.example | 6 ----- minifirewall.d/dns-output-v6 | 5 ---- minifirewall.d/ipv6 | 26 +++++++++++++++++++++ minifirewall.d/ntp-output-v6 | 5 ---- minifirewall.d/traceroute-output-v6.example | 5 ---- 6 files changed, 26 insertions(+), 30 deletions(-) delete mode 100644 minifirewall.d/default-input-v6 delete mode 100644 minifirewall.d/dhcp-v6.example delete mode 100644 minifirewall.d/dns-output-v6 create mode 100644 minifirewall.d/ipv6 delete mode 100644 minifirewall.d/ntp-output-v6 delete mode 100644 minifirewall.d/traceroute-output-v6.example diff --git a/minifirewall.d/default-input-v6 b/minifirewall.d/default-input-v6 deleted file mode 100644 index 6ec4fd4..0000000 --- a/minifirewall.d/default-input-v6 +++ /dev/null @@ -1,9 +0,0 @@ -# shellcheck shell=sh disable=SC2034 -# allow input HTTP/HTTPS/SMTP/DNS traffic -if [ "${IPV6}" != "off" ]; then - /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT - /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT - /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT - /sbin/ip6tables -A INPUT -i ${INT} -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT - /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT -fi \ No newline at end of file diff --git a/minifirewall.d/dhcp-v6.example b/minifirewall.d/dhcp-v6.example deleted file mode 100644 index 84e0438..0000000 --- a/minifirewall.d/dhcp-v6.example +++ /dev/null @@ -1,6 +0,0 @@ -# shellcheck shell=sh disable=SC2034 -# allow DHCPv6 -if [ "${IPV6}" != "off" ]; then - /sbin/ip6tables -A INPUT -i ${INT} -p udp --dport 546 -d fe80::/64 -j ACCEPT - /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 547 -j ACCEPT -fi \ No newline at end of file diff --git a/minifirewall.d/dns-output-v6 b/minifirewall.d/dns-output-v6 deleted file mode 100644 index 6711eb5..0000000 --- a/minifirewall.d/dns-output-v6 +++ /dev/null @@ -1,5 +0,0 @@ -# shellcheck shell=sh disable=SC2034 -# allow DNS output -if [ "${IPV6}" != "off" ]; then - /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 53 --match state --state NEW -j ACCEPT -fi \ No newline at end of file diff --git a/minifirewall.d/ipv6 b/minifirewall.d/ipv6 new file mode 100644 index 0000000..5484a12 --- /dev/null +++ b/minifirewall.d/ipv6 @@ -0,0 +1,26 @@ +# shellcheck shell=sh disable=SC2034 + +# Set of rules for IPv6 +# They should be moved to the macros in the init script + +if [ "${IPV6}" != "off" ]; then + # allow HTTP/HTTPS/SMTP/DNS input + /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT + /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT + /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT + /sbin/ip6tables -A INPUT -i ${INT} -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT + /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT + + # allow DNS output + /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 53 --match state --state NEW -j ACCEPT + + # allow NTP output + /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 123 --match state --state NEW -j ACCEPT + + # allow DHCPv6 + # /sbin/ip6tables -A INPUT -i ${INT} -p udp --dport 546 -d fe80::/64 -j ACCEPT + # /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 547 -j ACCEPT + + # allow traceroute output + # /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +fi \ No newline at end of file diff --git a/minifirewall.d/ntp-output-v6 b/minifirewall.d/ntp-output-v6 deleted file mode 100644 index dc7b1c4..0000000 --- a/minifirewall.d/ntp-output-v6 +++ /dev/null @@ -1,5 +0,0 @@ -# shellcheck shell=sh disable=SC2034 -# allow NTP output -if [ "${IPV6}" != "off" ]; then - /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 123 --match state --state NEW -j ACCEPT -fi \ No newline at end of file diff --git a/minifirewall.d/traceroute-output-v6.example b/minifirewall.d/traceroute-output-v6.example deleted file mode 100644 index 73696ae..0000000 --- a/minifirewall.d/traceroute-output-v6.example +++ /dev/null @@ -1,5 +0,0 @@ -# shellcheck shell=sh disable=SC2034 -# allow traceroute output -if [ "${IPV6}" != "off" ]; then - /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT -fi \ No newline at end of file From c31288f3181b6859f4dce1c0885674ac03164282 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Tue, 14 Sep 2021 08:54:52 +0200 Subject: [PATCH 27/42] Correct is_ipv6 --- minifirewall | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 minifirewall diff --git a/minifirewall b/minifirewall old mode 100755 new mode 100644 index 64002e8..d1049c9 --- a/minifirewall +++ b/minifirewall @@ -110,7 +110,7 @@ is_proxy_enabled() { test "${PROXY}" = "on" } is_ipv6() { - grep -q ':' "$1" + echo "$1" | grep -q ':' } chain_exists() { chain_name="$1" From 79c17905649f1377c7c1be8ad7edcf6c64a8c8f5 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Tue, 14 Sep 2021 09:12:08 +0200 Subject: [PATCH 28/42] WIP - IPv6 Handleing for output authorisation --- minifirewall | 95 ++++++++++++++++++++++++++++++++++++++--------- minifirewall.conf | 14 +++---- 2 files changed, 84 insertions(+), 25 deletions(-) mode change 100644 => 100755 minifirewall diff --git a/minifirewall b/minifirewall old mode 100644 new mode 100755 index d1049c9..cfe8d45 --- a/minifirewall +++ b/minifirewall @@ -369,52 +369,111 @@ start() { # DNS authorizations for src in ${DNSSERVEURS}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${src} -j ACCEPT - ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${src} -m state --state ESTABLISHED,RELATED -j ACCEPT - ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 53 --match state --state NEW -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${src} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT6} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 53 --match state --state NEW -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${src} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 53 --match state --state NEW -j ACCEPT + fi done # HTTP (TCP/80) authorizations for src in ${HTTPSITES}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${src} -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi done # HTTPS (TCP/443) authorizations for src in ${HTTPSSITES}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${src} -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi done # FTP (so complex protocol...) authorizations for src in ${FTPSITES}; do - # requests on Control connection - ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${src} -j ACCEPT - # FTP port-mode on Data Connection - ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${src} -j ACCEPT - # FTP passive-mode on Data Connection - # WARNING, this allow all connections on TCP ports > 1024 - ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${src} -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + # requests on Control connection + ${IPT6} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${src} -j ACCEPT + # FTP port-mode on Data Connection + ${IPT6} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${src} -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + ${IPT6} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi + else + # requests on Control connection + ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${src} -j ACCEPT + # FTP port-mode on Data Connection + ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${src} -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi done # SSH authorizations for src in ${SSHOK}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 22 -s ${src} -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi done # SMTP authorizations for src in ${SMTPOK}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${src} -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi done # secure SMTP (TCP/465 et TCP/587) authorizations for src in ${SMTPSECUREOK}; do - ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${src} -j ACCEPT - ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${src} -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${src} -j ACCEPT + fi done # NTP authorizations for src in ${NTPOK}; do - ${IPT} -A INPUT -p udp --sport 123 -s ${src} -j ACCEPT - ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 123 --match state --state NEW -j ACCEPT + + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --sport 123 -s ${src} -j ACCEPT + ${IPT6} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 123 --match state --state NEW -j ACCEPT + fi + else + ${IPT} -A INPUT -p udp --sport 123 -s ${src} -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 123 --match state --state NEW -j ACCEPT + fi done # Proxy (Squid) diff --git a/minifirewall.conf b/minifirewall.conf index 92ad55b..9eead6a 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -47,35 +47,35 @@ SERVICESTCP3='5666' SERVICESUDP3='' -# Standard output IPv4 access restrictions +# Standard output IPv4/IPv6 access restrictions ########################################## # DNS authorizations # (if you have local DNS server, set 0.0.0.0/0) -DNSSERVEURS='0.0.0.0/0' +DNSSERVEURS='0.0.0.0/0 ::/0' # HTTP authorizations # (you can use DNS names but set cron to reload minifirewall regularly) # (if you have HTTP proxy, set 0.0.0.0/0) -HTTPSITES='0.0.0.0/0' +HTTPSITES='0.0.0.0/0 ::/0' # HTTPS authorizations -HTTPSSITES='0.0.0.0/0' +HTTPSSITES='0.0.0.0/0 ::/0' # FTP authorizations FTPSITES='' # SSH authorizations -SSHOK='0.0.0.0/0' +SSHOK='0.0.0.0/0 ::/0' # SMTP authorizations -SMTPOK='0.0.0.0/0' +SMTPOK='0.0.0.0/0 ::/0' # SMTP secure authorizations (ports TCP/465 and TCP/587) SMTPSECUREOK='' # NTP authorizations -NTPOK='0.0.0.0/0' +NTPOK='0.0.0.0/0 ::/0' # Proxy (Squid) PROXY='off' From 351158891e59e90586990c450a554d9b35de52f9 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Tue, 14 Sep 2021 09:44:58 +0200 Subject: [PATCH 29/42] Add sort, to source files in alphanumerical order as expected --- minifirewall | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minifirewall b/minifirewall index cfe8d45..ddfd8e9 100755 --- a/minifirewall +++ b/minifirewall @@ -147,7 +147,7 @@ source_configuration() { source_file_or_error ${config_file} if [ -d "${includes_dir}" ]; then - include_files=$(find ${includes_dir} -type f -readable -not -name '*.*') + include_files=$(find ${includes_dir} -type f -readable -not -name '*.*' | sort) for include_file in ${include_files}; do source_file_or_error "${include_file}" done From cfa1c203329f5e12711d4a6dfb0ea7b5a2491a62 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 14 Sep 2021 11:05:59 +0200 Subject: [PATCH 30/42] Add IPv6 support on many macros --- minifirewall | 106 ++++++++++++++++++++++++++++++++++++++++++---- minifirewall.conf | 17 ++++---- 2 files changed, 106 insertions(+), 17 deletions(-) diff --git a/minifirewall b/minifirewall index ddfd8e9..9cbce22 100755 --- a/minifirewall +++ b/minifirewall @@ -214,20 +214,43 @@ start() { # Trusted ip addresses ${IPT} -N ONLYTRUSTED ${IPT} -A ONLYTRUSTED -j LOG_DROP + if is_ipv6_enabled; then + ${IPT6} -N ONLYTRUSTED + ${IPT6} -A ONLYTRUSTED -j LOG_DROP + fi for ip in ${TRUSTEDIPS}; do - ${IPT} -I ONLYTRUSTED -s ${ip} -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -I ONLYTRUSTED -s ${ip} -j ACCEPT + fi + else + ${IPT} -I ONLYTRUSTED -s ${ip} -j ACCEPT + fi done # Privilegied ip addresses # (trusted ip addresses *are* privilegied) ${IPT} -N ONLYPRIVILEGIED ${IPT} -A ONLYPRIVILEGIED -j ONLYTRUSTED + if is_ipv6_enabled; then + ${IPT6} -N ONLYPRIVILEGIED + ${IPT6} -A ONLYPRIVILEGIED -j ONLYTRUSTED + fi for ip in ${PRIVILEGIEDIPS}; do - ${IPT} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT + fi + else + ${IPT} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT + fi done # Chain for restrictions (blacklist IPs/ranges) ${IPT} -N NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -N NEEDRESTRICT + fi # We allow all on loopback interface ${IPT} -A INPUT -i lo -j ACCEPT @@ -243,9 +266,18 @@ start() { # We avoid "martians" packets, typical when W32/Blaster virus # attacked windowsupdate.com and DNS was changed to 127.0.0.1 # ${IPT} -t NAT -I PREROUTING -s ${LOOPBACK} -i ! lo -j DROP - ${IPT} -A INPUT -s ${LOOPBACK} ! -i lo -j DROP + for IP in ${LOOPBACK}; do + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -s ${IP} ! -i lo -j DROP + fi + else + ${IPT} -A INPUT -s ${IP} ! -i lo -j DROP + fi + done if is_docker_enabled; then + # WARN: IPv6 not yet supported for Docker rules ${IPT} -N MINIFW-DOCKER-TRUSTED ${IPT} -A MINIFW-DOCKER-TRUSTED -j DROP @@ -274,15 +306,29 @@ start() { ############################# # Allow services for ${INTLAN} (local server or local network) - ${IPT} -A INPUT -s ${INTLAN} -j ACCEPT + for IP in ${INTLAN}; do + if is_ipv6 ${src}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -s ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -s ${IP} -j ACCEPT + fi + done # Enable protection chain for sensible services for port in ${SERVICESTCP1p}; do ${IPT} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT + fi done for port in ${SERVICESUDP1p}; do ${IPT} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT + fi done # Public service @@ -303,23 +349,37 @@ start() { # Privilegied services for port in ${SERVICESTCP2}; do ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED + fi done for port in ${SERVICESUDP2}; do ${IPT} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED + fi done # Private services for port in ${SERVICESTCP3}; do ${IPT} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED + fi done for port in ${SERVICESUDP3}; do ${IPT} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED + fi done if is_docker_enabled; then + # WARN: IPv6 not yet supported + # Public services defined in SERVICESTCP1 & SERVICESUDP1 for dstport in ${SERVICESTCP1}; do ${IPT} -I MINIFW-DOCKER-PUB -p tcp --dport "${dstport}" -j RETURN @@ -478,6 +538,9 @@ start() { # Proxy (Squid) if is_proxy_enabled; then + # WARN: Squid only listen on IPv4 yet + # TODO: verify that the pattern used for IPv4 is relevant with IPv6 + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT for dstip in ${PROXYBYPASS}; do ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "${dstip}" -j ACCEPT @@ -487,10 +550,16 @@ start() { # Output for backup servers for server in ${BACKUPSERVERS}; do - server_ip=$(echo "${server}" | cut -d ':' -f1) - server_port=$(echo "${server}" | cut -d ':' -f2) + server_port=$(echo "${server}" | awk '{print $NF}') + server_ip=$(echo "${server}" | sed -e "s/:${server_port}$//") if [ -n "${server_ip}" ] && [ -n "${server_port}" ]; then - ${IPT} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT + if is_ipv6 ${server_ip}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT + fi else echo "Unrecognized syntax for BACKUPSERVERS '${server}\`. Use space-separated IP:PORT tuples." >&2 exit 1 @@ -552,7 +621,7 @@ stop() { if is_ipv6_enabled; then ${IPT6} -F INPUT fi - + ${IPT} -F OUTPUT if is_ipv6_enabled; then ${IPT6} -F OUTPUT @@ -563,10 +632,22 @@ stop() { ${IPT} -F ONLYTRUSTED ${IPT} -F ONLYPRIVILEGIED ${IPT} -F NEEDRESTRICT - + if is_ipv6_enabled; then + ${IPT6} -F LOG_DROP + ${IPT6} -F LOG_ACCEPT + ${IPT6} -F ONLYTRUSTED + ${IPT6} -F ONLYPRIVILEGIED + ${IPT6} -F NEEDRESTRICT + fi + ${IPT} -t mangle -F + if is_ipv6_enabled; then + ${IPT6} -t mangle -F + fi if is_docker_enabled; then + # WARN: IPv6 not yet supported + ${IPT} -F DOCKER-USER ${IPT} -A DOCKER-USER -j RETURN @@ -600,6 +681,13 @@ stop() { ${IPT} -X ONLYPRIVILEGIED ${IPT} -X ONLYTRUSTED ${IPT} -X NEEDRESTRICT + if is_ipv6_enabled; then + ${IPT6} -X LOG_DROP + ${IPT6} -X LOG_ACCEPT + ${IPT6} -X ONLYPRIVILEGIED + ${IPT6} -X ONLYTRUSTED + ${IPT6} -X NEEDRESTRICT + fi echo "...flushing IPTables rules is now finish : OK" } diff --git a/minifirewall.conf b/minifirewall.conf index 9eead6a..df519b4 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -14,19 +14,20 @@ IPV6='on' # Also, we'll add the DOCKER-USER chain, in iptable DOCKER='off' -# Trusted IPv4 local network -# ...will be often IP/32 if you don't trust anything -INTLAN='192.168.0.2/32' +# Trusted local network +# ...will be often IPv4/32 or IPv6/128 if you don't trust anything +INTLAN='192.0.2.1/32 2001:db8::1/128' -# Trusted IPv4 addresses for private and semi-public services -TRUSTEDIPS='31.170.9.129 62.212.121.90 31.170.8.4 82.65.34.85 54.37.106.210 51.210.84.146' +# Trusted IP addresses for private and semi-public services +# TODO: add all our IPv6 adresses +TRUSTEDIPS='31.170.9.129 2a01:9500:37:129::/64 62.212.121.90 31.170.8.4 2a01:9500::fada/128 82.65.34.85 54.37.106.210 51.210.84.146' -# Privilegied IPv4 addresses for semi-public services +# Privilegied IP addresses for semi-public services # (no need to add again TRUSTEDIPS) PRIVILEGIEDIPS='' -# Local services IPv4/IPv6 restrictions +# Local services IP restrictions ####################################### # Protected services @@ -82,7 +83,7 @@ PROXY='off' # (proxy port) PROXYPORT='8888' # (destinations that bypass the proxy) -PROXYBYPASS="${INTLAN} 127.0.0.0/8" +PROXYBYPASS="${INTLAN} 127.0.0.0/8 ::1/128" # Backup servers # (add IP:PORT for each one, example: '192.168.10.1:1234 192.168.10.2:5678') From 48983bfa2de1fc0bdcb52e13da18a84c33036cb4 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 14 Sep 2021 12:36:43 +0200 Subject: [PATCH 31/42] fix mistakes * forgotten chains * wrong variable names * baf field separator for awk --- minifirewall | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/minifirewall b/minifirewall index 9cbce22..11e59a2 100755 --- a/minifirewall +++ b/minifirewall @@ -208,6 +208,14 @@ start() { ${IPT} -N LOG_ACCEPT ${IPT} -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' ${IPT} -A LOG_ACCEPT -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -N LOG_DROP + ${IPT6} -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' + ${IPT6} -A LOG_DROP -j DROP + ${IPT6} -N LOG_ACCEPT + ${IPT6} -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' + ${IPT6} -A LOG_ACCEPT -j ACCEPT + fi source_configuration @@ -219,7 +227,7 @@ start() { ${IPT6} -A ONLYTRUSTED -j LOG_DROP fi for ip in ${TRUSTEDIPS}; do - if is_ipv6 ${src}; then + if is_ipv6 ${ip}; then if is_ipv6_enabled; then ${IPT6} -I ONLYTRUSTED -s ${ip} -j ACCEPT fi @@ -237,7 +245,7 @@ start() { ${IPT6} -A ONLYPRIVILEGIED -j ONLYTRUSTED fi for ip in ${PRIVILEGIEDIPS}; do - if is_ipv6 ${src}; then + if is_ipv6 ${ip}; then if is_ipv6_enabled; then ${IPT6} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT fi @@ -267,7 +275,7 @@ start() { # attacked windowsupdate.com and DNS was changed to 127.0.0.1 # ${IPT} -t NAT -I PREROUTING -s ${LOOPBACK} -i ! lo -j DROP for IP in ${LOOPBACK}; do - if is_ipv6 ${src}; then + if is_ipv6 ${IP}; then if is_ipv6_enabled; then ${IPT6} -A INPUT -s ${IP} ! -i lo -j DROP fi @@ -307,7 +315,7 @@ start() { # Allow services for ${INTLAN} (local server or local network) for IP in ${INTLAN}; do - if is_ipv6 ${src}; then + if is_ipv6 ${IP}; then if is_ipv6_enabled; then ${IPT6} -A INPUT -s ${IP} -j ACCEPT fi @@ -524,7 +532,6 @@ start() { # NTP authorizations for src in ${NTPOK}; do - if is_ipv6 ${src}; then if is_ipv6_enabled; then ${IPT6} -A INPUT -p udp --sport 123 -s ${src} -j ACCEPT @@ -550,8 +557,9 @@ start() { # Output for backup servers for server in ${BACKUPSERVERS}; do - server_port=$(echo "${server}" | awk '{print $NF}') + server_port=$(echo "${server}" | awk -F : '{print $(NF)}') server_ip=$(echo "${server}" | sed -e "s/:${server_port}$//") + if [ -n "${server_ip}" ] && [ -n "${server_port}" ]; then if is_ipv6 ${server_ip}; then if is_ipv6_enabled; then From a600d03ab469b34273a1c6e52289c3b6584ee28b Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 14 Sep 2021 12:37:04 +0200 Subject: [PATCH 32/42] split configuration and includes --- minifirewall | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/minifirewall b/minifirewall index 11e59a2..c6cc2c1 100755 --- a/minifirewall +++ b/minifirewall @@ -35,10 +35,13 @@ NAME="minifirewall" set -u - # Variables configuration ######################### +legacy_config_file="/etc/firewall.rc" +config_file="/etc/default/minifirewall" +includes_dir="/etc/minifirewall.d" + # iptables paths IPT=$(command -v iptables) if [ -z "${IPT}" ]; then @@ -92,14 +95,6 @@ PROXYBYPASS='' PROXYPORT='' BACKUPSERVERS='' -legacy_config_file="/etc/firewall.rc" -config_file="/etc/default/minifirewall" -includes_dir="/etc/minifirewall.d" - -IPV6=$(grep "IPV6=" "${config_file}" | awk -F '=' -F "'" '{print $2}') -DOCKER=$(grep "DOCKER=" "${config_file}" | awk -F '=' -F "'" '{print $2}') -INT=$(grep "INT=" "${config_file}" | awk -F '=' -F "'" '{print $2}') - is_ipv6_enabled() { test "${IPV6}" != "off" } @@ -135,7 +130,7 @@ source_file_or_error() { } source_configuration() { if test -f ${legacy_config_file}; then - echo "${legacy_config_file} is deprecated, rename to ${config_file}" >&2 + echo "${legacy_config_file} is deprecated. Rename it to ${config_file}" >&2 exit 1 fi @@ -144,10 +139,17 @@ source_configuration() { exit 1 fi - source_file_or_error ${config_file} + if grep -e iptables -e ip6tables "${config_file}" | grep -qvE "^#"; then + echo "iptables/ip6tables commands found in ${config_file}." >&2 + echo "Move them in included files (in ${includes_dir})." >&2 + exit 1 + fi + source_file_or_error ${config_file} +} +source_includes() { if [ -d "${includes_dir}" ]; then - include_files=$(find ${includes_dir} -type f -readable -not -name '*.*' | sort) + include_files=$(find ${includes_dir} -type f -readable -not -name '*.*' | sort -h) for include_file in ${include_files}; do source_file_or_error "${include_file}" done @@ -161,7 +163,6 @@ start() { set -e trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT - # sysctl network security settings ################################## @@ -217,8 +218,6 @@ start() { ${IPT6} -A LOG_ACCEPT -j ACCEPT fi - source_configuration - # Trusted ip addresses ${IPT} -N ONLYTRUSTED ${IPT} -A ONLYTRUSTED -j LOG_DROP @@ -616,6 +615,9 @@ start() { ${IPT6} -A OUTPUT -p udp -j DROP fi + # Source files present in optional directory + source_includes + trap - INT TERM EXIT echo "...starting IPTables rules is now finish : OK" @@ -726,37 +728,35 @@ reset() { echo "...reseting IPTables counters is now finish : OK" } -case "$1" in +echo "${NAME} version ${VERSION}" +source_configuration + +case "${1:-''}" in start) - echo "${NAME} version ${VERSION}" start ;; stop) - echo "${NAME} version ${VERSION}" stop ;; status) - echo "${NAME} version ${VERSION}" status ;; reset) - echo "${NAME} version ${VERSION}" reset ;; restart) - echo "${NAME} version ${VERSION}" stop start ;; *) - echo "${NAME} version ${VERSION}" - echo "Usage: $0 {start|stop|restart|status|reset}" + echo "Usage: $0 {start|stop|restart|status|reset}" exit 1 + ;; esac exit 0 From 30838eb892f665a4ad53359de5092771f83f2abe Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 14 Sep 2021 12:47:17 +0200 Subject: [PATCH 33/42] rename variables for readability --- minifirewall | 88 ++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/minifirewall b/minifirewall index c6cc2c1..00f2c68 100755 --- a/minifirewall +++ b/minifirewall @@ -435,110 +435,110 @@ start() { ################### # DNS authorizations - for src in ${DNSSERVEURS}; do - if is_ipv6 ${src}; then + for IP in ${DNSSERVEURS}; do + if is_ipv6 ${IP}; then if is_ipv6_enabled; then - ${IPT6} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${src} -j ACCEPT - ${IPT6} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${src} -m state --state ESTABLISHED,RELATED -j ACCEPT - ${IPT6} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 53 --match state --state NEW -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + ${IPT6} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${IP} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT6} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 53 --match state --state NEW -j ACCEPT fi else - ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${src} -j ACCEPT - ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${src} -m state --state ESTABLISHED,RELATED -j ACCEPT - ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 53 --match state --state NEW -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + ${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${IP} -m state --state ESTABLISHED,RELATED -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 53 --match state --state NEW -j ACCEPT fi done # HTTP (TCP/80) authorizations - for src in ${HTTPSITES}; do - if is_ipv6 ${src}; then + for IP in ${HTTPSITES}; do + if is_ipv6 ${IP}; then if is_ipv6_enabled; then - ${IPT6} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi else - ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi done # HTTPS (TCP/443) authorizations - for src in ${HTTPSSITES}; do - if is_ipv6 ${src}; then + for IP in ${HTTPSSITES}; do + if is_ipv6 ${IP}; then if is_ipv6_enabled; then - ${IPT6} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi else - ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi done # FTP (so complex protocol...) authorizations - for src in ${FTPSITES}; do - if is_ipv6 ${src}; then + for IP in ${FTPSITES}; do + if is_ipv6 ${IP}; then if is_ipv6_enabled; then # requests on Control connection - ${IPT6} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${IP} -j ACCEPT # FTP port-mode on Data Connection - ${IPT6} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${IP} -j ACCEPT # FTP passive-mode on Data Connection # WARNING, this allow all connections on TCP ports > 1024 - ${IPT6} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi else # requests on Control connection - ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${IP} -j ACCEPT # FTP port-mode on Data Connection - ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp --sport 20 --dport ${PORTSUSER} -s ${IP} -j ACCEPT # FTP passive-mode on Data Connection # WARNING, this allow all connections on TCP ports > 1024 - ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi done # SSH authorizations - for src in ${SSHOK}; do - if is_ipv6 ${src}; then + for IP in ${SSHOK}; do + if is_ipv6 ${IP}; then if is_ipv6_enabled; then - ${IPT6} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi else - ${IPT} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi done # SMTP authorizations - for src in ${SMTPOK}; do - if is_ipv6 ${src}; then + for IP in ${SMTPOK}; do + if is_ipv6 ${IP}; then if is_ipv6_enabled; then - ${IPT6} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi else - ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi done # secure SMTP (TCP/465 et TCP/587) authorizations - for src in ${SMTPSECUREOK}; do - if is_ipv6 ${src}; then + for IP in ${SMTPSECUREOK}; do + if is_ipv6 ${IP}; then if is_ipv6_enabled; then - ${IPT6} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${src} -j ACCEPT - ${IPT6} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + ${IPT6} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi else - ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${src} -j ACCEPT - ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${src} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 465 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${IP} -j ACCEPT fi done # NTP authorizations - for src in ${NTPOK}; do - if is_ipv6 ${src}; then + for IP in ${NTPOK}; do + if is_ipv6 ${IP}; then if is_ipv6_enabled; then - ${IPT6} -A INPUT -p udp --sport 123 -s ${src} -j ACCEPT - ${IPT6} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 123 --match state --state NEW -j ACCEPT + ${IPT6} -A INPUT -p udp --sport 123 -s ${IP} -j ACCEPT + ${IPT6} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 123 --match state --state NEW -j ACCEPT fi else - ${IPT} -A INPUT -p udp --sport 123 -s ${src} -j ACCEPT - ${IPT} -A OUTPUT -o ${INT} -p udp -d ${src} --dport 123 --match state --state NEW -j ACCEPT + ${IPT} -A INPUT -p udp --sport 123 -s ${IP} -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 123 --match state --state NEW -j ACCEPT fi done From 3b4ffec1748835afb849de6a86ea6c0b559b5ceb Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 14 Sep 2021 12:47:32 +0200 Subject: [PATCH 34/42] Document helper functions that are accessible inincluded files --- minifirewall.conf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/minifirewall.conf b/minifirewall.conf index df519b4..e4b4872 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -93,4 +93,9 @@ BACKUPSERVERS='' ##################### # Files in /etc/minifirewall.d/* (without "." in name) -# are automatically included in alphanumerical order. \ No newline at end of file +# are automatically included in alphanumerical order. +# +# Within included files, you can use those helper functions : +# * is_ipv6_enabled: returns true if IPv6 is enabled, or false +# * is_docker_enabled: returns true if Docker mode is eabled, or false +# * is_proxy_enabled: returns true if Proxy mode is enabled , or false \ No newline at end of file From 7f3f69329f8299f92425190348c21e2abbd2dff0 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Fri, 3 Dec 2021 11:29:32 +0100 Subject: [PATCH 35/42] Don't throw ipv6 to iptables in the squid macro --- minifirewall | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/minifirewall b/minifirewall index 00f2c68..66fed55 100755 --- a/minifirewall +++ b/minifirewall @@ -549,7 +549,9 @@ start() { ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT for dstip in ${PROXYBYPASS}; do - ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "${dstip}" -j ACCEPT + if ! is_ipv6 ${dstip}; then + ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -d "${dstip}" -j ACCEPT + fi done ${IPT} -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port "${PROXYPORT:-'8888'}" fi From e7aaefef9a9d3cb186f1a7b09519066efe4b98b2 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 6 Dec 2021 11:53:10 +0100 Subject: [PATCH 36/42] Release 21.12 --- minifirewall | 2 +- minifirewall.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/minifirewall b/minifirewall index 66fed55..b62109b 100755 --- a/minifirewall +++ b/minifirewall @@ -28,7 +28,7 @@ # Description: Firewall designed for standalone server ### END INIT INFO -VERSION="21.09" +VERSION="21.12" DESC="minifirewall" NAME="minifirewall" diff --git a/minifirewall.conf b/minifirewall.conf index e4b4872..c3567eb 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -1,5 +1,5 @@ # Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall -# Version 21.05 — 2021-05-22 23:22:10 +# Version 21.12 — 2021-12-06 # shellcheck shell=sh disable=SC2034 # Main interface From 0b3ed7ae25f80230b5859b0070f1cc33f8652564 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 11 Dec 2021 10:13:38 +0100 Subject: [PATCH 37/42] Backward compatible mode --- minifirewall | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/minifirewall b/minifirewall index b62109b..46570c8 100755 --- a/minifirewall +++ b/minifirewall @@ -38,7 +38,6 @@ set -u # Variables configuration ######################### -legacy_config_file="/etc/firewall.rc" config_file="/etc/default/minifirewall" includes_dir="/etc/minifirewall.d" @@ -95,6 +94,8 @@ PROXYBYPASS='' PROXYPORT='' BACKUPSERVERS='' +LEGACY_CONFIG='off' + is_ipv6_enabled() { test "${IPV6}" != "off" } @@ -107,6 +108,9 @@ is_proxy_enabled() { is_ipv6() { echo "$1" | grep -q ':' } +is_legacy_config() { + test "${LEGACY_CONFIG}" != "off" +} chain_exists() { chain_name="$1" if [ $# -ge 2 ]; then @@ -121,6 +125,7 @@ source_file_or_error() { tmpfile=$(mktemp --tmpdir=/tmp minifirewall.XXX) . "${file}" 2>"${tmpfile}" >&2 + if [ -s "${tmpfile}" ]; then echo "${file} returns standard or error output (see below). Stopping." >&2 cat "${tmpfile}" @@ -129,23 +134,37 @@ source_file_or_error() { rm "${tmpfile}" } source_configuration() { - if test -f ${legacy_config_file}; then - echo "${legacy_config_file} is deprecated. Rename it to ${config_file}" >&2 - exit 1 - fi - if ! test -f ${config_file}; then echo "${config_file} does not exist" >&2 + + old_config_file="/etc/firewall.rc" + if test -f ${old_config_file}; then + echo "${old_config_file} is deprecated. Rename it to ${config_file}" >&2 + fi + exit 1 fi - if grep -e iptables -e ip6tables "${config_file}" | grep -qvE "^#"; then - echo "iptables/ip6tables commands found in ${config_file}." >&2 - echo "Move them in included files (in ${includes_dir})." >&2 - exit 1 + if grep -e "iptables" -e "ip6tables" "${config_file}" | grep -qvE "^#"; then + ## Backward compatible mode + echo "Legacy config detected" + LEGACY_CONFIG='on' + + ## Non-backward compatible mode + # echo "iptables/ip6tables commands found in ${config_file}." >&2 + # echo "Move them in included files (in ${includes_dir})." >&2 + # exit 1 fi - source_file_or_error ${config_file} + if is_legacy_config; then + tmp_config_file=$(mktemp --tmpdir=/tmp minifirewall.XXX) + grep -E "^\s*[_a-zA-Z0-9]+=" "${config_file}" > "${tmp_config_file}" + + source_file_or_error "${tmp_config_file}" + rm "${tmp_config_file}" + else + source_file_or_error "${config_file}" + fi } source_includes() { if [ -d "${includes_dir}" ]; then @@ -601,12 +620,12 @@ start() { if is_ipv6_enabled; then ${IPT6} -P OUTPUT ACCEPT fi - + ${IPT} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT if is_ipv6_enabled; then ${IPT6} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT fi - + ${IPT} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT if is_ipv6_enabled; then ${IPT6} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT @@ -617,6 +636,10 @@ start() { ${IPT6} -A OUTPUT -p udp -j DROP fi + if is_legacy_config; then + source_file_or_error "${config_file}" + fi + # Source files present in optional directory source_includes From be023616a53775efc0cc8474cf1a01a1302517a3 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 12 Dec 2021 19:29:05 +0100 Subject: [PATCH 38/42] more comments --- minifirewall | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/minifirewall b/minifirewall index 46570c8..5515c73 100755 --- a/minifirewall +++ b/minifirewall @@ -137,6 +137,8 @@ source_configuration() { if ! test -f ${config_file}; then echo "${config_file} does not exist" >&2 + ## We still want to deal with this really old configuration file + ## even if it has been deprecated since Debian 8 old_config_file="/etc/firewall.rc" if test -f ${old_config_file}; then echo "${old_config_file} is deprecated. Rename it to ${config_file}" >&2 @@ -146,17 +148,30 @@ source_configuration() { fi if grep -e "iptables" -e "ip6tables" "${config_file}" | grep -qvE "^#"; then - ## Backward compatible mode + # Backward compatible mode + ########################### + echo "Legacy config detected" LEGACY_CONFIG='on' - ## Non-backward compatible mode + # Non-backward compatible mode + ############################### + + # If we ever want to remove the backward compatible mode + # we can remove the two lines above and uncomment the lines below. + # They break if any iptables/ip6tables command is found in the configuration file + # echo "iptables/ip6tables commands found in ${config_file}." >&2 # echo "Move them in included files (in ${includes_dir})." >&2 # exit 1 fi if is_legacy_config; then + # In this mode, we extract all variable definitions + # to a temporary file that we can source. + # It allow iptables/ip6tables commands to remain in the configuration file + # and not interfere with the configuration step. + tmp_config_file=$(mktemp --tmpdir=/tmp minifirewall.XXX) grep -E "^\s*[_a-zA-Z0-9]+=" "${config_file}" > "${tmp_config_file}" From c36be1c9c962df32f3ddca2e725e3bfa8d6c0212 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 15 Mar 2022 16:01:42 +0100 Subject: [PATCH 39/42] Add variables and documentation for sysctl variables (fixes #7) --- minifirewall | 99 +++++++++++++++++++++++++++++++++-------------- minifirewall.conf | 33 +++++++++++++++- 2 files changed, 103 insertions(+), 29 deletions(-) diff --git a/minifirewall b/minifirewall index 5515c73..a821d61 100755 --- a/minifirewall +++ b/minifirewall @@ -200,39 +200,82 @@ start() { # sysctl network security settings ################################## - # Don't answer to broadcast pings - echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts - - # Ignore bogus ICMP responses - echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses - - # Disable Source Routing - for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_source_route; do - echo 0 > "${proc_sys_file}" - done - - # Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks + # Set 1 to ignore broadcast pings (default) + : "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS:='1'}" + # Set 1 to ignore bogus ICMP responses (default) + : "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES:='1'}" + # Set 0 to disable source routing (default) + : "${SYSCTL_ACCEPT_SOURCE_ROUTE:='0'}" + # Set 1 to enable TCP SYN cookies (default) # cf http://cr.yp.to/syncookies.html - echo 1 > /proc/sys/net/ipv4/tcp_syncookies + : "${SYSCTL_TCP_SYNCOOKIES:='1'}" + # Set 0 to disable ICMP redirects (default) + : "${SYSCTL_ICMP_REDIRECTS:='0'}" + # Set 1 to enable Reverse Path filtering (default) + # Set 0 if VRRP is used + : "${SYSCTL_RP_FILTER:='1'}" + # Set 1 to log packets with inconsistent address (default) + : "${SYSCTL_LOG_MARTIANS:='1'}" - # Disable ICMP redirects - for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_redirects; do - echo 0 > "${proc_sys_file}" - done + if [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "1" ] || [ "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" = "0" ]; then + echo "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts + else + echo "Invalid SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS value '${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}', must be '0' or '1'." >&2 + exit 1 + fi - for proc_sys_file in /proc/sys/net/ipv4/conf/*/send_redirects; do - echo 0 > "${proc_sys_file}" - done + if [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "1" ] || [ "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" = "0" ]; then + echo "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses + else + echo "Invalid SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES value '${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES}', must be '0' or '1'." >&2 + exit 1 + fi - # Enable Reverse Path filtering : verify if responses use same network interface - for proc_sys_file in /proc/sys/net/ipv4/conf/*/rp_filter; do - echo 1 > "${proc_sys_file}" - done + if [ "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = "1" ] || [ "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = "0" ]; then + for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_source_route; do + echo "${SYSCTL_ACCEPT_SOURCE_ROUTE}" = > "${proc_sys_file}" + done + else + echo "Invalid SYSCTL_ACCEPT_SOURCE_ROUTE value '${SYSCTL_ACCEPT_SOURCE_ROUTE}', must be '0' or '1'." >&2 + exit 1 + fi - # log des paquets avec adresse incoherente - for proc_sys_file in /proc/sys/net/ipv4/conf/*/log_martians; do - echo 1 > "${proc_sys_file}" - done + if [ "${SYSCTL_TCP_SYNCOOKIES}" = "1" ] || [ "${SYSCTL_TCP_SYNCOOKIES}" = "0" ]; then + echo "${SYSCTL_TCP_SYNCOOKIES}" > /proc/sys/net/ipv4/tcp_syncookies + else + echo "Invalid SYSCTL_TCP_SYNCOOKIES value '${SYSCTL_TCP_SYNCOOKIES}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_ICMP_REDIRECTS}" = "1" ] || [ "${SYSCTL_ICMP_REDIRECTS}" = "0" ]; then + for proc_sys_file in /proc/sys/net/ipv4/conf/*/accept_redirects; do + echo "${SYSCTL_ICMP_REDIRECTS}" > "${proc_sys_file}" + done + for proc_sys_file in /proc/sys/net/ipv4/conf/*/send_redirects; do + echo "${SYSCTL_ICMP_REDIRECTS}" > "${proc_sys_file}" + done + else + echo "Invalid SYSCTL_ICMP_REDIRECTS value '${SYSCTL_ICMP_REDIRECTS}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_RP_FILTER}" = "1" ] || [ "${SYSCTL_RP_FILTER}" = "0" ]; then + for proc_sys_file in /proc/sys/net/ipv4/conf/*/rp_filter; do + echo "${SYSCTL_RP_FILTER}" > "${proc_sys_file}" + done + else + echo "Invalid SYSCTL_RP_FILTER value '${SYSCTL_RP_FILTER}', must be '0' or '1'." >&2 + exit 1 + fi + + if [ "${SYSCTL_LOG_MARTIANS}" = "1" ] || [ "${SYSCTL_LOG_MARTIANS}" = "0" ]; then + for proc_sys_file in /proc/sys/net/ipv4/conf/*/log_martians; do + echo "${SYSCTL_LOG_MARTIANS}" > "${proc_sys_file}" + done + else + echo "Invalid SYSCTL_LOG_MARTIANS value '${SYSCTL_LOG_MARTIANS}', must be '0' or '1'." >&2 + exit 1 + fi # IPTables configuration ######################## diff --git a/minifirewall.conf b/minifirewall.conf index c3567eb..17d539a 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -89,6 +89,7 @@ PROXYBYPASS="${INTLAN} 127.0.0.0/8 ::1/128" # (add IP:PORT for each one, example: '192.168.10.1:1234 192.168.10.2:5678') BACKUPSERVERS='' + # Includes ##################### @@ -98,4 +99,34 @@ BACKUPSERVERS='' # Within included files, you can use those helper functions : # * is_ipv6_enabled: returns true if IPv6 is enabled, or false # * is_docker_enabled: returns true if Docker mode is eabled, or false -# * is_proxy_enabled: returns true if Proxy mode is enabled , or false \ No newline at end of file +# * is_proxy_enabled: returns true if Proxy mode is enabled , or false + + +# Custom sysctl values (advanced) +################################# + +# In most cases, the default values set by minifirewall are good. +# If you really know what you are doing, +# you can uncomment some lines and customize the values. + +# Set 1 to ignore broadcast pings (default) +# SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS='1' + +# Set 1 to ignore bogus ICMP responses (default) +# SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES='1' + +# Set 0 to disable source routing (default) +# SYSCTL_ACCEPT_SOURCE_ROUTE='0' + +# Set 1 to enable TCP SYN cookies (default) +# SYSCTL_TCP_SYNCOOKIES='1' + +# Set 0 to disable ICMP redirects (default) +# SYSCTL_ICMP_REDIRECTS='0' + +# Set 1 to enable Reverse Path filtering (default) +# Set 0 if VRRP is used +# SYSCTL_RP_FILTER='1' + +# Set 1 to log packets with inconsistent address (default) +# SYSCTL_LOG_MARTIANS='1' \ No newline at end of file From 0041789d5eba74f4ff7d7d2d804ec4885fe33187 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 15 Mar 2022 16:21:38 +0100 Subject: [PATCH 40/42] improve docs and merge 45f04e --- README.md | 34 ++++++++++++++++++++-------------- minifirewall.conf | 8 ++++++-- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 97e78cd..c6d9901 100644 --- a/README.md +++ b/README.md @@ -8,35 +8,41 @@ See https://gitea.evolix.org/evolix/minifirewall ## Install ~~~ -install -m 0700 minifirewall /etc/init.d/minifirewall -install -m 0600 minifirewall.conf /etc/default/minifirewall +install --mode 0700 minifirewall /etc/init.d/minifirewall +install --mode 0600 minifirewall.conf /etc/default/minifirewall +mkdir --mode 0700 /etc/minifirewall.d ~~~ ## Config Edit /etc/default/minifirewall file: -* If your interface is not _eth0_, change *INT* variable -* If you don't IPv6 : *IPv6=off* -* Modify *INTLAN* variable, probably with your *IP/32* or your local network if you trust it -* Set your trusted and privilegied IP addresses in *TRUSTEDIPS* and *PRIVILEGIEDIPS* variables -* Authorize your +public+ services with *SERVICESTCP1* and *SERVICESUDP1* variables -* Authorize your +semi-public+ services (only for *TRUSTEDIPS* and *PRIVILEGIEDIPS* ) with *SERVICESTCP2* and *SERVICESUDP2* variables -* Authorize your +private+ services (only for *TRUSTEDIPS* ) with *SERVICESTCP3* and *SERVICESUDP3* variables +* If your interface is not `eth0`, change `INT` variable +* If you don't use IPv6, set `IPv6='off'` +* Modify `INTLAN` variable, probably with your `/32` or your local network if you trust it +* Set your trusted and privilegied IP addresses in `TRUSTEDIPS` and `PRIVILEGIEDIPS` variables +* Authorize your **public** services with `SERVICESTCP1` and `SERVICESUDP1` variables +* Authorize your **semi-public** services (only for `TRUSTEDIPS` and `PRIVILEGIEDIPS` ) with `SERVICESTCP2` and `SERVICESUDP2` variables +* Authorize your **private** services (only for `TRUSTEDIPS` ) with `SERVICESTCP3` and `SERVICESUDP3` variables * Configure your authorizations for external services : DNS, HTTP, HTTPS, SMTP, SSH, NTP * Add your specific rules +### Docker + +To use minifirewall with Docker you need to change the variable `DOCKER='on'` +Then, authorisation for public/semi-public/private ports will also work for dockerized services + + +**WARNING** : When the port mapping on the host is different than in the container (ie: listen on :8090 on the host, but the service in the container listen on :8080) +you need to use the port used by the container (ie: 8080) in the public/semi-public/private port list + ## Usage ~~~ /etc/init.d/minifirewall start/stop/restart ~~~ -If you want to add minifirewall in boot sequence: - -~~~ -systemctl enable minifirewall -~~~ +If you want to add minifirewall in boot sequence, add the start command to `/usr/share/scripts/alert5`. ## License diff --git a/minifirewall.conf b/minifirewall.conf index 17d539a..83c7af3 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -1,5 +1,5 @@ # Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall -# Version 21.12 — 2021-12-06 +# Version 22.3 — 2022-03-15 # shellcheck shell=sh disable=SC2034 # Main interface @@ -11,7 +11,11 @@ IPV6='on' # Docker Mode # Changes the behaviour of minifirewall to not break the containers' network # For instance, turning it on will disable nat table purge -# Also, we'll add the DOCKER-USER chain, in iptable +# Also, we'll add the DOCKER-USER chain, in iptables +# +# WARNING : If the port mapping is different between the host and the container +# (ie: Listen on :8090 on host, but :8080 in container) +# then you need to give the port used inside the container DOCKER='off' # Trusted local network From 92f4751ccbdfa5a60e7533ac8a6a7b4e6a4e2550 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 15 Mar 2022 16:29:22 +0100 Subject: [PATCH 41/42] drop useless ipv6 include file --- minifirewall.d/ipv6 | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 minifirewall.d/ipv6 diff --git a/minifirewall.d/ipv6 b/minifirewall.d/ipv6 deleted file mode 100644 index 5484a12..0000000 --- a/minifirewall.d/ipv6 +++ /dev/null @@ -1,26 +0,0 @@ -# shellcheck shell=sh disable=SC2034 - -# Set of rules for IPv6 -# They should be moved to the macros in the init script - -if [ "${IPV6}" != "off" ]; then - # allow HTTP/HTTPS/SMTP/DNS input - /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT - /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT - /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT - /sbin/ip6tables -A INPUT -i ${INT} -p udp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT - /sbin/ip6tables -A INPUT -i ${INT} -p tcp --sport 53 --match state --state ESTABLISHED,RELATED -j ACCEPT - - # allow DNS output - /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 53 --match state --state NEW -j ACCEPT - - # allow NTP output - /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 123 --match state --state NEW -j ACCEPT - - # allow DHCPv6 - # /sbin/ip6tables -A INPUT -i ${INT} -p udp --dport 546 -d fe80::/64 -j ACCEPT - # /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 547 -j ACCEPT - - # allow traceroute output - # /sbin/ip6tables -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT -fi \ No newline at end of file From 54f7021d6a6330aef981aa858c4335acf99cd224 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 15 Mar 2022 16:30:39 +0100 Subject: [PATCH 42/42] Add test configurations in tests directory --- tests/minifirewall-legacy.conf | 136 +++++++++ tests/minifirewall-master | 492 +++++++++++++++++++++++++++++++++ 2 files changed, 628 insertions(+) create mode 100644 tests/minifirewall-legacy.conf create mode 100644 tests/minifirewall-master diff --git a/tests/minifirewall-legacy.conf b/tests/minifirewall-legacy.conf new file mode 100644 index 0000000..9784325 --- /dev/null +++ b/tests/minifirewall-legacy.conf @@ -0,0 +1,136 @@ +# Fichier de configuration +# pour minifirewall + +# version 0.1 - 12 juillet 2007 $Id: firewall.rc,v 1.2 2007/07/12 19:08:59 reg Exp $ + +# Interface concernee +INT='eth0.11' + +IPV6=on + +# IP associee (plus utilisee dans les scripts) +# INTIP='192.168.0.2' +# reseau beneficiant d'acces privilegies +# (sera souvent IP/32) +INTLAN='192.0.2.1/32' + +# trusted ip addresses +TRUSTEDIPS='62.212.121.90 62.212.111.216 88.179.18.233 85.118.59.4 85.118.59.50 31.170.8.4 31.170.9.129 82.65.34.85 54.37.106.210 51.210.84.146' + +# privilegied ip addresses +# (trusted ip addresses *are* privilegied) +PRIVILEGIEDIPS='80.14.117.69 31.170.8.6 31.170.11.167 31.170.11.167 31.170.8.7 31.170.8.249 31.170.8.76 31.170.8.222 80.245.23.179 51.38.233.228' + +# Services "protected" +# a mettre aussi en public si necessaire !! +SERVICESTCP1p='' +SERVICESUDP1p='' + +# Services "publics" +SERVICESTCP1='21 80 443 2222' +SERVICESUDP1='' + +# Services "semi-publics" +SERVICESTCP2='20 22 25' +SERVICESUDP2='' + +# Services "prives" +SERVICESTCP3='5666' +SERVICESUDP3='' + +################### SORTANTS + +# DNS +# (Attention, si un serveur DNS est installe en local +# mettre 0.0.0.0/0) +DNSSERVEURS='0.0.0.0/0' + +# HTTP : security.d.o x3, zidane, modsecurity www.debian.org +# /!\ Possibilite d'utiliser des noms de domaines +# mais il est conseiller de placer un rechargement +# du minifirewall en crontab +# (Attention, si un proxy HTTP est installe en local +# mettre 0.0.0.0/0) +HTTPSITES='0.0.0.0/0' + +# HTTPS +# /!\ Possibilite d'utiliser des noms de domaines +# mais il est conseiller de placer un rechargement +# du minifirewall en crontab +HTTPSSITES='0.0.0.0/0' + +# FTP +FTPSITES='0.0.0.0/0' + +# SSH +SSHOK='0.0.0.0/0' + +# SMTP +SMTPOK='0.0.0.0/0' + +# SMTP secure (port 465 et 587) +SMTPSECUREOK='0.0.0.0/0' + +# NTP +NTPOK='0.0.0.0/0' + +################### IPv6 Specific rules +# /sbin/ip6tables ... + +# Allow HTTP/HTTPS/SMTP traffic +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 80 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 443 --match state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 25 --match state --state ESTABLISHED,RELATED -j ACCEPT + +# Allow DNS, NTP and traceroute traffic +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 53 --match state --state NEW -j ACCEPT +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 123 --match state --state NEW -j ACCEPT +/sbin/ip6tables -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + +# Allow DHCPv6 +/sbin/ip6tables -t filter -A INPUT -i $INT -p udp --dport 546 -d fe80::/64 -j ACCEPT +/sbin/ip6tables -t filter -A OUTPUT -o $INT -p udp --dport 547 -j ACCEPT + +################### IPv4 Specific rules +# /sbin/iptables ... + +# Allow DNS, NTP and traceroute traffic +/sbin/iptables -A OUTPUT -o $INT -p udp --dport 53 --match state --state NEW -j ACCEPT +/sbin/iptables -A OUTPUT -o $INT -p udp --dport 123 --match state --state NEW -j ACCEPT +/sbin/iptables -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT + +# EvoBackup +# /sbin/iptables -A INPUT -p tcp --sport XXXX --dport 1024:65535 -s 85.118.59.1 -m state --state ESTABLISHED,RELATED -j ACCEPT +# /sbin/iptables -A INPUT -p tcp --sport XXXX --dport 1024:65535 -s 31.170.8.1 -m state --state ESTABLISHED,RELATED -j ACCEPT +# /sbin/iptables -A INPUT -p tcp --sport XXXX --dport 1024:65535 -s 178.32.100.48 -m state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/iptables -A INPUT -p tcp --sport 2223 --dport 1024:65535 -s 62.210.209.17 -m state --state ESTABLISHED,RELATED -j ACCEPT + +# FTP en mode passif +/sbin/iptables -A INPUT -p tcp --dport 60000:61000 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT + +# EvoMaintenance +/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s 31.170.8.4 -m state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s 62.212.121.90 -m state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s 62.212.111.216 -m state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s 88.179.18.233 -m state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s 85.118.59.50 -m state --state ESTABLISHED,RELATED -j ACCEPT +/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s 31.170.9.129 -m state --state ESTABLISHED,RELATED -j ACCEPT + +# Proxy +/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT +/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 31.170.8.7 -j ACCEPT +/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 31.170.8.10 -j ACCEPT +/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 31.170.8.217 -j ACCEPT +/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 31.170.8.218 -j ACCEPT +/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.1 -j ACCEPT +/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -j LOG --log-uid +/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8888 + +#43251 +iptables -I INPUT -s 5.188.211.0/24 -p tcp --dport 80 -j DROP +iptables -I INPUT -s 5.188.211.0/24 -p tcp --dport 443 -j DROP + +/sbin/iptables -A INPUT -p tcp --sport 2222 --dport 1024:65535 -s 31.170.11.167,31.170.8.7,31.170.8.249,31.170.8.76,31.170.8.222 -m state --state ESTABLISHED,RELATED -j ACCEPT + +# Ticket #52247 : Blocage git / Autorisation port 22 en IPv6 +/sbin/ip6tables -A INPUT -p tcp ! --syn --sport 22 -s ::/0 -j ACCEPT diff --git a/tests/minifirewall-master b/tests/minifirewall-master new file mode 100644 index 0000000..c1a7251 --- /dev/null +++ b/tests/minifirewall-master @@ -0,0 +1,492 @@ +#!/bin/sh + +# minifirewall is shellscripts for easy firewalling on a standalone server +# we used netfilter/iptables http://netfilter.org/ designed for recent Linux kernel +# See https://gitea.evolix.org/evolix/minifirewall + +# Copyright (c) 2007-2020 Evolix +# 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 3 +# of the License. + +# Description +# script for standalone server + +# Start or stop minifirewall +# + +### BEGIN INIT INFO +# Provides: minfirewall +# Required-Start: +# Required-Stop: +# Should-Start: $network $syslog $named +# Should-Stop: $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start and stop the firewall +# Description: Firewall designed for standalone server +### END INIT INFO + +DESC="minifirewall" +NAME="minifirewall" + + +# Variables configuration +######################### + +# iptables paths +IPT=/sbin/iptables +IPT6=/sbin/ip6tables + +# TCP/IP variables +LOOPBACK='127.0.0.0/8' +CLASSA='10.0.0.0/8' +CLASSB='172.16.0.0/12' +CLASSC='192.168.0.0/16' +CLASSD='224.0.0.0/4' +CLASSE='240.0.0.0/5' +ALL='0.0.0.0' +BROAD='255.255.255.255' +PORTSROOT='0:1023' +PORTSUSER='1024:65535' + +chain_exists() +{ + local chain_name="$1" ; shift + [ $# -eq 1 ] && local intable="--table $1" + iptables $intable -nL "$chain_name" >/dev/null 2>&1 +} + +# Configuration +oldconfigfile="/etc/firewall.rc" +configfile="/etc/default/minifirewall" + +IPV6=$(grep "IPV6=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') +DOCKER=$(grep "DOCKER=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') +INT=$(grep "INT=" /etc/default/minifirewall | awk -F '=' -F "'" '{print $2}') + +case "$1" in + start) + + echo "Start IPTables rules..." + +# Stop and warn if error! +set -e +trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT + + +# sysctl network security settings +################################## + +# Don't answer to broadcast pings +echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts + +# Ignore bogus ICMP responses +echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses + +# Disable Source Routing +for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do +echo 0 > $i +done + +# Enable TCP SYN cookies to avoid TCP-SYN-FLOOD attacks +# cf http://cr.yp.to/syncookies.html +echo 1 > /proc/sys/net/ipv4/tcp_syncookies + +# Disable ICMP redirects +for i in /proc/sys/net/ipv4/conf/*/accept_redirects; do +echo 0 > $i +done + +for i in /proc/sys/net/ipv4/conf/*/send_redirects; do +echo 0 > $i +done + +# Enable Reverse Path filtering : verify if responses use same network interface +for i in /proc/sys/net/ipv4/conf/*/rp_filter; do +echo 1 > $i +done + +# log des paquets avec adresse incoherente +for i in /proc/sys/net/ipv4/conf/*/log_martians; do +echo 1 > $i +done + +# IPTables configuration +######################## + +$IPT -N LOG_DROP +$IPT -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' +$IPT -A LOG_DROP -j DROP +$IPT -N LOG_ACCEPT +$IPT -A LOG_ACCEPT -j LOG --log-prefix '[IPTABLES ACCEPT] : ' +$IPT -A LOG_ACCEPT -j ACCEPT + +if test -f $oldconfigfile; then + echo "$oldconfigfile is deprecated, rename to $configfile" >&2 + exit 1 +fi + +if ! test -f $configfile; then + echo "$configfile does not exist" >&2 + exit 1 +fi + +tmpfile=`mktemp` +. $configfile 2>$tmpfile >&2 +if [ -s $tmpfile ]; then + echo "$configfile returns standard or error output (see below). Stopping." >&2 + cat $tmpfile + exit 1 +fi +rm $tmpfile + +# Trusted ip addresses +$IPT -N ONLYTRUSTED +$IPT -A ONLYTRUSTED -j LOG_DROP +for x in $TRUSTEDIPS + do + $IPT -I ONLYTRUSTED -s $x -j ACCEPT + done + +# Privilegied ip addresses +# (trusted ip addresses *are* privilegied) +$IPT -N ONLYPRIVILEGIED +$IPT -A ONLYPRIVILEGIED -j ONLYTRUSTED +for x in $PRIVILEGIEDIPS + do + $IPT -I ONLYPRIVILEGIED -s $x -j ACCEPT + done + +# Chain for restrictions (blacklist IPs/ranges) +$IPT -N NEEDRESTRICT + +# We allow all on loopback interface +$IPT -A INPUT -i lo -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A INPUT -i lo -j ACCEPT +# if OUTPUTDROP +$IPT -A OUTPUT -o lo -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o lo -j ACCEPT + +# We avoid "martians" packets, typical when W32/Blaster virus +# attacked windowsupdate.com and DNS was changed to 127.0.0.1 +# $IPT -t NAT -I PREROUTING -s $LOOPBACK -i ! lo -j DROP +$IPT -A INPUT -s $LOOPBACK ! -i lo -j DROP + + +if [ "$DOCKER" = "on" ]; then + + $IPT -N MINIFW-DOCKER-TRUSTED + $IPT -A MINIFW-DOCKER-TRUSTED -j DROP + + $IPT -N MINIFW-DOCKER-PRIVILEGED + $IPT -A MINIFW-DOCKER-PRIVILEGED -j MINIFW-DOCKER-TRUSTED + $IPT -A MINIFW-DOCKER-PRIVILEGED -j RETURN + + $IPT -N MINIFW-DOCKER-PUB + $IPT -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED + $IPT -A MINIFW-DOCKER-PUB -j RETURN + + # Flush DOCKER-USER if exist, create it if absent + if chain_exists 'DOCKER-USER'; then + $IPT -F DOCKER-USER + else + $IPT -N DOCKER-USER + fi; + + # Pipe new connection through MINIFW-DOCKER-PUB + $IPT -A DOCKER-USER -i $INT -m state --state NEW -j MINIFW-DOCKER-PUB + $IPT -A DOCKER-USER -j RETURN + +fi + + +# Local services restrictions +############################# + +# Allow services for $INTLAN (local server or local network) +$IPT -A INPUT -s $INTLAN -j ACCEPT + +# Enable protection chain for sensible services +for x in $SERVICESTCP1p + do + $IPT -A INPUT -p tcp --dport $x -j NEEDRESTRICT + done + +for x in $SERVICESUDP1p + do + $IPT -A INPUT -p udp --dport $x -j NEEDRESTRICT + done + +# Public service +for x in $SERVICESTCP1 + do + $IPT -A INPUT -p tcp --dport $x -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p tcp --dport $x -j ACCEPT + done + +for x in $SERVICESUDP1 + do + $IPT -A INPUT -p udp --dport $x -j ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -A INPUT -p udp --dport $x -j ACCEPT + done + +# Privilegied services +for x in $SERVICESTCP2 + do + $IPT -A INPUT -p tcp --dport $x -j ONLYPRIVILEGIED + done + +for x in $SERVICESUDP2 + do + $IPT -A INPUT -p udp --dport $x -j ONLYPRIVILEGIED + done + +# Private services +for x in $SERVICESTCP3 + do + $IPT -A INPUT -p tcp --dport $x -j ONLYTRUSTED + done + +for x in $SERVICESUDP3 + do + $IPT -A INPUT -p udp --dport $x -j ONLYTRUSTED + done + + +if [ "$DOCKER" = "on" ]; then + + # Public services defined in SERVICESTCP1 & SERVICESUDP1 + for dstport in $SERVICESTCP1 + do + $IPT -I MINIFW-DOCKER-PUB -p tcp --dport "$dstport" -j RETURN + done + + for dstport in $SERVICESUDP1 + do + $IPT -I MINIFW-DOCKER-PUB -p udp --dport "$dstport" -j RETURN + done + + # Privileged services (accessible from privileged & trusted IPs) + for dstport in $SERVICESTCP2 + do + for srcip in $PRIVILEGIEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done + + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + for dstport in $SERVICESUDP2 + do + for srcip in $PRIVILEGIEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-PRIVILEGED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + # Trusted services (accessible from trusted IPs) + for dstport in $SERVICESTCP3 + do + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-TRUSTED -p tcp -s "$srcip" --dport "$dstport" -j RETURN + done + done + + for dstport in $SERVICESUDP3 + do + for srcip in $TRUSTEDIPS + do + $IPT -I MINIFW-DOCKER-TRUSTED -p udp -s "$srcip" --dport "$dstport" -j RETURN + done + done +fi + +# External services +################### + +# DNS authorizations +for x in $DNSSERVEURS + do + $IPT -A INPUT -p tcp ! --syn --sport 53 --dport $PORTSUSER -s $x -j ACCEPT + $IPT -A INPUT -p udp --sport 53 --dport $PORTSUSER -s $x -m state --state ESTABLISHED,RELATED -j ACCEPT + $IPT -A OUTPUT -o $INT -p udp -d $x --dport 53 --match state --state NEW -j ACCEPT + done + +# HTTP (TCP/80) authorizations +for x in $HTTPSITES + do + $IPT -A INPUT -p tcp ! --syn --sport 80 --dport $PORTSUSER -s $x -j ACCEPT + done + +# HTTPS (TCP/443) authorizations +for x in $HTTPSSITES + do + $IPT -A INPUT -p tcp ! --syn --sport 443 --dport $PORTSUSER -s $x -j ACCEPT + done + +# FTP (so complex protocol...) authorizations +for x in $FTPSITES + do + # requests on Control connection + $IPT -A INPUT -p tcp ! --syn --sport 21 --dport $PORTSUSER -s $x -j ACCEPT + # FTP port-mode on Data Connection + $IPT -A INPUT -p tcp --sport 20 --dport $PORTSUSER -s $x -j ACCEPT + # FTP passive-mode on Data Connection + # WARNING, this allow all connections on TCP ports > 1024 + $IPT -A INPUT -p tcp ! --syn --sport $PORTSUSER --dport $PORTSUSER -s $x -j ACCEPT + done + +# SSH authorizations +for x in $SSHOK + do + $IPT -A INPUT -p tcp ! --syn --sport 22 -s $x -j ACCEPT + done + +# SMTP authorizations +for x in $SMTPOK + do + $IPT -A INPUT -p tcp ! --syn --sport 25 --dport $PORTSUSER -s $x -j ACCEPT + done + +# secure SMTP (TCP/465 et TCP/587) authorizations +for x in $SMTPSECUREOK + do + $IPT -A INPUT -p tcp ! --syn --sport 465 --dport $PORTSUSER -s $x -j ACCEPT + $IPT -A INPUT -p tcp ! --syn --sport 587 --dport $PORTSUSER -s $x -j ACCEPT + done + +# NTP authorizations +for x in $NTPOK + do + $IPT -A INPUT -p udp --sport 123 -s $x -j ACCEPT + $IPT -A OUTPUT -o $INT -p udp -d $x --dport 123 --match state --state NEW -j ACCEPT + done + +# Always allow ICMP +$IPT -A INPUT -p icmp -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A INPUT -p icmpv6 -j ACCEPT + + +# IPTables policy +################# + +# by default DROP INPUT packets +$IPT -P INPUT DROP +[ "$IPV6" != "off" ] && $IPT6 -P INPUT DROP + +# by default, no FORWARING (deprecated for Virtual Machines) +#echo 0 > /proc/sys/net/ipv4/ip_forward +#$IPT -P FORWARD DROP +#$IPT6 -P FORWARD DROP + +# by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) +$IPT -P OUTPUT ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT +$IPT -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +$IPT -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT +$IPT -A OUTPUT -p udp -j DROP +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -o $INT -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT +[ "$IPV6" != "off" ] && $IPT6 -A OUTPUT -p udp -j DROP + +trap - INT TERM EXIT + + echo "...starting IPTables rules is now finish : OK" + ;; + + stop) + + echo "Flush all rules and accept everything..." + + # Delete all rules + $IPT -F INPUT + $IPT -F OUTPUT + $IPT -F LOG_DROP + $IPT -F LOG_ACCEPT + $IPT -F ONLYTRUSTED + $IPT -F ONLYPRIVILEGIED + $IPT -F NEEDRESTRICT + [ "$DOCKER" = "off" ] && $IPT -t nat -F + $IPT -t mangle -F + [ "$IPV6" != "off" ] && $IPT6 -F INPUT + [ "$IPV6" != "off" ] && $IPT6 -F OUTPUT + + if [ "$DOCKER" = "on" ]; then + $IPT -F DOCKER-USER + $IPT -A DOCKER-USER -j RETURN + + $IPT -F MINIFW-DOCKER-PUB + $IPT -X MINIFW-DOCKER-PUB + $IPT -F MINIFW-DOCKER-PRIVILEGED + $IPT -X MINIFW-DOCKER-PRIVILEGED + $IPT -F MINIFW-DOCKER-TRUSTED + $IPT -X MINIFW-DOCKER-TRUSTED + + fi + + # Accept all + $IPT -P INPUT ACCEPT + $IPT -P OUTPUT ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -P INPUT ACCEPT + [ "$IPV6" != "off" ] && $IPT6 -P OUTPUT ACCEPT + #$IPT -P FORWARD ACCEPT + #$IPT -t nat -P PREROUTING ACCEPT + #$IPT -t nat -P POSTROUTING ACCEPT + + # Delete non-standard chains + $IPT -X LOG_DROP + $IPT -X LOG_ACCEPT + $IPT -X ONLYPRIVILEGIED + $IPT -X ONLYTRUSTED + $IPT -X NEEDRESTRICT + + echo "...flushing IPTables rules is now finish : OK" + ;; + + status) + + $IPT -L -n -v --line-numbers + $IPT -t nat -L -n -v --line-numbers + $IPT -t mangle -L -n -v --line-numbers + $IPT6 -L -n -v --line-numbers + $IPT6 -t mangle -L -n -v --line-numbers + ;; + + reset) + + echo "Reset all IPTables counters..." + + $IPT -Z + $IPT -t nat -Z + $IPT -t mangle -Z + [ "$IPV6" != "off" ] && $IPT6 -Z + [ "$IPV6" != "off" ] && $IPT6 -t mangle -Z + + echo "...reseting IPTables counters is now finish : OK" + ;; + + restart) + + $0 stop + $0 start + ;; + + *) + + echo "Usage: $0 {start|stop|restart|status|reset|squid}" + exit 1 +esac + +exit 0