Network Security Controls: SGs, NACLs, Network Firewall, and Egress
Network security in a VPC is a layered system, not a single control: security groups give you stateful, identity-like micro-segmentation at the ENI; network ACLs give you stateless, subnet-level guardrails and the only explicit deny at that layer; AWS Network Firewall adds deep packet inspection and domain-based egress filtering; and Route 53 Resolver DNS Firewall polices what your workloads can even resolve. Task 3.3 tests whether you can pick the right layer for a requirement, compose them into a defense-in-depth design — segmented and isolated subnets, VPC endpoints with restrictive endpoint policies, centralized inspection through Transit Gateway, encrypted hybrid links and VPN-less application access with AWS Verified Access — and then troubleshoot the result when legitimate traffic breaks or traffic silently bypasses inspection. This lesson works through each control layer, the egress-control and data-perimeter patterns, how to find unnecessary network access with Network Access Analyzer and Amazon Inspector network reachability findings, and the evidence-driven diagnostic method — Flow Logs from both ends, firewall logs and route-table tracing — that separates a Specialty candidate from an Associate one.
On this page12 sections
- Security groups and NACLs: the security reading
- Segmentation: subnet tiers, route tables, and traffic direction
- VPC endpoints and endpoint policies: private access with a perimeter
- AWS Network Firewall: deployment models and rule groups
- Network Firewall rule evaluation: action order, default actions, HOME_NET and logging
- Egress control: stopping exfiltration to arbitrary hosts
- Choosing the control layer
- Hybrid connectivity: encrypting Direct Connect and VPN links
- AWS Verified Access: per-request access for hybrid users
- Transit Gateway security and the centralized inspection walkthrough
- Identifying unnecessary network access: Network Access Analyzer and Inspector
- Troubleshooting: blocked traffic and bypassed inspection
- Design layered VPC controls using security groups for micro-segmentation and NACLs for subnet-level guardrails, explicit denies and ordered exceptions.
- Keep service traffic private with gateway and interface VPC endpoints, constrain it with endpoint policies, and choose between aws:ResourceOrgID, aws:PrincipalOrgID and aws:SourceVpce.
- Deploy AWS Network Firewall with correct route steering (including inbound edge routing), and predict how action order, default actions, domain lists and HOME_NET decide what is blocked.
- Build egress control that blocks exfiltration to arbitrary hosts by combining Network Firewall with Route 53 Resolver DNS Firewall, knowing what each one can and cannot see.
- Segment inter-VPC traffic with Transit Gateway route tables, steer east-west flows through an inspection VPC with appliance mode, and know the limits of security group referencing.
- Encrypt hybrid connectivity with MACsec or IPsec (including private IP VPN over Direct Connect), and replace user VPNs with AWS Verified Access trust providers and Cedar policies.
- Identify unnecessary network access with Network Access Analyzer scopes and Amazon Inspector network reachability findings, and troubleshoot blocked or uninspected traffic from Flow Logs and firewall logs.
Security groups and NACLs: the security reading
You already know the mechanics; the exam tests the security design reading. A security group is stateful: return traffic for an allowed connection is permitted automatically, rules are allow-only, and every rule is evaluated. Its killer security feature is referencing other security groups as sources. A rule on the database tier allowing port 3306 from the app tier's security group is effectively identity-based micro-segmentation: membership in the source group is the credential, and the rule survives Auto Scaling, IP churn, and subnet redesigns that would break any CIDR-based rule — and, unlike a subnet CIDR, it excludes other workloads that share those subnets. Least privilege here means one rule per required flow, SG references instead of CIDRs wherever the source is inside AWS, and no default-open outbound where egress matters.
A reference matches the security group of the ENI that opens the connection, so anything that terminates and re-originates traffic changes what the rule must name. Behind an Application Load Balancer, the targets must allow the load balancer's security group, not the clients' group: the ALB opens new connections to the targets from its own interfaces (the original client appears only in headers such as X-Forwarded-For, which security groups never read). A Network Load Balancer with a security group works the same way for the rule — targets reference the NLB's group — even when client IP preservation makes the client's address the visible source. Across VPCs, a transit gateway can carry security group references too: enable security group referencing on the transit gateway and on the VPC attachments, and it then works for inbound rules only, between VPCs on the same transit gateway. It does not survive a middlebox: once traffic is routed through an inspection VPC with Network Firewall or a Gateway Load Balancer, the referenced group no longer matches, so you fall back to CIDR rules for the source subnets (the firewall preserves the original source addresses).
A network ACL is stateless and evaluated at the subnet boundary as an ordered, numbered rule list — the lowest-numbered matching rule wins and evaluation stops. Statelessness means you must explicitly allow return traffic, which in practice means allowing the ephemeral port range (for Linux clients typically 32768–60999; NACL rules commonly open 1024–65535) in the reverse direction. Rules match the destination port, so think about which side opened the connection: a subnet whose instances call out needs an inbound allow for the ephemeral range (the replies come back to the client port, never to 443); a subnet whose instances serve requests needs an outbound allow for the ephemeral range, scoped to the callers' CIDR where you can.
That cost buys you two things security groups cannot do: an explicit deny and a subnet-wide blast radius. NACLs are the coarse guardrail layer: deny a known-malicious CIDR across an entire subnet, enforce that an isolated subnet never talks to the internet regardless of what any instance's SG says, or act as an incident-response kill switch — a low-numbered deny rule cuts an attacker off mid-session, whereas removing an SG rule only prevents new connections because existing tracked flows can persist. Because first match wins, an exception to a range-wide deny must carry a lower rule number than the deny and must match the packets you actually receive. The exception names only the address that must stay reachable, uses the ports the arriving packets are actually addressed to — for replies to connections your instances opened, that is your ephemeral range, not the service port — and takes a smaller rule number than the range-wide deny; numbered above it, it is never reached.
Defense in depth uses both: SGs express intended flows tightly; NACLs enforce what must never happen at the subnet tier.
Segmentation: subnet tiers, route tables, and traffic direction
Segmentation in a VPC is built from subnets and route tables, because a subnet's route table decides what its workloads can even attempt to reach. The three-tier reference design: a public tier (route to an internet gateway) holding only load balancers and NAT gateways; a private tier (default route to a NAT gateway, no inbound path from the internet) holding application compute; and an isolated tier (no route to an internet gateway, NAT gateway or egress-only internet gateway at all) holding databases and other crown-jewel data stores, which reach AWS services only through VPC endpoints. Each tier gets its own route table — sharing one route table across tiers is how a database subnet quietly inherits a NAT route it should never have.
In a dual-stack VPC, check both address families. An egress-only internet gateway blocks unsolicited inbound IPv6, but it is still an outbound internet path: an isolated subnet must have no ::/0 route either, just as it has no 0.0.0.0/0 route to a NAT or internet gateway. What it keeps is the local route plus endpoint routes — for S3 and DynamoDB, the gateway endpoint's prefix-list route.
Isolated subnets fail in a predictable way: a workload needs a service you forgot to give an endpoint. Container workloads are the classic case. Pulling an image from Amazon ECR needs the ecr.api interface endpoint (authentication and API calls), the ecr.dkr interface endpoint (registry and manifests), and an S3 gateway endpoint, because ECR serves image layers from Amazon S3, so all three are needed for a pull to complete. Tasks that ship logs with the awslogs driver also need the CloudWatch Logs interface endpoint, and tasks that read secrets need the Secrets Manager or Systems Manager endpoint. Interface endpoints need private DNS enabled and a security group that allows HTTPS from the workloads.
The guide's language of north/south versus east/west maps directly onto this: north/south is traffic crossing the perimeter (internet or hybrid), controlled by edge services, NAT placement, and egress firewalls; east/west is lateral traffic between tiers, VPCs, or accounts, controlled by SG references, NACLs, and Transit Gateway route-table segmentation. Attackers who land on an app instance pivot east-west, so a design that only hardens the perimeter is incomplete at Specialty level. Once a design is built, prove it with the tools covered in Identifying unnecessary network access below.
VPC endpoints and endpoint policies: private access with a perimeter
VPC endpoints are a security control, not just a networking convenience: they keep service traffic on the AWS network so an isolated subnet can use S3 or KMS with no internet path at all. Know both flavors. A gateway endpoint (S3 and DynamoDB only) is a route-table entry targeting a managed prefix list — no hourly or data charge, highly available, but usable only from within that VPC. An interface endpoint (most other services, including KMS, powered by AWS PrivateLink) is an ENI with a private IP in your subnet; you attach security groups to it, enable private DNS so the service's normal hostname resolves to the private IP, and it is reachable over peering, VPN, or Direct Connect — which is why a centralized shared-endpoints VPC is a common design pattern. S3 supports both types: an S3 interface endpoint with private DNS turned off is reachable only through its endpoint-specific DNS names, so code using the default S3 hostname still resolves public addresses — which an isolated subnet cannot reach. Use a gateway endpoint, or enable private DNS, when clients use default hostnames.
The Specialty differentiator is the endpoint policy: a resource policy attached to the endpoint that constrains what the endpoint can be used for, whatever credentials the caller presents. This is the data-perimeter angle. An S3 gateway endpoint policy can allow access only to your approved bucket ARNs, so a compromised instance cannot push data to an attacker-owned bucket through your own endpoint. Three condition keys are easy to confuse, because each protects a different side:
| Condition key | Where you put it | What it limits | What it does not stop |
|---|---|---|---|
aws:ResourceOrgID | Endpoint policy | Which resources the endpoint can reach — only those owned by accounts in your organization | Nothing on the exfiltration path through this endpoint: a bucket outside the organization is denied whether the caller uses the instance role or keys from another account |
aws:PrincipalOrgID | Endpoint policy (or resource policies) | Who may use the endpoint — only principals from your organization | A trusted role in your organization writing to a bucket outside it |
aws:SourceVpce / aws:SourceVpc | Bucket policy on your buckets | Your buckets accept requests only through your endpoint or VPC | Anything sent to buckets you do not own — it protects your data from outside access, not your network from exfiltration |
Together, endpoint policies with org-level conditions and bucket policies with aws:SourceVpce keep trusted identities talking to trusted resources over trusted networks; when a legitimate third-party bucket is needed, it has to be added as an explicit exception.
PrivateLink also solves private service exposure: publish your service behind a Network Load Balancer as an endpoint service, and consumer VPCs — in any account, inside or outside your organization — connect via interface endpoints with no peering, no route exchange, and no CIDR-overlap concerns; consumers see one ENI, not your network. The provider controls exposure with two settings on the endpoint service: allowed principals (which accounts, roles or users may create interface endpoints to it at all) and acceptance required (each new endpoint connection stays pending until the provider accepts it, so no traffic flows before review). Endpoint policies are a consumer-side control on the interface endpoint, not something the provider sets on the service, and a verified private DNS name for the service is only a naming convenience — it grants or restricts nothing.
AWS Network Firewall: deployment models and rule groups
AWS Network Firewall is the managed layer 3–7 inspection engine for traffic SGs and NACLs cannot understand. It deploys as firewall endpoints in dedicated firewall subnets (one per AZ), and it inspects only what routing sends through it — route steering is the deployment. Creating the firewall and attaching a policy changes nothing until route tables point at the endpoints. In the distributed model, each VPC gets its own firewall, and every Availability Zone needs the same routes pointing at its own zone's endpoint:
- Outbound through a NAT gateway: workload subnets route
0.0.0.0/0to the same-zone firewall endpoint; the firewall subnet routes0.0.0.0/0to the NAT gateway; and the NAT gateway's subnet routes the workload CIDRs back to the same firewall endpoint, so replies are inspected on the way in too. - Inbound from the internet (for example to an internet-facing ALB): the protected subnet routes
0.0.0.0/0to its firewall endpoint, the firewall subnet routes to the internet gateway, and an internet gateway edge-associated (ingress) route table sends each protected subnet's CIDR to the same-zone firewall endpoint. Gateway route tables accept only the VPC CIDR or subnet CIDRs as destinations — never0.0.0.0/0. Without the edge routes, inbound packets follow the local route straight to the target while replies go through the firewall; the stateful engine sees only half the flow and drops it, so connections time out.
In the centralized model, a dedicated inspection VPC attached to a Transit Gateway inspects traffic for the whole organization — covered in the Transit Gateway section below.
Two properties matter for every design that inserts the firewall into an existing path. Firewall endpoints have no security groups of their own, and the firewall does not change the source or destination address of inspected traffic. Downstream security group and NACL rules therefore keep seeing the original client addresses — after inspection is inserted, rules must match the clients' CIDRs, not anything that belongs to the firewall.
Rules come in two engines. Stateless rule groups match 5-tuples with actions pass, drop, or forward to stateful — fast, no context, analogous to NACLs. Stateful rule groups are Suricata-compatible: they track connections and can match on protocol semantics, including the TLS SNI and HTTP Host header, which is what enables domain list rules — an allow list ("walled garden": permit .amazonaws.com and your approved SaaS domains) or a deny list of known-bad domains, applied to HTTP/HTTPS egress without decrypting traffic and without tracking IP addresses, which is why they suit SaaS destinations whose IPs change. TLS inspection (decryption) is a separate configuration, needed only when you must see inside the encrypted payload. You can also write raw Suricata rules for IPS-style signatures and use AWS managed rule groups for threat intelligence; how the engine orders and defaults these rules is the next section.
Managing firewall policies across many accounts is AWS Firewall Manager's job — know it as the central deployment answer.
Network Firewall rule evaluation: action order, default actions, HOME_NET and logging
Whether a Network Firewall policy blocks what you intend depends on four settings that sit outside the rules themselves: the rule evaluation order, the stateful default action, the HOME_NET variable, and what gets logged.
Default action order versus strict order. In default action order, the stateful engine evaluates rules by action — pass, then drop, then reject, then alert — and a domain list of type Allow adds an implied deny: traffic of the protocols the list covers (HTTP and/or TLS, as you select) that matches no listed domain is dropped. That implied deny covers only those protocols; it does not drop a custom TCP protocol to a raw IP address, SSH, or anything else the list does not name. In strict order, rule groups and rules are evaluated exactly in the priority order you set, a broad pass rule above a targeted drop wins, and a domain allow list adds no implied deny at all — so moving a policy to strict order without choosing a default action silently opens egress to everything.
Stateful default actions (strict order only). These decide what happens to packets no rule matched:
| Default action | Effect | With a domain allow list |
|---|---|---|
| Drop all | Drops every unmatched packet, including the TCP handshake | Breaks approved domains too: the handshake is dropped before the SNI or Host header exists to match |
| Drop established | Lets the handshake through, then drops established connections no rule passed | The compatible choice: approved names pass on SNI/Host, and every other established flow — including non-HTTP protocols to raw IPs — is dropped |
| Application drop established (bidirectional or server-directed only) | Like Drop established, but tolerates segmented TLS ClientHello and HTTP request packets until the SNI or Host field is seen. The bidirectional variant also drops server-initiated banners and some TCP control packets after the handshake; the server-directed variant drops only client-to-server packets | Also compatible; more robust when the SNI or Host spans several packets |
| Alert all / Alert established | Logs only — traffic still flows | Blocks nothing; visibility, not enforcement |
HOME_NET. Domain list rules inspect traffic whose source is in the HOME_NET variable, which defaults to the CIDR of the VPC where the firewall is deployed. In a centralized inspection VPC, that default covers only the inspection VPC itself, so traffic sourced from spoke workloads is not evaluated by the domain rules even though it is routed through the firewall. Set HOME_NET to the spoke CIDR ranges together with the inspection VPC's own CIDR — either in the rule group's variables or once in the firewall policy's HOME_NET variable, which applies across the policy's rule groups; EXTERNAL_NET describes the destination side and does not fix this.
Logging covers only the stateful engine. Flow and alert logs are produced for traffic forwarded to the stateful engine. Traffic that a stateless rule passes, or that a stateless default action of pass lets through, reaches the firewall but leaves no log record. That cause is policy-wide — it affects every zone equally — which is how you tell it apart from a routing bypass that affects only one zone (see Troubleshooting).
Egress control: stopping exfiltration to arbitrary hosts
"Prevent workloads from sending data to arbitrary internet hosts" is one of the most repeatable scenario families in Domain 3, and NAT alone is not an answer — a NAT gateway grants outbound reach, it does not filter it. The layered egress design: private subnets route through NAT, with an AWS Network Firewall domain allow list in the path so only approved destinations (patch mirrors, package repos, your SaaS vendors) succeed — plus, in strict order, a Drop established default action so that non-HTTP protocols and direct-to-IP connections are dropped as well, not just unapproved HTTPS names.
One layer up the stack sits Route 53 Resolver DNS Firewall, which filters at the resolution step: rule groups of allowed or blocked domain lists (including AWS managed threat lists) are associated with a VPC, and a query for a disallowed domain is blocked (NODATA, NXDOMAIN or an override answer) before any connection is attempted. It supports the same walled-garden pattern — allow your known-good domains, block * — and its query logs show who asked for what.
The two firewalls see different things, and the scenarios are decided by that difference:
- Network Firewall cannot see queries to the VPC resolver. The Amazon-provided resolver (at the VPC base address plus two) answers inside the VPC; those queries are never routed through subnet route tables, so they never reach a firewall endpoint. A Network Firewall rule that drops port 53 to everything except the VPC resolver closes the external-resolver hole, but DNS tunnelling through the VPC resolver — data encoded into lookups for an attacker's subdomains — is only stopped by DNS Firewall, which filters exactly those queries.
- DNS Firewall cannot see connections. It controls lookups, not packets: malware that connects to a hard-coded IP address makes no query at all, and malware that sends DNS directly to a public resolver never asks the VPC resolver. Both are ordinary routed packets that only Network Firewall can drop — the latter with a stateful rule dropping TCP and UDP 53 to internet addresses.
- Encrypted DNS bypasses both lookup-based controls: DNS over TLS runs on TCP 853 and DNS over HTTPS hides inside ordinary 443 traffic, so block 853 outbound and deny known DoH resolver domains on SNI in Network Firewall.
So a requirement to enforce policy on the connections themselves in the routed path points to Network Firewall; a requirement about what workloads can resolve, or about DNS-based exfiltration through the VPC resolver, points to DNS Firewall; and the strong design uses both. One DNS Firewall setting is often misread: fail open versus fail closed is a VPC-level DNS Firewall configuration (default: fail closed) that only decides what happens when DNS Firewall cannot evaluate a query because of an impairment. It changes nothing about rule matching and nothing about traffic that never queries the resolver.
A forward proxy fleet (explicit proxy with allow-listed URLs) is the third pattern to recognize at concept level: more control (full URL path filtering, authentication) at the cost of managing infrastructure and client configuration.
Choosing the control layer
Most Task 3.3 questions reduce to "which control, at which layer, for this requirement." Anchor on what each control can see and what its unique capability is:
| Control | Scope | State | Unique strength | Reach for it when… |
|---|---|---|---|---|
| Security group | ENI / instance | Stateful, allow-only | SG references = micro-segmentation that survives IP churn | Least-privilege tier-to-tier flows |
| Network ACL | Subnet | Stateless, allow + deny | Explicit deny; ordered rules; subnet-wide kill switch | Coarse guardrails, blocking known-bad CIDRs, containment |
| Network Firewall | Routed traffic (L3–L7) | Stateless + Suricata-compatible stateful | Domain/SNI egress filtering, IPS signatures, central inspection | Egress allow lists, deep inspection, org-wide east-west control |
| DNS Firewall | Queries to the VPC resolver | Query-level | Blocks domains before any connection exists; query logging | Domain walled garden at resolution, DNS-tunnelling defense |
| Endpoint policy | Traffic through one VPC endpoint | Request-level (IAM) | Limits which resources and principals the private path serves | Data perimeter, stopping exfiltration to outside buckets |
| AWS Verified Access | One application, per request | Request-level (Cedar) | Identity + device posture checked on every request, no VPN | Hybrid users reaching internal applications |
| AWS WAF | L7 HTTP on CloudFront/ALB/API Gateway (Task 3.1) | Request-level | Inspects HTTP request content, rate limiting | Inbound web-app threats — not general VPC traffic |
Hybrid links and hybrid users have their own controls, covered next: encryption choices for Site-to-Site VPN and Direct Connect, then AWS Verified Access.
Hybrid connectivity: encrypting Direct Connect and VPN links
Hybrid and multi-cloud connectivity is secured by choosing where the encryption happens, because AWS Direct Connect is a private circuit but is not encrypted by default. There are three ways to encrypt it, and the deciding facts are the connection type and whether any endpoint may sit on a public IP address:
| Option | How it works | Requirements and limits |
|---|---|---|
| MACsec | IEEE 802.1AE layer 2 encryption between your router and the AWS Direct Connect device, at line rate, with no tunnels; keys are a CKN/CAK pair associated with the connection | Only on dedicated connections (10, 100 and 400 Gbps at supported locations) and LAGs of them; not on hosted connections. It protects the link to the AWS device, not the path end to end |
| Site-to-Site VPN over a public VIF | IPsec tunnels over Direct Connect to the VPN's public tunnel endpoints | Works on any connection type, but the tunnel endpoints use public IP addresses; per-tunnel throughput limits apply |
| Private IP VPN | IPsec tunnels over a transit VIF, through a Direct Connect gateway, terminating on a transit gateway with private tunnel addresses | No public endpoints; requires the transit VIF + Direct Connect gateway + transit gateway combination (not a private VIF to a virtual private gateway) |
Read the table as two filters: the connection type decides whether MACsec is available at all, and whether tunnel endpoints may use public IP addresses decides between the two IPsec options. Over the internet, and to another cloud provider's VPN gateway, a standard Site-to-Site VPN with IPsec is the encryption answer; terminate it on a transit gateway to apply the same route-table segmentation as your VPCs. Two look-alikes encrypt nothing: an MD5 key on the BGP session of a virtual interface only authenticates the routing peer, and a Direct Connect circuit being "private" only means it does not cross the internet. For data that must be protected end to end regardless of the link, add TLS at the application layer as well (Task 5.1).
AWS Verified Access: per-request access for hybrid users
AWS Verified Access gives users on any network access to internal applications without a VPN, by evaluating every request against the user's identity and the device's security posture. Where a client VPN grants network reach to a whole subnet once at connection time, Verified Access exposes one application at a time and decides per request — the zero-trust answer for Skill 3.3.3, and a way to remove unnecessary network access for Skill 3.3.5.
The building blocks:
- Verified Access instance — the regional container that evaluates requests. Trust providers attach to it: an identity trust provider (IAM Identity Center or any OIDC-compatible IdP) supplies user claims such as group membership, and one or more device trust providers (CrowdStrike, Jamf or JumpCloud) supply device posture such as patch level or endpoint-protection status.
- Verified Access group — a set of endpoints with a shared security requirement. Its group policy is inherited by every endpoint in the group.
- Verified Access endpoint — one application. Types: load balancer (which must be an internal ALB or NLB), network interface, network CIDR and RDS. Browser-based HTTP(S) applications need no client; non-HTTP TCP applications (SSH, RDP, databases) are reached through the AWS Verified Access Connectivity Client. Each endpoint has its own security group, and the application's security group must allow inbound from that endpoint security group. Policy evaluation and network reachability are separate checks: a permit decides who may use the application, the security groups decide whether the endpoint can reach it.
- Access logs — every request with its decision and trust context, delivered to CloudWatch Logs, Amazon S3 or Amazon Data Firehose; they show who actually uses each application, which is the evidence for narrowing policies.
Policies are written in Cedar and are default deny. A policy document allows a request only if at least one permit statement applies and no forbid statement applies; a document with no matching permit — including one that contains only forbid statements — allows nobody, and a group with no policy blocks every request. When both a group policy and an endpoint policy exist, both must allow; an endpoint without its own policy is governed by the group policy alone. To restrict one sensitive application inside a broadly permitted group, keep the group policy and attach an endpoint policy with a narrower permit (for example, only members of the on-call engineering group) to that endpoint only; the other endpoints keep relying on the group policy.
Transit Gateway security and the centralized inspection walkthrough
Transit Gateway is a security boundary because its route tables decide which attachments can reach which. Instead of the default single route table (full mesh), you create multiple TGW route tables and control two knobs per attachment: association (which table routes that attachment's outbound traffic — exactly one per attachment) and propagation (which tables learn that attachment's CIDR). Segmentation pattern: production spokes associate with a production route table into which only shared services (and, for inspection, the inspection VPC) propagate — never the other production spokes — so two prod VPCs cannot talk laterally even though both hang off the same TGW.
Now walk the classic design: centralized egress and east-west inspection for an organization. Spoke VPCs in member accounts attach to the TGW (shared via AWS RAM). The spoke route table's only meaningful route is 0.0.0.0/0 → inspection VPC attachment, and it must contain no propagated routes to other spokes: a more specific propagated route sends the packet straight to the destination spoke and the inspection VPC never sees it. The inspection VPC contains TGW attachment subnets and firewall subnets holding Network Firewall endpoints; its VPC route tables steer arriving traffic into the same-zone firewall endpoint and, post-inspection, onward — back to the TGW for east-west flows, or out through a NAT/IGW for north/south. A second TGW route table, associated with the inspection VPC attachment, receives the propagated routes of every spoke so inspected traffic can be delivered and returned — and that propagation is also what lets appliance mode (below) keep flows in their own zone. Network Firewall can also attach to a transit gateway directly as a network function attachment, in which AWS manages the inspection VPC and enables appliance mode for you; the routing logic is the same.
The detail that breaks real designs: enable appliance mode on the inspection VPC's attachment — the attachment of the VPC that holds the stateful appliance, not the spokes. Without it, the TGW keeps each direction of a flow in its originating Availability Zone, so when two spokes' workloads sit in different zones, the reply can arrive at a different firewall endpoint than the request used; a stateful engine that never saw the start of the connection drops it. That produces intermittent timeouts between some cross-zone pairs while same-zone flows work. With appliance mode on, the TGW keeps each flow on one zone of the inspection VPC, in both directions, for the life of the flow. It is zone-aware: it stays in the source zone where it can — a flow between two workloads in the same zone, or traffic with no destination zone such as internet-bound traffic, uses the appliance interface in the source zone — and picks a zone by flow hash only when the source and destination sit in different zones. That zone awareness has a prerequisite: route propagation must be enabled on the TGW route table associated with the appliance-mode attachment. Without propagation the transit gateway cannot tell which zones the source and destination are in, so every flow — even a same-zone one — falls back to flow-hash selection and can be inspected in another zone: flows stay symmetric, but zone isolation is lost and same-zone traffic picks up cross-zone hops. Keep exactly one transit gateway attached to the inspection VPC, because separate transit gateways do not share flow state.
Both settings live on the same command, which is why they get confused: modify-transit-gateway-vpc-attachment --options ApplianceModeSupport=enable on the inspection attachment fixes flow symmetry, while SecurityGroupReferencingSupport=enable (on the TGW and the attachments) lets security groups reference groups in other attached VPCs — and, as covered earlier, that referencing stops working once traffic is inspected in a middlebox VPC.
Identifying unnecessary network access: Network Access Analyzer and Inspector
Unnecessary network access is found by analysing configuration, not by waiting for traffic, and the guide names two tools that answer different questions: Network Access Analyzer checks your own definition of forbidden paths, and Amazon Inspector network reachability findings flag exposed EC2 instances automatically.
Network Access Analyzer evaluates route tables, security groups, NACLs, gateways, load balancers, peering and transit gateways to find every path that matches a Network Access Scope — without sending any packets. A scope has:
- MatchPaths — the paths you consider violations, each with a source and destination (and optionally
ThroughResources), selected by resource ID, resource type (for example all internet gateways, all network interfaces) or tag. Direction matters: a scope with resource set A as the source and resource set B as the destination finds connections that A could open to B, not connections B could open to A — swap them to ask the reverse question. - ExcludePaths — approved exceptions removed from the results, such as the tagged public load balancer that is meant to be reachable from the internet. Findings then show only unintended paths.
Because scopes select by type and tag, one analysis covers every ENI (EC2, RDS, Lambda in a VPC and so on) and can be rerun after every change — the evidence an auditor wants for statements like "no path exists from any internet gateway to anything tagged as in audit scope". AWS also provides ready-made scopes to start from.
Amazon Inspector network reachability findings come with Inspector's EC2 scanning, with no path definitions to write. Inspector analyses each EC2 instance about every 12 hours and reports TCP and UDP ports reachable from the VPC edges — internet gateways (including through load balancers), VPC peering connections and virtual private gateways (VPN and Direct Connect) — with the security groups, NACLs and routes that make up the path. It covers EC2 only.
| Tool | What it answers | Basis |
|---|---|---|
| Network Access Analyzer | Does any path match my definition of forbidden access? (any resource, any direction) | Configuration, your scopes |
| Inspector network reachability | Which ports on my EC2 instances are reachable from the VPC edges? | Configuration, automatic |
| Security Hub CSPM controls | Does a security group allow 0.0.0.0/0 on sensitive ports? | One resource's settings, not a path |
| GuardDuty | Is someone probing or abusing the network now? | Observed activity |
The third tool the guide lists here is Verified Access, from the other direction: moving users off a subnet-wide VPN onto per-application endpoints removes network access that was never needed, and its access logs show which applications each group really uses. VPC Reachability Analyzer, which proves a single point-to-point path, is no longer a named tool in the SCS-C03 guide.
Troubleshooting: blocked traffic and bypassed inspection
Troubleshooting questions give you a symptom and four plausible layers; win them with evidence, not recall. Symptom: legitimate traffic broke after a change. Check in order: (1) Security group source — a rule referencing an SG stops matching if traffic now arrives through a load balancer (whose own group must be referenced) or through an inspection VPC (where only CIDR rules work), or if new instances are not in the referenced group; a CIDR rule breaks when subnets were renumbered. (2) NACL return traffic — a tightened NACL that forgot the ephemeral range in the reply direction. (3) Endpoint policy too strict — S3 calls failing with AccessDenied only from inside the VPC, while the same role works elsewhere, points at the endpoint policy (or an aws:ResourceOrgID condition meeting a legitimate third-party bucket). (4) Firewall rule order and default action — in strict order, a drop placed above the intended pass wins, and Drop all breaks domain lists.
Read Flow Logs as signatures, and from both ends. On one interface: an inbound ACCEPT followed by an outbound REJECT for the same flow is a stateless NACL dropping the reply; a lone inbound REJECT with no accepted half — while the NACL allows the request — is the security group. When the client and server are in different subnets, compare both interfaces: the drop happened on the side whose records carry the REJECT, and a REJECT on a reply can only come from a NACL, because security groups are stateful and never reject a reply to a connection they allowed. A reply rejected as it arrives at the client means the client subnet's NACL lacks an inbound allow for the client's ephemeral ports.
Symptom: traffic is not being inspected. This is almost always routing, not rules, and the logs tell you where:
- No trace on the inspection VPC's TGW attachment ENIs (Flow Logs on those interfaces show nothing for the flow) — the transit gateway never sent it there: the source spoke's associated route table holds a propagated route to the destination spoke, or the attachment is associated with the wrong table.
- A trace on the attachment ENIs but nothing in the firewall logs — the traffic reached the inspection VPC but its subnet routing does not send it through a firewall endpoint.
- Firewall logs show one zone's flows but not another's — a zone-specific route bypass: that zone's workload subnets (or, in a firewall-before-NAT design, its NAT subnet return routes) do not target that zone's endpoint. A stateless rule or stateless default action of pass also leaves flows unlogged, but it is policy-wide and would hide every zone's traffic.
- Inbound connections time out after the firewall was added — the internet gateway edge route table is missing, so the flow is asymmetric; intermittent cross-zone timeouts in a centralized design — appliance mode is off on the inspection attachment.
Your visibility toolkit: VPC Flow Logs with custom fields (flow-direction, traffic-path, tcp-flags, pkt-srcaddr, pkt-dstaddr) to see where flows actually go; Network Firewall flow and alert logs for what the stateful engine saw and decided; Network Access Analyzer to confirm intended segmentation after the fix; and Traffic Mirroring when you genuinely need packet payloads for out-of-band analysis. Reachability Analyzer can still trace one point-to-point path if you use it, but the guide centres on the tools above.
Tip. Task 3.3 questions map requirements to layers: "S3 access must never traverse the internet and only reach the organization's buckets" → gateway endpoint plus an endpoint policy (aws:ResourceOrgID, not aws:PrincipalOrgID); "block all egress except approved domains" → Network Firewall domain allow list (with Drop established in strict order), with DNS Firewall for lookups through the VPC resolver; "inspect all inter-VPC traffic centrally" → Transit Gateway with an inspection VPC, no direct spoke routes, and appliance mode on the inspection attachment; "encrypt Direct Connect" → MACsec on dedicated connections or private IP VPN over a transit VIF; "retire the user VPN" → Verified Access; "prove no path exists" → Network Access Analyzer. Troubleshooting stems hinge on one telling detail — inbound ACCEPT plus outbound REJECT means a stateless NACL reply block, a flow missing from one zone's firewall logs means that zone's routes bypass the endpoint, and a domain filter that ignores spoke traffic means HOME_NET.
- Security groups are stateful and allow-only; referencing SGs as sources gives micro-segmentation that survives IP churn — behind a load balancer reference the load balancer's group, and across a transit gateway referencing works inbound only and not through an inspection VPC.
- NACLs are stateless, ordered (lowest matching number wins), subnet-wide, and the only layer with an explicit deny: allow the ephemeral range in the reply direction, and number an exception below the deny it carves out.
- Isolated subnets have no route to an internet gateway, NAT gateway or egress-only internet gateway (no 0.0.0.0/0 and no ::/0) and reach AWS services through endpoints — ECR needs ecr.api, ecr.dkr and the S3 gateway endpoint for layers.
- Endpoint policies are data-perimeter checkpoints: aws:ResourceOrgID limits which resources the endpoint reaches (stops exfiltration with any credentials), aws:PrincipalOrgID limits who uses it, and aws:SourceVpce in a bucket policy protects your own buckets.
- Network Firewall inspects only what routing steers to its per-zone endpoints, including an internet gateway edge route table for inbound traffic; it has no security groups, preserves source addresses, and logs only traffic sent to the stateful engine.
- A domain allow list implies a deny only in default action order and only for the listed protocols; in strict order use the Drop established default action (Drop all kills the handshake before the SNI is visible), and in a central inspection VPC set HOME_NET to the spoke CIDRs plus the inspection VPC's own.
- DNS Firewall filters queries to the VPC resolver, which Network Firewall never sees; Network Firewall filters routed connections, which DNS Firewall never sees — use both, and block direct DNS, DoT and DoH to the internet.
- Centralized inspection needs spoke TGW route tables with no propagated spoke routes plus appliance mode on the inspection VPC attachment, whose associated route table needs route propagation for zone-aware flow placement; MACsec (dedicated connections only) or private IP VPN over a transit VIF encrypt Direct Connect; Verified Access replaces VPNs with per-request Cedar policies where group and endpoint policies must both allow.
- Find unnecessary access with Network Access Analyzer scopes (MatchPaths and ExcludePaths, any resource) and Inspector network reachability findings (EC2, automatic); troubleshoot from Flow Logs on both ends and from where a flow stops appearing in the logs.
Frequently asked questions
How do I block outbound traffic to unknown domains in AWS?
Use an AWS Network Firewall stateful domain allow list in the egress path: route private subnets through firewall endpoints before the NAT gateway, allow only your approved domains (matched on TLS SNI or HTTP Host), and make sure everything else is dropped — automatically for the listed protocols in default action order, or with the Drop established default action in strict order. Pair it with Route 53 Resolver DNS Firewall so disallowed domains fail at the DNS lookup and DNS tunnelling through the VPC resolver is blocked, and drop DNS, DNS over TLS and known DNS-over-HTTPS resolvers to the internet so workloads cannot sidestep the policy with an external resolver.
What is the difference between a security group and a network ACL on the SCS-C03 exam?
Security groups are stateful, instance/ENI-level, allow-only, evaluate all rules, and can reference other security groups as sources — the least-privilege micro-segmentation tool. Network ACLs are stateless, subnet-level, evaluated in numbered order, and support explicit deny — the coarse guardrail and kill-switch tool, which must explicitly allow ephemeral-port return traffic. Specialty questions test the design reading: SGs for intended flows, NACLs for what must never happen.
Can a VPC endpoint policy restrict S3 access to only my organization's buckets?
Yes. Attach an endpoint policy to the S3 gateway endpoint that allows actions only on approved bucket ARNs, or use the aws:ResourceOrgID condition key so the endpoint only reaches resources owned by your AWS Organization — that blocks copying data to an outside bucket whichever credentials are used. aws:PrincipalOrgID is different: it restricts who may use the endpoint, so it does not stop a trusted role writing to an outside bucket. A bucket policy with aws:SourceVpce protects your own buckets, not your network.
What is the difference between Route 53 Resolver DNS Firewall and AWS Network Firewall?
DNS Firewall filters queries sent to the VPC resolver — a blocked domain never resolves — but it inspects no packets, so connections to raw IPs or via an external resolver bypass it. Network Firewall inspects the actual traffic in the routed path and can drop flows by domain (SNI/Host), signature, or 5-tuple regardless of how the destination was resolved, but it never sees queries to the VPC resolver, so DNS tunnelling through that resolver is DNS Firewall's job. Strong egress designs use both.
How do I inspect all traffic between VPCs centrally in AWS?
Attach every spoke VPC to a Transit Gateway and use TGW route tables to force inter-VPC (east-west) traffic through a dedicated inspection VPC running AWS Network Firewall endpoints. Spoke route tables default-route to the inspection VPC attachment and hold no propagated routes to other spokes, the inspection attachment's route table learns every spoke, and appliance mode must be enabled on the inspection VPC attachment so both directions of each flow hit the same firewall Availability Zone; with route propagation enabled on that attachment's route table, appliance mode also keeps same-zone flows in their own zone.
Why is my traffic bypassing AWS Network Firewall?
Almost always routing: the firewall only sees traffic that route tables steer through its endpoints. Check each Availability Zone's workload and NAT subnet route tables, the internet gateway edge route table for inbound traffic, and Transit Gateway route tables that might send traffic straight between spokes. Flows that a stateless rule passes reach the firewall but are not logged, and asymmetric flows from a disabled appliance mode drop at the stateful engine and look like random timeouts.
What is AWS Verified Access and when does it replace a VPN?
AWS Verified Access gives users access to internal applications without a VPN by checking every request against Cedar policies that use the user's identity (IAM Identity Center or an OIDC provider) and the device's posture (CrowdStrike, Jamf or JumpCloud). Each application is an endpoint in a group; when both a group policy and an endpoint policy exist, both must allow, and policies deny by default. Use it when hybrid users need specific applications rather than network-wide access, which also removes unnecessary network reach.
What is the difference between Network Access Analyzer and Amazon Inspector network reachability findings?
Network Access Analyzer finds every network path that matches a scope you define — MatchPaths for forbidden paths, ExcludePaths for approved exceptions — across any resource type, without sending traffic. Amazon Inspector network reachability findings are automatic: for EC2 instances only, Inspector reports ports reachable from internet gateways, load balancers, peering connections and virtual private gateways. Use the first to prove your segmentation intent, the second for continuous exposure of instances.
Source
This lesson covers the "Infrastructure Security" domain of the official SCS-C03 exam guide. Vendors revise their guides — check the source for the current version.
- AWS Certified Security – Specialty (SCS-C03) exam guide — Amazon Web Services
Sign up free to mark lessons complete, bookmark topics and track your exam readiness.