Exposing your local server on the Internet (clearnet) has various solutions, but the Cloudflare Tunnel stands out as the easiest and most cost-effective option. Traditionally, configuring Firewalls, using Tor, or setting up an SSH reverse tunnel to a public VPS were common approaches, each with its challenges and costs. Cloudflare Tunnel offers an alternative, though it acts as a middleman and can access or modify your traffic.
{% hint style="warning" %}
Cost: Paid service
{% hint style="warning" %}
Difficulty: Medium

With Cloudflare Tunnel, you gain low-latency access to your server on clearnet, without the need for complex firewall or router configurations, dynamic DNS, or relying on an internet service provider.
Cloudflare Tunnel ensures secure connectivity without exposing your server's publicly routable IP address. Instead, a lightweight daemon, cloudflared, creates outbound-only connections to Cloudflare's global network. This establishes persistent tunnels that route traffic to DNS records. You can run multiple cloudflared processes within a tunnel, connecting your resources securely to Cloudflare's nearest data center.
Before you start, make sure you:
example.com) and then click on the [Add site] button again


{% hint style="info" %}
Once all of this is done, you need to wait for the registrar to update the nameservers. This process can take up to 24 hours, but it is usually much more immediate. In any case, Cloudflare will send an email when the process is finished

Example of email notification received from Cloudflare

{% hint style="info" %}
You can manually add a new record by clicking the "Add record" button. More later, we will use this. Right now, you will not have any record
{% hint style="info" %}
Keep this Cloudflare session open. We will add and modify some registries to configure the tunnel
admin, go to the temporary foldercd /tmp
VERSION=2026.1.1
wget https://github.com/cloudflare/cloudflared/releases/download/$VERSION/cloudflared-linux-amd64.deb
SHA256=a982b43a93b4e1d3dd290fbf08a7ed76f199a773fa60d487939892677501ca70
echo "$SHA256 cloudflared-linux-amd64.deb" | sha256sum --check
Example of expected output:
cloudflared-linux-amd64.deb: OK
sudo dpkg -i cloudflared-linux-amd64.deb
cloudflared --version
Example of expected output:
cloudflared version 2023.6.1 (built 2023-06-20-0926 UTC)
sudo rm cloudflared-linux-amd64.deb
{% hint style="info" %}
If you come to update, this is the final step
admin, authenticate Cloudflared with your Cloudflare accountcloudflared tunnel login
Example of expected output:
Please open the following URL and log in with your Cloudflare account:
https://dash.cloudflare.com/argotunnel?aud=&callback=https%3A%2F%2Flogin.cloudflareaccess.org%2FCBH_YLs-WM2DIR5j4NahjstGErge5AE79YIBNiZsV1Y%4D
Leave cloudflared running to download the cert automatically.
You have successfully logged in.
If you wish to copy your credentials to a server, they have been saved to:
/home/admin/.cloudflared/cert.pem
{% hint style="info" %}
Leave Cloudflared running to download the cert automatically while you complete the authentication on the Cloudflare account

