diff --git a/README.md b/README.md index 678ac5a..714f463 100644 --- a/README.md +++ b/README.md @@ -8,30 +8,30 @@ 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* from _off_ to _on_ +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 @@ -41,11 +41,7 @@ you need to use the port used by the container (ie: 8080) in the public/semi-pub /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 b/minifirewall index c1a7251..a821d61 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 @@ -28,16 +28,30 @@ # Description: Firewall designed for standalone server ### END INIT INFO +VERSION="21.12" + DESC="minifirewall" NAME="minifirewall" +set -u # Variables configuration ######################### +config_file="/etc/default/minifirewall" +includes_dir="/etc/minifirewall.d" + # 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' @@ -51,442 +65,781 @@ 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 + +INT='' +IPV6='' +DOCKER='' +INTLAN='' +TRUSTEDIPS='' +PRIVILEGIEDIPS='' +SERVICESTCP1p='' +SERVICESUDP1p='' +SERVICESTCP1='' +SERVICESUDP1='' +SERVICESTCP2='' +SERVICESUDP2='' +SERVICESTCP3='' +SERVICESUDP3='' +DNSSERVEURS='' +HTTPSITES='' +HTTPSSITES='' +FTPSITES='' +SSHOK='' +SMTPOK='' +SMTPSECUREOK='' +NTPOK='' +PROXY='' +PROXYBYPASS='' +PROXYPORT='' +BACKUPSERVERS='' + +LEGACY_CONFIG='off' + +is_ipv6_enabled() { + test "${IPV6}" != "off" +} +is_docker_enabled() { + test "${DOCKER}" = "on" +} +is_proxy_enabled() { + test "${PROXY}" = "on" +} +is_ipv6() { + echo "$1" | grep -q ':' +} +is_legacy_config() { + test "${LEGACY_CONFIG}" != "off" +} +chain_exists() { + 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}\`" + + 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_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 + fi + + exit 1 + fi + + 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 + ############################### + + # 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}" + + 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 + 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 + fi } -# Configuration -oldconfigfile="/etc/firewall.rc" -configfile="/etc/default/minifirewall" +start() { + echo "Start IPTables rules..." -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}') + # Stop and warn if error! + set -e + trap 'echo "ERROR in minifirewall configuration (fix it now!) or script manipulation (fix yourself)." ' INT TERM EXIT -case "$1" in - start) + # sysctl network security settings + ################################## - echo "Start IPTables rules..." + # 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 + : "${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'}" -# 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 + 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 - $IPT -N DOCKER-USER - fi; + echo "Invalid SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS value '${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS}', must be '0' or '1'." >&2 + exit 1 + 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 + 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 -fi + 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 + 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 -# Local services restrictions -############################# + 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 -# Allow services for $INTLAN (local server or local network) -$IPT -A INPUT -s $INTLAN -j ACCEPT + 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 -# Enable protection chain for sensible services -for x in $SERVICESTCP1p - do - $IPT -A INPUT -p tcp --dport $x -j NEEDRESTRICT + 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 + ######################## + + ${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 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 + + # 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 + if is_ipv6 ${ip}; then + if is_ipv6_enabled; then + ${IPT6} -I ONLYTRUSTED -s ${ip} -j ACCEPT + fi + else + ${IPT} -I ONLYTRUSTED -s ${ip} -j ACCEPT + fi done -for x in $SERVICESUDP1p - do - $IPT -A INPUT -p udp --dport $x -j NEEDRESTRICT + # 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 + if is_ipv6 ${ip}; then + if is_ipv6_enabled; then + ${IPT6} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT + fi + else + ${IPT} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT + fi 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 + # 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 + if is_ipv6_enabled; then + ${IPT6} -A INPUT -i lo -j ACCEPT + fi + # if OUTPUTDROP + ${IPT} -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 + # ${IPT} -t NAT -I PREROUTING -s ${LOOPBACK} -i ! lo -j DROP + for IP in ${LOOPBACK}; do + if is_ipv6 ${IP}; 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 -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 + 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 + + ${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) + for IP in ${INTLAN}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${IPT6} -A INPUT -s ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -s ${IP} -j ACCEPT + fi done -# Privilegied services -for x in $SERVICESTCP2 - do - $IPT -A INPUT -p tcp --dport $x -j ONLYPRIVILEGIED + # 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 x in $SERVICESUDP2 - do - $IPT -A INPUT -p udp --dport $x -j ONLYPRIVILEGIED + 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 -# Private services -for x in $SERVICESTCP3 - do - $IPT -A INPUT -p tcp --dport $x -j ONLYTRUSTED + # Public service + for port in ${SERVICESTCP1}; do + ${IPT} -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 x in $SERVICESUDP3 - do - $IPT -A INPUT -p udp --dport $x -j ONLYTRUSTED + for port in ${SERVICESUDP1}; do + ${IPT} -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 + 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 [ "$DOCKER" = "on" ]; then + 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 + # 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 + 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 + # 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 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 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 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 + # 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 + 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 + fi -# External services -################### + # 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 + # DNS authorizations + 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 ${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 ${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 x in $HTTPSITES - do - $IPT -A INPUT -p tcp ! --syn --sport 80 --dport $PORTSUSER -s $x -j ACCEPT + # HTTP (TCP/80) authorizations + 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 ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi done -# HTTPS (TCP/443) authorizations -for x in $HTTPSSITES - do - $IPT -A INPUT -p tcp ! --syn --sport 443 --dport $PORTSUSER -s $x -j ACCEPT + # HTTPS (TCP/443) authorizations + 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 ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi 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 + # FTP (so complex protocol...) authorizations + 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 ${IP} -j ACCEPT + # FTP port-mode on Data Connection + ${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 ${IP} -j ACCEPT + fi + else + # requests on Control connection + ${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 ${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 ${IP} -j ACCEPT + fi done -# SSH authorizations -for x in $SSHOK - do - $IPT -A INPUT -p tcp ! --syn --sport 22 -s $x -j ACCEPT + # SSH authorizations + 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 ${IP} -j ACCEPT + fi + else + ${IPT} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + done + + # SMTP authorizations + 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 ${IP} -j ACCEPT + fi + else + ${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 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 ${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 ${IP} -j ACCEPT + ${IPT} -A INPUT -p tcp ! --syn --sport 587 --dport ${PORTSUSER} -s ${IP} -j ACCEPT + fi + done + + # NTP authorizations + for IP in ${NTPOK}; do + if is_ipv6 ${IP}; then + if is_ipv6_enabled; then + ${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 ${IP} -j ACCEPT + ${IPT} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 123 --match state --state NEW -j ACCEPT + fi + done + + # 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 + 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 -# SMTP authorizations -for x in $SMTPOK - do - $IPT -A INPUT -p tcp ! --syn --sport 25 --dport $PORTSUSER -s $x -j ACCEPT + # Output for backup servers + for server in ${BACKUPSERVERS}; do + 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 + ${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 + fi 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 + # Always allow ICMP + ${IPT} -A INPUT -p icmp -j ACCEPT + if is_ipv6_enabled; then + ${IPT6} -A INPUT -p icmpv6 -j ACCEPT + fi -# IPTables policy -################# + # IPTables policy + ################# -# by default DROP INPUT packets -$IPT -P INPUT DROP -[ "$IPV6" != "off" ] && $IPT6 -P INPUT DROP + # by default DROP INPUT packets + ${IPT} -P INPUT DROP + if is_ipv6_enabled; then + ${IPT6} -P INPUT DROP + fi -# 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, 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 -$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 + # by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets) + ${IPT} -P OUTPUT ACCEPT + if is_ipv6_enabled; then + ${IPT6} -P OUTPUT ACCEPT + fi -trap - INT TERM EXIT + ${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 + if is_ipv6_enabled; then + ${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 + + trap - INT TERM EXIT echo "...starting IPTables rules is now finish : OK" - ;; - - stop) +} +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 + if is_ipv6_enabled; then + ${IPT6} -F INPUT + fi - if [ "$DOCKER" = "on" ]; then - $IPT -F DOCKER-USER - $IPT -A DOCKER-USER -j RETURN + ${IPT} -F OUTPUT + if is_ipv6_enabled; then + ${IPT6} -F OUTPUT + fi - $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 LOG_DROP + ${IPT} -F LOG_ACCEPT + ${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 + + ${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 + else + ${IPT} -t nat -F 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 + if is_ipv6_enabled; then + ${IPT6} -P INPUT ACCEPT + fi + + ${IPT} -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 # 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 + 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" - ;; +} - 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) +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 + ${IPT} -Z + if is_ipv6_enabled; then + ${IPT6} -Z + fi + + ${IPT} -t nat -Z + + ${IPT} -t mangle -Z + if is_ipv6_enabled; then + ${IPT6} -t mangle -Z + fi echo "...reseting IPTables counters is now finish : OK" - ;; +} - restart) +echo "${NAME} version ${VERSION}" +source_configuration - $0 stop - $0 start - ;; +case "${1:-''}" in + start) + start + ;; - *) + stop) + stop + ;; - echo "Usage: $0 {start|stop|restart|status|reset|squid}" - exit 1 + status) + status + ;; + + reset) + reset + ;; + + restart) + stop + start + ;; + + *) + echo "Usage: $0 {start|stop|restart|status|reset}" + exit 1 + ;; esac exit 0 diff --git a/minifirewall.conf b/minifirewall.conf index 7dc39c1..e16c8fb 100644 --- a/minifirewall.conf +++ b/minifirewall.conf @@ -1,34 +1,40 @@ # Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall -# Version 20.12 — 2020-12-01 22:55:35 +# Version 22.3 — 2022-03-15 +# shellcheck shell=sh disable=SC2034 # Main interface INT='eth0' # IPv6 -IPV6=on +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' # WARNING : If the port mapping is different between host and container # (ie: Listen on :8090 on host but :8080 in container) # Then you need to makes the rules with the port used inside the container -# 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 @@ -49,57 +55,85 @@ 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='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 ::/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' +# (proxy port) +PROXYPORT='8888' +# (destinations that bypass the proxy) +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') +BACKUPSERVERS='' -# 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 +# Files in /etc/minifirewall.d/* (without "." in name) +# 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 -# 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 +# Custom sysctl values (advanced) +################################# -# IPv4 Specific rules -##################### +# 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. -# /sbin/iptables ... +# 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 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