minifirewall: upstream release 22.03.1 and use includes directory
Some checks reported errors
continuous-integration/drone/push Build was killed

This commit is contained in:
Jérémy Lecour 2022-03-15 23:07:33 +01:00 committed by Jérémy Lecour
parent 17f884b04a
commit ba90203f21
9 changed files with 971 additions and 584 deletions

View file

@ -17,6 +17,7 @@ The **patch** part changes is incremented if multiple releases happen the same m
* evolinux-base: backup-server-state release 22.03
* evolinux-base: Add non-free repos & install non-free firmware on dedicated hardware
* generate-ldif: Add services check for bkctld
* minifirewall: upstream release 22.03.1 and use includes directory
### Fixed

View file

@ -1,13 +1,19 @@
---
minifirewall_main_file: /etc/default/minifirewall
minifirewall_tail_file: /etc/default/minifirewall.tail
# Deprecated variable
# minifirewall_main_file: /etc/default/minifirewall
minifirewall_tail_file: zzz-tail
minifirewall_tail_included: False
minifirewall_tail_force: True
# Overwrite files completely
minifirewall_force_upgrade_script: False
minifirewall_force_upgrade_config: False
# Update specific values in configuration
minifirewall_update_config: True
minifirewall_git_url: "https://forge.evolix.org/minifirewall.git"
minifirewall_checkout_path: "/tmp/minifirewall"
minifirewall_int: "{{ ansible_default_ipv4.interface }}"
@ -31,7 +37,7 @@ minifirewall_private_ports_tcp: [5666]
minifirewall_private_ports_udp: []
# Keep a null value to leave the setting as is
# otherwise use an Array, eg. "minifirewall_ssh_ok: ['0.0.0.0/0']"
# otherwise use an Array, eg. "minifirewall_ssh_ok: ['0.0.0.0/0', '::/0']"
minifirewall_dns_servers: Null
minifirewall_http_sites: Null
minifirewall_https_sites: Null

845
minifirewall/files/minifirewall Executable file
View file

@ -0,0 +1,845 @@
#!/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-2022 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: minifirewall
# 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
VERSION="22.03.1"
NAME="minifirewall"
DESC="Firewall designed for standalone server"
set -u
# Variables configuration
#########################
config_file="/etc/default/minifirewall"
includes_dir="/etc/minifirewall.d"
# iptables paths
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'
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'
# 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
}
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
##################################
# 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}"
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
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
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
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
########################
${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
# 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
# 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
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
# 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
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 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 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
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 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 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 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 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 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
# 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
# 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
#################
# by default DROP INPUT packets
${IPT} -P INPUT DROP
if is_ipv6_enabled; then
${IPT6} -P INPUT DROP
fi
# 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
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
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() {
echo "Flush all rules and accept everything..."
# 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
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
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
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() {
echo "Reset all IPTables counters..."
${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"
}
echo "${NAME} version ${VERSION}"
source_configuration
case "${1:-''}" in
start)
start
;;
stop)
stop
;;
status)
status
;;
reset)
reset
;;
restart)
stop
start
;;
*)
echo "Usage: $0 {start|stop|restart|status|reset}"
exit 1
;;
esac
exit 0

View file

@ -1,31 +1,37 @@
# Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall
# Version 20.12 — 2020-12-01 22:55:35
# Version 22.03.1 — 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'
# 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
@ -45,62 +51,86 @@ SERVICESUDP2=''
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'
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 SSH from Trusted IPv6 addresses
/sbin/ip6tables -A INPUT -i $INT -p tcp --dport 22 -s 2a01:9500:37:129::/64 -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 outgoing SSH/HTTP/HTTPS/SMTP/DNS traffic
/sbin/ip6tables -A INPUT -i $INT -p tcp --sport 22 --match state --state ESTABLISHED,RELATED -j ACCEPT
/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
# Custom sysctl values (advanced)
#################################
# 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
# 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.
# IPv4 Specific rules
#####################
# Set 1 to ignore broadcast pings (default)
# SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS='1'
# /sbin/iptables ...
# 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'

View file

