Skip to content

Illogical Behavior of AWS Firewall

0

Hello, I am pretty new in terms of managing AWS Firewall, though I'm not a total newbie in this field, as I have dealt with Azure Firewall, Cisco, Fortigate, etc. Nevertheless for the past few days I've been really struggling to get even a basic AWS Firewall setup to work. In my current approach I'm trying to use Suricata rules. Not my preferred choice, as I am not familiar with them, but apparently I need to use them to be able to deploy the infrastructure with Terraform (based on this: https://discuss.hashicorp.com/t/aws-network-firewall-policy-strict-order-on-a-rules-source-of-rules-source-list-domain-list/68019)

The current setup is as follows:

Stateful rule evaluation order and default actions Rule order: Strict order Default actions: Drop established

Stateful rule groups

  • Priority 2: AllowInteriaTraffic
  • Priority 3: AllowWpTraffic
  • Priority 4: DropAll

AllowInteriaTraffic

alert tcp $HOME_NET any -> $INTERIA $HTTP_PORTS (msg:"Interia HTTP traffic alert"; sid:1000001; rev:1;)

AllowWpTraffic

alert tcp $HOME_NET any -> $WP $HTTP_PORTS (msg:"WP HTTP traffic alert"; sid:1000001; rev:1;)

DropAll

drop icmp any any -> any any (msg:"ICMP Packet detected"; sid:1000002; rev:1;)
drop tcp any any -> any any (msg:"Default Drop"; sid:9999999; rev:1;)

What I would expect is that I can successfully test connectivity on port 443 to the IP addresses specified in the $INTERIA and $WP variabled, and everything else is dropped. But what happens is that everything gets dropped. CloudWatch logs show the following:

AWS Cloud Watch Logs

My understanding of firewalls is that when a rule is hit, and in the case of strict order the allow rules should be hit first, then other rules are not being evaluated. But in here it looks like both the allow rules and the explicit DropAll are evaluated. Is this normal or am I doing something wrong? I cannot abandon the DropAll, because from what I've learned, AWS does not have an implicit Deny rule (which I really can't understand). Please help me out. Thanks in advance. Wojtek

9 Answers
1

Based on your setup, there are a few issues that could be causing all traffic to be dropped:

  1. Rule Action Type: You're using alert in your allow rules instead of pass. The alert action only logs the traffic but doesn't actually allow it to pass through. For your allow rules to work properly, you should change them to use pass instead of alert.

  2. Flow Direction: Your rules don't specify the flow direction. Adding flow:to_server, established; to your allow rules can help ensure the traffic flow is properly identified.

  3. Rule Evaluation: In AWS Network Firewall with strict order evaluation, rules are processed in order of priority. However, the rules still need to have the correct action type to function as expected.

Here's how you could modify your allow rules:

pass tcp $HOME_NET any -> $INTERIA $HTTP_PORTS (msg:"Interia HTTP traffic allowed"; flow:to_server, established; sid:1000001; rev:1;)
pass tcp $HOME_NET any -> $WP $HTTP_PORTS (msg:"WP HTTP traffic allowed"; flow:to_server, established; sid:1000002; rev:1;)

Also, ensure that your variables ($INTERIA and $WP) are correctly defined with the IP addresses you want to allow.

The CloudWatch logs you're seeing indicate that the traffic is being evaluated against all rules because the alert action doesn't stop rule processing - it just logs the match but continues evaluating other rules, eventually hitting your drop rule.

Unlike some other firewall systems, AWS Network Firewall does require explicit deny rules at the end to block traffic that doesn't match any allow rules, which is why your DropAll rule group is necessary.
Sources
Domain and Port Filtering with Network Firewall | AWS re:Post
Issue with AWS Network Firewall - Suricata Rules Allowing Connections to Non-Whitelisted Public IPs | AWS re:Post
Examples of stateful rules for Network Firewall - AWS Network Firewall

answered a year ago

AWS
EXPERT

reviewed a year ago

0
Accepted Answer

