Cloudflare, Reverse Proxy, and Public Service Exposure
I designed a safer public access model for selected homelab services by separating internet-facing access from internal management paths. Instead of exposing everything the same way, I used Cloudflare and reverse proxying to control how services were published, which upstreams they targeted, and which systems were kept internal only.
Environment
Problem
Publishing services to the internet is not just a matter of making them reachable. It also requires deciding which systems should be exposed at all, which path they should use, and how to avoid mixing public access with administrative access. Without that separation, it becomes easier to point traffic at the wrong upstream, expose a service too broadly, or create confusion during troubleshooting.
Why This Matters
- Public service exposure increases risk if access paths are not intentionally designed.
- Management interfaces should not be treated the same way as user-facing applications.
- Clear publishing rules make troubleshooting easier when DNS, proxying, or upstream targets fail.
Approach
I treated public exposure as a design decision instead of a default convenience. Services that needed external access were evaluated individually, then assigned an access method that matched their purpose. I used Cloudflare for external entry points and reverse proxying for controlled routing, while keeping internal management paths separate from public-facing traffic. This reduced ambiguity and made it easier to reason about what should be reachable from where.
Implementation
- Defined which services were allowed to be publicly reachable and which were to remain internal only.
- Configured Cloudflare DNS records for published services using the correct upstream targets.
- Used Nginx Proxy Manager to route subdomains to internal services where reverse proxying made sense.
- Separated public access paths from management access paths so administrative interfaces were not exposed in the same way as normal service traffic.
- Validated that each published hostname pointed to the intended internal service and not to the wrong node or stale address.
Validation
- Tested external access to published services through their intended public hostnames.
- Verified internal-only services stayed internal and were not accidentally exposed.
- Confirmed reverse proxy targets matched the correct internal applications.
- Used troubleshooting to distinguish DNS issues, proxy issues, and upstream service issues when something failed.
Outcome
The final design gave me a clearer boundary between public services and internal administration. Services intended for external use had a defined publishing path, while management access stayed more controlled. It also improved troubleshooting because I could break the path into layers: public DNS, Cloudflare, reverse proxy, and internal upstream service.
Key Lesson
One of the biggest lessons from this project was that public exposure should be treated as an architecture choice, not just a connectivity task. A service being reachable is not the same as it being safely and intentionally published. Clear separation between public access, proxy routing, and internal management makes the environment easier to secure and easier to troubleshoot.
What I'd Improve Next
- Document a stricter source-of-truth list for which services are allowed public exposure.
- Add more formal validation for upstream targets after infrastructure changes.
- Further reduce management-plane exposure by tightening which interfaces can be reached externally.
- Add architecture diagrams showing the full request path from public DNS to internal service.