Suricata
Overview
Suricata is a high-performance network threat detection engine. It reads frames off a network interface, reassembles the flows they belong to, evaluates them against a signature set, and writes alerts and rich protocol metadata to a JSON event log. It works as an intrusion detection system (IDS), as an intrusion prevention system (IPS) when placed inline, and as a network security monitor that records what happened on the wire even when nothing matched.
This SecureAnyCloud image ships Suricata 8.0.6 on Ubuntu 24.04 LTS, ready to inspect traffic from the first boot of every deployed virtual machine. Suricata is installed unmodified from the Suricata project's own apt repository, so the engine stays patchable through the normal apt path for the life of the release.
What you get:
- Suricata 8.0.6 on Ubuntu 24.04 LTS, installed unmodified from the Suricata project's apt repository
- An engine with no signature ruleset baked in: a first-boot service fetches a current ruleset onto your VM, and a daily timer keeps it current
- No credentials, no web interface and no network-listening management port
- An engine that refuses to start until it has been configured for your VM
- An image with no build-time traffic, event logs, rule files or packet captures
- Three deployment topologies: host sensor, inline network virtual appliance and offline analysis
What this sensor can and cannot see on Azure
Read this section before you deploy. It explains what the sensor can and cannot observe on Azure.
Suricata's core mechanism works exactly as designed on Azure. The engine inspects the packets it is given, and on an Azure virtual machine it is given this machine's traffic. This was verified during the build of this image, with a real signature firing on real traffic captured from the network interface.
What Azure changes is not the mechanism but the visibility scope. An Azure virtual network interface receives only the frames addressed to it. The software-defined network does not flood traffic to every host. There is no promiscuous mode that would let one machine observe a neighbor's traffic, and Azure Virtual Network TAP, which would have provided a packet mirror to subscribe to, never reached general availability. So this appliance cannot passively monitor a subnet the way a physical network tap or a switch SPAN port can. No configuration of this image, or any other Suricata image, changes that.
This image supports three deployment topologies:
- Host sensor (default). Sees this virtual machine's own inbound and outbound traffic. No configuration needed; it works on first boot.
- Inline network virtual appliance. Sees everything you route through this machine. Needs IP forwarding plus a user-defined route (see section 7).
- Offline analysis. Sees any packet capture you bring to it. No configuration needed (see section 6).
The default host sensor protects the machine it runs on. That suits a jump box, a bastion, a public-facing web server or any workload whose traffic you want a second opinion on. The inline topology is the way to cover other machines, and it is a first-class Azure pattern rather than a workaround.
What makes this image different
The image contains no signature ruleset. Most IDS images bake a ruleset in at build time, so the threat intelligence is already stale on the day you deploy. An IDS with stale rules reports healthy while missing everything published since the image was captured. This image ships the engine only. A first-boot service fetches a current ruleset onto your virtual machine directly from its provider, and a daily timer keeps it current for the life of the machine.
There are no credentials anywhere in this image, because the product has none. Suricata has no login, no web interface and no management port that listens on the network. It binds nothing. It is controlled locally through a root-owned unix socket and administered over SSH with the key you supplied at deployment. There is no default password to rotate and nothing to leak.
The engine refuses to start until it has been configured for your virtual machine. The shipped configuration is a template. The network it should treat as home and the interface it should watch are facts about your machine that cannot be known at build time. Two independent mechanisms enforce this, so the engine can never run on values left over from the build.
No traffic from the build survives. A carelessly captured network sensor leaks other people's traffic, not just its configuration. The build of this image is torn down before capture. The event log, every rule file, all rule update state and any packet capture are removed, and the configuration is restored to the template.
1. Deploy the virtual machine
In the Azure portal, search the Marketplace for Suricata on Ubuntu 24.04 LTS by SecureAnyCloud and select Create. Choose your subscription, resource group and region. Set the authentication type to SSH public key and the username to azureuser, then review and create.
To deploy from the Azure CLI instead, run:
az vm image terms accept --urn sac1647283583153:suricata-ubuntu-24-04:default:latest
az vm create \
--resource-group my-resource-group \
--name my-suricata-vm \
--image sac1647283583153:suricata-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardSuricata needs no inbound port of its own, so open nothing beyond SSH. The sensor listens on no network port at all.
Allow SSH from your own address only, never from the whole internet:
az vm open-port --resource-group my-resource-group --name my-suricata-vm \
--port 22 --source-address-prefixes "$(curl -s https://api.ipify.org)/32"2. Connect to the virtual machine
Connect over SSH as azureuser:
ssh azureuser@<vm-ip>3. Confirm the sensor is running
First boot configures the engine for your machine and fetches a current ruleset. On a Standard_B2s, this takes a minute or two. Confirm that it finished and the engine is live:
sudo systemctl is-active suricata
sudo systemctl is-active suricata-firstbootBoth commands report active. The engine is running with a configuration derived from your machine, not from the build.
Suricata is a passive sensor and binds no network port. Confirm that it has opened nothing:
sudo ss -lntup | awk '/suricata/' | wc -lThe command reports 0. The only management surface is a unix socket on the filesystem, readable by root alone.
The command uses awk rather than grep on purpose. grep exits non-zero when it finds no match, so under set -o pipefail the pipeline would report failure on the very result you want to see here, zero. awk prints the same count and exits cleanly.
Your machine's own facts, recorded at first boot, are in a plain-text note. It holds no secrets, because there are none:
sudo cat /root/suricata-instance.txt4. Confirm the ruleset is current
The ruleset was fetched onto this machine at first boot, not baked into the image. Ask the running engine what it actually loaded:
sudo suricatasc -c ruleset-statsThe output shows tens of thousands of rules loaded and zero failed. Count the rules on disk as well, and check when they arrived:
wc -l < /var/lib/suricata/rules/suricata.rules stat -c '%y' /var/lib/suricata/rules/suricata.rulesThe timestamp is the first boot of your machine. The threat intelligence is as fresh as your deployment, not as old as the image.
A timer refreshes the ruleset daily and reloads the engine without dropping it:
systemctl list-timers suricata-update.timer --no-pager5. Prove the sensor actually detects something
A service reporting active proves very little about an IDS. What matters is whether the whole chain works: capture off the interface, evaluation against the ruleset, and an alert written to the event log. Verify it end to end.
Ask the engine whether it is genuinely reading packets off the wire:
sudo suricatasc -c dump-counters | python3 -c 'import sys,json; print("packets captured:", json.load(sys.stdin)["message"]["capture"]["kernel_packets"])'A number greater than zero means the engine is reading live frames, not merely running.
Now trigger a real signature. The command below emits a single packet whose payload matches a well-known rule, the classic check for a command response that reveals a root shell. The packet is addressed to 192.0.2.1, an address reserved by RFC 5737 for documentation and examples, so it is never routed anywhere and nothing outside your machine is contacted. Suricata sees it on the way out:
python3 -c 'import socket; s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM); s.sendto(b"uid=0(root) gid=0(root) groups=0(root)\n", ("192.0.2.1", 9)); s.close()' sleep 8
sudo grep '"signature_id":2100498' /var/log/suricata/eve.json | tail -1 | python3 -m json.tool | head -20The output is a real alert record: the signature that matched, its severity and category, the addresses and ports involved, and a timestamp. The full pipeline is working on your machine.
Every alert, and a great deal of protocol metadata besides, is written to /var/log/suricata/eve.json as one JSON object per line. Follow the log live:
sudo tail -f /var/log/suricata/eve.json | python3 -c 'import sys,json for line in sys.stdin: e = json.loads(line) if e.get("event_type") == "alert": print(e["timestamp"], e["alert"]["signature"])'Press Ctrl+C to stop.
6. Analyze a packet capture offline
Suricata does not need live traffic. Point it at a capture taken anywhere, including from a machine that is not in Azure at all, and it evaluates the same ruleset against it. This is the fastest way to triage an incident.
sudo mkdir -p /tmp/offline
sudo timeout 20 tcpdump -i any -c 200 -w /tmp/offline/sample.pcap 2>/dev/null || true
sudo suricata -r /tmp/offline/sample.pcap -l /tmp/offline
sudo head -3 /tmp/offline/eve.jsonThe results land in /tmp/offline, entirely separate from the live sensor's own log.
7. Deploy inline to inspect other machines
This is the only way to see traffic that is not your own. You route a subnet's traffic through this virtual machine, which is a supported Azure pattern for a network virtual appliance.
The setup has three parts. First, allow the machine's network interface to forward traffic that is not addressed to it:
az network nic update --resource-group my-resource-group \
--name my-suricata-vmVMNic --ip-forwarding trueSecond, enable forwarding in the guest and make it persist across reboots:
sudo sysctl -w net.ipv4.ip_forward=1 echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-suricata-forward.confThird, create a route table that sends the protected subnet's traffic to this machine as the next hop, and associate it with that subnet:
az network route-table create --resource-group my-resource-group --name suricata-rt
az network route-table route create --resource-group my-resource-group \
--route-table-name suricata-rt --name via-suricata \
--address-prefix 0.0.0.0/0 --next-hop-type VirtualAppliance \
--next-hop-ip-address <suricata-private-ip>Traffic from that subnet now traverses this machine, and Suricata inspects it. Widen the home network to match what you are protecting. Edit vars.address-groups.HOME_NET in /etc/suricata/suricata.yaml, then reload:
sudo systemctl reload suricataSize the machine for the throughput you are routing. Standard_B2s is right for a host sensor. An inline appliance that carries a subnet's traffic needs more cores and accelerated networking.
To move from detection to prevention (IPS), route the forwarded traffic through NFQUEUE and run Suricata in inline mode. Switch only when detection behaves as you expect on your traffic, because in IPS mode a false positive drops real packets.
8. Scanning scope and authorization
Monitor only networks you own or are explicitly authorized to monitor. Traffic inspection captures the content of communications. In an inline deployment, it inspects the traffic of every machine whose route you have redirected. Make sure that this is intended, that you have authority over those machines, and that it is consistent with your obligations to the people whose traffic they carry. Alerts and metadata in /var/log/suricata/eve.json may themselves contain sensitive material and should be treated as such.
9. Security posture
The appliance ships with no credentials, because Suricata has none: there is no login, no web interface and no listening management port. Administration is over SSH with your own key.
The engine cannot start on build-time values. The configuration shipped in the image is a template holding values that the engine itself rejects. Two independent mechanisms enforce that your machine's facts replace them first. The service requires the first-boot unit to have succeeded. A preflight check re-runs on every start and refuses to launch if any template value survives, if the first-boot marker is missing, or if no ruleset is present. This prevents an IDS with no signatures from reporting healthy.
Confirm that nothing from the build survived onto your machine:
sudo test ! -e /usr/share/doc/sac/build-residue && echo "no build residue" stat -c '%y' /var/log/suricata/eve.jsonThe event log's timestamp is from your machine's first boot. The image contains no build-time alert history, no packet capture and no stale ruleset.
10. Logs and troubleshooting
The engine's own log is separate from the event log:
sudo tail -20 /var/log/suricata/suricata.logIf the engine does not start, the preflight check explains why in the journal:
sudo journalctl -u suricata -n 30 --no-pager sudo journalctl -u suricata-firstboot -n 30 --no-pagerThe most common cause is a first boot that could not reach the ruleset provider. First boot needs outbound HTTPS to fetch a current ruleset. A machine deployed with no outbound internet access reports that plainly rather than starting with no signatures.
Validate any configuration change before you apply it:
sudo suricata -T -c /etc/suricata/suricata.yaml11. License
Suricata is distributed under the GNU General Public License, version 2. The license as published by the Suricata project is on the image:
sudo head -20 /usr/share/doc/suricata/copyrightSecureAnyCloud installs Suricata unmodified from the Suricata project's own apt repository and has made no change to the program. That same repository publishes the complete corresponding source for the exact package installed here. A written offer for the source, valid for three years, ships on the image:
sudo cat /usr/share/doc/sac/SURICATA-GPL-2-WRITTEN-OFFER.txtSecureAnyCloud does not distribute the signature ruleset. Your machine fetches it at first boot directly from Emerging Threats, and it is covered by that provider's own license terms, which are published with the ruleset.
Support
For help with this image, contact sales@secureanycloud.com. For questions about Suricata itself, see the Suricata documentation.
Deploy on Azure
Launch Suricata on Ubuntu 24.04 LTS by SecureAnyCloud with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com