My comment around only using 'alert' in your default actions was based on your statement of having configured just one rule from the sample rule group. I've just tested the sample rule group in my lab and it's working as expected (e.g. a curl request to https://www.cnn.com is blocked but a request to https://checkip.amazonaws.com is allowed) If you are using the sample rulegroup 'as is' with the settings you have mentioned, and it's still not blocking traffic to domains outside of example.com and *.amazon.com, then I would suggest you have a different problem occurring. Best guess is that you have asymmetric routing so the network firewall is not seeing all the traffic correctly. I would start with the steps in the troubleshooting guide here first: https://docs.aws.amazon.com/network-firewall/latest/developerguide/troubleshooting-general-issues.html On top of that, make sure you have logging configured so that you can examine the allowed traffic, which will help validate which rules it did/did not trigger.

AWS

answered a year ago

0

Just wanted to say thank you! I had another look at the setup and I did find an asymetric routing issue. After some adjustments I can confirm that the firewall is behaving as expected. Kind regards. Wojciech.

answered a year ago

  • Excellent. Glad you got it working! Appreciate you sharing feedback.

0

Never mind. That's me being stupid. Of course everything works after adding a pass rule... I feel dumb.

answered a year ago

0

OK, when I am operating within the IP address realm, everything works more or less as expected. Now I'm trying to configure access based on URLs. And this is where I'm struggling with, just as I have struggled with standard rule groups.

I have this rule:

alert tls $HOME_NET any -> any $HTTP_PORTS (msg:"HTTPS traffic to cnn.com"; tls.sni; content:".cnn.com"; nocase; sid:1000001; rev:1;)
pass tls $HOME_NET any -> any $HTTP_PORTS (msg:"HTTPS traffic to cnn.com"; tls.sni; content:".cnn.com"; nocase; sid:1000002; rev:1;)
alert http $HOME_NET any -> any $HTTP_PORTS (msg:"HTTP traffic to cnn.com"; http.host; content:".cnn.com"; sid:1000003; rev:1;)
pass http $HOME_NET any -> any $HTTP_PORTS (msg:"HTTP traffic to cnn.com"; http.host; content:".cnn.com"; sid:1000004; rev:1;

But when I do an Invoke-WebRequest I do not see any alerts and the traffic eventually reaches the last rule group, which is DenyAll. This happens for both HTTP and HTTPS. Any tips? Thanks. Wojtek

answered a year ago

0

I expect your issue is that you have two drop rules, the default rule action (drop established) and your rule below:

drop tcp any any -> any any (msg:"Default Drop"; sid:9999999; rev:1;)

Without seeing your new ruleset in full, I'm guessing that means that the TCP handshake is not allowed to complete hence the "pass tls" rules are never triggered because the connection does not get a chance to progress to the TLS connection phase. Try removing your additional drop rule above and re-testing. Also, as I don't see the use of the flow:to_server keyword in any of your rules, I would highly recommend reviewing the best practises outlined in the site below. https://aws.github.io/aws-security-services-best-practices/guides/network-firewall/

AWS

answered a year ago

0

Thanks for the feedback. Based on that, I decided to start from scratch and I have only implemented a single rule, the exact rule from the link you mentioned. With the only difference, I changed example.com to cnn.com. My expectation was that I will be able to access cnn.com only. But in reality, I can access all websites using Invoke-WebRequest. Do you might have an idea why? The firewall policy currently does not have any default actions for stateful rules specified. Thanks. Wojtek.

answered a year ago

0

Hello. Please see the screenshot below. I would have assumed that if there is a "-" in the Default Actions, it means there is nothing assigned.

Enter image description here

According to you, I cannot assign alert because it will not block unwanted domains. And according to the AWS article you mentioned, I cannot assign Deny because it conflicts with the Sucricata template.

The rule group config is below:

Enter image description here

Right now the Suricata rules are an exact 1:1 copy from the article. Didn't even change example.com. Still can access all URLs. Thank you. Wojtek

answered a year ago

0

The firewall policy currently does not have any default actions for stateful rules specified

By this do you mean the default stateful action is an "alert"? You cannot have no default action, there must be at least one of the "drop" or "alert" options set in the policy configuration. If it is set to alert, then that would be why access to other domains is still permitted (as you are not blocking anything by default). If not, please share your ruleset in full and confirm the policy settings. I will add that there are some edge cases that can cause issues with domain blocking but I would recommend opening up a support case to confirm the details on those.

AWS

answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.