Suricata as IPS and NAT Instance in AWS

I’ve been trying to build a POC of suricata in an AWS environment to act as an IPS for instances in a private subnet. AWS Network Firewall and NAT gateway are very expensive as services so I wanted to try and build in manually as a POC.

I’d like to do this on Rocky 8 or 9.

AF_PACKET IPS mode

Does AF Packet Mode with IPS effectively act as both a firewall and NAT instance? I have been able to set this up and can get suricata to log traffic on the “LAN” side of the private subnet, but I can’t get traffic to flow OUT to the internet on the “WAN” side of the public subnet.

I’ve done the normal source/destination check disable. Can configure the linux instnace as a tradtional NAT instance just fine. Would like to get suricata “in line” to monitor traffice and buiild rules to block/allow.

Any reccomendations on how to achieve this?

I would first read the docs on AF_PACKET IPS at 15. Setting up IPS/inline for Linux — Suricata 8.0.0-dev documentation and there will be no NAT being done by Suricata itself. It’s purely passing the packets from one interface to the other after the inspection.

If you want to do that logic you would have to do that in netfilter for example and go with that IPS part: 15. Setting up IPS/inline for Linux — Suricata 8.0.0-dev documentation

Thank you for the clarification. I got my setup working with NFQUEUE now.

Trying to figure out how to setup a DENY ALL system that whitelists particular URLS. These are my rules but I still can’t curl example.com


# Pass HTTP traffic to example.com

pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".example.com"; endswith; msg:"Pass HTTP to .example.com"; sid:998; rev:1;)

# Pass TLS traffic to example.com

pass tls $HOME_NET any -> $EXTERNAL_NET 443 (tls.sni; dotprefix; content:".example.com"; endswith; msg:"Pass TLS to .example.com"; sid:999; rev:1;)

# Drop all other traffic

drop ip any any -> any any (msg:"Drop all other traffic"; sid:20000; rev:1;)

Was able to achieve want I wanted with these rules

#Example Domains
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".example.com"; endswith; msg:"Pass HTTP to .example.com"; sid:1001; rev:1;)
pass tls $HOME_NET any -> $EXTERNAL_NET 443 (tls.sni; dotprefix; content:".example.com"; endswith; msg:"Pass TLS to .example.com"; sid:1002; rev:1;)

# Drop other traffic
drop tcp $HOME_NET any -> $EXTERNAL_NET ![80,443] (msg:"Drop any TCP traffic not on port 80/443"; sid:2001; rev:1;)
drop tcp $HOME_NET any -> $EXTERNAL_NET [80,443] (msg:"Drop any non-HTTP/TLS traffic on TCP 80/443"; flow:established; sid:2002; rev:1;)
drop ip $HOME_NET any <> $EXTERNAL_NET any (msg:"Drop all other non-TCP traffic"; ip_proto:!TCP; sid:2003; rev:1;)

Thanks for the info in this article