====== PFSense - Suricata - Rules - Breakdown of a rule ====== ===== Example Rule ===== alert ip any any -> any any (msg:"IP detected"; sid:2; rev:1;) where * **alert**: The action to perform on the rule. * **ip**: The protocol that the rule will match. When ip is specified it will watch for all or any packets on the network involving the adapter. * **any any -> any any**: Source IP and Port; Direction; Destination IP and Port. * **(msg:"ICMP detected"; sid:2; rev:1;)**: The options. ---- **NOTE:** Aliases can also be used. alert ip $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"IP detected"; sid:2; rev:1;) where: * **$HOME_NET**: An alias of internal IPs. * **$EXTERNAL_NET**: An alias of non HOME_NET. * **$HTTP_PORTS**: An alias of ports. ---- ===== Actions ===== Actions are performed in the following precedence order by default if multiple rules exist; but can be changed through Action Order. * **pass**: If the packet matches this rule it will be accepted through. * **drop**: The packet will be silently removed from the network stack. An alert will be generated as well. * **reject**: This acts the same as drop but will also notify the sender that the packet has been removed from the stack. * **alert**: - Just notifies of any packets that have matched rules. ---- ===== Protocol ==== * **ip**: Any packets on the network involving the adapter. * **tcp**: TCP. * **udp**: UDP. * **icm**: ICMP packets, such as ping. **NOTE:** Suricata also allows you to specify layer 7 protocols as well, such as HTTP (http), SSL and TLS (tls for both), FTP (ftp) and SMB (smb). ---- ===== Source IP and Port; Direction; Destination IP and Port ===== any any -> any any Source and Destination IP can be configured as: * **any**: Any IP. * **192.168.1.10**: An actual IP. * **10.0.1.0/8**: A CIDR in the 10.0.1.0 subnet. * **!192.168.1.10**: An exclamation mark specifies “not”, so this means any IP but not 192.168.1.10. * **!10.0.1.0/8**: Any IP not in the 10.0.1.0 subnet. * **[192.168.1.10, !192.168.1.10]**: Multiple addresses. You can also mix-and-match with the ! as well. * **[$EXTERNAL_NET, !$HOME_NET]**: Multiple addresses, using built-in variables. * **![192.168.1.0/24,192.168.0.0/24]**: Not with Multiple addresses. Ports act similarly: * **any**: Any Port. * **80**: Port 80. * **[80:85]**: A range of ports. * **[:1024]**: Matches all ports from 0-1024. * **[1024:]**: Matches ports from 1024 to the highest (typically 65535). Direction Specification: * **->**: This is the most common and means only check if the source IP and port are coming in to the destination IP and port. * **<>**: This will match packet flow in either direction. **NOTE:** Built-in Variables include: * **HOME_NET**: * **EXTERNAL_NET**: ---- ===== Rule Options ===== Options fall into different categories: * **[[https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings|meta-settings]]**: Options not pertaining to any specifics about the packet; including msg, sid, rev. * **[[https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords|payload]]**: The packet data itself. **content: "peter";**. * **[[https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords|HTTP]]**: Heavily used when TCP protocol is set, useful for using Suricata as a content filtering system. **GET, POST, index.html, cookies, user-agents, response-status 302, 500 etc.**. * **[[https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Flow-keywords|flow]]**: More fine-grained control over the connection’s status and such. **established, memory usage, timeouts, user logged in**. * **[[https://redmine.openinfosecfoundation.org/projects/suricata/wiki/IPReputationRules|IP reputation]]**: Is an IP legit or known to be associated with malware, spam, etc... ---- msg:"IP detected"; sid:2; rev:1; * The 3 most basic options are: * **msg**: - What will be prompted in an alert (unless you’re using pass as the action, set this regardless). * **sid**: - This is a unique ID for the rule. * If multiple rules have the same sid Suricata will let you know, and not be nice about it. * Typically you should pick a really high number (> 100000) if you are going to write your own. * **rev**: - Revision number/ID. * Incremented by 1 every time the rule is changed. ---- ==== Other Rule Examples ==== alert icmp any any -> \ any any (msg:"PING detected"; \ sid:2; rev:1;) alert tcp any any <> \ any any (pcre:"/3\d{3}\ (\s|-)?\d{6}(\s|-)?\d{5}/";\ msg:"American Express card number \ detected in clear text";content: \ "amex";nocase;sid: 9000003;rev:1;) alert tcp 1.2.3.4 1024 - > 5.6.7.8 80 # Detect SSH protocol anomalies. alert tcp any any -> any 22 (msg:"ALERT TCP port 22 but not SSH"; app-layer-protocol:!ssh; sid:2271009; rev:1;) # Non-TLS traffic on TLS ports. alert tcp any any -> any [443,465] (msg:"Detected non-TLS on TLS port"; flow:to_server; app-layer-protocol:!tls; threshold: type limit, track by_src, seconds 90, count 1; sid:210003; rev:1;) alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:\".htpasswd access attempt\"; flow:to_server,established; content:\".htpasswd\"; nocase; sid:210503; rev:1;) ----