From 549089a970e39d1ea09c10af5eaf8f696dd19d40 Mon Sep 17 00:00:00 2001 From: Maxime THIEBAUT <46688461+0xThiebaut@users.noreply.github.com> Date: Wed, 1 May 2024 22:16:03 +0200 Subject: suricata: T751: Initial support for suricata --- interface-definitions/service_ids_suricata.xml.in | 250 ++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 interface-definitions/service_ids_suricata.xml.in (limited to 'interface-definitions') diff --git a/interface-definitions/service_ids_suricata.xml.in b/interface-definitions/service_ids_suricata.xml.in new file mode 100644 index 000000000..8c1973567 --- /dev/null +++ b/interface-definitions/service_ids_suricata.xml.in @@ -0,0 +1,250 @@ + + + + + + + + + Network IDS, IPS and Network Security Monitoring + 740 + + + #include + + + Address group name + + home-net external-net http-servers smtp-servers sql-servers dns-servers telnet-servers aim-servers dc-servers dnp3-server dnp3-client modbus-client modbus-server enip-client enip-server + + + [a-z0-9-]+ + + + + + + IP address or subnet + + ipv4 + IPv4 address to match + + + ipv6 + IPv6 address to match + + + ipv4net + IPv4 prefix to match + + + ipv6net + IPv6 prefix to match + + + !ipv4 + Exclude the specified IPv4 address from matches + + + !ipv6 + Exclude the specified IPv6 address from matches + + + !ipv4net + Exclude the specified IPv6 prefix from matches + + + !ipv6net + Exclude the specified IPv6 prefix from matches + + + + + + + + + + + + + + + + + Address group + + service ids suricata address-group + home-net external-net http-servers smtp-servers sql-servers dns-servers telnet-servers aim-servers dc-servers dnp3-server dnp3-client modbus-client modbus-server enip-client enip-server + + + string + Address group to match + + + !string + Exclude the specified address group from matches + + + !?[a-z0-9-]+ + + + + + + + + + Port group name + + http-ports shellcode-ports oracle-ports ssh-ports dnp3-ports modbus-ports file-data-ports ftp-ports geneve-ports vxlan-ports teredo-ports + + + [a-z0-9-]+ + + + + + + Port number + + u32:1-65535 + Numeric port to match + + + !u32:1-65535 + Numeric port to exclude from matches + + + start-end + Numbered port range (e.g. 1001-1005) to match + + + !start-end + Numbered port range (e.g. !1001-1005) to exclude from matches + + + + + + + + + + + Port group + + service ids suricata port-group + http-ports shellcode-ports oracle-ports ssh-ports dnp3-ports modbus-ports file-data-ports ftp-ports geneve-ports vxlan-ports teredo-ports + + + string + Port group to match + + + !string + Exclude the specified port group from matches + + + !?[a-z0-9-]+ + + + + + + + + + Suricata log outputs + + + + + Extensible Event Format (EVE) + + + + + EVE logging destination + + regular syslog + + + regular + Log to filename + + + syslog + Log to syslog + + + (regular|syslog) + + + regular + + + + Log file + + filename + File name in default Suricata log directory + + + /path + Absolute file path + + + eve.json + + + + Log types + + alert anomaly drop files http dns tls smtp dnp3 ftp rdp nfs smb tftp ikev2 dcerpc krb5 snmp rfb sip dhcp ssh mqtt http2 flow netflow + + + alert + Record events for rule matches + + + anomaly + Record unexpected conditions such as truncated packets, packets with invalid IP/UDP/TCP length values, and other events that render the packet invalid for further processing or describe unexpected behavior on an established stream + + + drop + Record events for dropped packets + + + file + Record file details (e.g., MD5) for files extracted from application protocols (e.g., HTTP) + + + application (http, dns, tls, ...) + Record application-level transactions + + + flow + Record bi-directional flows + + + netflow + Record uni-directional flows + + + (alert|anomaly|http|dns|tls|files|drop|smtp|dnp3|ftp|rdp|nfs|smb|tftp|ikev2|dcerpc|krb5|snmp|rfb|sip|dhcp|ssh|mqtt|http2|flow|netflow) + + + + + + + + + + + + + + + -- cgit v1.2.3 From cd32928e1856b0a7e9781709cfc3b0db16b6abcb Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Thu, 23 May 2024 21:36:04 +0200 Subject: suricata: T751: move CLI from "service ids suricata" -> "service suricata" --- interface-definitions/service_ids_suricata.xml.in | 250 ---------------------- interface-definitions/service_suricata.xml.in | 246 +++++++++++++++++++++ src/conf_mode/service_ids_suricata.py | 190 ---------------- src/conf_mode/service_suricata.py | 190 ++++++++++++++++ 4 files changed, 436 insertions(+), 440 deletions(-) delete mode 100644 interface-definitions/service_ids_suricata.xml.in create mode 100644 interface-definitions/service_suricata.xml.in delete mode 100755 src/conf_mode/service_ids_suricata.py create mode 100755 src/conf_mode/service_suricata.py (limited to 'interface-definitions') diff --git a/interface-definitions/service_ids_suricata.xml.in b/interface-definitions/service_ids_suricata.xml.in deleted file mode 100644 index 8c1973567..000000000 --- a/interface-definitions/service_ids_suricata.xml.in +++ /dev/null @@ -1,250 +0,0 @@ - - - - - - - - - Network IDS, IPS and Network Security Monitoring - 740 - - - #include - - - Address group name - - home-net external-net http-servers smtp-servers sql-servers dns-servers telnet-servers aim-servers dc-servers dnp3-server dnp3-client modbus-client modbus-server enip-client enip-server - - - [a-z0-9-]+ - - - - - - IP address or subnet - - ipv4 - IPv4 address to match - - - ipv6 - IPv6 address to match - - - ipv4net - IPv4 prefix to match - - - ipv6net - IPv6 prefix to match - - - !ipv4 - Exclude the specified IPv4 address from matches - - - !ipv6 - Exclude the specified IPv6 address from matches - - - !ipv4net - Exclude the specified IPv6 prefix from matches - - - !ipv6net - Exclude the specified IPv6 prefix from matches - - - - - - - - - - - - - - - - - Address group - - service ids suricata address-group - home-net external-net http-servers smtp-servers sql-servers dns-servers telnet-servers aim-servers dc-servers dnp3-server dnp3-client modbus-client modbus-server enip-client enip-server - - - string - Address group to match - - - !string - Exclude the specified address group from matches - - - !?[a-z0-9-]+ - - - - - - - - - Port group name - - http-ports shellcode-ports oracle-ports ssh-ports dnp3-ports modbus-ports file-data-ports ftp-ports geneve-ports vxlan-ports teredo-ports - - - [a-z0-9-]+ - - - - - - Port number - - u32:1-65535 - Numeric port to match - - - !u32:1-65535 - Numeric port to exclude from matches - - - start-end - Numbered port range (e.g. 1001-1005) to match - - - !start-end - Numbered port range (e.g. !1001-1005) to exclude from matches - - - - - - - - - - - Port group - - service ids suricata port-group - http-ports shellcode-ports oracle-ports ssh-ports dnp3-ports modbus-ports file-data-ports ftp-ports geneve-ports vxlan-ports teredo-ports - - - string - Port group to match - - - !string - Exclude the specified port group from matches - - - !?[a-z0-9-]+ - - - - - - - - - Suricata log outputs - - - - - Extensible Event Format (EVE) - - - - - EVE logging destination - - regular syslog - - - regular - Log to filename - - - syslog - Log to syslog - - - (regular|syslog) - - - regular - - - - Log file - - filename - File name in default Suricata log directory - - - /path - Absolute file path - - - eve.json - - - - Log types - - alert anomaly drop files http dns tls smtp dnp3 ftp rdp nfs smb tftp ikev2 dcerpc krb5 snmp rfb sip dhcp ssh mqtt http2 flow netflow - - - alert - Record events for rule matches - - - anomaly - Record unexpected conditions such as truncated packets, packets with invalid IP/UDP/TCP length values, and other events that render the packet invalid for further processing or describe unexpected behavior on an established stream - - - drop - Record events for dropped packets - - - file - Record file details (e.g., MD5) for files extracted from application protocols (e.g., HTTP) - - - application (http, dns, tls, ...) - Record application-level transactions - - - flow - Record bi-directional flows - - - netflow - Record uni-directional flows - - - (alert|anomaly|http|dns|tls|files|drop|smtp|dnp3|ftp|rdp|nfs|smb|tftp|ikev2|dcerpc|krb5|snmp|rfb|sip|dhcp|ssh|mqtt|http2|flow|netflow) - - - - - - - - - - - - - - - diff --git a/interface-definitions/service_suricata.xml.in b/interface-definitions/service_suricata.xml.in new file mode 100644 index 000000000..e21320bfe --- /dev/null +++ b/interface-definitions/service_suricata.xml.in @@ -0,0 +1,246 @@ + + + + + + + Network IDS, IPS and Security Monitoring + 740 + + + #include + + + Address group name + + home-net external-net http-servers smtp-servers sql-servers dns-servers telnet-servers aim-servers dc-servers dnp3-server dnp3-client modbus-client modbus-server enip-client enip-server + + + [a-z0-9-]+ + + + + + + IP address or subnet + + ipv4 + IPv4 address to match + + + ipv6 + IPv6 address to match + + + ipv4net + IPv4 prefix to match + + + ipv6net + IPv6 prefix to match + + + !ipv4 + Exclude the specified IPv4 address from matches + + + !ipv6 + Exclude the specified IPv6 address from matches + + + !ipv4net + Exclude the specified IPv6 prefix from matches + + + !ipv6net + Exclude the specified IPv6 prefix from matches + + + + + + + + + + + + + + + + + Address group + + service ids suricata address-group + home-net external-net http-servers smtp-servers sql-servers dns-servers telnet-servers aim-servers dc-servers dnp3-server dnp3-client modbus-client modbus-server enip-client enip-server + + + string + Address group to match + + + !string + Exclude the specified address group from matches + + + !?[a-z0-9-]+ + + + + + + + + + Port group name + + http-ports shellcode-ports oracle-ports ssh-ports dnp3-ports modbus-ports file-data-ports ftp-ports geneve-ports vxlan-ports teredo-ports + + + [a-z0-9-]+ + + + + + + Port number + + u32:1-65535 + Numeric port to match + + + !u32:1-65535 + Numeric port to exclude from matches + + + start-end + Numbered port range (e.g. 1001-1005) to match + + + !start-end + Numbered port range (e.g. !1001-1005) to exclude from matches + + + + + + + + + + + Port group + + service ids suricata port-group + http-ports shellcode-ports oracle-ports ssh-ports dnp3-ports modbus-ports file-data-ports ftp-ports geneve-ports vxlan-ports teredo-ports + + + string + Port group to match + + + !string + Exclude the specified port group from matches + + + !?[a-z0-9-]+ + + + + + + + + + Suricata log outputs + + + + + Extensible Event Format (EVE) + + + + + EVE logging destination + + regular syslog + + + regular + Log to filename + + + syslog + Log to syslog + + + (regular|syslog) + + + regular + + + + Log file + + filename + File name in default Suricata log directory + + + /path + Absolute file path + + + eve.json + + + + Log types + + alert anomaly drop files http dns tls smtp dnp3 ftp rdp nfs smb tftp ikev2 dcerpc krb5 snmp rfb sip dhcp ssh mqtt http2 flow netflow + + + alert + Record events for rule matches + + + anomaly + Record unexpected conditions such as truncated packets, packets with invalid IP/UDP/TCP length values, and other events that render the packet invalid for further processing or describe unexpected behavior on an established stream + + + drop + Record events for dropped packets + + + file + Record file details (e.g., MD5) for files extracted from application protocols (e.g., HTTP) + + + application (http, dns, tls, ...) + Record application-level transactions + + + flow + Record bi-directional flows + + + netflow + Record uni-directional flows + + + (alert|anomaly|http|dns|tls|files|drop|smtp|dnp3|ftp|rdp|nfs|smb|tftp|ikev2|dcerpc|krb5|snmp|rfb|sip|dhcp|ssh|mqtt|http2|flow|netflow) + + + + + + + + + + + + + diff --git a/src/conf_mode/service_ids_suricata.py b/src/conf_mode/service_ids_suricata.py deleted file mode 100755 index 49fbce244..000000000 --- a/src/conf_mode/service_ids_suricata.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2024 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# 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 . - -import os - -from sys import exit - -from vyos.base import Warning -from vyos.config import Config -from vyos.template import render -from vyos.utils.process import call -from vyos import ConfigError -from vyos import airbag -airbag.enable() - -config_file = '/run/suricata/suricata.yaml' -rotate_file = '/etc/logrotate.d/suricata' - -address_group_defaults = { - 'home-net': {'address': ['192.168.0.0/16','10.0.0.0/8','172.16.0.0/12']}, - 'external-net': {'group': ['!home-net']}, - 'http-servers': {'group': ['home-net']}, - 'smtp-servers': {'group': ['home-net']}, - 'sql-servers': {'group': ['home-net']}, - 'dns-servers': {'group': ['home-net']}, - 'telnet-servers': {'group': ['home-net']}, - 'aim-servers': {'group': ['external-net']}, - 'dc-servers': {'group': ['home-net']}, - 'dnp3-server': {'group': ['home-net']}, - 'modbus-client': {'group': ['home-net']}, - 'modbus-server': {'group': ['home-net']}, - 'enip-client': {'group': ['home-net']}, - 'enip-server': {'group': ['home-net']}, -} - -port_group_defaults = { - 'http-ports': {'port': ['80']}, - 'shellcode-ports': {'port': ['!80']}, - 'oracle-ports': {'port': ['1521']}, - 'ssh-ports': {'port': ['22']}, - 'dnp3-ports': {'port': ['20000']}, - 'modbus-ports': {'port': ['502']}, - 'file-data-ports': {'port': ['110', '143'], 'group': ['http-ports']}, - 'ftp-ports': {'port': ['21']}, - 'geneve-ports': {'port': ['6081']}, - 'vxlan-ports': {'port': ['4789']}, - 'teredo-ports': {'port': ['3544']}, -} - -def get_config(config=None): - if config: - conf = config - else: - conf = Config() - base = ['service', 'ids', 'suricata'] - if not conf.exists(base): - return None - - suricata = conf.get_config_dict(base, - get_first_key=True, - with_recursive_defaults=True) - - # Ensure minimal defaults are present - suricata['address-group'] = address_group_defaults | suricata.get('address-group', {}) - suricata['port-group'] = port_group_defaults | suricata.get('port-group', {}) - - return suricata - -# https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search -def topological_sort(source): - sorted_nodes = [] - permanent_marks = set() - temporary_marks = set() - - def visit(n, v): - if n in permanent_marks: - return - if n in temporary_marks: - raise ConfigError('At least one cycle exists in the referenced groups') - - temporary_marks.add(n) - - for m in v.get('group', []): - m = m.lstrip('!') - if m not in source: - raise ConfigError(f'Undefined referenced group "{m}"') - visit(m, source[m]) - - temporary_marks.remove(n) - permanent_marks.add(n) - sorted_nodes.append((n, v)) - - while len(permanent_marks) < len(source): - n = next(n for n in source.keys() if n not in permanent_marks) - visit(n, source[n]) - - return sorted_nodes - -def verify(suricata): - if not suricata: - return None - - if 'interface' not in suricata: - raise ConfigError('No interfaces configured') - - try: - topological_sort(suricata['address-group']) - except (ConfigError,StopIteration) as e: - raise ConfigError(f'Invalid address-group: {e}') - - try: - topological_sort(suricata['port-group']) - except (ConfigError,StopIteration) as e: - raise ConfigError(f'Invalid port-group: {e}') - -def generate(suricata): - if not suricata: - for file in [config_file, rotate_file]: - if os.path.isfile(file): - os.unlink(file) - - return None - - # Config-related formatters - def to_var(s:str): - return s.replace('-','_').upper() - - def to_val(s:str): - return s.replace('-',':') - - def to_ref(s:str): - if s[0] == '!': - return '!$' + to_var(s[1:]) - return '$' + to_var(s) - - def to_config(kind:str): - def format_group(group): - (name, value) = group - property = [to_val(property) for property in value.get(kind,[])] - group = [to_ref(group) for group in value.get('group',[])] - return (to_var(name), property + group) - return format_group - - # Format the address group - suricata['address-group'] = map(to_config('address'), - topological_sort(suricata['address-group'])) - - # Format the port group - suricata['port-group'] = map(to_config('port'), - topological_sort(suricata['port-group'])) - - render(config_file, 'ids/suricata.j2', {'suricata': suricata}) - render(rotate_file, 'ids/suricata_logrotate.j2', suricata) - return None - -def apply(suricata): - systemd_service = 'suricata.service' - if not suricata or 'interface' not in suricata: - # Stop suricata service if removed - call(f'systemctl stop {systemd_service}') - else: - Warning('To fetch the latest rules, use "update suricata"; ' - 'To periodically fetch the latest rules, ' - 'use the task scheduler!') - call(f'systemctl restart {systemd_service}') - - return None - -if __name__ == '__main__': - try: - c = get_config() - verify(c) - generate(c) - apply(c) - except ConfigError as e: - print(e) - exit(1) diff --git a/src/conf_mode/service_suricata.py b/src/conf_mode/service_suricata.py new file mode 100755 index 000000000..cce4de6e3 --- /dev/null +++ b/src/conf_mode/service_suricata.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# 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 . + +import os + +from sys import exit + +from vyos.base import Warning +from vyos.config import Config +from vyos.template import render +from vyos.utils.process import call +from vyos import ConfigError +from vyos import airbag +airbag.enable() + +config_file = '/run/suricata/suricata.yaml' +rotate_file = '/etc/logrotate.d/suricata' + +address_group_defaults = { + 'home-net': {'address': ['192.168.0.0/16','10.0.0.0/8','172.16.0.0/12']}, + 'external-net': {'group': ['!home-net']}, + 'http-servers': {'group': ['home-net']}, + 'smtp-servers': {'group': ['home-net']}, + 'sql-servers': {'group': ['home-net']}, + 'dns-servers': {'group': ['home-net']}, + 'telnet-servers': {'group': ['home-net']}, + 'aim-servers': {'group': ['external-net']}, + 'dc-servers': {'group': ['home-net']}, + 'dnp3-server': {'group': ['home-net']}, + 'modbus-client': {'group': ['home-net']}, + 'modbus-server': {'group': ['home-net']}, + 'enip-client': {'group': ['home-net']}, + 'enip-server': {'group': ['home-net']}, +} + +port_group_defaults = { + 'http-ports': {'port': ['80']}, + 'shellcode-ports': {'port': ['!80']}, + 'oracle-ports': {'port': ['1521']}, + 'ssh-ports': {'port': ['22']}, + 'dnp3-ports': {'port': ['20000']}, + 'modbus-ports': {'port': ['502']}, + 'file-data-ports': {'port': ['110', '143'], 'group': ['http-ports']}, + 'ftp-ports': {'port': ['21']}, + 'geneve-ports': {'port': ['6081']}, + 'vxlan-ports': {'port': ['4789']}, + 'teredo-ports': {'port': ['3544']}, +} + +def get_config(config=None): + if config: + conf = config + else: + conf = Config() + base = ['service', 'suricata'] + if not conf.exists(base): + return None + + suricata = conf.get_config_dict(base, + get_first_key=True, + with_recursive_defaults=True) + + # Ensure minimal defaults are present + suricata['address-group'] = address_group_defaults | suricata.get('address-group', {}) + suricata['port-group'] = port_group_defaults | suricata.get('port-group', {}) + + return suricata + +# https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search +def topological_sort(source): + sorted_nodes = [] + permanent_marks = set() + temporary_marks = set() + + def visit(n, v): + if n in permanent_marks: + return + if n in temporary_marks: + raise ConfigError('At least one cycle exists in the referenced groups') + + temporary_marks.add(n) + + for m in v.get('group', []): + m = m.lstrip('!') + if m not in source: + raise ConfigError(f'Undefined referenced group "{m}"') + visit(m, source[m]) + + temporary_marks.remove(n) + permanent_marks.add(n) + sorted_nodes.append((n, v)) + + while len(permanent_marks) < len(source): + n = next(n for n in source.keys() if n not in permanent_marks) + visit(n, source[n]) + + return sorted_nodes + +def verify(suricata): + if not suricata: + return None + + if 'interface' not in suricata: + raise ConfigError('No interfaces configured') + + try: + topological_sort(suricata['address-group']) + except (ConfigError,StopIteration) as e: + raise ConfigError(f'Invalid address-group: {e}') + + try: + topological_sort(suricata['port-group']) + except (ConfigError,StopIteration) as e: + raise ConfigError(f'Invalid port-group: {e}') + +def generate(suricata): + if not suricata: + for file in [config_file, rotate_file]: + if os.path.isfile(file): + os.unlink(file) + + return None + + # Config-related formatters + def to_var(s:str): + return s.replace('-','_').upper() + + def to_val(s:str): + return s.replace('-',':') + + def to_ref(s:str): + if s[0] == '!': + return '!$' + to_var(s[1:]) + return '$' + to_var(s) + + def to_config(kind:str): + def format_group(group): + (name, value) = group + property = [to_val(property) for property in value.get(kind,[])] + group = [to_ref(group) for group in value.get('group',[])] + return (to_var(name), property + group) + return format_group + + # Format the address group + suricata['address-group'] = map(to_config('address'), + topological_sort(suricata['address-group'])) + + # Format the port group + suricata['port-group'] = map(to_config('port'), + topological_sort(suricata['port-group'])) + + render(config_file, 'ids/suricata.j2', {'suricata': suricata}) + render(rotate_file, 'ids/suricata_logrotate.j2', suricata) + return None + +def apply(suricata): + systemd_service = 'suricata.service' + if not suricata or 'interface' not in suricata: + # Stop suricata service if removed + call(f'systemctl stop {systemd_service}') + else: + Warning('To fetch the latest rules, use "update suricata"; ' + 'To periodically fetch the latest rules, ' + 'use the task scheduler!') + call(f'systemctl restart {systemd_service}') + + return None + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + exit(1) -- cgit v1.2.3 From 2af04a53a4c1aa30118f4c799eb7d1c4cd63be66 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Thu, 23 May 2024 21:54:26 +0200 Subject: suricata: T751: remove implicit default dictionary --- interface-definitions/service_suricata.xml.in | 16 +++------ src/conf_mode/service_suricata.py | 47 +++++---------------------- 2 files changed, 13 insertions(+), 50 deletions(-) (limited to 'interface-definitions') diff --git a/interface-definitions/service_suricata.xml.in b/interface-definitions/service_suricata.xml.in index e21320bfe..e0159e2ba 100644 --- a/interface-definitions/service_suricata.xml.in +++ b/interface-definitions/service_suricata.xml.in @@ -12,9 +12,6 @@ Address group name - - home-net external-net http-servers smtp-servers sql-servers dns-servers telnet-servers aim-servers dc-servers dnp3-server dnp3-client modbus-client modbus-server enip-client enip-server - [a-z0-9-]+ @@ -73,14 +70,13 @@ Address group service ids suricata address-group - home-net external-net http-servers smtp-servers sql-servers dns-servers telnet-servers aim-servers dc-servers dnp3-server dnp3-client modbus-client modbus-server enip-client enip-server - string + txt Address group to match - !string + !txt Exclude the specified address group from matches @@ -94,9 +90,6 @@ Port group name - - http-ports shellcode-ports oracle-ports ssh-ports dnp3-ports modbus-ports file-data-ports ftp-ports geneve-ports vxlan-ports teredo-ports - [a-z0-9-]+ @@ -133,14 +126,13 @@ Port group service ids suricata port-group - http-ports shellcode-ports oracle-ports ssh-ports dnp3-ports modbus-ports file-data-ports ftp-ports geneve-ports vxlan-ports teredo-ports - string + txt Port group to match - !string + !txt Exclude the specified port group from matches diff --git a/src/conf_mode/service_suricata.py b/src/conf_mode/service_suricata.py index cce4de6e3..06d68a637 100755 --- a/src/conf_mode/service_suricata.py +++ b/src/conf_mode/service_suricata.py @@ -29,53 +29,18 @@ airbag.enable() config_file = '/run/suricata/suricata.yaml' rotate_file = '/etc/logrotate.d/suricata' -address_group_defaults = { - 'home-net': {'address': ['192.168.0.0/16','10.0.0.0/8','172.16.0.0/12']}, - 'external-net': {'group': ['!home-net']}, - 'http-servers': {'group': ['home-net']}, - 'smtp-servers': {'group': ['home-net']}, - 'sql-servers': {'group': ['home-net']}, - 'dns-servers': {'group': ['home-net']}, - 'telnet-servers': {'group': ['home-net']}, - 'aim-servers': {'group': ['external-net']}, - 'dc-servers': {'group': ['home-net']}, - 'dnp3-server': {'group': ['home-net']}, - 'modbus-client': {'group': ['home-net']}, - 'modbus-server': {'group': ['home-net']}, - 'enip-client': {'group': ['home-net']}, - 'enip-server': {'group': ['home-net']}, -} - -port_group_defaults = { - 'http-ports': {'port': ['80']}, - 'shellcode-ports': {'port': ['!80']}, - 'oracle-ports': {'port': ['1521']}, - 'ssh-ports': {'port': ['22']}, - 'dnp3-ports': {'port': ['20000']}, - 'modbus-ports': {'port': ['502']}, - 'file-data-ports': {'port': ['110', '143'], 'group': ['http-ports']}, - 'ftp-ports': {'port': ['21']}, - 'geneve-ports': {'port': ['6081']}, - 'vxlan-ports': {'port': ['4789']}, - 'teredo-ports': {'port': ['3544']}, -} - def get_config(config=None): if config: conf = config else: conf = Config() base = ['service', 'suricata'] + if not conf.exists(base): return None suricata = conf.get_config_dict(base, - get_first_key=True, - with_recursive_defaults=True) - - # Ensure minimal defaults are present - suricata['address-group'] = address_group_defaults | suricata.get('address-group', {}) - suricata['port-group'] = port_group_defaults | suricata.get('port-group', {}) + get_first_key=True, with_recursive_defaults=True) return suricata @@ -114,7 +79,13 @@ def verify(suricata): return None if 'interface' not in suricata: - raise ConfigError('No interfaces configured') + raise ConfigError('No interfaces configured!') + + if 'address-group' not in suricata: + raise ConfigError('No address-group configured!') + + if 'port-group' not in suricata: + raise ConfigError('No port-group configured!') try: topological_sort(suricata['address-group']) -- cgit v1.2.3