]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
firewall: add --firewall and firewall.enabled
authorVictor Julien <vjulien@oisf.net>
Wed, 11 Jun 2025 09:00:50 +0000 (11:00 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 11 Jun 2025 18:49:16 +0000 (20:49 +0200)
Allows for enabling firewall mode

src/suricata.c
src/suricata.h
suricata.yaml.in

index 2158aaeea21be4635c6c59216455587dd67d59fc..023c1dc160c76d6142b3c1721acac3ffba3613f8 100644 (file)
@@ -232,10 +232,17 @@ int EngineModeIsUnknown(void)
     return (g_engine_mode == ENGINE_MODE_UNKNOWN);
 }
 
+bool EngineModeIsFirewall(void)
+{
+    DEBUG_VALIDATE_BUG_ON(g_engine_mode == ENGINE_MODE_UNKNOWN);
+    return (g_engine_mode == ENGINE_MODE_FIREWALL);
+}
+
+/* this returns true for firewall mode as well */
 int EngineModeIsIPS(void)
 {
     DEBUG_VALIDATE_BUG_ON(g_engine_mode == ENGINE_MODE_UNKNOWN);
-    return (g_engine_mode == ENGINE_MODE_IPS);
+    return (g_engine_mode >= ENGINE_MODE_IPS);
 }
 
 int EngineModeIsIDS(void)
@@ -244,6 +251,11 @@ int EngineModeIsIDS(void)
     return (g_engine_mode == ENGINE_MODE_IDS);
 }
 
+void EngineModeSetFirewall(void)
+{
+    g_engine_mode = ENGINE_MODE_FIREWALL;
+}
+
 void EngineModeSetIPS(void)
 {
     g_engine_mode = ENGINE_MODE_IPS;
@@ -619,6 +631,7 @@ static void PrintUsage(const char *progname)
     printf("\t--fatal-unittests                    : enable fatal failure on unittest error\n");
     printf("\t--unittests-coverage                 : display unittest coverage report\n");
 #endif /* UNITTESTS */
+    printf("\t--firewall                           : enable firewall mode\n");
     printf("\t--firewall-rules-exclusive=<path>    : path to firewall rule file loaded "
            "exclusively\n");
     printf("\t--list-app-layer-protos              : list supported app layer protocols\n");
@@ -1336,6 +1349,7 @@ TmEcode SCParseCommandLine(int argc, char **argv)
     int conf_test = 0;
     int engine_analysis = 0;
     int ret = TM_ECODE_OK;
+    int is_firewall = 0;
 
 #ifdef UNITTESTS
     coverage_unittests = 0;
@@ -1420,6 +1434,7 @@ TmEcode SCParseCommandLine(int argc, char **argv)
 
         {"qa-skip-prefilter", 0, &g_skip_prefilter, 1 },
 
+        {"firewall", 0, &is_firewall, 1 },
         {"firewall-rules-exclusive", required_argument, 0, 0},
 
         {"include", required_argument, 0, 0},
@@ -1833,6 +1848,7 @@ TmEcode SCParseCommandLine(int argc, char **argv)
                 }
                 suri->firewall_rule_file = optarg;
                 suri->firewall_rule_file_exclusive = true;
+                suri->is_firewall = true;
             } else {
                 int r = ExceptionSimulationCommandLineParser(
                         (long_opts[option_index]).name, optarg);
@@ -2058,6 +2074,10 @@ TmEcode SCParseCommandLine(int argc, char **argv)
         }
     }
 
+    if (is_firewall) {
+        suri->is_firewall = true;
+    }
+
     if (suri->disabled_detect && (suri->sig_file != NULL || suri->firewall_rule_file != NULL)) {
         SCLogError("can't use -s/-S or --firewall-rules-exclusive when detection is disabled");
         return TM_ECODE_FAILED;
@@ -2662,6 +2682,21 @@ static void SetupUserMode(SCInstance *suri)
  */
 int PostConfLoadedSetup(SCInstance *suri)
 {
+    int cnf_firewall_enabled = 0;
+    if (SCConfGetBool("firewall.enabled", &cnf_firewall_enabled) == 1) {
+        if (cnf_firewall_enabled == 1) {
+            suri->is_firewall = true;
+        } else {
+            if (suri->is_firewall) {
+                FatalError("firewall mode enabled through commandline, but disabled in config");
+            }
+        }
+    }
+    if (suri->is_firewall) {
+        SCLogWarning("firewall mode is EXPERIMENTAL and subject to change");
+        EngineModeSetFirewall();
+    }
+
     /* load the pattern matchers */
     MpmTableSetup();
     SpmTableSetup();
index 1b1a4b198c8ecd40074616c859de0de86f712f37..5e1e72259c598b956548f2d668fa97e19b20dd88 100644 (file)
@@ -106,12 +106,17 @@ enum {
 enum EngineMode {
     ENGINE_MODE_UNKNOWN,
     ENGINE_MODE_IDS,
+    /* order matters, we need to be able to do IPS is true for >= ENGINE_MODE_IPS */
     ENGINE_MODE_IPS,
+    ENGINE_MODE_FIREWALL,
 };
 
+/* superset of IPS mode */
+void EngineModeSetFirewall(void);
 void EngineModeSetIPS(void);
 void EngineModeSetIDS(void);
 int EngineModeIsUnknown(void);
+bool EngineModeIsFirewall(void);
 int EngineModeIsIPS(void);
 int EngineModeIsIDS(void);
 
@@ -136,6 +141,8 @@ typedef struct SCInstance_ {
     char *regex_arg;
     char *firewall_rule_file;
     bool firewall_rule_file_exclusive;
+    /* is firewall mode enabled */
+    bool is_firewall;
 
     char *keyword_info;
     char *runmode_custom_mode;
index 9ff696a99928066f48b18c313b49b1458f34789c..9b96a59ea3d5973a8344b77156b84ef8e0b7e026 100644 (file)
@@ -2313,6 +2313,9 @@ reference-config-file: @e_sysconfdir@reference.config
 ## Suricata as a Firewall options (experimental)
 ##
 firewall:
+  # toggle to enable firewall mode
+  #enabled: no
+
   # Firewall rule file are in their own path and are not managed
   # by Suricata-Update.
   #rule-path: /etc/suricata/firewall/