One place for hosting & domains

      Configure

      How To Configure Suricata as an Intrusion Prevention System (IPS) on Rocky Linux 8


      Not using Rocky Linux 8?


      Choose a different version or distribution.

      Introduction

      In this tutorial you will learn how to configure Suricata’s built-in Intrusion Prevention System (IPS) mode on Rocky Linux 8. By default Suricata is configured to run as an Intrusion Detection System (IDS), which only generates alerts and logs suspicious traffic. When you enable IPS mode, Suricata can actively drop suspicious network traffic in addition to generating alerts for further analysis.

      Before enabling IPS mode, it is important to check which signatures you have enabled, and their default actions. An incorrectly configured signature, or a signature that is overly broad may result in dropping legitimate traffic to your network, or even block you from accessing your servers over SSH and other management protocols.

      In the first part of this tutorial you will check the signatures that you have installed and enabled. You will also learn how to include your own signatures. Once you know which signatures you would like to use in IPS mode, you’ll convert their default action to drop or reject traffic. With your signatures in place, you’ll learn how to send network traffic through Suricata using the netfilter NFQUEUE iptables target, and then generate some invalid network traffic to ensure that Suricata drops it as expected.

      Prerequisites

      If you have been following this tutorial series then you should already have Suricata running on a Rocky Linux 8 server.

      • If you still need to install Suricata then you can follow How To Install Suricata on Rocky Linux 8

      • You should also have the ET Open Ruleset downloaded using the suricata-update command, and included in your Suricata signatures.

      • The jq command line JSON processing tool. If you do not have it installed from a previous tutorial, you can do so using the dnf command:

      You may also have custom signatures that you would like to use from the previous Understanding Suricata Signatures tutorial.

      Step 1 — Including Custom Signatures

      The previous tutorials in this series explored how to install and configure Suricata, as well as how to understand signatures. If you would like to create and include your own rules then you need to edit Suricata’s /etc/suricata/suricata.yaml file to include a custom path to your signatures.

      First, let’s find your server’s public IPs so that you can use them in your custom signatures. To find your IPs you can use the ip command:

      You should receive output like the following:

      Output

      lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 203.0.113.0.5/20 10.20.0.5/16 2001:DB8::1/32 fe80::94ad:d4ff:fef9:cee0/64 eth1 UP 10.137.0.2/16 fe80::44a2:ebff:fe91:5187/64

      Your public IP address(es) will be similar to the highlighted 203.0.113.0.5 and 2001:DB8::1/32 IPs in the output.

      Now let’s create the following custom signature to scan for SSH traffic to non-SSH ports and include it in a file called /var/lib/suricata/rules/local.rules. Open the file with nano or your preferred editor:

      • sudo vi /var/lib/suricata/rules/local.rules

      Copy and paste the following signature:

      Invalid SSH Traffic Signature

      alert ssh any any -> 203.0.113.0.5 !22 (msg:"SSH TRAFFIC on non-SSH port"; flow:to_client, not_established; classtype: misc-attack; target: dest_ip; sid:1000000;)
      alert ssh any any -> 2001:DB8::1/32 !22 (msg:"SSH TRAFFIC on non-SSH port"; flow:to_client, not_established; classtype: misc-attack; target: dest_ip; sid:1000001;)
      

      Substitute your server’s public IP address in place of the 203.0.113.5 and 2001:DB8::1/32 addresses in the rule. If you are not using IPv6 then you can skip adding that signature in this and the following rules.

      You can continue adding custom signatures to this local.rules file depending on your network and applications. For example, if you wanted to alert about HTTP traffic to non-standard ports, you could use the following signatures:

      HTTP traffic on non-standard port signature

      alert http any any -> 203.0.113.0.5 !80 (msg:"HTTP REQUEST on non-HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000002;)
      alert http any any -> 2001:DB8::1/32 !80 (msg:"HTTP REQUEST on non-HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000003;)
      

      To add a signature that checks for TLS traffic to ports other than the default 443 for web servers, add the following:

      TLS traffic on non-standard port signature

      alert tls any any -> 203.0.113.0.5 !443 (msg:"TLS TRAFFIC on non-TLS HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000004;)
      alert tls any any -> 2001:DB8::1/32 !443 (msg:"TLS TRAFFIC on non-TLS HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000005;)
      

      When you are done adding signatures, save and close the file. If you are using vi, press ESC and then :x then ENTER to save and exit.

      Now that you have some custom signatures defined, edit Suricata’s /etc/suricata/suricata.yaml configuration file using nano or your preferred editor to include them:

      • sudo vi /etc/suricata/suricata.yaml

      Find the rule-files: portion of the configuration. If you are using vi enter 1879gg to go to the line. The exact location in your file may be different, but you should be in the correct general region of the file.

      Edit the section and add the following highlighted - local.rules line:

      /etc/suricata/suricata.yaml

      . . .
      rule-files:
        - suricata.rules
        - local.rules
      . . .
      

      Save and exit the file. Be sure to validate Suricata’s configuration after adding your rules. To do so run the following command:

      • sudo suricata -T -c /etc/suricata/suricata.yaml -v

      The test can take some time depending on how many rules you have loaded in the default suricata.rules file. If you find the test takes too long, you can comment out the - suricata.rules line in the configuration by adding a # to the beginning of the line and then run your configuration test again. Be sure to remove the # comment if you plan to use the suricata.rules signature in your final running configuration.

      Once you are satisfied with the signatures that you have created or included using the suricata-update tool, you can proceed to the next step, where you’ll switch the default action for your signatures from alert or log to actively dropping traffic.

      Step 2 — Configuring Signature Actions

      Now that you have your custom signatures tested and working with Suricata, you can change the action to drop or reject. When Suricata is operating in IPS mode, these actions will actively block invalid traffic for any matching signature.

      These two actions are described in the previous tutorial in this series, Understanding Suricata Signatures. The choice of which action to use is up to you. A drop action will immediately discard a packet and any subsequent packets that belong to the network flow. A reject action will send both the client and server a reset packet if the traffic is TCP-based, and an ICMP error packet for any other protocol.

      Let’s use the custom rules from the previous section and convert them to use the drop action, since the traffic that they match is likely to be a network scan, or some other invalid connection.

      Open your /var/lib/suricata/rules/local.rules file using nano or your preferred editor and change the alert action at the beginning of each line in the file to drop:

      • sudo vi /var/lib/suricata/rules/local.rules

      /var/lib/suricata/rules/local.rules

      drop ssh any any -> 203.0.113.0.5 !22 (msg:"SSH TRAFFIC on non-SSH port"; classtype: misc-attack; target: dest_ip; sid:1000000;)
      drop ssh any any -> 2001:DB8::1/32 !22 (msg:"SSH TRAFFIC on non-SSH port"; classtype: misc-attack; target: dest_ip; sid:1000001;)
      . . .
      

      Repeat the step above for any signatures in /var/lib/suricata/rules/suricata.rules that you would like to convert to drop or reject mode.

      Note: If you ran suricata-update in the prerequisite tutorial, you may have more than 30,000 signatures included in your suricata.rules file.

      If you convert every signature to drop or reject you risk blocking legitimate access to your network or servers. Instead, leave the rules in suricata.rules for the time being, and add your custom signatures to local.rules. Suricata will continue to generate alerts for suspicious traffic that is described by the signatures in suricata.rules while it is running in IPS mode.

      After you have a few days or weeks of alerts collected, you can analyze them and choose the relevant signatures to convert to drop or reject based on their sid.

      Once you have all the signatures configured with the action that you would like them to take, the next step is to reconfigure and then restart Suricata in IPS mode.

      Step 3 — Enabling nfqueue Mode

      Suricata runs in IDS mode by default, which means it will not actively block network traffic. To switch to IPS mode, you’ll need to edit Suricata’s /etc/sysconfig/suricata configuration file.

      Open the file in nano or your preferred editor:

      • sudo vi /etc/sysconfig/suricata

      Find the OPTIONS="-i eth0 --user suricata" line and comment it out by adding a # to the beginning of the line. Then add a new line OPTIONS="-q 0 -vvv --user suricata" line that tells Suricata to run in IPS mode.

      Your file should have the following highlighted lines in it when you are done editing:

      /etc/sysconfig/suricata

      . . .
      # OPTIONS="-i eth0 --user suricata"
      OPTIONS="-q 0 -vvv --user suricata"
      . . .
      

      Save and close the file. Now you can restart Suricata using systemctl:

      • sudo systemctl restart suricata.service

      Check Suricata’s status using systemctl:

      • sudo systemctl status suricata.service

      You should receive output like the following:

      Output

      ● suricata.service - Suricata Intrusion Detection Service Loaded: loaded (/usr/lib/systemd/system/suricata.service; disabled; vendor preset: disabled) Active: active (running) since Tue 2021-12-14 16:52:07 UTC; 6s ago Docs: man:suricata(1) Process: 44256 ExecStartPre=/bin/rm -f /var/run/suricata.pid (code=exited, status=0/SUCCESS) Main PID: 44258 (Suricata-Main) Tasks: 10 (limit: 11188) Memory: 52.8M CGroup: /system.slice/suricata.service └─44258 /sbin/suricata -c /etc/suricata/suricata.yaml --pidfile /var/run/suricata.pid -q 0 -vvv --user suricata . . . Dec 14 16:52:07 suricata suricata[44258]: 14/12/2021 -- 16:52:07 - <Notice> - all 4 packet processing threads, 4 management threads initialized, engine started.

      Note the highlighted active (running) line that indicates Suricata restarted successfully.

      With this change you are now ready to send traffic to Suricata using Firewalld in the next step.

      Step 4 — Configuring Firewalld To Send Traffic to Suricata

      Now that you have configured Suricata to process traffic in IPS mode, the next step is to direct incoming packets to Suricata. If you followed the prerequisite tutorials for this series and are using a Rocky Linux 8 system, you should have Firewalld installed and enabled.

      To add the required rules for Suricata to Firewalld, you will need to run the following commands:

      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j NFQUEUE --queue-bypass
      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p tcp --sport 22 -j NFQUEUE --queue-bypass

      These two rules ensure that SSH traffic on IPv4 interfaces will bypass Suricata so that you can connect to your server using SSH, even when Suricata is not running. Without these rules, an incorrect or overly broad signature could block your SSH access. Additionally, if Suricata is stopped, all traffic will be sent to the NFQUEUE target and then dropped since Suricata is not running.

      Add the same rules for IPv6 using the following commands:

      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 0 -p tcp --dport 22 -j NFQUEUE --queue-bypass
      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter OUTPUT 0 -p tcp --sport 22 -j NFQUEUE --queue-bypass

      Next, add FORWARD rules to ensure that if your server is acting as a gateway for other systems, all that traffic will also go to Suricata for processing.

      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -j NFQUEUE
      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter FORWARD 0 -j NFQUEUE

      The final two INPUT and OUTPUT rules send all remaining traffic that is not SSH traffic to Suricata for processing.

      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1 -j NFQUEUE
      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 1 -j NFQUEUE

      Repeat the commands for IPv6 traffic:

      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 1 -j NFQUEUE
      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter OUTPUT 1 -j NFQUEUE

      Now reload Firewalld to make the rules persistent:

      • sudo firewall-cmd --reload

      Note: If you are using another firewall like iptables you will need to modify these rules to match the format your firewall expects.

      At this point in the tutorial you have Suricata configured to run in IPS mode, and your network traffic is being sent to Suricata by default. You will be able to restart your server at any time and your Suricata and firewall rules will be persistent.

      The last step in this tutorial is to verify Suricata is dropping traffic correctly.

      Step 5 — Testing Invalid Traffic

      Now that you have Suricata and your firewall configured to process network traffic, you can test whether Suricata will drop packets that match your custom and other included signatures.

      Recall signature sid:2100498 from the previous tutorial, which is modified in this example to drop matching packets:

      sid:2100498

      drop ip any any -> any any (msg:"GPL ATTACK_RESPONSE id check returned root"; content:"uid=0|28|root|29|"; classtype:bad-unknown; sid:2100498; rev:7; metadata:created_at 2010_09_23, updated_at 2010_09_23;)
      

      Find and edit the rule in your /var/lib/suricata/rules/suricata.rules file to use the drop action if you have the signature included there. Otherwise, add the rule to your /var/lib/suricata/rules/local.rules file.

      Send Suricata the SIGUSR2 signal to get it to reload its signatures:

      • sudo kill -usr2 $(pidof suricata)

      Now test the rule using curl:

      • curl --max-time 5 http://testmynids.org/uid/index.html

      You should receive an error stating that the request timed out, which indicates Suricata blocked the HTTP response:

      Output

      curl: (28) Operation timed out after 5000 milliseconds with 0 out of 39 bytes received

      You can confirm that Suricata dropped the HTTP response using jq to examine the eve.log file:

      • sudo jq 'select(.alert .signature_id==2100498)' /var/log/suricata/eve.json

      You should receive output like the following:

      Output

      { . . . "community_id": "1:SbOgFh2T3DZvwsoyMH4xfxOoVas=", "alert": { "action": "blocked", "gid": 1, "signature_id": 2100498, "rev": 7, "signature": "GPL ATTACK_RESPONSE id check returned root", "category": "Potentially Bad Traffic", "severity": 2, "metadata": { "created_at": [ "2010_09_23" ], "updated_at": [ "2010_09_23" ] } }, "http": { "hostname": "testmynids.org", "url": "/uid/index.html", "http_user_agent": "curl/7.61.1", "http_content_type": "text/html", "http_method": "GET", "protocol": "HTTP/1.1", "status": 200, "length": 39 }, . . .

      The highlighted "action": "blocked" line confirms that the signature matched, and Suricata dropped or rejected the test HTTP request.

      Conclusion

      In this tutorial you configured Suricata to block suspicious network traffic using its built-in IPS mode on Rocky Linux 8. You also added custom signatures to examine and block SSH, HTTP, and TLS traffic on non-standard ports. To tie everything together, you also added firewall rules to direct traffic through Suricata for processing.

      Now that you have Suricata installed and configured in IPS mode, and can write your own signatures that either alert on or drop suspicious traffic, you can continue monitoring your servers and networks, and refining your signatures.

      Once you are satisfied with your Suricata signatures and configuration, you can continue with the last tutorial in this series, which will guide you through sending logs from Suricata to a Security and Information Event Management (SIEM) system built using the Elastic Stack.



      Source link

      How To Configure Suricata as an Intrusion Prevention System (IPS) on Debian 11


      Not using Debian 11?


      Choose a different version or distribution.

      Introduction

      In this tutorial you will learn how to configure Suricata’s built-in Intrusion Prevention System (IPS) mode on Debian 11. By default Suricata is configured to run as an Intrusion Detection System (IDS), which only generates alerts and logs suspicious traffic. When you enable IPS mode, Suricata can actively drop suspicious network traffic in addition to generating alerts for further analysis.

      Before enabling IPS mode, it is important to check which signatures you have enabled, and their default actions. An incorrectly configured signature, or a signature that is overly broad may result in dropping legitimate traffic to your network, or even block you from accessing your servers over SSH and other management protocols.

      In the first part of this tutorial you will check the signatures that you have installed and enabled. You will also learn how to include your own signatures. Once you know which signatures you would like to use in IPS mode, you’ll convert their default action to drop or reject traffic. With your signatures in place, you’ll learn how to send network traffic through Suricata using the netfilter NFQUEUE iptables target, and then generate some invalid network traffic to ensure that Suricata drops it as expected.

      Prerequisites

      If you have been following this tutorial series then you should already have Suricata running on a server. If you still need to install Suricata then you can follow one of these tutorials depending on your server’s operating system:

      • How To Install Suricata on Debian 11

      • You should also have the ET Open Ruleset downloaded using the suricata-update command, and included in your Suricata signatures.

      • The jq command line JSON processing tool. If you do not have it installed from a previous tutorial, you can do so using the apt command:

        • sudo apt update
        • sudo apt install jq

      You may also have custom signatures that you would like to use from the previous Understanding Suricata Signatures tutorial.

      Step 1 — Including Custom Signatures

      The previous tutorials in this series explored how to install and configure Suricata, as well as how to understand signatures. If you would like to create and include your own signatures then you need to edit Suricata’s /etc/suricata/suricata.yaml file to add them.

      First, let’s find your server’s public IPs so that you can use them in your custom signatures. To find your IPs you can use the ip command:

      You should receive output like the following:

      Output

      lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 203.0.113.0.5/20 10.20.0.5/16 2604:a880:cad:d0::dc8:4001/64 fe80::94ad:d4ff:fef9:cee0/64 eth1 UP 10.137.0.2/16 fe80::44a2:ebff:fe91:5187/64

      Your public IP address(es) will be similar to the highlighted 203.0.113.0.5 and 2604:a880:cad:d0::dc8:4001/64 IPs in the output.

      Now let’s create the following custom signature to scan for SSH traffic to non-SSH ports and include it in a file called /etc/suricata/rules/local.rules. Open the file with nano or your preferred editor:

      • sudo nano /etc/suricata/rules/local.rules

      Copy and paste the following signature:

      Invalid SSH Traffic Signature

      alert ssh any any -> 203.0.113.0.5 !22 (msg:"SSH TRAFFIC on non-SSH port"; flow:to_client, not_established; classtype: misc-attack; target: dest_ip; sid:1000000;)
      alert ssh any any -> 2604:a880:cad:d0::dc8:4001/64 !22 (msg:"SSH TRAFFIC on non-SSH port"; flow:to_client, not_established; classtype: misc-attack; target: dest_ip; sid:1000001;)
      

      Substitute in your server’s public IP address in place of the 203.0.113.5 and 2604:a880:cad:d0::dc8:4001/64 addresses in the rule. If you are not using IPv6 then you can skip adding that signature in this and the following rules.

      You can continue adding custom signatures to this local.rules file depending on your network and applications. For example, if you wanted to alert about HTTP traffic to non-standard ports, you could use the following signatures:

      HTTP traffic on non-standard port signature

      alert http any any -> 203.0.113.0.5 !80 (msg:"HTTP REQUEST on non-HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000002;)
      alert http any any -> 2604:a880:cad:d0::dc8:4001/64 !80 (msg:"HTTP REQUEST on non-HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000003;)
      

      To add a signature that checks for TLS traffic to ports other than the default 443 for web servers, add the following:

      TLS traffic on non-standard port signature

      alert tls any any -> 203.0.113.0.5 !443 (msg:"TLS TRAFFIC on non-TLS HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000004;)
      alert tls any any -> 2604:a880:cad:d0::dc8:4001/64 !443 (msg:"TLS TRAFFIC on non-TLS HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000005;)
      

      When you are done adding signatures, save and close the file. If you are using nano, you can do so with CTRL+X, then Y and ENTER to confirm. If you are using vi, press ESC and then :x then ENTER to save and exit.

      Now that you have some custom signatures defined, edit Suricata’s /etc/suricata/suricata.yaml configuration file using nano or your preferred editor to include them:

      • sudo nano /etc/suricata/suricata.yaml

      Find the rule-files: portion of the configuration. If you are using nano use CTRL+_ and then enter the line number 1879. If you are using vi enter 1879gg to go to the line.

      Edit the section and add the following highlighted - local.rules line:

      /etc/suricata/suricata.yaml

      . . .
      rule-files:
        - suricata.rules
        - local.rules
      . . .
      

      Save and exit the file. Be sure to validate Suricata’s configuration after adding your rules. To do so run the following command:

      • sudo suricata -T -c /etc/suricata/suricata.yaml -v

      The test can take some time depending on how many rules you have loaded in the default suricata.rules file. If you find the test takes too long, you can comment out the - suricata.rules line in the configuration by adding a # to the beginning of the line and then run your configuration test again.

      Once you are satisfied with the signatures that you have created or included using the suricata-update tool, you can proceed to the next step, where you’ll switch the default action for your signatures from alert or log to actively dropping traffic.

      Step 2 — Configuring Signature Actions

      Now that you have your custom signatures tested and working with Suricata, you can change the action to drop or reject. When Suricata is operating in IPS mode, these actions will actively block invalid traffic for any matching signature.

      These two actions are described in the previous tutorial in this series, Understanding Suricata Signatures. The choice of which action to use is up to you. A drop action will immediately discard a packet and any subsequent packets that belong to the network flow. A reject action will send both the client and server a reset packet if the traffic is TCP-based, and an ICMP error packet for any other protocol.

      Let’s use the custom rules from the previous section and convert them to use the drop action, since the traffic that they match is likely to be a network scan, or some other invalid connection.

      Open your /etc/suricata/rules/local.rules file using nano or your preferred editor and change the alert action at the beginning of each line in the file to drop:

      /etc/suricata/rules/local.rules

      drop ssh any any -> 203.0.113.0.5 !22 (msg:"SSH TRAFFIC on non-SSH port"; classtype: misc-attack; target: dest_ip; sid:1000000;)
      drop ssh any any -> 2604:a880:cad:d0::dc8:4001/64 !22 (msg:"SSH TRAFFIC on non-SSH port"; classtype: misc-attack; target: dest_ip; sid:1000001;)
      . . .
      

      Repeat the step above for any signatures in /etc/suricata/rules/suricata.rules that you would like to convert to drop or reject mode.

      Note: If you ran suricata-update in the prerequisite tutorial, you may have more than 30,000 signatures included in your suricata.rules file.

      If you convert every signature to drop or reject you risk blocking legitimate access to your network or servers. Instead, leave the rules in suricata.rules for the time being, and add your custom signatures to local.rules. Suricata will continue to generate alerts for suspicious traffic that is described by the signatures in suricata.rules while it is running in IPS mode.

      After you have a few days or weeks of alerts collected, you can analyze them and choose the relevant signatures to convert to drop or reject based on their sid.

      Once you have all the signatures configured with the action that you would like them to take, the next step is to reconfigure and then restart Suricata in IPS mode.

      Step 3 — Enabling nfqueue Mode

      Suricata runs in IDS mode by default, which means it will not actively block network traffic. To switch to IPS mode, you’ll need to modify Suricata’s default settings.

      Use the systemctl edit command to create a new systemd override file:

      • sudo systemctl edit suricata.service

      Add the following highlighted lines at the start of the file, in between the comments:

      systemctl edit suricata.service

      ### Editing /etc/systemd/system/suricata.service.d/override.conf
      ### Anything between here and the comment below will become the new contents of the file
      
      [Service]
      ExecStart=
      ExecStart=/usr/bin/suricata -c /etc/suricata/suricata.yaml --pidfile /run/suricata.pid -q 0 -vvv
      Type=simple
      
      ### Lines below this comment will be discarded
      . . .
      
      • The ExecStart= line clears the default systemd command that starts a service. The next line defines the new ExecStart command to use.
      • The Type=simple line ensures that systemd can manage the Suricata process when it is running in IPS mode.

      Save and close the file. If you are using nano, you can do so with CTRL+X, then Y and ENTER to confirm. If you are using vi, press ESC and then :x then ENTER to save and exit.

      Now reload systemd so that it detects the new Suricata settings:

      • sudo systemctl daemon-reload

      Now you can restart Suricata using systemctl:

      • sudo systemctl restart suricata.service

      Check Suricata’s status using systemctl:

      • sudo systemctl status suricata.service

      You should receive output like the following:

      Output

      ● suricata.service - Suricata IDS/IDP daemon Loaded: loaded (/lib/systemd/system/suricata.service; enabled; vendor preset: enabled) Drop-In: /etc/systemd/system/suricata.service.d └─override.conf Active: active (running) since Wed 2021-12-15 14:35:21 UTC; 38s ago Docs: man:suricata(8) man:suricatasc(8) https://suricata-ids.org/docs/ Main PID: 29890 (Suricata-Main) Tasks: 10 (limit: 2340) Memory: 54.9M CPU: 3.957s CGroup: /system.slice/suricata.service └─29890 /usr/bin/suricata -c /etc/suricata/suricata.yaml --pidfile /run/suricata.pid -q 0 -vvv . . . Dec 15 14:35:21 suricata suricata[29890]: 15/12/2021 -- 14:35:21 - <Notice> - all 4 packet processing threads, 4 management threads initialized, engine started

      Note the highlighted active (running) line that indicates Suricata restarted successfully.

      With this change you are now ready to send traffic to Suricata using the UFW firewall in the next step.

      Step 4 — Configuring UFW To Send Traffic to Suricata

      Now that you have configured Suricata to process traffic in IPS mode, the next step is to direct incoming packets to Suricata. If you followed the prerequisite tutorials for this series and are using an Ubuntu 20.04 system, you should have the Uncomplicated Firewall (UFW) installed and enabled by default.

      To add the required rules for Suricata to UFW, you will need to edit the firewall files in the /etc/ufw/before.rules and /etc/ufw/before6.rules directly.

      Open the first file using nano or your preferred editor:

      • sudo nano /etc/ufw/before.rules

      Near the beginning of the file, insert the following highlighted lines:

      /etc/ufw/before.rules

      . . .
      # Don't delete these required lines, otherwise there will be errors
      *filter
      :ufw-before-input - [0:0]
      :ufw-before-output - [0:0]
      :ufw-before-forward - [0:0]
      :ufw-not-local - [0:0]
      # End required lines
      
      ## Start Suricata NFQUEUE rules
      -I INPUT 1 -p tcp --dport 22 -j NFQUEUE --queue-bypass
      -I OUTPUT 1 -p tcp --sport 22 -j NFQUEUE --queue-bypass
      -I FORWARD -j NFQUEUE
      -I INPUT 2 -j NFQUEUE
      -I OUTPUT 2 -j NFQUEUE
      ## End Suricata NFQUEUE rules
      
      # allow all on loopback
      -A ufw-before-input -i lo -j ACCEPT
      -A ufw-before-output -o lo -j ACCEPT
      . . .
      

      Save and exit the file when you are done editing it. Now add the same lines to the same section in the /etc/ufw/before6.rules file.

      The first two INPUT and OUTPUT rules are used to bypass Suricata so that you can connect to your server using SSH, even when Suricata is not running. Without these rules, an incorrect or overly broad signature could block your SSH access. Additionally, if Suricata is stopped, all traffic will be sent to the NFQUEUE target and then dropped since Suricata is not running.

      The next FORWARD rule ensures that if your server is acting as a gateway for other systems, all that traffic will also go to Suricata for processing.

      The final two INPUT and OUTPUT rules send all remaining traffic that is not SSH traffic to Suricata for processing.

      Restart UFW to load the new rules:

      • sudo systemctl restart ufw.service

      Note: If you are using another firewall you will need to modify these rules to match the format your firewall expects.

      If you are using iptables, then you can insert these rules directly using the iptables and ip6tables commands. However, you will need to ensure that the rules are persistent across reboots with a tool like iptables-persistent.

      If you are using firewalld, then the following rules will direct traffic to Suricata:

      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j NFQUEUE --queue-bypass
      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1 -j NFQUEUE
      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 0 -p tcp --dport 22 -j NFQUEUE --queue-bypass
      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 1 -j NFQUEUE
      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -j NFQUEUE
      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter FORWARD 0 -j NFQUEUE
      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p tcp --sport 22 -j NFQUEUE --queue-bypass
      • sudo firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 1 -j NFQUEUE
      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter OUTPUT 0 -p tcp --sport 22 -j NFQUEUE --queue-bypass
      • sudo firewall-cmd --permanent --direct --add-rule ipv6 filter OUTPUT 1 -j NFQUEUE
      • sudo firewall-cmd --reload

      At this point in the tutorial you have Suricata configured to run in IPS mode, and your network traffic is being sent to Suricata by default. You will be able to restart your server at any time and your Suricata and firewall rules will be persistent.

      The last step in this tutorial is to verify Suricata is dropping traffic correctly.

      Step 5 — Testing Invalid Traffic

      Now that you have Suricata and your firewall configured to process network traffic, you can test whether Suricata will drop packets that match your custom and other included signatures.

      Recall signature sid:2100498 from the previous tutorial, which is modified in this example to drop matching packets:

      sid:2100498

      drop ip any any -> any any (msg:"GPL ATTACK_RESPONSE id check returned root"; content:"uid=0|28|root|29|"; classtype:bad-unknown; sid:2100498; rev:7; metadata:created_at 2010_09_23, updated_at 2010_09_23;)
      

      Find and edit the rule in your /etc/suricata/rules/suricata.rules file to use the drop action if you have the signature included there. Otherwise, add the rule to your /etc/suricata/rules/local.rules file.

      Send Suricata the SIGUSR2 signal to get it to reload its signatures:

      • sudo kill -usr2 $(pidof suricata)

      Now test the rule using curl:

      • curl --max-time 5 http://testmynids.org/uid/index.html

      You should receive an error stating that the request timed out, which indicates Suricata blocked the HTTP response:

      Output

      curl: (28) Operation timed out after 5000 milliseconds with 0 out of 39 bytes received

      You can confirm that Suricata dropped the HTTP response using jq to examine the eve.log file:

      • jq 'select(.alert .signature_id==2100498)' /var/log/suricata/eve.json

      You should receive output like the following:

      Output

      { . . . "community_id": "1:Z+RcUB32putNzIZ38V/kEzZbWmQ=", "alert": { "action": "blocked", "gid": 1, "signature_id": 2100498, "rev": 7, "signature": "GPL ATTACK_RESPONSE id check returned root", "category": "Potentially Bad Traffic", "severity": 2, "metadata": { "created_at": [ "2010_09_23" ], "updated_at": [ "2010_09_23" ] } }, "http": { "hostname": "testmynids.org", "url": "/uid/index.html", "http_user_agent": "curl/7.68.0", "http_content_type": "text/html", "http_method": "GET", "protocol": "HTTP/1.1", "status": 200, "length": 39 }, . . .

      The highlighted "action": "blocked" line confirms that the signature matched, and Suricata dropped or rejected the test HTTP request.

      Conclusion

      In this tutorial you configured Suricata to block suspicious network traffic using its built-in IPS mode. You also added custom signatures to examine and block SSH, HTTP, and TLS traffic on non-standard ports. To tie everything together, you also added firewall rules that direct traffic through Suricata for processing.

      Now that you have Suricata installed and configured in IPS mode, and can write your own signatures that either alert on or drop suspicious traffic, you can continue monitoring your servers and networks, and refining your signatures.

      Once you are satisfied with your Suricata signatures and configuration, you can continue with the last tutorial in this series, which will guide you through sending logs from Suricata to a Security and Information Event Management (SIEM) system built using the Elastic Stack.



      Source link

      How To Configure Suricata as an Intrusion Prevention System (IPS) on Ubuntu 20.04


      Introduction

      In this tutorial you will learn how to configure Suricata’s built-in Intrusion Prevention System (IPS) mode. By default Suricata is configured to run as an Intrusion Detection System (IDS), which only generates alerts and logs suspicious traffic. When you enable IPS mode, Suricata can actively drop suspicious network traffic in addition to generating alerts for further analysis.

      Before enabling IPS mode, it is important to check which signatures you have enabled, and their default actions. An incorrectly configured signature, or a signature that is overly broad may result in dropping legitimate traffic to your network, or even block you from accessing your servers over SSH and other management protocols.

      In the first part of this tutorial you will check the signatures that you have installed and enabled. You will also learn how to include your own signatures. Once you know which signatures you would like to use in IPS mode, you’ll convert their default action to drop or reject traffic. With your signatures in place, you’ll learn how to send network traffic through Suricata using the netfilter NFQUEUE iptables target, and then generate some invalid network traffic to ensure that Suricata drops it as expected.

      Prerequisites

      If you have been following this tutorial series then you should already have Suricata running on an Ubuntu 20.04 server.

      • If you still need to install Suricata then you can follow How To Install Suricata on Ubuntu 20.04

      • You should also have the ET Open Ruleset downloaded using the suricata-update command, and included in your Suricata signatures.

      • The jq command line JSON processing tool. If you do not have it installed from a previous tutorial, you can do so using the apt command:

        • sudo apt update
        • sudo apt install jq

      You may also have custom signatures that you would like to use from the previous Understanding Suricata Signatures tutorial.

      Step 1 — Including Custom Signatures

      The previous tutorials in this series explored how to install and configure Suricata, as well as how to understand signatures. If you would like to create and include your own rules then you need to edit Suricata’s /etc/suricata/suricata.yaml file to include a custom path to your signatures.

      First, let’s find your server’s public IPs so that you can use them in your custom signatures. To find your IPs you can use the ip command:

      You should receive output like the following:

      Output

      lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 203.0.113.0.5/20 10.20.0.5/16 2001:DB8::1/32 fe80::94ad:d4ff:fef9:cee0/64 eth1 UP 10.137.0.2/16 fe80::44a2:ebff:fe91:5187/64

      Your public IP address(es) will be similar to the highlighted 203.0.113.0.5 and 2001:DB8::1/32 IPs in the output.

      Now let’s create the following custom signature to scan for SSH traffic to non-SSH ports and include it in a file called /var/lib/suricata/rules/local.rules. Open the file with nano or your preferred editor:

      • sudo nano /var/lib/suricata/rules/local.rules

      Copy and paste the following signature:

      Invalid SSH Traffic Signature

      alert ssh any any -> 203.0.113.0.5 !22 (msg:"SSH TRAFFIC on non-SSH port"; flow:to_client, not_established; classtype: misc-attack; target: dest_ip; sid:1000000;)
      alert ssh any any -> 2001:DB8::1/32 !22 (msg:"SSH TRAFFIC on non-SSH port"; flow:to_client, not_established; classtype: misc-attack; target: dest_ip; sid:1000001;)
      

      Substitute your server’s public IP address in place of the 203.0.113.5 and 2001:DB8::1/32 addresses in the rule. If you are not using IPv6 then you can skip adding that signature in this and the following rules.

      You can continue adding custom signatures to this local.rules file depending on your network and applications. For example, if you wanted to alert about HTTP traffic to non-standard ports, you could use the following signatures:

      HTTP traffic on non-standard port signature

      alert http any any -> 203.0.113.0.5 !80 (msg:"HTTP REQUEST on non-HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000002;)
      alert http any any -> 2001:DB8::1/32 !80 (msg:"HTTP REQUEST on non-HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000003;)
      

      To add a signature that checks for TLS traffic to ports other than the default 443 for web servers, add the following:

      TLS traffic on non-standard port signature

      alert tls any any -> 203.0.113.0.5 !443 (msg:"TLS TRAFFIC on non-TLS HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000004;)
      alert tls any any -> 2001:DB8::1/32 !443 (msg:"TLS TRAFFIC on non-TLS HTTP port"; flow:to_client, not_established; classtype:misc-activity; sid:1000005;)
      

      When you are done adding signatures, save and close the file. If you are using nano, you can do so with CTRL+X, then Y and ENTER to confirm. If you are using vi, press ESC and then :x then ENTER to save and exit.

      Now that you have some custom signatures defined, edit Suricata’s /etc/suricata/suricata.yaml configuration file using nano or your preferred editor to include them:

      • sudo nano /etc/suricata/suricata.yaml

      Find the rule-files: portion of the configuration. If you are using nano use CTRL+_ and then enter the line number 1879. If you are using vi enter 1879gg to go to the line. The exact location in your file may be different, but you should be in the correct general region of the file.

      Edit the section and add the following highlighted - local.rules line:

      /etc/suricata/suricata.yaml

      . . .
      rule-files:
        - suricata.rules
        - local.rules
      . . .
      

      Save and exit the file. Be sure to validate Suricata’s configuration after adding your rules. To do so run the following command:

      • sudo suricata -T -c /etc/suricata/suricata.yaml -v

      The test can take some time depending on how many rules you have loaded in the default suricata.rules file. If you find the test takes too long, you can comment out the - suricata.rules line in the configuration by adding a # to the beginning of the line and then run your configuration test again. Be sure to remove the # comment if you plan to use the suricata.rules signature in your final running configuration.

      Once you are satisfied with the signatures that you have created or included using the suricata-update tool, you can proceed to the next step, where you’ll switch the default action for your signatures from alert or log to actively dropping traffic.

      Step 2 — Configuring Signature Actions

      Now that you have your custom signatures tested and working with Suricata, you can change the action to drop or reject. When Suricata is operating in IPS mode, these actions will actively block invalid traffic for any matching signature.

      These two actions are described in the previous tutorial in this series, Understanding Suricata Signatures. The choice of which action to use is up to you. A drop action will immediately discard a packet and any subsequent packets that belong to the network flow. A reject action will send both the client and server a reset packet if the traffic is TCP-based, and an ICMP error packet for any other protocol.

      Let’s use the custom rules from the previous section and convert them to use the drop action, since the traffic that they match is likely to be a network scan, or some other invalid connection.

      Open your /var/lib/suricata/rules/local.rules file using nano or your preferred editor and change the alert action at the beginning of each line in the file to drop:

      • sudo nano /var/lib/suricata/rules/local.rules

      /var/lib/suricata/rules/local.rules

      drop ssh any any -> 203.0.113.0.5 !22 (msg:"SSH TRAFFIC on non-SSH port"; classtype: misc-attack; target: dest_ip; sid:1000000;)
      drop ssh any any -> 2001:DB8::1/32 !22 (msg:"SSH TRAFFIC on non-SSH port"; classtype: misc-attack; target: dest_ip; sid:1000001;)
      . . .
      

      Repeat the step above for any signatures in /var/lib/suricata/rules/suricata.rules that you would like to convert to drop or reject mode.

      Note: If you ran suricata-update in the prerequisite tutorial, you may have more than 30,000 signatures included in your suricata.rules file.

      If you convert every signature to drop or reject you risk blocking legitimate access to your network or servers. Instead, leave the rules in suricata.rules for the time being, and add your custom signatures to local.rules. Suricata will continue to generate alerts for suspicious traffic that is described by the signatures in suricata.rules while it is running in IPS mode.

      After you have a few days or weeks of alerts collected, you can analyze them and choose the relevant signatures to convert to drop or reject based on their sid.

      Once you have all the signatures configured with the action that you would like them to take, the next step is to reconfigure and then restart Suricata in IPS mode.

      Step 3 — Enabling nfqueue Mode

      Suricata runs in IDS mode by default, which means it will not actively block network traffic. To switch to IPS mode, you’ll need to edit Suricata’s /etc/default/suricata configuration file.

      Open the file in nano or your preferred editor:

      • sudo nano /etc/default/suricata

      Find the LISTENMODE=af-packet line and comment it out by adding a # to the beginning of the line. Then add a new line LISTENMODE=nfqueue line that tells Suricata to run in IPS mode.

      Your file should have the following highlighted lines in it when you are done editing:

      /etc/default/suricata

      . . .
      # LISTENMODE=af-packet
      LISTENMODE=nfqueue
      . . .
      

      Save and close the file. Now you can restart Suricata using systemctl:

      • sudo systemctl restart suricata.service

      Check Suricata’s status using systemctl:

      • sudo systemctl status suricata.service

      You should receive output like the following:

      Output

      ● suricata.service - LSB: Next Generation IDS/IPS Loaded: loaded (/etc/init.d/suricata; generated) Active: active (running) since Wed 2021-12-01 15:54:28 UTC; 2s ago Docs: man:systemd-sysv-generator(8) Process: 1452 ExecStart=/etc/init.d/suricata start (code=exited, status=0/SUCCESS) Tasks: 12 (limit: 9513) Memory: 63.6M CGroup: /system.slice/suricata.service └─1472 /usr/bin/suricata -c /etc/suricata/suricata.yaml --pidfile /var/run/suricata.pid -q 0 -D -vvv Dec 01 15:54:28 suricata systemd[1]: Starting LSB: Next Generation IDS/IPS... Dec 01 15:54:28 suricata suricata[1452]: Starting suricata in IPS (nfqueue) mode... done. Dec 01 15:54:28 suricata systemd[1]: Started LSB: Next Generation IDS/IPS.

      Note the highlighted active (running) line that indicates Suricata restarted successfully. Also note the Starting suricata in IPS (nfqueue) mode... done. line, which confirms Suricata is now running in IPS mode.

      With this change you are now ready to send traffic to Suricata using the UFW firewall in the next step.

      Step 4 — Configuring UFW To Send Traffic to Suricata

      Now that you have configured Suricata to process traffic in IPS mode, the next step is to direct incoming packets to Suricata. If you followed the prerequisite tutorials for this series and are using an Ubuntu 20.04 system, you should have the Uncomplicated Firewall (UFW) installed and enabled.

      To add the required rules for Suricata to UFW, you will need to edit the firewall files in the /etc/ufw/before.rules (IPv4 rules) and /etc/ufw/before6.rules (IPv6) directly.

      Open the first file for IPv4 rules using nano or your preferred editor:

      • sudo nano /etc/ufw/before.rules

      Near the beginning of the file, insert the following highlighted lines:

      /etc/ufw/before.rules

      . . .
      # Don't delete these required lines, otherwise there will be errors
      *filter
      :ufw-before-input - [0:0]
      :ufw-before-output - [0:0]
      :ufw-before-forward - [0:0]
      :ufw-not-local - [0:0]
      # End required lines
      
      ## Start Suricata NFQUEUE rules
      -I INPUT 1 -p tcp --dport 22 -j NFQUEUE --queue-bypass
      -I OUTPUT 1 -p tcp --sport 22 -j NFQUEUE --queue-bypass
      -I FORWARD -j NFQUEUE
      -I INPUT 2 -j NFQUEUE
      -I OUTPUT 2 -j NFQUEUE
      ## End Suricata NFQUEUE rules
      
      # allow all on loopback
      -A ufw-before-input -i lo -j ACCEPT
      -A ufw-before-output -o lo -j ACCEPT
      . . .
      

      Save and exit the file when you are done editing it. Now add the same highlighted lines to the same section in the /etc/ufw/before6.rules file:

      • sudo nano /etc/ufw/before.rules

      Ensure that both files have the same contents. Save and exit the file when you are done editing it.

      The first two INPUT and OUTPUT rules are used to bypass Suricata so that you can connect to your server using SSH, even when Suricata is not running. Without these rules, an incorrect or overly broad signature could block your SSH access. Additionally, if Suricata is stopped, all traffic will be sent to the NFQUEUE target and then dropped since Suricata is not running.

      The next FORWARD rule ensures that if your server is acting as a gateway for other systems, all that traffic will also go to Suricata for processing.

      The final two INPUT and OUTPUT rules send all remaining traffic that is not SSH traffic to Suricata for processing.

      Restart UFW to load the new rules:

      • sudo systemctl restart ufw.service

      Note: If you are using another firewall you will need to modify these rules to match the format your firewall expects.

      If you are using iptables, then you can insert these rules directly using the iptables and ip6tables commands. However, you will need to ensure that the rules are persistent across reboots with a tool like iptables-persistent.

      If you are using firewalld, then the following rules will direct traffic to Suricata:

      • firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j NFQUEUE --queue-bypass
      • firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1 -j NFQUEUE
      • firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 0 -p tcp --dport 22 -j NFQUEUE --queue-bypass
      • firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 1 -j NFQUEUE
      • firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -j NFQUEUE
      • firewall-cmd --permanent --direct --add-rule ipv6 filter FORWARD 0 -j NFQUEUE
      • firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p tcp --sport 22 -j NFQUEUE --queue-bypass
      • firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 1 -j NFQUEUE
      • firewall-cmd --permanent --direct --add-rule ipv6 filter OUTPUT 0 -p tcp --sport 22 -j NFQUEUE --queue-bypass
      • firewall-cmd --permanent --direct --add-rule ipv6 filter OUTPUT 1 -j NFQUEUE

      At this point in the tutorial you have Suricata configured to run in IPS mode, and your network traffic is being sent to Suricata by default. You will be able to restart your server at any time and your Suricata and firewall rules will be persistent.

      The last step in this tutorial is to verify Suricata is dropping traffic correctly.

      Step 5 — Testing Invalid Traffic

      Now that you have Suricata and your firewall configured to process network traffic, you can test whether Suricata will drop packets that match your custom and other included signatures.

      Recall signature sid:2100498 from the previous tutorial, which is modified in this example to drop matching packets:

      sid:2100498

      drop ip any any -> any any (msg:"GPL ATTACK_RESPONSE id check returned root"; content:"uid=0|28|root|29|"; classtype:bad-unknown; sid:2100498; rev:7; metadata:created_at 2010_09_23, updated_at 2010_09_23;)
      

      Find and edit the rule in your /var/lib/suricata/rules/suricata.rules file to use the drop action if you have the signature included there. Otherwise, add the rule to your /var/lib/suricata/rules/local.rules file.

      Send Suricata the SIGUSR2 signal to get it to reload its signatures:

      • sudo kill -usr2 $(pidof suricata)

      Now test the rule using curl:

      • curl --max-time 5 http://testmynids.org/uid/index.html

      You should receive an error stating that the request timed out, which indicates Suricata blocked the HTTP response:

      Output

      curl: (28) Operation timed out after 5000 milliseconds with 0 out of 39 bytes received

      You can confirm that Suricata dropped the HTTP response using jq to examine the eve.log file:

      • jq 'select(.alert .signature_id==2100498)' /var/log/suricata/eve.json

      You should receive output like the following:

      Output

      { . . . "community_id": "1:tw19kjR2LeWacglA094gRfEEuDU=", "alert": { "action": "blocked", "gid": 1, "signature_id": 2100498, "rev": 7, "signature": "GPL ATTACK_RESPONSE id check returned root", "category": "Potentially Bad Traffic", "severity": 2, "metadata": { "created_at": [ "2010_09_23" ], "updated_at": [ "2010_09_23" ] } }, "http": { "hostname": "testmynids.org", "url": "/uid/index.html", "http_user_agent": "curl/7.68.0", "http_content_type": "text/html", "http_method": "GET", "protocol": "HTTP/1.1", "status": 200, "length": 39 }, . . .

      The highlighted "action": "blocked" line confirms that the signature matched, and Suricata dropped or rejected the test HTTP request.

      Conclusion

      In this tutorial you configured Suricata to block suspicious network traffic using its built-in IPS mode. You also added custom signatures to examine and block SSH, HTTP, and TLS traffic on non-standard ports. To tie everything together, you also added firewall rules to direct traffic through Suricata for processing.

      Now that you have Suricata installed and configured in IPS mode, and can write your own signatures that either alert on or drop suspicious traffic, you can continue monitoring your servers and networks, and refining your signatures.

      Once you are satisfied with your Suricata signatures and configuration, you can continue with the last tutorial in this series, which will guide you through sending logs from Suricata to a Security and Information Event Management (SIEM) system built using the Elastic Stack.



      Source link