Restrict Outbound Traffic with Terraform and Sentinel
Engineers configuring security groups and firewalls tend to focus on inbound/ingress rules to restrict the networks from which requests to their applications can originate. A common best practice has long been to prevent the use of the 0.0.0.0/0 CIDR — and aliases for it — that would allow inbound access from any IP.
However, the recent 2020 United States federal government data breach reminded me that it is also important to restrict outbound access. After all, the code originally loaded by supply chain attacks against SolarWinds and Microsoft software could not have sent any information to the Russian intelligence agencies behind the hacks and could not have downloaded and installed additional malware unless the federal security groups and firewalls allowed arbitrary outbound access.
Properly configured security groups and firewalls block outbound access to the 0.0.0.0/0 CIDR in the same way that they block inbound access to it.
At this point, I want to confess that I have also been negligent in this area. As a field expert in the use of HashiCorp’s policy as code solution, Sentinel, I have written many example Sentinel policies including some that restrict inbound access in security groups and firewalls created by Terraform in AWS, Azure, and GCP. But I had not previously created policies that restricted outbound access.
I rectified that today by writing 3 new Sentinel policies that do prevent security groups and firewalls from using 0.0.0.0/0 in outbound/egress rules.
How to Restrict Inbound/Ingress Access
I’ll describe my new outbound/egress rules in more detail below, but I would first like to mention the 3 existing policies that restricted inbound/ingress rules:
- restrict-ingress-sg-rule-cidr-blocks.sentinel prevents use of 0.0.0.0/0 in ingress rules of AWS security groups.
- restrict-inbound-source-address-prefixes.sentinel prevents use of 0.0.0.0/0, “*”, and “Internet” in Inbound rules of Azure network security groups.
- restrict-ingress-firewall-source-ranges.sentinel prevents use of 0.0.0.0/0 in GCP ingress compute firewalls.
How to Restrict Outbound/Egress Access
It was quite easy for me to create the 3 new Sentinel policies that restrict outbound access from the 3 policies listed above.
For AWS, I wrote restrict-egress-sg-rule-cidr-blocks.sentinel by changing the type
of security group rules from ingress
to egress
and examined egress
blocks of security groups instead of their ingress
blocks. I also changed the names of various variables to use “Egress” instead of “Ingress”.
For Azure, I wrote restrict-outbound-destination-address-prefixes.sentinel by changing the direction
of network security rules from Inbound
to Outbound
and checking the destination_address_prefix
and destination_address_prefixes
attributes of network security groups and network security rules instead of their source_address_prefix
and source_address_prefixes
attributes. I also changed the names of various variables to use “Outbound” instead of “Inbound”.
For GCP, I wrote restrict-egress-firewall-destination-ranges.sentinel by changing the direction
of compute firewalls from INGRESS
to EGRESS
and checking their destination_ranges
attribute instead of their source_ranges
attribute. I also renamed the ingressFirewalls
variable to egressFirewalls
.
I was able to write and test all 3 of the new policies as well as new test cases and mock files for them in 90 minutes. I copied the test cases and mock files from the original policies and then edited the mock files by hand to convert inbound/ingress rules to outbound/egress rules. I tested the new policies with the test command of the Sentinel CLI.
Potential Inconveniences
Restricting outbound security group and firewall rules can be inconvenient. For example, if you are downloading software with tools like curl
and wget
, this will only be allowed from specific networks. That means you can no longer simply clone a public GitHub repository. After all, if you allowed outbound access to GitHub, you would be allowing cloning from all public repositories, not just the ones you want! Instead, you need to copy the code from desired public repositories into a private registry on a controlled network to which your security group or firewall rules allow egress.
But any inconvenience for the developers of applications is worth the extra security derived from restricting outbound access to the entire internet.