So you built something cool at home. Maybe it is a Nextcloud instance, a media server, a home automation dashboard, or a custom web app running on a Raspberry Pi. It works perfectly on your local network. Now you want to access it from anywhere, and you started googling how to open a port on your router.
Stop right there. Opening a port directly to the internet is the single fastest way to get your home network compromised. Within hours of exposing a service, automated scanners will find it, probe it, and start hammering it with login attempts. I have seen fresh servers get hit by brute-force attacks within 30 minutes of going live.
The right approach is to put a reverse proxy in front of your self-hosted service. A reverse proxy acts as a gateway that sits between the public internet and your internal application, handling encryption, authentication, and traffic filtering before anything reaches your actual service. This guide walks through the entire process of securely exposing a single self-hosted service to the internet with a reverse proxy, from choosing your method to locking it down.
We will cover why direct exposure is dangerous, compare every major method for reaching your service remotely, pick the right proxy software, walk through a real setup, and build a security checklist you can follow. By the end, you will have a single service accessible from anywhere without exposing your home network to the world.
Table of Contents
What Is a Reverse Proxy and Why Use One?
A reverse proxy is a server that accepts incoming internet traffic on behalf of your application and forwards it to the internal service running on your network. Instead of the internet talking directly to your app, the internet talks to the proxy, and the proxy decides what gets through.
Think of it like a receptionist at a secure office building. Visitors do not wander the halls looking for the right door. They check in at the front desk, get verified, and the receptionist directs them to the correct room. The reverse proxy is that receptionist for your network traffic.
For a single self-hosted service, a reverse proxy gives you four major benefits that direct port forwarding simply cannot match.
SSL and TLS encryption. The proxy handles HTTPS certificates automatically, so your traffic is encrypted between the user and your network. Tools like Let’s Encrypt provide free certificates, and modern proxy software renews them without any manual work.
Centralized authentication. You can require a login at the proxy layer before traffic ever reaches your application. This means even if your app has weak or missing authentication, the proxy blocks unauthorized access.
Traffic filtering and rate limiting. A reverse proxy can throttle requests, block suspicious IPs, and absorb basic DDoS attempts. Your actual service never sees the malicious traffic.
Hidden infrastructure. The outside world only sees the proxy. Your internal IP addresses, port numbers, and server details stay hidden. An attacker who compromises the proxy still faces another layer before reaching your network.
The Dangers of Direct Port Forwarding
Port forwarding is what most people try first because it is simple. You tell your router to send all traffic on a specific port to your service, and suddenly the world can reach it. The problem is that the world includes bots, scanners, and attackers who are constantly looking for exposed services.
When you forward a port, you are punching a hole through your firewall. That hole is permanent, visible to anyone running a port scan, and directly connected to your internal network. There is no filter, no authentication layer, and no encryption unless you set it up yourself on the application side.
Here is what happens in practice when you expose a service directly.
Automated scanning starts immediately. Services like Shodan and Censys continuously map every internet-connected device. Within hours, your service appears in their databases, tagged with its software version and known vulnerabilities.
Brute-force attacks never stop. If your service has any login mechanism, bots will start guessing credentials around the clock. Default usernames like admin get thousands of attempts per day.
Software vulnerabilities become critical. If your self-hosted app has a known exploit and you have forwarded a port to it, anyone can use that exploit against you. There is no buffer between the attacker and your application.
Your home network is at risk. A compromised service on your local network can be used as a foothold to attack other devices, including computers, phones, and smart home equipment that shares the same network.
The bottom line is that port forwarding without a proxy is like leaving your front door open because you want friends to be able to walk in. Sure, they can, but so can everyone else.
Choosing Your Exposure Method
There are several ways to reach a self-hosted service from the internet, and each has trade-offs between security, simplicity, and cost. The right choice depends on your threat model, technical comfort, and whether you need public access or just personal remote access.
Here is how the main methods compare.
| Method | Security | Setup Difficulty | Public Access | Cost |
|---|---|---|---|---|
| Port Forwarding | Low | Easy | Yes | Free |
| VPN (WireGuard) | High | Medium | No (members only) | Free |
| Cloudflare Tunnel | High | Easy | Yes | Free tier |
| SSH Reverse Tunnel | Medium | Medium | Yes (with VPS) | Low (VPS cost) |
| VPS Reverse Proxy | High | Hard | Yes | VPS cost |
Port forwarding routes traffic from a public port directly to your service. It is the simplest method but also the least secure. I only recommend it when combined with a reverse proxy, firewall rules, and strong authentication, never on its own.
A VPN like WireGuard creates an encrypted tunnel between your remote device and your home network. When connected, you can access services as if you were at home. This is extremely secure because the service is never exposed publicly. The downside is that every person who needs access must install and configure a VPN client. It works great for personal use but not for sharing a service with others.
Cloudflare Tunnel is a popular choice that requires no open ports on your router. You run the cloudflared daemon on your server, and it establishes an outbound connection to Cloudflare. Traffic flows through Cloudflare’s network to your service. This hides your home IP address and gives you free DDoS protection. The trade-off is that Cloudflare sits in the middle of all your traffic, and their terms of service restrict certain types of content.
An SSH reverse tunnel uses a cheap VPS as a relay. Your home server connects out to the VPS via SSH and creates a tunnel that forwards traffic back to your service. This is a favorite among power users on self-hosting forums because it is free, requires no special software, and works with any VPS provider. You still need a reverse proxy on the VPS to handle SSL.
A VPS-based reverse proxy is the most flexible approach for public-facing services. You rent a small VPS, install a reverse proxy with SSL, and connect it to your home network via a WireGuard tunnel. Your home IP stays completely hidden, and the VPS absorbs all the scanning and probing traffic. This costs a few dollars per month but gives you the best combination of security and flexibility.
For most people exposing a single service for personal use, I recommend either WireGuard for private access or Cloudflare Tunnel for public access with minimal setup. If you want full control and do not mind a little server administration, the VPS and reverse proxy approach is the gold standard.
Picking a Reverse Proxy for a Single Service
Once you have chosen your exposure method, you need reverse proxy software to sit in front of your application. There are four main options that the self-hosting community relies on, and each has strengths depending on your experience level.
Nginx is the battle-tested industry standard. It powers a huge portion of the internet and handles massive traffic loads. For a single service, the configuration is manageable but requires manual editing of config files. You will need to set up SSL certificates yourself, either through Certbot or a similar tool. Nginx gives you maximum control but has the steepest learning curve.
Caddy is the best choice for beginners and single-service setups. Its killer feature is automatic HTTPS. Caddy obtains and renews Let’s Encrypt certificates by default, with zero configuration. You write a three-line config file, and Caddy handles the rest. For one service, Caddy is hard to beat.
Traefik is designed for Docker environments. It automatically discovers containers and routes traffic to them based on labels. If your service runs in Docker and you plan to add more services later, Traefik scales beautifully. For a single static service, it can feel like overkill.
Nginx Proxy Manager wraps Nginx in a web interface. You configure proxies, SSL, and authentication through a dashboard instead of config files. It is popular in the home lab community because it makes the process visual. If you are intimidated by command-line configuration, this is a great starting point.
For this guide, I will walk through the setup using Caddy because it is the simplest option for a single self-hosted service and handles SSL automatically. If you prefer a different tool, the security principles apply equally to all of them.
Step-by-Step: Setting Up a Reverse Proxy With Caddy
This walkthrough assumes you have a service running locally on your home server and you want to expose it through a reverse proxy with automatic SSL. You will need a domain name pointing to your server and a service already running on a local port.
Step 1: Get a domain name and configure DNS.
You need a domain name for SSL certificates to work. Register a domain with any registrar, then create a DNS A record pointing your subdomain to your public IP address. For example, point app.yourdomain.com to your home IP. If your home IP changes, set up dynamic DNS to keep the record updated automatically.
If you are using Cloudflare Tunnel instead of direct DNS, skip this step. The tunnel handles routing for you.
Step 2: Install Caddy on your server.
On a Debian or Ubuntu system, install Caddy through the official repository. The exact commands are on the Caddy download page, but the process adds the Caddy repository and installs the package. Once installed, Caddy runs as a systemd service.
Step 3: Write the Caddyfile.
The Caddyfile is Caddy’s configuration file. For a single service, it is remarkably short. Here is a basic example that proxies traffic to a service running on local port 8080.
app.yourdomain.com {
reverse_proxy localhost:8080
}That is it. Caddy automatically obtains an SSL certificate for your domain, sets up HTTPS, and renews the certificate before it expires. When a visitor goes to app.yourdomain.com, Caddy forwards their request to your service on port 8080 and sends the response back over an encrypted connection.
Step 4: Open ports 80 and 443 on your router.
For Caddy to obtain certificates and serve HTTPS, ports 80 and 443 must reach your server. Forward these two ports on your router to the internal IP of your Caddy server. Do not forward port 8080 or whatever port your actual service uses. Only the proxy should be reachable from outside.
If you are using Cloudflare Tunnel, you do not need to open any ports. The tunnel handles all traffic over an outbound connection.
Step 5: Test and verify.
Visit your domain in a browser. You should see your service load over HTTPS with a valid certificate. If something is wrong, check the Caddy logs with systemctl status caddy for error messages. Common issues are DNS not propagating, ports not forwarded correctly, or the local service not running.
Step 6: Add basic authentication.
Before you consider the setup complete, add a login prompt at the proxy level. Caddy supports basic authentication with a few extra lines in the Caddyfile. Generate a password hash using Caddy’s hash-password command, then add an encode block.
app.yourdomain.com {
basicauth {
yourusername $2a$14$hashedpassword
}
reverse_proxy localhost:8080
}Now anyone visiting your domain sees a login dialog before they can reach your service. This is a simple but effective first layer of defense.
Securing Your Reverse Proxy
Getting the proxy running is only half the job. The other half is hardening it so it can withstand the constant probing that anything on the public internet receives. Here is a security checklist that covers the most important layers.
Enable multi-factor authentication.
Basic authentication with a username and password is better than nothing, but it is still vulnerable to brute-force attacks. For services that support it, add MFA through an identity provider. Authelia is a popular open-source solution that sits alongside your reverse proxy and provides multi-factor authentication, session management, and access control. For a single service, it adds significant protection with moderate setup effort.
OAuth2 proxy is another option that lets users authenticate through providers like GitHub, Google, or Auth0. This eliminates password management entirely and gives you enterprise-grade authentication for free.
Install and configure fail2ban.
Fail2ban monitors your logs for repeated failed login attempts and automatically bans the offending IP addresses using firewall rules. It is one of the highest-impact security tools you can install, and the self-hosting community recommends it universally. Set it up to monitor both your SSH logs and your reverse proxy logs. A typical configuration bans IPs after five failed attempts for one hour.
Lock down your firewall.
Your server should only expose the ports that are absolutely necessary. On the proxy server, allow inbound traffic on ports 80 and 443 for web traffic and port 22 for SSH, then deny everything else by default. If you use a VPS, restrict SSH to key-based authentication only and disable password login entirely.
On your home network, use network segmentation if your router supports it. Put your self-hosted services on a separate VLAN from your personal devices. This way, even if a service is compromised, the attacker cannot easily reach your computers and phones.
Enable rate limiting.
Rate limiting caps how many requests a single IP can make in a given time period. This protects against brute-force attacks and basic denial-of-service attempts. Caddy, Nginx, and Traefik all support rate limiting through configuration. A reasonable starting point is 10 requests per second per IP, adjusted based on your service’s normal traffic patterns.
Keep everything updated.
Software vulnerabilities are discovered regularly in web servers, proxy software, and the applications themselves. Set up automatic updates for your operating system, or at minimum check for updates weekly. If you run services in Docker, use a tool like Watchtower to automatically pull updated container images. An outdated reverse proxy with a known vulnerability is worse than no proxy at all.
Disable directory listing and hide version information.
By default, some web servers reveal their software version in HTTP headers and list directory contents when no index file is present. This information helps attackers identify known exploits. Configure your proxy to strip version headers and return a custom error page instead of a directory listing.
Security hardening checklist:
SSL certificate active and auto-renewing
Multi-factor authentication or OAuth2 enabled
Fail2ban running on SSH and proxy logs
Firewall allows only ports 80, 443, and 22
SSH set to key-based authentication only
Rate limiting configured on the proxy
All software updated to latest stable versions
Version headers stripped from HTTP responses
Services on a separate VLAN from personal devices
Regular backups of configuration and data
Docker Considerations for Self-Hosted Services
If your self-hosted service runs in Docker, the reverse proxy setup changes slightly but becomes more manageable. Docker isolates your application in a container with its own network stack, which adds a natural layer of separation between the service and your host system.
The cleanest approach is to run both your service and the reverse proxy as containers in the same Docker network. This way, the proxy can reach the service by container name without exposing any ports to the host. Only the proxy container maps ports 80 and 443 to the host. Your application container is completely invisible from outside the Docker network.
If you use Docker Compose, you can define both containers in a single compose file. The service container exposes its port only within the internal Docker network, while the proxy container handles external traffic. This makes the setup reproducible and easy to back up, since the entire configuration lives in one file.
Traefik deserves a mention here because it integrates with Docker natively. Instead of writing configuration files, you add labels to your service container, and Traefik automatically creates the proxy route. For a single service this is convenient but not essential. For multiple services, it becomes invaluable.
Monitoring and Logging
Once your service is live, you need visibility into what is hitting it. Without monitoring, you have no way to know if you are under attack, if your certificate is about to expire, or if your service has gone down.
At minimum, check your reverse proxy access logs regularly. Look for patterns like repeated 401 unauthorized responses, which indicate brute-force attempts. Unusual spikes in traffic volume can signal a scanning bot or a DDoS attempt. Most proxy software writes logs in a standard format that is easy to parse.
For a more complete setup, consider a monitoring stack. Grafana paired with Prometheus gives you dashboards showing traffic volume, response times, and error rates. Graylog or Loki centralizes your logs so you can search across all your services from one interface. Uptime Kuma is a lightweight option that pings your service at regular intervals and alerts you if it goes down.
For a single self-hosted service, a full monitoring stack might be overkill. At the very least, set up Uptime Kuma so you get a notification if your service stops responding. It is free, easy to install, and runs in Docker alongside your other containers.
Fail2ban already gives you a basic form of security monitoring by watching logs and banning IPs. Review its banned IP list periodically to understand the threat landscape your service faces. You might be surprised how active it is.
Common Mistakes to Avoid
I have spent time in self-hosting communities, and the same mistakes come up over and over. Here are the ones that cause the most problems.
Exposing the service port instead of only the proxy port. Some people forward both port 443 for the proxy and port 8080 for the actual service. This defeats the entire purpose of the proxy because attackers can bypass it entirely and hit the service directly. Only expose ports 80 and 443, and let the proxy handle everything internally.
Forgetting to set up certificate renewal. SSL certificates from Let’s Encrypt expire every 90 days. If you configured Nginx manually with Certbot, make sure the renewal cron job is active. Caddy handles this automatically, but other tools do not. An expired certificate means browsers show scary warnings and your service becomes effectively unreachable.
Using weak credentials on the proxy. If you set up basic authentication with a weak password, you have added almost no security. Use a long, random password generated by a password manager. Better yet, use key-based authentication or OAuth2 so passwords are not involved at all.
Ignoring updates for months. The excitement of getting a service online fades, and before long your proxy software is six months out of date. Set a calendar reminder or automate updates. Vulnerabilities in proxy software are actively exploited, and running an outdated version puts your entire setup at risk.
Not testing from outside your network. Everything might work perfectly when you test from your couch on the same network as the server. The real test is accessing it from a different network, like a mobile data connection. DNS rebinding, hairpin NAT issues, and firewall rules can all break external access while internal access works fine.
Running the proxy and services on the same network as personal devices. Without network segmentation, a compromised service gives an attacker a foothold on the same network as your laptop and phone. Use a separate VLAN or at minimum restrict what the service can reach on your local network.
Frequently Asked Questions
Can I use a reverse proxy for self-hosting?
Yes. A reverse proxy is one of the best ways to expose self-hosted services because it handles SSL encryption, authentication, and traffic filtering while keeping your internal network hidden from the public internet.
How can I expose my local server to the internet?
The safest methods are using a VPN like WireGuard for private access, Cloudflare Tunnel for public access without opening ports, or a VPS with a reverse proxy connected to your home via an encrypted tunnel. Avoid direct port forwarding without a proxy.
Can CloudFlare act as a reverse proxy?
Yes. Cloudflare Tunnel acts as a reverse proxy by connecting your server to Cloudflare through an outbound tunnel. It handles SSL, DDoS protection, and hides your home IP address without requiring any open ports on your router.
What are the downsides of using reverse proxies?
Reverse proxies add configuration complexity, a potential performance overhead from encrypting and decrypting traffic, and a single point of failure if the proxy goes down. They also require ongoing maintenance like certificate renewal and security updates.
Can a reverse proxy be hacked?
Yes, if it is misconfigured or running outdated software with known vulnerabilities. Reduce the risk by keeping software updated, using fail2ban, enabling rate limiting, requiring multi-factor authentication, and restricting access with strict firewall rules.
Is a reverse proxy better than a VPN for self-hosting?
It depends on your needs. A VPN is more secure for personal access because the service is never exposed publicly. A reverse proxy is better when you need to share the service with others or access it without installing client software. Many setups use both together.
Conclusion
Securely exposing a single self-hosted service to the internet with a reverse proxy comes down to three things: choosing the right exposure method, picking proxy software that fits your skill level, and hardening every layer from DNS to authentication.
Start with Caddy for its automatic SSL and minimal configuration if this is your first time. Use Cloudflare Tunnel if you want to avoid opening ports entirely, or set up a VPS with WireGuard if you want full control. Add fail2ban, configure your firewall, enable multi-factor authentication, and keep everything updated.
The effort is small compared to the risk of exposing your home network directly. Take it one step at a time, test from outside your network, and you will have a self-hosted service that is accessible from anywhere and secure enough to sleep well at night.