Skip to content
Mustafa Erbay
Tutorials · 9 min read · görüntülenme Türkçe oku

5 Ways to Securely Publish Self-Hosted Services with Cloudflare Tunnel

Steps, security benefits, and considerations for securely exposing your self-hosted services to the internet using Cloudflare Tunnel.

100%

Recently, when I needed to make an internal API of a production ERP accessible from the outside, the idea of opening a port in the firewall made me uncomfortable. Exposing a service to the internet using traditional methods typically requires opening specific ports in the firewall and configuring a reverse proxy, which increases the potential attack surface and leaves you directly vulnerable to threats like DDoS. This is precisely where Cloudflare Tunnel eliminates these problems by offering an outbound-only solution for securely publishing self-hosted services.

Cloudflare Tunnel creates an encrypted tunnel from your server to the Cloudflare network, allowing you to securely expose your services to the internet without opening any inbound ports. This keeps your server’s IP address hidden, protects it from direct attacks, and allows you to benefit from Cloudflare’s extensive security layers (DDoS protection, WAF, authentication). In this post, drawing from my own experiences, I will detail how we set up and configured Cloudflare Tunnel and the five fundamental steps involved in this process.

What is Cloudflare Tunnel and Why Should We Use It?

Cloudflare Tunnel is a Zero Trust service that establishes a persistent, encrypted connection from your server to the Cloudflare network via a lightweight agent called cloudflared running on your server. Unlike traditional approaches, you don’t need to open any inbound ports in your server’s firewall; all traffic is routed through this tunnel via Cloudflare’s global network.

This approach offers significant security advantages, especially for those publishing services on their home servers or internal infrastructure. Your server’s real IP address is hidden, you are protected from direct DDoS attacks or port scans, and you automatically benefit from additional Cloudflare security features like WAF (Web Application Firewall). When I chose this method to make a client’s internal application externally accessible without a VPN and without opening firewall ports, I was quite impressed by the simplicity of the setup and the security it provided.

graph TD;
  A["User"] --> B["Cloudflare Edge"];
  B --> C["Cloudflare Tunnel"];
  C --> D["cloudflared agent (on server)"];
  D --> E["Self-Hosted Service"];

The diagram above illustrates the basic working principle of Cloudflare Tunnel. Requests from the user first reach Cloudflare’s global edge servers, from there they are forwarded via the secure tunnel to the cloudflared agent, which then finally delivers them to your local service. This flow optimizes performance and activates security layers.

How to Get Started with Cloudflare Tunnel Setup?

The first step to using Cloudflare Tunnel is to install the cloudflared agent on your server and connect it to your Cloudflare account. This agent is the critical component that creates the tunnel and routes incoming requests to the correct services. Since I generally work on Linux servers, I will provide installation steps based on Ubuntu/Debian-based systems, but cloudflared is supported on almost all popular operating systems.

First, you need to download the cloudflared binary from the official Cloudflare repository and install it on your system:

# First, add the Cloudflare GPG key
curl -fsSL https://pkg.cloudflare.com/cloudflare-req.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloudflare-archive-keyring.gpg

# Then, add the Cloudflare repository to the sources.list.d directory
echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list

# Update the package list and install cloudflared
sudo apt update
sudo apt install cloudflared

Once the installation is complete, you need to authenticate cloudflared with your Cloudflare account. This process is done via a browser and downloads the necessary credentials to manage your tunnel.

cloudflared tunnel login

This command will provide you with a URL and ask you to open it in your browser to log in to your Cloudflare account. After a successful login, a certificate file named cert.pem will be created, and your cloudflared agent will be associated with your Cloudflare account.

How to Create a New Cloudflare Tunnel and Define Services?

After installing the cloudflared agent and authenticating it, you are now ready to create your first tunnel. Creating a tunnel essentially means defining a persistent connection point on the Cloudflare network and specifying which services will be published through this tunnel.

First, create your tunnel and give it a name:

cloudflared tunnel create my-erp-tunnel

This command will generate a unique UUID (Universally Unique Identifier) and an authentication key for the tunnel. Note down the UUID provided in the output, as this is the unique identifier for your tunnel.

