I recently hit an issue with OCI Network Firewall that we had configured with NAT GW (see previous posts on it). We expected only to use it for egress traffic from OCI to public internet from our private compute VMs but a new requirement came which required to access some privately exposed services on OCI, and traffic would still need to flow through firewall.
I was reading documentation for OCI Network Firewall and like I mentioned in the previous posts, compared to networking documentation in general, this feels quite high level in many cases still today. (May 2024)
Before diving deeper, just want to acknowledge the help I got from Oracle’s side on bouncing ideas and confirming this is viable solution, Oracle’s very own Raffi Shahbazian provided really good insight on this and I can’t thank him enough on helping with this!
The Problem
Obvious challenge with having NAT GW with private OCI Network Firewall is that you can’t route traffic from public internet towards your private network. With some of the self managed 3rd party firewall you typically setup the firewall with multiple interfaces untrust/trust etc. and that way you can do NAT through the interface if needed.
What possible options we would have in this case?
Bouncing ideas
One option I tested was changing the OCI Network Firewall to a public subnet with internet gateway. Challenge with that is that I can’t route private traffic anymore through firewall even towards public internet, firewall won’t know how to route traffic from it’s public interface to my private VM. Checking logs I can see traffic arriving up to firewall from private VM, but that’s where it stops.
Solution
Thinking on solution I was playing with an idea if it would be possible to have another VCN with a public load balancer, would public load balancer know how to route traffic to private backend like it does without a firewall? Outgoing traffic from my VM would still flow through NAT GW.
It wouldn’t be ideal solution as I would expose the Load Balancer to public but could optionally always configure further rules and Web Application Firewall for the Load Balancer.
This seemed to be the solution! Even though my Load Balancer is public, it will have a private IP associated so it will know where to route traffic towards to a private backend. For testing I would need to add new my-lb-vcn (10.0.3.0/24) VCN with a single public subnet and a Load Balancer. Traffic would be routed with following additions in my-lb-vcn:
- 0.0.0.0/0 towards IGW
- 10.0.1.0/24 towards DRG (my-another-vcn CIDR)
- 10.0.200.0/24 towards DRG (my-firewall-vcn CIDR)
- my-lb-vcn DRG attachment route table two rules with above CIDR blocks towards my-firewall-vcn
I would need to add route rule in my-firewall-vcn
- 10.0.3.0/24 towards DRG
I wouldn’t need to add any new routes in my-another-vcn route table, why?
It’s because I already have quad-zero rule going towards DRG, so all traffic gets send out to DRG attachment which handles the routing.
For my-firewall-vcn DRG VCN attachment I need to add route rule towards my-lb-vcn attachment that once traffic leaves from firewall and if it’s destined towards public LB VCN CIDR (private), it knows where to go.
Routing and setup becomes slightly more complex but it’s still very logical in my opinion if we just think on the initial design. Now after we’ve sorted out the new design, let’s test it!
Testing connectivity
After adding VCN, routes and necessary gateways I still have some tasks which I’ve completed:
- Provision a public LB (IP 192.18.158.84) and listener on port 80
- Add LB backend 10.0.1.238 port 80 which has Apache web server running
- Allow port 80 traffic in security lists for LB and Apache Web server Compute VM
- Clone the existing Network Firewall policy and add new source CIDR block 10.0.3.0/24 (LB subnet) and target Compute VM 10.0.1.238
- Attach new policy to OCI Network Firewall
I can see port 80 is active on my 10.0.1.238 server as below.
[opc@server1 ~]$ curl localhost
This is my Apache Webserver 1 in Oracle Cloud Infrastructure
After applying the rule, I can see I get the public LB showing up the backend http page accordingly. Great success!
I still want to validate that I’m hitting the right rule in the load balancer and any other details I can see from the OCI Network Firewall traffic logs.
{
"datetime": 1716163866000,
"logContent": {
"data": {
"action": "allow",
"dport": "80",
"dst": "10.0.1.238",
"dstloc": "10.0.0.0-10.255.255.255",
"rule": "allow-http-traffic-from-lb",
"src": "10.0.3.114",
"srcloc": "10.0.0.0-10.255.255.255",
"regionId": "ca-toronto-1"
}
I’ve taken other data out but most important rows above, you can see traffic is allowed, destination port 80, destination my compute VM and source is 10.0.3.114 which is private IP of my public load balancer.
It also shows that rule allow-http-traffic-from-lb is being used.
This time I allowed the whole 10.0.3.0/24 subnet range, in reality you might have smaller CIDR allocation for your load balancer subnet and might track down the exact IPs LB is using (remember HA with failover etc.)
Summary
This was a really fun activity to troubleshoot real world problem which came up recently! Even though OCI Network Firewall doesn’t have all the capabilities you might have with managed firewall, you have ways to solve some of the problems that come in front of you when you think those through.
I’d pay extra attention on security if you want to use similar solution than this. What rules you allow in the firewall, how you configure your OCI security lists and/or network security groups and how do you configure WAF for Load Balancer.
This concludes my series on OCI Network Firewall, leave some comment and or feedback if you found this useful!