mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-23 09:22:59 +02:00
181 lines
5.4 KiB
Bash
181 lines
5.4 KiB
Bash
#!/bin/sh
|
|
###############################################################################
|
|
# #
|
|
# IPFire.org - A linux based firewall #
|
|
# Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> #
|
|
# #
|
|
# 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, or #
|
|
# (at your option) any later version. #
|
|
# #
|
|
# This program is distributed in the hope that it will be useful, #
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
# GNU General Public License for more details. #
|
|
# #
|
|
# You should have received a copy of the GNU General Public License #
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
# #
|
|
###############################################################################
|
|
|
|
. /etc/sysconfig/rc
|
|
. ${rc_functions}
|
|
|
|
PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin; export PATH
|
|
|
|
eval $(/usr/local/bin/readhash /var/ipfire/suricata/settings)
|
|
eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
|
|
|
|
IPS_REPEAT_MARK="0x80000000"
|
|
IPS_REPEAT_MASK="0x80000000"
|
|
IPS_BYPASS_MARK="0x40000000"
|
|
IPS_BYPASS_MASK="0x40000000"
|
|
|
|
# Optional options for the Netfilter queue.
|
|
NFQ_OPTS=(
|
|
"--queue-bypass"
|
|
)
|
|
|
|
# PID file of suricata.
|
|
PID_FILE="/var/run/suricata.pid"
|
|
|
|
# Function to flush the firewall chains.
|
|
flush_fw_chain() {
|
|
iptables -w -t mangle -F IPS
|
|
}
|
|
|
|
# Function to create the firewall rules to pass the traffic to suricata.
|
|
generate_fw_rules() {
|
|
# Assign NFQ_OPTS
|
|
local NFQ_OPTIONS=( "${NFQ_OPTS[@]}" )
|
|
|
|
local cpu_count="$(getconf _NPROCESSORS_ONLN)"
|
|
|
|
# Check if there are multiple cpu cores available.
|
|
if [ "$cpu_count" -gt "1" ]; then
|
|
# Balance beetween all queues
|
|
NFQ_OPTIONS+=(
|
|
"--queue-balance" "0:$(($cpu_count-1))"
|
|
"--queue-cpu-fanout"
|
|
)
|
|
else
|
|
# Send all packets to queue 0
|
|
NFQ_OPTIONS+=(
|
|
"--queue-num" "0"
|
|
)
|
|
fi
|
|
|
|
# Flush the firewall chains.
|
|
flush_fw_chain
|
|
|
|
# Don't process packets where the IPS has requested to bypass the stream
|
|
iptables -w -t mangle -A IPS -m mark --mark "$(( IPS_BYPASS_MARK ))/$(( IPS_BYPASS_MASK ))" -j RETURN
|
|
|
|
# Don't process packets that have already been seen by the IPS
|
|
iptables -w -t mangle -A IPS -m mark --mark "$(( IPS_REPEAT_MARK ))/$(( IPS_REPEAT_MASK ))" -j RETURN
|
|
|
|
# Never send any whitelisted packets to the IPS
|
|
if [ -r "/var/ipfire/suricata/ignored" ]; then
|
|
local id network remark enabled rest
|
|
|
|
while IFS=',' read -r id network remark enabled rest; do
|
|
echo "$network"
|
|
echo "$remark"
|
|
# Skip disabled entries
|
|
[ "${enabled}" = "enabled" ] || continue
|
|
|
|
iptables -w -t mangle -A IPS -s "${network}" -j RETURN
|
|
iptables -w -t mangle -A IPS -d "${network}" -j RETURN
|
|
done < "/var/ipfire/suricata/ignored"
|
|
fi
|
|
|
|
# Send packets to suricata
|
|
iptables -w -t mangle -A IPS -j NFQUEUE "${NFQ_OPTIONS[@]}"
|
|
|
|
# If suricata decided to bypass a stream, we will store the mark in the connection tracking table
|
|
iptables -w -t mangle -A IPS \
|
|
-m mark --mark "$(( IPS_BYPASS_MARK ))/$(( IPS_BYPASS_MASK ))" \
|
|
-j CONNMARK --save-mark --mask "$(( IPS_BYPASS_MASK ))"
|
|
|
|
return 0
|
|
}
|
|
|
|
case "$1" in
|
|
start)
|
|
# Get amount of CPU cores
|
|
cpu_count="$(getconf _NPROCESSORS_ONLN)"
|
|
|
|
# Numer of NFQUES.
|
|
NFQUEUES="-q 0"
|
|
|
|
if [ $cpu_count -gt "1" ]; then
|
|
NFQUEUES+=":$(($cpu_count-1))"
|
|
fi
|
|
|
|
# Check if the IDS should be started.
|
|
if [ "$ENABLE_IDS" == "on" ]; then
|
|
# Start the IDS.
|
|
boot_mesg "Starting Intrusion Detection System..."
|
|
/usr/bin/suricata -c /etc/suricata/suricata.yaml -D $NFQUEUES >/dev/null 2>/dev/null
|
|
evaluate_retval
|
|
|
|
# Allow reading the pidfile.
|
|
chmod 644 $PID_FILE
|
|
|
|
# Flush the firewall chain
|
|
flush_fw_chain
|
|
|
|
# Generate firewall rules
|
|
generate_fw_rules
|
|
fi
|
|
;;
|
|
|
|
stop)
|
|
boot_mesg "Stopping Intrusion Detection System..."
|
|
killproc -p $PID_FILE /var/run
|
|
|
|
# Flush firewall chain.
|
|
flush_fw_chain
|
|
|
|
# Sometimes suricata not correct shutdown. So killall.
|
|
killall -KILL /usr/bin/suricata 2>/dev/null
|
|
|
|
# Remove suricata control socket.
|
|
rm /var/run/suricata/* >/dev/null 2>/dev/null
|
|
|
|
# Trash remain pid file if still exists.
|
|
rm -f $PID_FILE >/dev/null 2>/dev/null
|
|
|
|
# Don't report returncode of rm if suricata was not started
|
|
exit 0
|
|
;;
|
|
|
|
status)
|
|
statusproc /usr/bin/suricata
|
|
;;
|
|
|
|
restart)
|
|
$0 stop
|
|
$0 start
|
|
;;
|
|
reload)
|
|
# Send SIGUSR2 to the suricata process to perform a reload
|
|
# of the ruleset.
|
|
kill -USR2 $(pidof suricata)
|
|
|
|
# Flush the firewall chain.
|
|
flush_fw_chain
|
|
|
|
# Generate firewall rules.
|
|
generate_fw_rules
|
|
;;
|
|
|
|
*)
|
|
echo "Usage: $0 {start|stop|restart|reload|status}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
chmod 644 /var/log/suricata/* 2>/dev/null
|