Home

Awesome

Terraform Module for Suricata

This module sets up packet mirroring in a Google Cloud VPC and a collector instance behind an ILB, running Suricata IDS.

Architecture

Usage

See example directory for usage. This will setup a network, two subnets, packet mirroring and the Suricata instance, which collects packets from the other subnet.

module "suricata" {
  source  = "onetwopunch/suricata/google"

  project = var.project
  network = google_compute_network.ids.id
  subnet  = google_compute_subnetwork.ids.id
  zone    = "us-central1-a"
  target_subnets = [
    google_compute_subnetwork.test.id
  ]

  custom_rules_path = var.custom_rules_path
}

Testing

To test that packet mirroring and Suricata are working properly, we'll create a simple rules file that triggers an alert on an innocuous event such as a DNS query. These alerts were taken from the Qwiklab on this topic.

1. Prerequisites

First create a bucket, it doesn't matter the name, using gsutil mb $BUCKET.

The upload the file example/my.rules into the bucket using:

gsutil cp example/my.rules gs://$BUCKET

2. Terraform

Next, create a file called terraform.tfvars in the example directory. And copy this, replacing the placeholder values:

project = "MY_PROJECT_NAME"
custom_rules_path = "gs://MY_BUCKET_NAME/my.rules"

Now run terraform apply.

3. Testing Suricata

To verify packet mirroring and Suricata is working properly, let's open one terminal and SSH into the test instance we created. The command should look similar to this, assuming your project has been set by gcloud config set project ...:

gcloud compute ssh test --zone us-central1-a --tunnel-through-iap

Now in a new terminal, let's SSH into our Suricata collector instance.

gcloud compute instances list | grep suricata
# This should output the name of the instance
gcloud compute ssh SURICATA_INSTANCE_NAME --zone us-central1-a --tunnel-through-iap

Once in your Suricata instance, you first should tail the fast.log. We'll see an alert here in a moment.

# Suricata Instance
tail -f /var/log/suricata/fast.log

Now back in your test instance, let's make a DNS request:

# Test instance
sudo apt install dnsutils
dig @8.8.8.8 example.com

In your Suricata terminal (in your fast.log) you should see the alert show up immediately, something like this:

03/22/2021-21:05:17.558245  [**] [1:99996:1] BAD UDP DNS REQUEST [**] [Classification: (null)] [Priority: 3] {UDP} 172.21.1.3:55787 -> 8.8.8.8:53

Now that you verified that packet mirroring and Suricata are working correctly, you can verify the connection to Cloud Logging is setup by going to the Cloud Logging Logs viewer in the GCP console, and running the following query:

logName:"logs/suricata.fast"

You should have at least one entry. Now you have your Suricata alerts in Cloud Logging so you can eventually make alerts using Cloud Monitoring and get pestered by Pagerduty or whatever, when Suricata thinks you're being attacked!

Providers

NameVersion
googlen/a

Inputs

NameDescriptionTypeDefaultRequired
base_priorityTo make the IDS work with packet mirroring, we need to allow all ports access. However, we still don't want to allow SSH from anyhere.<br>To solve this, we have 3 firewall rules with increasing priority. The first allows all access, the second denies SSH, the third allows<br>SSH only from the IAP range. This value is the base priority, which is incremented for each rule.number1000no
custom_rules_pathGCS bucket path for Suricata .rules file. i.e gs://my-bucket/my.rulesstring""no
enable_eve_exportIf true, logs from /var/log/suricata/eve.json will be parsed and sent to Cloud Logging. Note that these are much more chatty and include stats and traffic.boolfalseno
enable_fast_exportIf true, logs from /var/log/suricata/fast.log will be parsed and sent to Cloud Logging. These only include alerts.booltrueno
filterFilter configuration for packet mirroring<pre>object({<br> ip_protocols = list(string)<br> cidr_ranges = list(string)<br> direction = string<br> })<br></pre><pre>{<br> "cidr_ranges": [<br> "0.0.0.0/0"<br> ],<br> "direction": "BOTH",<br> "ip_protocols": [<br> "tcp",<br> "udp",<br> "icmp"<br> ]<br>}<br></pre>no
networkSelf link of the network on which Suricata will be deployed and will monitorstringn/ayes
prefixPrefix of all resource namesstring"suricata"no
projectProject Id for the resourcesstringn/ayes
regionRegion for Suricata. Must match the zone of the subnetstring"us-central1"no
subnetSelf link of the subnet on which Suricata will be deployedstringn/ayes
suricata_config_pathA file path to a suricata.yaml file that you would like to override the default.string""no
target_instancesTarget instances that will be mirroredlist(string)[]no
target_subnetsTarget subnets that will be mirroredlist(string)[]no
target_tagsTarget tags that will be mirroredlist(string)<pre>[<br> "use-suricata"<br>]<br></pre>no
zoneZone for Suricata. Must match the zone of the subnetstring"us-central1-a"no

Outputs

No output.