@ -9,11 +9,12 @@
- name: Stat minifirewall config file (before)
stat:
path: "{{ minifirewall_main_file }}"
path: "/etc/default/minifirewall"
register: minifirewall_before
- name: Check if minifirewall is running
shell: /sbin/iptables -L -n | grep -E "^(DROP\s+udp|ACCEPT\s+icmp)\s+--\s+0\.0\.0\.0\/0\s+0\.0\.0\.0\/0\s*$"
shell:
cmd: /sbin/iptables -L -n | grep -E "^(DROP\s+udp|ACCEPT\s+icmp)\s+--\s+0\.0\.0\.0\/0\s+0\.0\.0\.0\/0\s*$"
changed_when: False
failed_when: False
check_mode: no
@ -25,14 +26,14 @@
- name: Begin marker for IP addresses
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "# BEGIN ANSIBLE MANAGED BLOCK FOR IPS"
insertbefore: '^# Main interface'
create: no
- name: End marker for IP addresses
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
create: no
line: "# END ANSIBLE MANAGED BLOCK FOR IPS"
insertafter: '^PRIVILEGIEDIPS='
@ -43,12 +44,16 @@
msg: You must provide at least 1 trusted IP
- debug:
msg: "Warning: minifirewall_trusted_ips='0.0.0.0/0', the firewall is useless!"
when: minifirewall_trusted_ips == ["0.0.0.0/0"]
msg: "Warning: minifirewall_trusted_ips contains '0.0.0.0/0', the firewall is useless on IPv4!"
when: "'0.0.0.0/0' in minifirewall_trusted_ips"
- debug:
msg: "Warning: minifirewall_trusted_ips contains '::/0', the firewall is useless on IPv6!"
when: "'::/0' in minifirewall_trusted_ips"
- name: Configure IP addresses
blockinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR IPS"
block: |
# Main interface
@ -60,8 +65,12 @@
# 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
DOCKER='{{ minifirewall_docker }}'
# 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 IPv4 local network
# ...will be often IP/32 if you don't trust anything
@ -78,21 +87,21 @@
- name: Begin marker for ports
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "# BEGIN ANSIBLE MANAGED BLOCK FOR PORTS"
insertbefore: '^# Protected services'
create: no
- name: End marker for ports
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "# END ANSIBLE MANAGED BLOCK FOR PORTS"
insertafter: '^SERVICESUDP3='
create: no
- name: Configure ports
blockinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR PORTS"
block: |
# Protected services
@ -116,7 +125,7 @@
- name: Configure DNSSERVEURS
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "DNSSERVEURS='{{ minifirewall_dns_servers | join(' ') }}'"
regexp: "DNSSERVEURS='.*'"
create: no
@ -124,7 +133,7 @@
- name: Configure HTTPSITES
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "HTTPSITES='{{ minifirewall_http_sites | join(' ') }}'"
regexp: "HTTPSITES='.*'"
create: no
@ -132,7 +141,7 @@
- name: Configure HTTPSSITES
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "HTTPSSITES='{{ minifirewall_https_sites | join(' ') }}'"
regexp: "HTTPSSITES='.*'"
create: no
@ -140,7 +149,7 @@
- name: Configure FTPSITES
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "FTPSITES='{{ minifirewall_ftp_sites | join(' ') }}'"
regexp: "FTPSITES='.*'"
create: no
@ -148,7 +157,7 @@
- name: Configure SSHOK
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "SSHOK='{{ minifirewall_ssh_ok | join(' ') }}'"
regexp: "SSHOK='.*'"
create: no
@ -156,7 +165,7 @@
- name: Configure SMTPOK
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "SMTPOK='{{ minifirewall_smtp_ok | join(' ') }}'"
regexp: "SMTPOK='.*'"
create: no
@ -164,7 +173,7 @@
- name: Configure SMTPSECUREOK
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "SMTPSECUREOK='{{ minifirewall_smtp_secure_ok | join(' ') }}'"
regexp: "SMTPSECUREOK='.*'"
create: no
@ -172,29 +181,15 @@
- name: Configure NTPOK
lineinfile:
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
line: "NTPOK='{{ minifirewall_ntp_ok | join(' ') }}'"
regexp: "NTPOK='.*'"
create: no
when: minifirewall_ntp_ok is not none
- name: evomaintenance
lineinfile:
dest: "{{ minifirewall_main_file }}"
line: "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s {{ item }} -m state --state ESTABLISHED,RELATED -j ACCEPT"
insertafter: "^# EvoMaintenance"
loop: "{{ evomaintenance_hosts }}"
- name: remove minifirewall example rule for the evomaintenance
lineinfile:
dest: "{{ minifirewall_main_file }}"
regexp: '^#.*(--sport 5432).*(-s X\.X\.X\.X)'
state: absent
when: evomaintenance_hosts | length > 0
- name: Stat minifirewall config file (after)
stat:
path: "{{ minifirewall_main_file }}"
path: "/etc/default/minifirewall"
register: minifirewall_after
- name: restart minifirewall

View file

@ -6,18 +6,26 @@
state: present
- name: init script is copied
template:
src: minifirewall.j2
copy:
src: minifirewall
dest: /etc/init.d/minifirewall
force: "{{ minifirewall_force_upgrade_script | default('no') }}"
mode: "0700"
owner: root
group: root
- name: include directory is present
file:
path: /etc/minifirewall.d/
state: directory
owner: root
group: root
mode: "0700"
- name: configuration is copied
copy:
src: minifirewall.conf
dest: "{{ minifirewall_main_file }}"
dest: "/etc/default/minifirewall"
force: "{{ minifirewall_force_upgrade_config | default('no') }}"
mode: "0600"
owner: root

View file

@ -4,9 +4,15 @@
set_fact:
minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
- name: Fail if minifirewall_main_file is defined
fail:
msg: "Variable minifirewall_main_file is deprecated and not configurable anymore."
when: minifirewall_main_file is defined
- include: install.yml
- include: config.yml
when: minifirewall_update_config | bool
- include: nrpe.yml

View file

@ -2,7 +2,7 @@
- name: Add some rules at the end of minifirewall file
template:
src: "{{ item }}"
dest: "{{ minifirewall_tail_file }}"
dest: "/etc/minifirewall.d/{{ minifirewall_tail_file }}"
force: "{{ minifirewall_tail_force | bool }}"
loop: "{{ query('first_found', templates) }}"
vars:
@ -17,18 +17,6 @@
var: minifirewall_tail_template
verbosity: 1
- name: source minifirewall.tail at the end of the main file
blockinfile:
dest: "{{ minifirewall_main_file }}"
marker: "# {mark} ANSIBLE MANAGED EXTERNAL RULES"
block: ". {{ minifirewall_tail_file }}"
insertbefore: EOF
register: minifirewall_tail_source
- debug:
var: minifirewall_tail_source
verbosity: 1
- name: restart minifirewall
# service:
# name: minifirewall

View file

@ -1,492 +0,0 @@
#!/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="{{ minifirewall_main_file }}"
IPV6=$(grep "IPV6=" {{ minifirewall_main_file }} | awk -F '=' -F "'" '{print $2}')
DOCKER=$(grep "DOCKER=" {{ minifirewall_main_file }} | awk -F '=' -F "'" '{print $2}')
INT=$(grep "INT=" {{ minifirewall_main_file }} | 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