This guide shows you how to securely expose a self-hosted service (like a web app, API, or home server) to the internet without relying on Cloudflare Tunnel. You’ll use a standard reverse proxy (like Nginx or Caddy) with TLS encryption, a firewall that only allows necessary ports, and optional authentication. By the end, you’ll have a publicly reachable service that’s protected against common threats. You’ll need a domain name, a machine with a public IP (or port forwarding), and basic command-line comfort.
What You’ll Need
- A domain name (e.g.,
example.com) with DNS control. - A server or computer that can accept inbound connections (static IP or dynamic DNS).
- Root/sudo access to that machine.
- A reverse proxy installed (Nginx or Caddy are recommended).
- Ports 80 and 443 open on your router/firewall (if behind NAT).
- Basic knowledge of editing config files and using the terminal.
Step-by-Step
- Set up DNS
Create an A record for your service, e.g.,service.example.com, pointing to your public IP. If you have a dynamic IP, use a dynamic DNS service like DuckDNS or No-IP. - Install a reverse proxy
For Nginx on Ubuntu/Debian:sudo apt update && sudo apt install nginx. For Caddy: follow the official install script. Caddy automatically handles TLS, which simplifies things. - Configure the reverse proxy
For Nginx, create a config file in/etc/nginx/sites-available/and symlink it tosites-enabled. Example for a local service on port 8080:server { listen 80; server_name service.example.com; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }For Caddy, add to
Caddyfile:service.example.com { reverse_proxy localhost:8080 }. - Enable TLS (HTTPS)
For Nginx, install Certbot:sudo apt install certbot python3-certbot-nginx, then runsudo certbot --nginx -d service.example.com. For Caddy, TLS is automatic—just ensure ports 80 and 443 are open. - Harden the firewall
Allow only ports 80 (HTTP), 443 (HTTPS), and SSH (22) if needed. Use UFW on Ubuntu:sudo ufw allow 80/tcp,sudo ufw allow 443/tcp,sudo ufw allow 22/tcp, thensudo ufw enable. Block all other inbound ports. - Add authentication (optional but recommended)
Set up HTTP Basic Auth in Nginx withhtpasswdor use Caddy’sbasicauthdirective. This adds a login prompt before reaching your service. - Test locally first
Accesshttps://service.example.comfrom your local network to ensure the proxy works. If it fails, check the service is running and the proxy config is correct. - Open ports on router (if needed)
If your server is behind a home router, forward ports 80 and 443 to the server’s local IP. This is usually done in the router’s admin panel under “Port Forwarding”. - Monitor logs
Check Nginx logs at/var/log/nginx/access.loganderror.logfor suspicious activity. Consider setting up fail2ban to block repeated failed login attempts. - Keep software updated
Regularly update your OS, reverse proxy, and the service itself to patch security vulnerabilities.
Common Mistakes
- Leaving port 80 open without redirecting to HTTPS—always redirect HTTP to HTTPS to prevent unencrypted traffic.
- Using a weak password for Basic Auth—use a strong, unique password or better, use client certificates.
- Forgetting to set the Host header—some services require the correct Host header; Nginx’s
proxy_set_header Host $hostis essential. - Opening too many ports—only expose what’s necessary. Don’t open port 8080 directly; let the proxy handle it.
- Not testing from an external network—local testing doesn’t verify that port forwarding works correctly.
Tips
- Use a non-standard port for SSH and disable password authentication to reduce brute-force attacks.
- Set up automatic HTTPS redirect in Nginx: add
return 301 https://$host$request_uri;in the port 80 server block. - Consider using a dedicated user for the service to limit damage if it’s compromised.
- Use a firewall that only allows connections from your own IP for administrative interfaces, if possible.
- Enable gzip compression in the proxy to speed up responses.
Troubleshooting
- Cannot reach the service from outside—Check that ports 80/443 are forwarded correctly, the firewall allows them, and the service is listening on all interfaces (not just localhost). Use
netstat -tulpnto verify. - Certificate errors—Ensure DNS points to the correct IP and that port 80 is open for Let’s Encrypt validation. Try renewing the certificate manually.
- 502 Bad Gateway—The proxy can’t reach your service. Confirm the service is running and the proxy_pass URL is correct (e.g.,
http://localhost:8080). - Service works locally but not externally—Often a firewall or NAT issue. Double-check your router’s port forwarding rules and that the server’s IP is static.
- Slow performance—Check if the service is CPU-bound or if the proxy needs more worker processes. Also, ensure DNS is resolving quickly.
Frequently Asked Questions
Is it safe to expose a service without Cloudflare Tunnel?
Yes, if you follow security best practices: use HTTPS, strong authentication, keep software updated, and limit exposure. A reverse proxy with TLS is a standard, secure method.
Do I need a static IP?
Not necessarily. You can use dynamic DNS to update your domain’s A record when your IP changes. Many home routers support this natively.
Can I use this for a service on a different port?
Yes, the reverse proxy can forward to any local port. Just set the proxy_pass to the correct port.
What if I don’t have a domain name?
You can use a free subdomain from services like DuckDNS or use a self-signed certificate, but that will cause browser warnings. A domain is strongly recommended.
How do I block specific IPs?
Use your firewall (e.g., ufw deny from IP) or configure Nginx’s deny directive in the server block.
Can I expose multiple services?
Yes, create a separate server block for each subdomain or use path-based routing with Nginx’s location blocks.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Mac Start Up Automatically After Power Failure?
- Nano Delivery for Functional Foods: What It Can and Can’t Do4.00
- Disable Apple Watch Turn-by-Turn Vibration While Driving
- Convert Play FLAC in iTunes: Full Guide
- Soda Foundation Charter: What It Means
- Assassin’s Creed Mirage: How Long to Beat