minifirewall/minifirewall

846 lines
26 KiB
Plaintext
Raw Normal View History

#!/bin/sh
2011-04-02 12:12:49 +02:00
# minifirewall is shellscripts for easy firewalling on a standalone server
# we used netfilter/iptables http://netfilter.org/ designed for recent Linux kernel
2020-02-17 10:54:01 +01:00
# See https://gitea.evolix.org/evolix/minifirewall
2022-03-15 16:37:20 +01:00
# 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
2022-03-15 16:37:20 +01:00
# 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
2022-03-15 18:57:30 +01:00
VERSION="22.03.1"
2021-09-06 14:02:03 +02:00
NAME="minifirewall"
2022-03-15 18:56:37 +01:00
DESC="Firewall designed for standalone server"
2021-05-22 22:44:47 +02:00
set -u
# Variables configuration
#########################
2021-09-14 12:37:04 +02:00
config_file="/etc/default/minifirewall"
includes_dir="/etc/minifirewall.d"
# iptables paths
2021-05-22 23:12:09 +02:00
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'
2020-02-21 16:26:41 +01:00
# Configuration
2021-05-22 22:44:47 +02:00
INT=''
IPV6=''
DOCKER=''
INTLAN=''
TRUSTEDIPS=''
PRIVILEGIEDIPS=''
SERVICESTCP1p=''
SERVICESUDP1p=''
SERVICESTCP1=''
SERVICESUDP1=''
SERVICESTCP2=''
SERVICESUDP2=''
SERVICESTCP3=''
SERVICESUDP3=''
DNSSERVEURS=''
HTTPSITES=''
HTTPSSITES=''
FTPSITES=''
SSHOK=''
SMTPOK=''
SMTPSECUREOK=''
NTPOK=''
2021-05-26 13:20:12 +02:00
PROXY=''
PROXYBYPASS=''
PROXYPORT=''
2021-05-26 13:12:15 +02:00
BACKUPSERVERS=''
2021-05-22 22:44:47 +02:00
2021-12-11 10:13:38 +01:00
LEGACY_CONFIG='off'
2021-05-22 22:46:02 +02:00
is_ipv6_enabled() {
test "${IPV6}" != "off"
}
is_docker_enabled() {
test "${DOCKER}" = "on"
}
2021-05-26 13:20:12 +02:00
is_proxy_enabled() {
test "${PROXY}" = "on"
}
2021-09-06 14:33:22 +02:00
is_ipv6() {
2021-09-14 08:54:52 +02:00
echo "$1" | grep -q ':'
2021-09-06 14:33:22 +02:00
}
2021-12-11 10:13:38 +01:00
is_legacy_config() {
test "${LEGACY_CONFIG}" != "off"
}
2021-05-22 09:46:22 +02:00
chain_exists() {
2021-05-22 23:14:40 +02:00
chain_name="$1"
if [ $# -ge 2 ]; then
intable="--table $2"
fi
# shellcheck disable=SC2086
iptables ${intable} -nL "${chain_name}" >/dev/null 2>&1
2021-05-22 09:23:14 +02:00
}
source_file_or_error() {
file=$1
echo "...sourcing '${file}\`"
2021-05-22 09:23:31 +02:00
tmpfile=$(mktemp --tmpdir=/tmp minifirewall.XXX)
. "${file}" 2>"${tmpfile}" >&2
2021-12-11 10:13:38 +01:00
if [ -s "${tmpfile}" ]; then
echo "${file} returns standard or error output (see below). Stopping." >&2
cat "${tmpfile}"
exit 1
fi
rm "${tmpfile}"
}
2021-05-22 23:14:27 +02:00
source_configuration() {
if ! test -f ${config_file}; then
echo "${config_file} does not exist" >&2
2021-12-11 10:13:38 +01:00
2021-12-12 19:29:05 +01:00
## We still want to deal with this really old configuration file
## even if it has been deprecated since Debian 8
2021-12-11 10:13:38 +01:00
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
2021-05-22 23:14:27 +02:00
exit 1
fi
2021-12-11 10:13:38 +01:00
if grep -e "iptables" -e "ip6tables" "${config_file}" | grep -qvE "^#"; then
2021-12-12 19:29:05 +01:00
# Backward compatible mode
###########################
2021-12-11 10:13:38 +01:00
echo "Legacy config detected"
LEGACY_CONFIG='on'
2021-12-12 19:29:05 +01:00
# 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
2021-12-11 10:13:38 +01:00
# echo "iptables/ip6tables commands found in ${config_file}." >&2
# echo "Move them in included files (in ${includes_dir})." >&2
# exit 1
2021-09-14 12:37:04 +02:00
fi
2021-05-22 23:14:27 +02:00
2021-12-11 10:13:38 +01:00
if is_legacy_config; then
2021-12-12 19:29:05 +01:00
# 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.
2021-12-11 10:13:38 +01:00
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
2021-09-14 12:37:04 +02:00
}
source_includes() {
2021-05-22 23:14:27 +02:00
if [ -d "${includes_dir}" ]; then
2021-09-14 12:37:04 +02:00
include_files=$(find ${includes_dir} -type f -readable -not -name '*.*' | sort -h)
2021-05-22 23:14:27 +02:00
for include_file in ${include_files}; do
source_file_or_error "${include_file}"
done
fi
}
2021-05-22 09:23:14 +02:00
start() {
2021-09-06 14:02:03 +02:00
echo "Start IPTables rules..."
2021-05-22 09:23:14 +02:00
# 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)
2022-03-15 18:55:48 +01:00
: "${SYSCTL_ICMP_ECHO_IGNORE_BROADCASTS:=1}"
# Set 1 to ignore bogus ICMP responses (default)
2022-03-15 18:55:48 +01:00
: "${SYSCTL_ICMP_IGNORE_BOGUS_ERROR_RESPONSES:=1}"
# Set 0 to disable source routing (default)
2022-03-15 18:55:48 +01:00
: "${SYSCTL_ACCEPT_SOURCE_ROUTE:=0}"
# Set 1 to enable TCP SYN cookies (default)
# cf http://cr.yp.to/syncookies.html
2022-03-15 18:55:48 +01:00
: "${SYSCTL_TCP_SYNCOOKIES:=1}"
# Set 0 to disable ICMP redirects (default)
2022-03-15 18:55:48 +01:00
: "${SYSCTL_ICMP_REDIRECTS:=0}"
# Set 1 to enable Reverse Path filtering (default)
# Set 0 if VRRP is used
2022-03-15 18:55:48 +01:00
: "${SYSCTL_RP_FILTER:=1}"
# Set 1 to log packets with inconsistent address (default)
2022-03-15 18:55:48 +01:00
: "${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
2021-05-22 09:23:14 +02:00
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
2021-05-22 09:23:14 +02:00
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
2021-05-22 09:23:14 +02:00
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
2021-05-22 09:23:14 +02:00
# 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
2021-05-22 09:23:14 +02:00
# Trusted ip addresses
${IPT} -N ONLYTRUSTED
${IPT} -A ONLYTRUSTED -j LOG_DROP
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -N ONLYTRUSTED
${IPT6} -A ONLYTRUSTED -j LOG_DROP
fi
2021-05-22 09:41:29 +02:00
for ip in ${TRUSTEDIPS}; do
if is_ipv6 ${ip}; then
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -I ONLYTRUSTED -s ${ip} -j ACCEPT
fi
else
${IPT} -I ONLYTRUSTED -s ${ip} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# Privilegied ip addresses
# (trusted ip addresses *are* privilegied)
${IPT} -N ONLYPRIVILEGIED
${IPT} -A ONLYPRIVILEGIED -j ONLYTRUSTED
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -N ONLYPRIVILEGIED
${IPT6} -A ONLYPRIVILEGIED -j ONLYTRUSTED
fi
2021-05-22 09:41:29 +02:00
for ip in ${PRIVILEGIEDIPS}; do
if is_ipv6 ${ip}; then
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT
fi
else
${IPT} -I ONLYPRIVILEGIED -s ${ip} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# Chain for restrictions (blacklist IPs/ranges)
${IPT} -N NEEDRESTRICT
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -N NEEDRESTRICT
fi
2021-05-22 09:23:14 +02:00
# We allow all on loopback interface
${IPT} -A INPUT -i lo -j ACCEPT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -i lo -j ACCEPT
fi
2021-05-22 09:23:14 +02:00
# if OUTPUTDROP
${IPT} -A OUTPUT -o lo -j ACCEPT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -A OUTPUT -o lo -j ACCEPT
fi
2021-05-22 09:23:14 +02:00
# 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
2021-09-14 11:05:59 +02:00
for IP in ${LOOPBACK}; do
if is_ipv6 ${IP}; then
2021-09-14 11:05:59 +02:00
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
2021-05-22 22:46:02 +02:00
if is_docker_enabled; then
2021-09-14 11:05:59 +02:00
# 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
2021-05-22 09:23:14 +02:00
# Flush DOCKER-USER if exist, create it if absent
if chain_exists 'DOCKER-USER'; then
${IPT} -F DOCKER-USER
2021-05-22 09:23:14 +02:00
else
${IPT} -N DOCKER-USER
2021-05-22 09:23:14 +02:00
fi;
2021-05-22 09:23:14 +02:00
# 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
2021-05-22 09:23:14 +02:00
fi
2021-05-22 09:23:14 +02:00
# Local services restrictions
#############################
# Allow services for ${INTLAN} (local server or local network)
2021-09-14 11:05:59 +02:00
for IP in ${INTLAN}; do
if is_ipv6 ${IP}; then
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -s ${IP} -j ACCEPT
fi
else
${IPT} -A INPUT -s ${IP} -j ACCEPT
fi
done
2021-05-22 09:23:14 +02:00
# Enable protection chain for sensible services
2021-05-22 09:41:29 +02:00
for port in ${SERVICESTCP1p}; do
${IPT} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p tcp --dport ${port} -j NEEDRESTRICT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:41:29 +02:00
for port in ${SERVICESUDP1p}; do
${IPT} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p udp --dport ${port} -j NEEDRESTRICT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# Public service
2021-05-22 09:41:29 +02:00
for port in ${SERVICESTCP1}; do
${IPT} -A INPUT -p tcp --dport ${port} -j ACCEPT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p tcp --dport ${port} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:41:29 +02:00
for port in ${SERVICESUDP1}; do
${IPT} -A INPUT -p udp --dport ${port} -j ACCEPT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p udp --dport ${port} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# Privilegied services
2021-05-22 09:41:29 +02:00
for port in ${SERVICESTCP2}; do
${IPT} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p tcp --dport ${port} -j ONLYPRIVILEGIED
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:41:29 +02:00
for port in ${SERVICESUDP2}; do
${IPT} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p udp --dport ${port} -j ONLYPRIVILEGIED
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# Private services
2021-05-22 09:41:29 +02:00
for port in ${SERVICESTCP3}; do
${IPT} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p tcp --dport ${port} -j ONLYTRUSTED
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:41:29 +02:00
for port in ${SERVICESUDP3}; do
${IPT} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p udp --dport ${port} -j ONLYTRUSTED
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 22:46:02 +02:00
if is_docker_enabled; then
2021-09-14 11:05:59 +02:00
# WARN: IPv6 not yet supported
2021-05-22 09:23:14 +02:00
# Public services defined in SERVICESTCP1 & SERVICESUDP1
2021-05-22 09:41:29 +02:00
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
2021-05-22 09:23:14 +02:00
done
2021-05-22 09:41:29 +02:00
for srcip in ${TRUSTEDIPS}; do
${IPT} -I MINIFW-DOCKER-PRIVILEGED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN
2021-05-22 09:23:14 +02:00
done
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
2021-05-22 09:41:29 +02:00
for dstport in ${SERVICESUDP2}; do
for srcip in ${PRIVILEGIEDIPS}; do
${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN
2021-05-22 09:23:14 +02:00
done
2021-05-22 09:41:29 +02:00
for srcip in ${TRUSTEDIPS}; do
${IPT} -I MINIFW-DOCKER-PRIVILEGED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN
2021-05-22 09:23:14 +02:00
done
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# Trusted services (accessible from trusted IPs)
2021-05-22 09:41:29 +02:00
for dstport in ${SERVICESTCP3}; do
for srcip in ${TRUSTEDIPS}; do
${IPT} -I MINIFW-DOCKER-TRUSTED -p tcp -s "${srcip}" --dport "${dstport}" -j RETURN
2021-05-22 09:23:14 +02:00
done
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
2021-05-22 09:41:29 +02:00
for dstport in ${SERVICESUDP3}; do
for srcip in ${TRUSTEDIPS}; do
${IPT} -I MINIFW-DOCKER-TRUSTED -p udp -s "${srcip}" --dport "${dstport}" -j RETURN
2021-05-22 09:23:14 +02:00
done
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
fi
# External services
###################
2021-05-22 09:23:14 +02:00
# DNS authorizations
2021-09-14 12:47:17 +02:00
for IP in ${DNSSERVEURS}; do
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
2021-09-14 12:47:17 +02:00
${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
2021-09-14 12:47:17 +02:00
${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
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# HTTP (TCP/80) authorizations
2021-09-14 12:47:17 +02:00
for IP in ${HTTPSITES}; do
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
2021-09-14 12:47:17 +02:00
${IPT6} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
else
2021-09-14 12:47:17 +02:00
${IPT} -A INPUT -p tcp ! --syn --sport 80 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# HTTPS (TCP/443) authorizations
2021-09-14 12:47:17 +02:00
for IP in ${HTTPSSITES}; do
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
2021-09-14 12:47:17 +02:00
${IPT6} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
else
2021-09-14 12:47:17 +02:00
${IPT} -A INPUT -p tcp ! --syn --sport 443 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# FTP (so complex protocol...) authorizations
2021-09-14 12:47:17 +02:00
for IP in ${FTPSITES}; do
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
# requests on Control connection
2021-09-14 12:47:17 +02:00
${IPT6} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
# FTP port-mode on Data Connection
2021-09-14 12:47:17 +02:00
${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
2021-09-14 12:47:17 +02:00
${IPT6} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
else
# requests on Control connection
2021-09-14 12:47:17 +02:00
${IPT} -A INPUT -p tcp ! --syn --sport 21 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
# FTP port-mode on Data Connection
2021-09-14 12:47:17 +02:00
${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
2021-09-14 12:47:17 +02:00
${IPT} -A INPUT -p tcp ! --syn --sport ${PORTSUSER} --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# SSH authorizations
2021-09-14 12:47:17 +02:00
for IP in ${SSHOK}; do
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
2021-09-14 12:47:17 +02:00
${IPT6} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
else
2021-09-14 12:47:17 +02:00
${IPT} -A INPUT -p tcp ! --syn --sport 22 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# SMTP authorizations
2021-09-14 12:47:17 +02:00
for IP in ${SMTPOK}; do
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
2021-09-14 12:47:17 +02:00
${IPT6} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
else
2021-09-14 12:47:17 +02:00
${IPT} -A INPUT -p tcp ! --syn --sport 25 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
fi
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# secure SMTP (TCP/465 et TCP/587) authorizations
2021-09-14 12:47:17 +02:00
for IP in ${SMTPSECUREOK}; do
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
2021-09-14 12:47:17 +02:00
${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
2021-09-14 12:47:17 +02:00
${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
2021-05-22 09:41:29 +02:00
done
2021-05-22 09:23:14 +02:00
# NTP authorizations
2021-09-14 12:47:17 +02:00
for IP in ${NTPOK}; do
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
2021-09-14 12:47:17 +02:00
${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
2021-09-14 12:47:17 +02:00
${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
2021-05-22 09:41:29 +02:00
done
2021-05-26 13:20:12 +02:00
# Proxy (Squid)
if is_proxy_enabled; then
2021-09-14 11:05:59 +02:00
# WARN: Squid only listen on IPv4 yet
# TODO: verify that the pattern used for IPv4 is relevant with IPv6
2021-05-26 13:20:12 +02:00
${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
2021-05-26 13:20:12 +02:00
done
${IPT} -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port "${PROXYPORT:-'8888'}"
fi
2021-05-26 13:12:15 +02:00
# Output for backup servers
for server in ${BACKUPSERVERS}; do
server_port=$(echo "${server}" | awk -F : '{print $(NF)}')
2021-09-14 11:05:59 +02:00
server_ip=$(echo "${server}" | sed -e "s/:${server_port}$//")
2021-05-26 13:12:15 +02:00
if [ -n "${server_ip}" ] && [ -n "${server_port}" ]; then
2021-09-14 11:05:59 +02:00
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
2021-05-26 13:12:15 +02:00
else
echo "Unrecognized syntax for BACKUPSERVERS '${server}\`. Use space-separated IP:PORT tuples." >&2
exit 1
fi
done
2021-05-22 09:23:14 +02:00
# Always allow ICMP
${IPT} -A INPUT -p icmp -j ACCEPT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -A INPUT -p icmpv6 -j ACCEPT
fi
2021-05-22 09:23:14 +02:00
# IPTables policy
#################
2021-05-22 09:23:14 +02:00
# by default DROP INPUT packets
${IPT} -P INPUT DROP
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -P INPUT DROP
fi
2021-05-22 22:46:02 +02:00
# by default, no FORWARDING (deprecated for Virtual Machines)
2021-05-22 09:23:14 +02:00
#echo 0 > /proc/sys/net/ipv4/ip_forward
#${IPT} -P FORWARD DROP
#${IPT6} -P FORWARD DROP
2021-05-22 09:23:14 +02:00
# by default allow OUTPUT packets... but drop UDP packets (see OUTPUTDROP to drop OUTPUT packets)
${IPT} -P OUTPUT ACCEPT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -P OUTPUT ACCEPT
fi
2021-12-11 10:13:38 +01:00
${IPT} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT
fi
2021-12-11 10:13:38 +01:00
${IPT} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT
2021-05-22 22:46:02 +02:00
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
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -A OUTPUT -p udp -j DROP
fi
2021-05-22 09:23:14 +02:00
2021-12-11 10:13:38 +01:00
if is_legacy_config; then
source_file_or_error "${config_file}"
fi
2021-09-14 12:37:04 +02:00
# Source files present in optional directory
source_includes
2021-05-22 09:23:14 +02:00
trap - INT TERM EXIT
echo "...starting IPTables rules is now finish : OK"
}
stop() {
2015-09-13 20:31:04 +02:00
echo "Flush all rules and accept everything..."
# Delete all rules
${IPT} -F INPUT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -F INPUT
fi
2021-09-14 11:05:59 +02:00
${IPT} -F OUTPUT
2021-05-22 22:46:02 +02:00
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
2021-09-14 11:05:59 +02:00
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
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -t mangle -F
fi
2021-05-22 22:46:02 +02:00
if is_docker_enabled; then
2021-09-14 11:05:59 +02:00
# 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
2021-05-22 22:46:02 +02:00
else
${IPT} -t nat -F
fi
# Accept all
${IPT} -P INPUT ACCEPT
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -P INPUT ACCEPT
fi
${IPT} -P OUTPUT ACCEPT
2021-05-22 22:46:02 +02:00
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
2021-09-14 11:05:59 +02:00
if is_ipv6_enabled; then
${IPT6} -X LOG_DROP
${IPT6} -X LOG_ACCEPT
${IPT6} -X ONLYPRIVILEGIED
${IPT6} -X ONLYTRUSTED
${IPT6} -X NEEDRESTRICT
fi
2015-09-13 20:31:04 +02:00
echo "...flushing IPTables rules is now finish : OK"
2021-05-22 09:23:14 +02:00
}
2021-05-22 09:23:14 +02:00
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
2021-05-22 09:23:14 +02:00
}
2021-05-22 09:23:14 +02:00
reset() {
echo "Reset all IPTables counters..."
${IPT} -Z
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -Z
fi
${IPT} -t nat -Z
2021-05-22 22:46:02 +02:00
${IPT} -t mangle -Z
2021-05-22 22:46:02 +02:00
if is_ipv6_enabled; then
${IPT6} -t mangle -Z
fi
2015-09-13 20:31:04 +02:00
echo "...reseting IPTables counters is now finish : OK"
2021-05-22 09:23:14 +02:00
}
2021-09-14 12:37:04 +02:00
echo "${NAME} version ${VERSION}"
source_configuration
case "${1:-''}" in
2021-05-22 09:23:14 +02:00
start)
start
;;
stop)
stop
;;
status)
status
;;
reset)
reset
;;
restart)
stop
start
;;
2021-09-06 14:02:03 +02:00
*)
2021-09-14 12:37:04 +02:00
echo "Usage: $0 {start|stop|restart|status|reset}"
2021-09-06 14:02:03 +02:00
exit 1
2021-09-14 12:37:04 +02:00
;;
esac
exit 0