return True
return False
+def check_vars(suriconf, rulemap):
+ """Check that all vars referenced by a rule exist. If a var is not
+ found, disable the rule.
+ """
+ if suriconf is None:
+ # Can't continue without a valid Suricata configuration
+ # object.
+ return
+ for rule in rulemap.itervalues():
+ disable = False
+ for var in suricata.update.rule.parse_var_names(
+ rule["source_addr"]):
+ if not suriconf.has_key("vars.address-groups.%s" % (var)):
+ logger.warning(
+ "Rule has unknown source address var and will be disabled: %s: %s" % (
+ var, rule.brief()))
+ disable = True
+ for var in suricata.update.rule.parse_var_names(
+ rule["dest_addr"]):
+ if not suriconf.has_key("vars.address-groups.%s" % (var)):
+ logger.warning(
+ "Rule has unknown dest address var and will be disabled: %s: %s" % (
+ var, rule.brief()))
+ disable = True
+ for var in suricata.update.rule.parse_var_names(
+ rule["source_port"]):
+ if not suriconf.has_key("vars.port-groups.%s" % (var)):
+ logger.warning(
+ "Rule has unknown source port var and will be disabled: %s: %s" % (
+ var, rule.brief()))
+ disable = True
+ for var in suricata.update.rule.parse_var_names(
+ rule["dest_port"]):
+ if not suriconf.has_key("vars.port-groups.%s" % (var)):
+ logger.warning(
+ "Rule has unknown dest port var and will be disabled: %s: %s" % (
+ var, rule.brief()))
+ disable = True
+
+ if disable:
+ rule.enabled = False
+
def test_suricata(suricata_path):
if not suricata_path:
logger.info("No suricata application binary found, skipping test.")
logger.info("Loading %s.", drop_conf_filename)
drop_filters += load_drop_filters(drop_conf_filename)
+ # Load the Suricata configuration if we can.
+ suriconf = None
if os.path.exists(config.get("suricata-conf")) and \
suricata_path and os.path.exists(suricata_path):
logger.info("Loading %s",config.get("suricata-conf"))
suriconf = suricata.update.engine.Configuration.load(
config.get("suricata-conf"), suricata_path=suricata_path)
+
+ # Disable rule that are for app-layers that are not enabled.
+ if suriconf:
for key in suriconf.keys():
if key.startswith("app-layer.protocols") and \
key.endswith(".enabled"):
rulemap[rule.id] = new_rule
modify_count += 1
+ # Check rule vars, disabling rules that use unknown vars.
+ check_vars(suriconf, rulemap)
+
logger.info("Disabled %d rules." % (len(disabled_rules)))
logger.info("Enabled %d rules." % (enable_count))
logger.info("Modified %d rules." % (modify_count))
self["enabled"] = enabled
self["action"] = action
self["proto"] = None
+ self["source_addr"] = None
+ self["source_port"] = None
self["direction"] = None
+ self["dest_addr"] = None
+ self["dest_port"] = None
self["group"] = group
self["gid"] = 1
self["sid"] = None
logger.error("Failed to format rule as sid-msg-v2.map: %s" % (
str(rule)))
return None
+
+def parse_var_names(var):
+ """ Parse out the variable names from a string. """
+ if var is None:
+ return []
+ return re.findall("\$([\w_]+)", var)