Self-hosted public exposure checklist · Updated 2026-07-05

Reverse Proxy & Public Exposure Checklist: DNS, TLS, Trusted Proxies, Authentication, WebSockets, Upload Limits, Rate Limits, Logs, and Emergency Shutoff

A practical public-exposure checklist for self-hosted apps behind NGINX, Caddy, tunnels, VPNs, and home-server gateways.

Putting a reverse proxy in front of a self-hosted app does not automatically make it safe for the internet. The real exposure chain includes DNS, TLS, proxy trust, client-IP handling, authentication, admin surface separation, WebSocket upgrades, upload limits, request and connection limits, logs, fail-open behavior, and the ability to shut off access quickly.

This checklist applies to CasaOS, Umbrel, Nextcloud, YunoHost, RomM, Penpot, and similar self-hosted systems. It treats LAN-only, VPN-only, authenticated public access, and fully public services as different operating modes with different controls.

RepoDaily verdict

Default to LAN-only or VPN-only access unless public exposure is a real product requirement. When public exposure is necessary, terminate TLS at a controlled edge, define trusted proxies explicitly, keep admin surfaces separate, preserve the real client IP without trusting arbitrary forwarding headers, test WebSockets and large uploads deliberately, apply rate and connection limits where appropriate, and keep a tested emergency shutoff path.

Quick matrix

SurfaceBaseline ruleFailure signalEvidence
DNSPoint only intended names at public ingressWildcard or stale records expose forgotten servicesDNS inventory and owner
TLSUse valid certificates and automated renewal with alertsExpired cert or fallback plaintext pathRenewal test and expiry monitor
Trusted proxiesTrust only known proxy addresses/rangesApp trusts arbitrary X-Forwarded-* headersProxy chain map and negative spoof test
Client IPPreserve real client identity through reviewed proxy chainAll users appear as proxy IP or attackers spoof source IPAccess-log sample and spoofing test
AuthenticationRequire real auth before privileged accessInternet reachability equals authorizationAnonymous and wrong-role tests
Admin surfaceKeep admin routes private or strongly separatedSame public entry point exposes root/admin consoleRoute inventory and access test
WebSocketsProxy upgrade explicitly and authenticate sessionHTTP works but socket bypasses controlsHandshake/origin/auth tests
UploadsSet intentional size and timeout limitsUnlimited uploads exhaust disk or legitimate files fail unexpectedlyBoundary-size tests
Rate limitsApply endpoint-appropriate request and connection controlsLogin/API endpoints can be hammered without boundLoad and abuse test
LogsRecord auth, proxy, upstream, and security events with redactionNo client identity or logs leak tokensSample incident trace
ShutoffHave a tested way to disable public ingressOnly recovery is editing production liveRunbook and exercise result

Public exposure readiness scorecard

Score the exposure path from internet to application, not only the reverse proxy config.

Control0 points1 point2 pointsOwner question
Exposure modeEverything publicSome routes privateLAN/VPN/public modes explicitly classifiedWhich services truly need internet access?
TLS lifecycleManual or unclearAuto renewal onlyAuto renewal + expiry monitoring + failure alertWho notices renewal failure?
Proxy trustTrust all headersSingle proxy configuredExplicit chain with trusted ranges and spoof testsWhich hop is allowed to assert client identity?
AuthenticationApp default onlyStrong app authStrong auth + admin separation + session controlsCan public users ever reach admin flows?
Protocol handlingHTTP only testedWebSockets/uploads tested manuallyAutomated HTTP/WS/upload boundary testsDo non-HTTP paths preserve the same policy?
Abuse controlsNoneBasic rate limitEndpoint-aware rate, connection, body-size and timeout controlsWhich endpoint is cheapest to abuse?
ObservabilityProxy logs onlyApp + proxy logsCorrelated client/proxy/upstream/security events with redactionCan one abusive session be reconstructed?
Emergency responseManual config editsDocumented disable stepTested ingress shutoff, DNS/tunnel revocation and rollback pathHow fast can public access be stopped?