Expected output:
You have successfully logged in.
If you wish to copy your credentials to a server, they have been saved to:
/home/admin/.cloudflared/cert.pem
cloudflared tunnel create <NAME>
{% hint style="info" %}
Suggestion: <NAME> = miniboltunnel
Example of expected output:
Tunnel credentials written to /home/admin/.cloudflared/<UUID>.json. cloudflared chose this file based on where your origin certificate was found. Keep this file secret. To revoke these credentials, delete the tunnel.
Created tunnel <NAME> with id <UUID>
{% hint style="info" %}
Take note of the tunnel ID -> <UUID> e.g: 8666c35d-6ac3-4b39-9324-12ae32ce64a8 you will need it later
cloudflared tunnel list
Example of expected output:
You can obtain more detailed information for each tunnel with `cloudflared tunnel info <name/uuid>`
ID NAME CREATED CONNECTIONS
8666c35d-6ac3-4b39-9324-12ae32ce64a8 miniboltunnel 2023-04-01T15:44:48Z
cloudflared tunnel info <NAME>
Example of expected output:
NAME: miniboltunnel
ID: 8666c35d-6ac3-4b39-9324-12ae32ce64a8
CREATED: 2023-07-09 19:16:12.744487 +0000 UTC
CONNECTOR ID CREATED ARCHITECTURE VERSION ORIGIN IP EDGE
8666c35d-6ac3-4b39-9324-12ae32ce64a8 2023-07-10T16:20:41Z linux_amd64 2023.6.1 <yourpublicip>
If you want to tunnel only a specific service, you can choose the final subdomain for that service, for example, if you going to expose only the
BTC RPC Explorer, chooseexplorer.<domain.com>or if you want to expose only theBTCPay Server, choosebtcpay.<domain.com>
Replace
<UUID>for your one obtained before andsubdomain.domain.comwith your data
cloudflared tunnel route dns <UUID> subdomain.domain.com
Example of expected output:
2023-07-09T18:01:07Z INF Added CNAME explorer.domain.com which will route to this tunnel tunnelID=8666c35d-6ac3-4b39-9324-12ae32ce64a7
We will create a configuration file in your .cloudflared directory. This file will configure the tunnel to route traffic from a given origin to the hostname of your choice. We will use ingress rules to let you specify which local services traffic should be proxied to.
admin, create config.ymlnano /home/admin/.cloudflared/config.yml
btcpay or explorer with your name (subdomain) chosen for the service, and <domain.com> with the domain, you purchased previously. Ensure to replace <UUID> with your obtained before# MiniBolt: cloudflared configuration
# /home/admin/.cloudflared/config.yml
tunnel: <UUID>
credentials-file: /home/admin/.cloudflared/<UUID>.json
origincert: /home/admin/.cloudflared/cert.pem
ingress:
# BTCPay Server
- hostname: btcpay.<domain.com>
service: http://localhost:23000
# BTC RPC Explorer
- hostname: explorer.<domain.com>
service: http://localhost:3002
- service: http_status:404
{% hint style="info" %}
To take into account:
- Electrum server are not supported using Cloudflared
- For security reasons, you shouldn't expose publically the administration access services using Cloudflared e.g SSH or Thunderhub, for these cases you should use Wireguard VPN
- If you want to expose only a service, you can delete or comment the associated lines of other services, always maintaining the "
- service: http_status:404" line at the end of the file. Example, expose only BTCPay Server, the comment the associated lines for BTC RPC Explorer:# BTC RPC Explorer # - hostname: explorer.<domain.com> # service: http://localhost:3002
Suppose you wanted to expose 2 services or more. In that case, that is to say, you ingressed more than one service on the ingress rules, follow the next steps; if not, you can only check the current recently created registry or jump directly to the next section: Increase the maximum UDP Buffer Sizes
- Edit the existing CNAME record that was recently created, and replace the
namevalue with the name of the first or one of the services selected, or keep it if it's correct. For example, if you selectedbtcpay, keep the existing target content, which is theUUIDof your tunnel- Add a new record by selecting CNAME type. Enter the second subdomain selected in the second ingress rule e.g
explorer, in thenamebox, and in thetargetcontent, enter theUUIDof your tunnel (the same content as before)- Ensure you have enabled
Proxyfor each record you have added (Proxy status: Proxied)

Example of DNS record table:

Experiments have shown that QUIC transfers on high-bandwidth connections can be limited by the size of the UDP receive and send buffer.
admin, create a file to add these parameters and increase the maximum buffer sizesudo nano /etc/sysctl.d/99-custom.conf
# Increase the maximum buffer size (Cloudflare optimization)
net.core.rmem_max=2500000
net.core.wmem_max=2500000
sudo sysctl --system
* Applying /etc/sysctl.d/10-console-messages.conf ...
kernel.printk = 4 4 1 7
* Applying /etc/sysctl.d/10-ipv6-privacy.conf ...
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
* Applying /etc/sysctl.d/10-kernel-hardening.conf ...
kernel.kptr_restrict = 1
* Applying /etc/sysctl.d/10-magic-sysrq.conf ...
kernel.sysrq = 176
* Applying /etc/sysctl.d/10-network-security.conf ...
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
* Applying /etc/sysctl.d/10-ptrace.conf ...
kernel.yama.ptrace_scope = 1
* Applying /etc/sysctl.d/10-zeropage.conf ...
vm.mmap_min_addr = 65536
* Applying /usr/lib/sysctl.d/50-default.conf ...
kernel.core_uses_pid = 1
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.default.accept_source_route = 0
sysctl: setting key "net.ipv4.conf.all.accept_source_route": Invalid argument
net.ipv4.conf.default.promote_secondaries = 1
sysctl: setting key "net.ipv4.conf.all.promote_secondaries": Invalid argument
net.ipv4.ping_group_range = 0 2147483647
net.core.default_qdisc = fq_codel
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.protected_regular = 1
fs.protected_fifos = 1
* Applying /usr/lib/sysctl.d/50-pid-max.conf ...
kernel.pid_max = 4194304
* Applying /etc/sysctl.d/99-custom.conf ...
net.core.rmem_max = 2500000
net.core.wmem_max = 2500000
* Applying /usr/lib/sysctl.d/99-protect-links.conf ...
fs.protected_fifos = 1
fs.protected_hardlinks = 1
fs.protected_regular = 2
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.conf ...
{% hint style="info" %}
These parameters would increase the maximum send and receive buffer size to roughly 2.5 MB
sudo nano /etc/systemd/system/cloudflared.service
# MiniBolt: systemd unit for Cloudflared
# /etc/systemd/system/cloudflared.service
[Unit]
Description=Cloudflared
Requires=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/bin/cloudflared --no-autoupdate --config /home/admin/.cloudflared/config.yml tunnel run
# Process management
####################
Type=notify
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
sudo systemctl enable cloudflared
cloudflared monitoring by the systemd journal and checking the logging output. You can exit monitoring at any time with Ctrl-Cjournalctl -fu cloudflared
{% hint style="info" %}
Keep this terminal open, you'll need to come back here on the next step to monitor the logs
To keep an eye on the software movements, start your SSH program (eg, PuTTY) a second time, connect to the MiniBolt node, and log in as admin. Run the tunnel to proxy incoming traffic from the tunnel to any number of services running locally on your origin
sudo systemctl start cloudflared
journalctl -fu cloudflared ⬇️Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF Starting tunnel tunnelID=8666c35d-6ac3-4b39-9324-12ae32ce64a8
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF Version 2023.6.1
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF GOOS: linux, GOVersion: go1.19.6, GoArch: amd64
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF Settings: map[config:/home/admin/.cloudflared/config.yml cred-file:/home/admin/.cloudflared/8666c35d-6ac3-4b39-9324-12ae32ce64a7.json credentials-file:/home/admin/.cloudflared/8666c35d-6ac3-4b39-9324-12ae32ce64a7.json no-autoupdate:true]
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF Generated Connector ID: ca7ebf91-844d-4025-89f0-e28df084d0a2
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF cloudflared will not automatically update if installed by a package manager.
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF Initial protocol quic
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF ICMP proxy will use 192.168.1.87 as source for IPv4
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF ICMP proxy will use fe80::42a8:f0ff:feb0:aa3d in zone eno1 as source for IPv6
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023-07-10T16:20:40Z INF Starting metrics server on 127.0.0.1:46345/metrics
Jul 10 18:20:40 minibolt cloudflared[3405663]: 2023/07/10 18:20:40 failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size for details.
Jul 10 18:20:41 minibolt cloudflared[3405663]: 2023-07-10T16:20:41Z INF Registered tunnel connection connIndex=0 connection=0c293573-9581-4087-ab56-504d7eca57a1 event=0 ip=198.41.200.23 location=MAD protocol=quic
Jul 10 18:20:41 minibolt systemd[1]: Started cloudflared.
Jul 10 18:20:41 minibolt cloudflared[3405663]: 2023-07-10T16:20:41Z INF Registered tunnel connection connIndex=1 connection=cb1e7bb6-9051-43da-802e-1791687f7385 event=0 ip=198.41.192.57 location=MRS protocol=quic
Jul 10 18:20:43 minibolt cloudflared[3405663]: 2023-07-10T16:20:43Z INF Registered tunnel connection connIndex=2 connection=749064a4-fe1d-4c07-b0b9-71dbc0bcbe3a event=0 ip=198.41.192.227 location=MRS protocol=quic
Jul 10 18:20:43 minibolt cloudflared[3405663]: 2023-07-10T16:20:43Z INF Registered tunnel connection connIndex=3 connection=00f2ca81-1dd1-4695-9857-6815b376855b event=0 ip=198.41.200.33 location=MAD protocol=quic
[...]
config.yml e.g https://explorer.domain.com or https://btcpay.domain.com and check if it resolves correctly to the local service{% hint style="info" %}
You should see the service running properly as if it were a local connection
sudo ss -tulpn | grep cloudflared
Example of expected output:
tcp LISTEN 0 4096 127.0.0.1:37599 0.0.0.0:* users:(("cloudflared",pid=311164,fd=3))
admin, stop Cloudflaredsudo systemctl stop cloudflared
cloudflared --version
"VERSION=x.xx" value for the latest if it has not already been changed in this guidesudo systemctl start cloudflared
{% hint style="info" %}
Monitor logs with journalctl -fu cloudflared to ensure that all is still working well
admin, stop the Cloudflaredsudo systemctl stop cloudflared
sudo dpkg -r cloudflared
Example of expected output:
(Reading database ... 74004 files and directories currently installed.)
Removing cloudflared (2023.7.2) ...
Processing triggers for man-db (2.10.2-1) ...
| Port | Protocol | Use |
|---|---|---|
| Random | TCP | Random port |