[10/20] suricata: Restore the interface selection

Message ID 20240910143748.3469271-11-michael.tremer@ipfire.org
State New
Headers
Series [01/20] suricata: Move the IPS into the mangle table |

Commit Message

Michael Tremer Sept. 10, 2024, 2:37 p.m. UTC
  Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
---
 src/initscripts/networking/functions.network | 48 ++++++++++++++++++++
 src/initscripts/system/suricata              | 32 +++++++++++++
 2 files changed, 80 insertions(+)
  

Patch

diff --git a/src/initscripts/networking/functions.network b/src/initscripts/networking/functions.network
index e134d0cce..c189c2fbc 100644
--- a/src/initscripts/networking/functions.network
+++ b/src/initscripts/networking/functions.network
@@ -54,6 +54,54 @@  bin2ip() {
 	echo "${address[*]}"
 }
 
+network_get_intf() {
+	local zone="${1}"
+
+	case "${zone}" in
+		RED)
+			# For PPPoE, the RED interface is called ppp0 (unless we use QMI)
+			if [ "${RED_TYPE}" = "PPPOE" ] && [ "${RED_DRIVER}" != "qmi_wwan" ]; then
+				echo "ppp0"
+				return 0
+
+			# Otherwise we return RED_DEV
+			elif [ -n "${RED_DEV}" ]; then
+				echo "${RED_DEV}"
+				return 0
+			fi
+			;;
+
+		GREEN)
+			if [ -n "${GREEN_DEV}" ]; then
+				echo "${GREEN_DEV}"
+				return 0
+			fi
+			;;
+
+		ORANGE)
+			if [ -n "${ORANGE_DEV}" ]; then
+				echo "${ORANGE_DEV}"
+				return 0
+			fi
+			;;
+
+		BLUE)
+			if [ -n "${BLUE_DEV}" ]; then
+				echo "${BLUE_DEV}"
+				return 0
+			fi
+			;;
+
+		OPENVPN|OVPN)
+			# OpenVPN is using all tun devices
+			echo "tun+"
+			;;
+	esac
+
+	# Not found
+	return 1
+}
+
 network_get_address() {
 	local network="${1}"
 
diff --git a/src/initscripts/system/suricata b/src/initscripts/system/suricata
index 455715d1b..8a1740528 100644
--- a/src/initscripts/system/suricata
+++ b/src/initscripts/system/suricata
@@ -21,6 +21,7 @@ 
 
 . /etc/sysconfig/rc
 . ${rc_functions}
+. /etc/init.d/networking/functions.network
 
 PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin; export PATH
 
@@ -38,6 +39,13 @@  IPS_BYPASS_REQUESTED_MASK="0x40000000"
 IPS_BYPASS_MARK="0x20000000"
 IPS_BYPASS_MASK="0x20000000"
 
+# Set if we request to scan this packet
+IPS_SCAN_MARK="0x10000000"
+IPS_SCAN_MASK="0x10000000"
+
+# Supported network zones
+NETWORK_ZONES=( "RED" "GREEN" "ORANGE" "BLUE" "OVPN" )
+
 # Optional options for the Netfilter queue.
 NFQ_OPTS=(
 	"--queue-bypass"
@@ -83,6 +91,30 @@  generate_fw_rules() {
 	# 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
 
+	local zone
+	local status
+	local intf
+
+	# Mark packets for all zones that we want to scan
+	for zone in "${NETWORK_ZONES[@]}"; do
+		status="ENABLE_IDS_${zone}"
+
+		if [ "${!status}" = "on" ]; then
+			intf="$(network_get_intf "${zone}")"
+
+			# Skip if we could not determine an interface
+			if [ -z "${intf}" ]; then
+				continue
+			fi
+
+			iptables -w -t mangle -A IPS -i "${intf}" -j MARK --set-mark "$(( IPS_SCAN_MARK ))/$(( IPS_SCAN_MASK ))"
+			iptables -w -t mangle -A IPS -o "${intf}" -j MARK --set-mark "$(( IPS_SCAN_MARK ))/$(( IPS_SCAN_MASK ))"
+		fi
+	done
+
+	# Don't keep processing packets we don't want to scan
+	iptables -w -t mangle -A IPS -m mark ! --mark "$(( IPS_SCAN_MARK ))/$(( IPS_SCAN_MASK ))" -j RETURN
+
 	# Never send any whitelisted packets to the IPS
 	if [ -r "/var/ipfire/suricata/ignored" ]; then
 		local id network remark enabled rest