45-minute public exposure review

Use this before opening a self-hosted service to the internet.

0–5 min: classify exposure

List every hostname, port, tunnel, CDN, proxy, and intended audience.

Success checkNo public route exists without a named need and owner.

5–10 min: trace proxy trust

Record TLS termination and trusted proxy addresses; try spoofed forwarded headers from an untrusted client.

Success checkClient identity cannot be forged through direct requests.

10–20 min: test auth and admin separation

Try anonymous, normal-user, wrong-role, and direct-origin access paths.

Success checkPublic users cannot reach admin surfaces or bypass the proxy path.

20–30 min: test protocols and limits

Exercise WebSocket upgrade, representative upload, oversize upload, slow request, and burst requests.

Success checkLegitimate flows work and abuse boundaries fail predictably.

30–40 min: inspect logs

Trace one login failure and one successful session across proxy and app logs; inspect redaction.

Success checkReal client identity and events are traceable without exposing secrets.

40–45 min: exercise shutoff

Disable the public route while keeping private operator access, then restore it deliberately.

Success checkEmergency response does not depend on improvising production edits.

Public exposure decision flow

  1. Classify each service as LAN-only, VPN-only, authenticated public service, or intentionally public anonymous content. Do not expose an entire host because one app needs remote access.
  2. Map the ingress chain: DNS, CDN or tunnel if used, edge proxy, internal proxy, application, and any WebSocket or upload endpoints. Record which hop terminates TLS and which hop may assert client identity.
  3. Configure trusted proxies narrowly. The application should trust forwarding headers only from known proxy addresses or ranges, and proxy logs should preserve both direct peer and resolved client identity where useful.
  4. Separate user-facing and administrative surfaces. Prefer VPN/private network access for admin consoles, host dashboards, database UIs, container managers, and backup interfaces.
  5. Verify protocol-specific behavior: HTTP redirects, WebSockets, large uploads, streaming, background callbacks, WebDAV-like clients, mobile clients, and OAuth redirect URIs where applicable.
  6. Set intentional request-body size, header size, idle/read/write timeouts, request rate, and concurrent connection policy based on application behavior rather than copying generic snippets.
  7. Test authentication and brute-force controls using real client IP handling. Misconfigured proxies can collapse all users behind one IP or allow spoofed forwarded addresses to poison logs and policy decisions.
  8. Centralize enough evidence to trace DNS name, client, proxy, upstream, auth result, status, latency, and security event without logging passwords, session cookies, Authorization headers, or sensitive payloads.
  9. Exercise emergency shutoff: disable public route or tunnel, preserve logs, keep LAN/VPN operator access, rotate exposed credentials if needed, patch, test privately, then reopen deliberately.

Scenario table

ScenarioRecommended exposure modeRequired controlsStop condition
CasaOS admin dashboardLAN or VPN onlyPrivate routing, strong admin auth, no direct public portDashboard is reachable anonymously or from arbitrary internet clients
Umbrel home cloudVPN-first; selective public apps onlyPer-app route review, TLS, auth, update ownershipWhole appliance is exposed because one app needs sharing
NextcloudAuthenticated public service if neededTrusted proxies, TLS, brute-force protection, upload/WebDAV tests, logsForwarded IP trust is broad or admin/login abuse cannot be traced
YunoHost multi-app serverPer-domain/per-app policyTLS, app auth, admin separation, firewall and app-specific reviewOne weak app compromises trust assumptions for every domain
RomM sharingAuthenticated public access or VPNUser roles, upload limits, WebSocket test if used, storage monitoringFriend-sharing endpoint grants broader library/admin access
Penpot team collaborationAuthenticated public or VPN-onlySSO/auth review, WebSocket support, upload limits, private admin opsRealtime collaboration bypasses proxy controls
Temporary demoShort-lived authenticated public routeExpiry, narrow DNS, no production secrets, auto shutoffDemo remains online after review window
Emergency incidentPublic ingress off, operator path privatePreserve logs, revoke tunnel/DNS route if needed, rotate secrets, patch privatelyTeam reopens before root cause and credential scope are known