Now we need to create a configuration file (config.yml) for this tunnel. This file defines which domain names the tunnel will be accessible through and which local services incoming requests to these domain names will be routed to. I generally prefer to create a configuration file in the /etc/cloudflared/ directory.

# /etc/cloudflared/config.yml
tunnel: <TUNNEL_UUID> # The UUID you got from the create command above
credentials-file: /root/.cloudflared/<TUNNEL_UUID>.json # Authentication file

ingress:
  - hostname: erp.example.com
    service: http://localhost:8000 # My local ERP API
  - hostname: dashboard.example.com
    service: http://localhost:3000 # Local admin panel
  - service: http_status:404 # Return 404 for other undefined requests

In this config.yml file, you should replace <TUNNEL_UUID> with your tunnel’s UUID and <TUNNEL_UUID>.json with the name of your authentication file. The ingress section determines how incoming requests will be routed. Here, I defined that requests coming to erp.example.com will be routed to the service on port localhost:8000, and requests to dashboard.example.com will be routed to the service on port localhost:3000. The final service: http_status:404 rule acts as a fallback for requests that do not match any other rule.

After saving the configuration file, you need to create CNAME records for erp.example.com and dashboard.example.com in your Cloudflare DNS panel and point these records to your tunnel. These records should point as CNAME to the cfargotunnel.com address associated with your tunnel’s UUID (e.g., erp.example.com CNAME <TUNNEL_UUID>.cfargotunnel.com).

Finally, we need to run the cloudflared tunnel as a systemd service so that it automatically starts when the server reboots and runs continuously in the background.

# Create the systemd service file
sudo nano /etc/systemd/system/[email protected]

Edit the content as follows:

[Unit]
Description=Cloudflared Tunnel %i
After=network-online.target

[Service]
ExecStart=/usr/bin/cloudflared tunnel --config /etc/cloudflared/config.yml run %i
Restart=on-failure
RestartSec=5s
User=root # or another user
Group=root # or another group
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=yes
StandardOutput=journal
StandardError=journal
SyslogIdentifier=cloudflared-%i

[Install]
WantedBy=multi-user.target

After saving the service file, update systemd and start the service:

sudo systemctl daemon-reload
sudo systemctl enable [email protected]
sudo systemctl start [email protected]

You can check the tunnel’s status and logs with the command journalctl -u [email protected]. Once the tunnel starts successfully, you will be able to access your local services via the specified domain names. I had published the backend of my own side product’s financial calculators this way some time ago and saw how simple and secure the setup was.

Tunnel Configuration for SSH and Other TCP Services

Cloudflare Tunnel can be used not only for HTTP/S services but also for SSH, RDP, or any TCP service. This is particularly useful when you want to securely access your servers remotely. In the config.yml file, in addition to ingress rules, we can use the tunnel command for ssh.

For SSH access, we can update the config.yml file as follows:

# /etc/cloudflared/config.yml (continued)
# ... existing ingress rules ...

  - service: ssh://localhost:22 # For SSH service
    hostname: ssh.example.com
    originRequest:
      noTLSVerify: true # Local SSH service usually doesn't use TLS

Then, don’t forget to create a CNAME record for ssh.example.com in the Cloudflare panel. Afterwards, to use this tunnel from your SSH client, you can add a configuration like the following to your ~/.ssh/config file:

Host ssh.example.com
  ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h

With this configuration, when you run the ssh ssh.example.com command, your SSH traffic will be securely routed through the Cloudflare Tunnel. This offers a great alternative to traditional VPN connections and extends Zero Trust principles to your SSH access.

What are the Security Benefits of Cloudflare Tunnel?

