Checklist / Defend Systems / Network Security
How to Validate That a Service Is Not Publicly Reachable
A repeatable checklist for confirming — through an actual external check, not an assumption drawn from a configuration file — that a service intended to be internal-only cannot be reached from the public internet. Covers the common ways a service becomes unintentionally exposed: a misconfigured load balancer, a cloud security-group rule broader than intended, a leftover NAT or port-forward rule, and a service binding to every interface instead of a loopback or internal one. Illustrated with a fictional example.
"The configuration says internal-only" and "this service cannot be reached from the public internet" are two different claims, and the gap between them is where a large share of accidental exposure lives. A configuration file, an infrastructure-as-code definition, or a security-group rule describes intent — what someone meant the network to allow. What actually determines reachability is the accumulated, live effect of every load balancer, security group, NAT rule, and interface binding sitting between the public internet and that service, and any one of those layers can quietly diverge from the intent recorded elsewhere.
Hover or focus a node to explore it.
Executive summary
This checklist gives you a repeatable way to close that gap: state what internal-only is supposed to mean for a specific service, enumerate the layers that could override that intent, and then actually confirm the result from a vantage point outside the network boundary — not merely read the configuration and assume it holds. A fictional example — a documented internal-only reporting service that turns out to be reachable anyway because of a load-balancer rule broader than intended — runs through the checklist and the accompanying interactive diagram so the process stays concrete without describing any real environment.
What you will learn
- Why a configuration's stated intent and a service's actual reachability are two separate claims, and why only one of them can be verified by reading a file.
- The most common ways a service becomes unintentionally exposed: an overly broad load-balancer or security-group rule, a leftover NAT or port-forward rule from earlier testing, and a service binding to every interface instead of a loopback or internal one.
- How to perform and interpret an external, outside-the-boundary check of a service's actual reachability, instead of relying on an internal test that never leaves the trusted network.
- Why a single passing check is not durable evidence, and what has to trigger revalidation.
- How to record a reachability finding as defensible evidence rather than as an assumption inherited from a configuration review.
Intended audience
- Network defenders and platform engineers responsible for services that are meant to stay internal-only.
- Security practitioners auditing whether an organization's internal-only claims are backed by actual verification or only by configuration review.
- Engineers moving from "we checked the security group" toward a repeatable, externally verified exposure-validation process.
Problem or security question
A common failure pattern looks like this: a service is designed and deployed as internal-only, the security-group rule or firewall policy that was written for it looks correct on inspection, and everyone involved treats that inspection as the answer. Nobody actually tries to reach the service from outside the network boundary, because the configuration already says it should not be reachable, and re-deriving the same conclusion by testing it feels redundant. The service then goes unreviewed for months, through a load-balancer change, a security-group edit made for an unrelated request, and a NAT rule added temporarily during a debugging session and never removed — any one of which could have quietly widened its actual exposure without anyone touching the original rule that was reviewed.
The underlying problem is treating configuration review as equivalent to reachability verification, when a configuration file only describes what one layer was asked to do — not what the full, layered path from the public internet to the service actually permits today. A load balancer can forward more than a downstream security group intends to allow. A security-group rule can be broader than the requirement that justified it. A NAT or port-forward rule can persist long after the testing it was created for has ended. A service can bind to every interface by default, regardless of what the network layer around it was configured to permit. Fixing this requires treating "internal-only" as a claim that must be tested from outside the boundary, not one that can be confirmed by reading configuration alone.
Threat model or relevant risk
This checklist's threat model assumes an adversary who benefits from exactly the gap this checklist closes: a service its owners believe is internal-only, reachable from the public internet because of a misconfiguration nobody has actually tested for. That adversary does not need to compromise anything to find the service — an externally reachable service intended to be internal-only is, by definition, already reachable to anyone who scans for it, whether or not the owner has audited the traffic yet.
Two failure modes recur most often, both represented in this checklist's interactive diagram: a layer in the path — a load-balancer listener, a cloud security-group rule, a NAT or port-forward rule, or a service bound to every interface instead of a loopback or internal one — is broader than the documented intent, and the resulting exposure is never actually tested for because internal-only status was assumed from configuration review rather than confirmed from an external vantage point. Either failure can persist indefinitely, since nothing about a passing internal check or a clean-looking configuration file reveals it.
Main technical content
Stating the intended reachability explicitly. Before anything can be validated, it has to be documented what "internal-only" is supposed to mean for this specific service: which networks or hosts are permitted to reach it, on which port and protocol, and — just as importantly — that the public internet is not one of the permitted sources. A vague or implicit assumption of internal-only status cannot be tested against; a documented statement can.
Enumerating every layer that determines actual reachability. A service's real-world reachability is the product of everything between the public internet and the service, not just the rule someone remembers writing. That typically includes, at minimum: any load balancer or reverse proxy in front of the service and its listener configuration, the cloud security-group or firewall rule attached to the service's network interface, any NAT or port-forward rule at a network edge, and the interface the service itself binds to. Reviewing only one of these layers and calling the service validated leaves every other layer unchecked.
Checking the service's own bind configuration. A service that binds to every available interface — commonly the address that means "listen on all interfaces" rather than a loopback or a specific internal interface — is reachable through any network path that can otherwise get a packet to that host, regardless of what the surrounding security-group or firewall rule was written to prevent. Confirm explicitly which interface the service binds to; do not infer it from the fact that a firewall rule exists in front of it.
Checking for load-balancer and reverse-proxy scope that exceeds intent. A load balancer or reverse proxy is frequently the actual public-facing edge of a system, and a listener configured more broadly than intended — for example, a rule meant to expose one public-facing service that also forwards to an internal one on a shared listener — can make an internal-only service reachable regardless of what its own security group says. This layer is easy to overlook precisely because the service's own configuration looks correct in isolation.
Checking for security-group or firewall rules broader than documented intent. Compare the deployed security-group or firewall rule against the documented intended source scope field by field, the same way a firewall-rule request should be validated against its requirement. A rule that allows a wider address range than intended, or that was copied and loosened from a similar rule rather than derived from this service's own requirement, is one of the most common quiet sources of unintended exposure.
Checking for leftover NAT or port-forward rules. A NAT or port-forward rule created temporarily — commonly during testing, a demo, or a debugging session — persists until someone deliberately removes it, and nothing about normal operation prompts that removal. Explicitly search for NAT and port-forward rules that reference this service's address or port, and treat any that lack a documented, current justification as a candidate for removal, not as background noise.
Performing the actual external check. Once every layer above has been reviewed, the review itself is still only an inspection of intent — the only way to confirm actual reachability is to test from a vantage point outside the network boundary: a scan or connection attempt against the service's port and protocol, performed from outside the perimeter the service is supposed to sit behind, not from inside the trusted network where an internal test would succeed regardless of how the perimeter is configured. An internal-only test proves the service works for the traffic it is supposed to serve; it proves nothing about whether traffic that should not reach the service also can.
Reconciling the result against documented intent, and revalidating on drift. A single external check that finds no reachability is evidence for exactly one point in time, not a permanent guarantee — a subsequent load-balancer change, security-group edit, or NAT rule added for an unrelated reason can silently reopen exposure that a prior check closed. Revalidate after any change to the layers enumerated above, and on a periodic review cadence for services where change history is not reliably tracked, rather than treating one clean result as final.
Checklist
| Control | Verification method | Required evidence | Result |
|---|---|---|---|
| Intended reachability documented explicitly | Confirm a written statement exists naming the permitted source networks or hosts, port, and protocol for the service, and stating explicitly that the public internet is not a permitted source. | A recorded reachability intent statement independent of the network configuration it will be validated against. | Pending verification for each service reviewed |
| Service interface binding confirmed | Confirm which network interface the service actually binds to, rather than inferring it from the surrounding firewall or security-group configuration. | A recorded binding configuration showing the service listens on a loopback or specific internal interface, not every available interface, unless a documented reason requires otherwise. | Pending verification for each service reviewed |
| Load-balancer and reverse-proxy scope checked against intent | Review any load balancer or reverse proxy in front of the service and confirm its listener configuration does not forward traffic to this service beyond the documented intended source scope. | A recorded review of the relevant listener configuration, compared field by field against the documented reachability intent. | Pending verification for each service reviewed |
| Security-group or firewall rule scope matches documented intent | Compare the deployed security-group or firewall rule's source, port, and protocol fields against the documented reachability intent, field by field. | A side-by-side comparison showing no deployed rule field is broader than the corresponding documented intent field. | Pending verification for each service reviewed |
| No leftover NAT or port-forward rule exposes the service | Search explicitly for NAT or port-forward rules referencing this service's address or port and confirm each has a current, documented justification. | A record showing every NAT or port-forward rule tied to this service is either justified and current, or has been removed. | Pending verification for each service reviewed |
| External reachability check performed from outside the network boundary | Perform an actual connection attempt or scan against the service's port and protocol from a vantage point outside the network boundary the service is supposed to sit behind, not from within the trusted internal network. | A recorded test result, including the vantage point used, the port and protocol tested, and the observed outcome, performed after the configuration review above — not assumed from it. | Pending verification for each service reviewed |
| External check result reconciled against documented intent | Confirm the external check's result matches the documented reachability intent exactly — no reachability from the public internet where none was intended — and that any discrepancy was investigated and resolved before the service is considered validated. | A recorded reconciliation showing the external check's actual result matched the documented intent, or documenting the investigation and remediation if it did not. | Pending verification for each service reviewed |
| Revalidation trigger defined for configuration drift | Confirm a defined trigger exists for repeating this checklist — at minimum, any change to the service's load-balancer, security-group, NAT, or interface-binding configuration, plus a periodic review cadence. | A recorded revalidation policy naming the specific triggers and, where applicable, the review cadence for this service. | Pending verification for each service reviewed |
Validation or evidence
This checklist is conceptual. It was not developed against a live or lab-reproduced service, no security-group, load-balancer, or NAT configuration described here was actually deployed, and no external scan was actually performed. Its evidence state is UNVERIFIED and stays UNVERIFIED until a human reviewer records actual reproduction evidence — the label must not be upgraded merely because the checklist's reasoning is internally consistent.
Limitations
This checklist describes principles and a fictional illustrative example, not a specific cloud provider's security-group model, a specific load-balancer product's listener syntax, or a specific external-scanning tool's command syntax. Applying it to a real environment requires translating each control into that environment's actual tooling and re-validating the result there.
It does not cover the deep-dive technical methodology of port scanning itself, service fingerprinting, or building an authorized external-scanning program — those are separate disciplines covered, where SecurityCorp publishes on them, by its own dedicated content rather than this checklist.
It does not address the legal, contractual, or provider-policy requirements that may govern who is authorized to scan a given service from outside its network — those requirements should be confirmed before performing the external check this checklist describes, and are outside this checklist's scope.
Defensive recommendations
- Document what "internal-only" is supposed to mean for a service — permitted sources, port, and protocol — before attempting to validate it; an implicit assumption cannot be tested against.
- Enumerate every layer between the public internet and the service — load balancer or reverse proxy, cloud security-group or firewall rule, NAT or port-forward rules, and the service's own interface binding — rather than validating only the layer that is easiest to check.
- Confirm explicitly which interface a service binds to; a service bound to every interface can be reachable through paths its surrounding firewall rule was never meant to permit.
- Treat a security-group or firewall rule copied and loosened from a similar rule as a warning sign, not a shortcut, and compare every deployed rule against its documented intended scope field by field.
- Search explicitly for leftover NAT or port-forward rules tied to a service's address or port, and remove any without a current, documented justification.
- Perform the actual reachability check from a vantage point outside the network boundary — an internal test proves the service works for intended traffic, not that unintended traffic is blocked.
- Revalidate reachability after any change to the layers that determine it, and on a periodic cadence otherwise — one clean external check is evidence for that point in time only, not a permanent guarantee.
Key takeaways
- "The configuration says internal-only" and "this service is not reachable from the public internet" are separate claims — only the second can be confirmed by an external check, and only the second is the one that matters to an adversary.
- Actual reachability is the product of every layer between the public internet and the service — load balancer, security group, NAT, and the service's own interface binding — not just the layer that is easiest to review.
- The most common unintentional-exposure causes are an overly broad load-balancer or security-group rule, a leftover NAT or port-forward rule, and a service binding to every interface instead of a loopback or internal one.
- An internal-only test proves a service works for its intended traffic; it proves nothing about whether unintended traffic, including traffic from the public internet, can also reach it.
- A passing external check is evidence for one point in time — revalidate after any change to the layers that determine reachability, not just once at deployment.
References
- NIST SP 800-53 Rev. 5, Security and Privacy Controls for Information Systems and Organizations (see the SC-7 Boundary Protection and CA-8 Penetration Testing controls): https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final
- NIST SP 800-41 Rev. 1, Guidelines on Firewalls and Firewall Policy: https://csrc.nist.gov/pubs/sp/800/41/r1/final
- NIST SP 800-115, Technical Guide to Information Security Testing and Assessment: https://csrc.nist.gov/pubs/sp/800/115/final