Public exposure risks

Reverse proxy as security placebo

A proxy can terminate TLS and centralize policy, but weak app authentication, broad admin routes, or trusted-header mistakes remain dangerous.

Forwarded-header spoofing

If an app trusts X-Forwarded-* headers from arbitrary clients, attackers may spoof client identity used in logs, redirects, or abuse controls.

Admin surface leakage

Home-server dashboards, container managers, backup consoles, and root admin panels should not become public merely because app traffic uses the same proxy.

WebSocket policy gap

HTTP requests may be protected while WebSocket upgrades fail, bypass expected middleware, or remain open longer than intended.

Upload exhaustion

Unlimited body size, long timeouts, and public upload endpoints can consume disk, memory, temp space, or upstream workers.

Global rate-limit mistake

One generic limit can break sync clients and uploads while still leaving sensitive login or expensive API endpoints insufficiently protected.

Log privacy leak

Access logs, debug traces, query strings, headers, and upstream errors can expose tokens, share links, filenames, or personal data.

No emergency cut path

During compromise, teams often need to stop public ingress while retaining private operator access and preserving evidence.

Exposure patterns

LAN by default

Keep host dashboards and admin interfaces on LAN or VPN. Publicly route only named services with reviewed requirements.

One trust boundary per proxy hop

Document which proxy can set client identity headers, and configure downstream trusted-proxy lists accordingly.

Public app, private admin

Use separate hostnames, routes, VPN policy, or identity-aware access so public user traffic cannot reach administrative surfaces.

Protocol fixture tests

Maintain simple automated tests for HTTP redirects, login, WebSocket upgrade, representative upload size, and real-client-IP logging.

Endpoint-aware abuse controls

Apply stricter limits to login, password reset, expensive search, upload, and API endpoints than to static assets or normal browsing.

Emergency ingress switch

Keep a documented and rehearsed way to disable a hostname, route, tunnel, or public listener while private operator access remains available.

FAQ

Short answers for self-hosted operators.

Is HTTPS enough for public exposure?

No. HTTPS protects transport. You still need authentication, proxy trust, admin separation, update discipline, abuse controls, logs, backups, and incident response.

Should I expose a home-server dashboard?

Usually keep host and platform administration on LAN or VPN. Expose only the application routes that genuinely need public access.

Why do trusted proxies matter?

Applications often rely on forwarded headers for client IP, host, and scheme. Only known proxies should be allowed to assert those values.

Do WebSockets need separate testing?

Yes. Proxy upgrade handling, authentication, origin expectations, idle timeouts, and connection limits can differ from ordinary HTTP requests.

Should every endpoint use the same rate limit?

No. Login, password reset, expensive search, API, and upload endpoints have different cost and abuse characteristics.

What is the emergency shutoff?

A tested way to disable public ingress quickly while preserving private operator access, logs, and recovery capability.

Related radar

Self-hosted Apps & Local Infrastructure Radar

Related RepoDaily briefs

Sources

  1. Nextcloud Reverse Proxy documentation
  2. Nextcloud Brute Force Protection
  3. NGINX WebSocket Proxying
  4. NGINX Request Rate Limiting module
  5. NGINX Connection Limiting module
  6. NGINX Core module client_max_body_size
  7. Caddy Reverse Proxy
  8. Caddy HTTPS Quick Start
  9. Caddy Trusted Proxies
  10. RepoDaily Home Server Backup & Recovery Checklist

Feedback

Did this page help you make a decision?

Anonymous feedback helps RepoDaily improve what is actually useful.

Report outdated or missing evidence