Using Cloudflare Tunnel provides a host of benefits that significantly enhance the security posture of your self-hosted services. These benefits create a layered defense mechanism that would be difficult or costly to achieve with traditional methods.

  1. No Inbound Ports, Reduced Attack Surface: Since no inbound ports are opened on your server, potential attackers cannot directly target your server’s IP address. Your server becomes much more secure against port scans, weak password SSH attempts, or unknown vulnerabilities. When I set up a similar structure to protect the backend API of my own Android spam blocker application, I experienced the peace of mind that comes from working on a server closed to the outside world.
  2. Origin IP Hiding: Since your services are published through Cloudflare, your server’s real IP address is not exposed to the internet. This makes targeted attacks and information gathering attempts more difficult.
  3. DDoS and Bot Protection: All traffic passes through the Cloudflare network, so you automatically benefit from Cloudflare’s extensive DDoS protection and bot management systems. This is vital for high-traffic applications or services with potential attack risks.
  4. Web Application Firewall (WAF): For HTTP/S traffic, Cloudflare WAF provides protection against common web attacks such as SQL injection and XSS. This helps to close potential security vulnerabilities in your application.
  5. Authentication and Authorization (Cloudflare Access): With Cloudflare Access, you can restrict access to services published through the tunnel on a per-user basis. For example, by integrating with Identity Providers (IdPs) like Google Workspace, Okta, or Azure AD, you can allow access only to specific users or groups. This is an excellent security layer for internal tools or admin panels. We have implemented such authentication mechanisms using JWT and OAuth2 patterns in multiple projects.
  6. Traffic Encryption: All traffic between the cloudflared agent and Cloudflare Edge is encrypted with TLS. This ensures the security of your data during transmission.

The combination of these benefits transforms Cloudflare Tunnel from just an access solution for self-hosted services into a cornerstone of a comprehensive security strategy.

What are the Challenges and Trade-offs When Using Cloudflare Tunnel?

While Cloudflare Tunnel offers many advantages, like any technology, it also has its unique challenges and trade-offs. By considering these points, you can make the right decision for your project.

  1. Vendor Lock-in: When you use Cloudflare Tunnel, you become tied to the Cloudflare ecosystem. Many components, from DNS management to tunnel configuration, become dependent on Cloudflare. This can make switching to a different provider difficult or incur additional costs in the long run. I generally prefer to use open-source and flexible solutions in infrastructure as much as possible, but the ease and security offered by Cloudflare sometimes make this “lock-in” risk worth taking.
  2. Performance Impact: Traffic traveling from your server to the Cloudflare network and then to the user adds an extra “hop” compared to a traditional direct connection. While this impact is negligible in most cases, it should be considered for applications requiring ultra-low latency. Thanks to Cloudflare’s extensive network, this latency is usually minimized, but it is still a factor.
  3. Reliability of the cloudflared Agent: Although the cloudflared agent generally runs stably, it can stop unexpectedly due to resource limitations (CPU, memory) or network issues on your server. In one project, when the cloudflared service unexpectedly stopped, I realized once again how important it is to correctly configure the systemd unit with parameters like Restart=on-failure and RestartSec. There were even cases where it was OOM-killed, so cgroup limits might need to be adjusted.
  4. Debugging Complexity: Troubleshooting can be a bit more complex compared to traditional setups. It can take time to pinpoint whether the error is in the tunnel itself, at the Cloudflare Edge, or in the backend service. Carefully examining journalctl outputs and logs in the Cloudflare dashboard is critically important in this process.
  5. Free Tier Limits: While Cloudflare’s free tier is sufficient for many users, there may be certain traffic or feature limits. For scenarios requiring more advanced security features (e.g., more comprehensive WAF rules) or higher bandwidth, upgrading to paid plans may be necessary.

Knowing these challenges and trade-offs helps you use Cloudflare Tunnel strategically. Like any tool, it provides the greatest benefit when used in the right scenario and with the right expectations.

How Do We Monitor and Manage the Tunnel Infrastructure?

