minifirewall/minifirewall

846 lines
26 KiB
Bash
Executable File

#!/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