Setting up a Cloudflare Tunnel is just the beginning; the real challenge is ensuring it runs stably and securely. Effectively monitoring and managing your tunnel infrastructure is vital for proactively detecting potential issues and preventing service outages.

  1. Following cloudflared Logs: The cloudflared agent generates important logs while it’s running. These logs contain valuable information about the tunnel’s status, incoming requests, error messages, and connection problems. When running it as a systemd service, we can easily follow the logs via journalctl:

    journalctl -u [email protected] -f

    This command shows the live log stream of the tunnel and allows us to intervene quickly in case of any anomaly. Last month, I saw from journalctl outputs that cloudflared was OOM-killed on a VPS, and then I solved the problem by adjusting the cgroup memory limits.

  2. Monitoring via Cloudflare Dashboard: The Cloudflare panel provides a central interface for managing your tunnels and monitoring their status. From here, you can see if your tunnels are active, review traffic statistics, and manage Access policies. The dashboard is particularly useful for providing an overview when you have multiple tunnels.

  3. Automatic Update Strategies: The cloudflared agent is updated from time to time with new features or security patches. Regularly applying these updates improves both the performance and security of your tunnel. cloudflared versions installed using package managers like apt or yum can be included in the system’s normal update flow. However, sometimes manual control and testing, especially in production environments, is a safer approach.

    sudo apt update && sudo apt upgrade cloudflared
  4. Multiple Agents for High Availability: To reduce the risk of a single cloudflared agent failing for critical services, you can run multiple cloudflared agents on different servers for the same tunnel. Cloudflare automatically load balances between these agents as long as the tunnel UUID is the same. This ensures that your service remains accessible even if one agent goes offline. Using this structure for the ERP’s API in a production environment provided us with great peace of mind regarding service continuity.

  5. Health Checks and Alerts: To monitor the health of services published through the tunnel and receive alerts for potential issues, you can integrate Cloudflare’s health check features or external monitoring tools like Prometheus/Grafana. This informs you if the backend service becomes inaccessible, even if the tunnel itself is running smoothly.

These management and monitoring practices ensure that your Cloudflare Tunnel setup not only works but is also reliable and sustainable.

Conclusion

Cloudflare Tunnel offers a powerful and practical solution for anyone looking to securely expose self-hosted services to the internet. It eliminates the security risks associated with traditional port-opening methods while allowing you to benefit from Cloudflare’s extensive security and performance features. As I’ve seen from my own experiences, Cloudflare Tunnel becomes an indispensable tool, especially for implementing Zero Trust principles, reducing the attack surface, and simplifying remote access processes.

The simplicity of its setup, flexible configuration options, and the layered security benefits it provides make it attractive for both small personal projects and large enterprise applications. Of course, like any technology, it has its trade-offs and management requirements; however, when these steps are correctly applied, you can significantly enhance the security of your self-hosted infrastructure and lighten your operational load. The next step would be to further restrict access to services published through these tunnels with Cloudflare Access and add an authentication layer.

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

How was this post?

Frequently Asked Questions

Common questions readers have about this article.

How should I start using Cloudflare Tunnel?
To start using Cloudflare Tunnel, I first began by installing the `cloudflared` agent on my server. Then, I made the necessary settings and configured the tunnel using my Cloudflare account. These steps were quite simple and straightforward, but it's important to read the documentation carefully.
What are the advantages and disadvantages of Cloudflare Tunnel?
In my experience, the biggest advantage of Cloudflare Tunnel is that it protects the server from direct attacks by hiding its IP address. Additionally, security features like DDoS protection and WAF are quite robust. As a disadvantage, in some cases, setting up the tunnel can take some time, but this is an acceptable trade-off given the security it provides.
What should I do if an error occurs during Cloudflare Tunnel setup?
I encountered some errors during setup, but I used Cloudflare's documentation and support resources to resolve them. Also, in some cases, it may be necessary to update the `cloudflared` agent or reconfigure its settings. Being patient and carefully checking each step ensures that errors are resolved quickly.
Is Cloudflare Tunnel more secure than traditional methods?
In my opinion, Cloudflare Tunnel is a more secure option than traditional methods. Traditional methods require opening ports in the firewall, which increases the potential attack surface. Cloudflare Tunnel, on the other hand, offers an outbound-only solution, hiding the server's IP address and protecting it from direct attacks. Furthermore, Cloudflare's security layers provide powerful security features like DDoS protection and WAF.
ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Comments

Server-side AI Moderation

Comments are AI-moderated server-side and stored permanently.

?
0/2000

Server-side AI moderation

✉️ Free · No spam · Unsubscribe anytime

Get notified about new posts

New content and technical notes — straight to your inbox.

  • 📌
    Best of the week Single most-worth-reading post
  • 🔧
    Toolbox notes Real tools I used this week
  • 🧠
    Behind-the-scenes Notes that don't make it to blog

We don't spam. Unsubscribe anytime. · Tracked only by Umami (self-hosted, no Google).

Your Reading Stats

0

Posts Read

0m

Reading Time

0

Day Streak

-

Favorite Category

Related Posts