#

cloudflare access

(1 articles)

Securely Expose Your LND Node via Cloudflared and a VPS

# **Securely Expose Your LND Node via Cloudflared and a VPS** ## **Introduction & Motivation** Exposing your Lightning Network Daemon (LND) node to the public internet is essential for full participation in the Lightning Network. However, doing so introduces critical challenges in terms of **security**, **privacy**, and **resilience against attacks**. This guide presents a solution using **Cloudflare Tunnel and Cloudflare Access**—a modern, secure method to expose services to the internet while maintaining strict control and minimizing exposure. We also compare this approach with more traditional methods such as **SSH tunnels** and **VPNs (WireGuard/OpenVPN + socat/iptables)** to highlight the trade-offs. --- ### **Traditional Exposure Methods: Risks and Limitations** #### **SSH Reverse Tunnels (`ssh -R`, `sshtunnel`)** * ✅ **Outbound-only**: The connection is initiated from the LND host. The VPS cannot reach the internal network on its own. * ⚠️ **Metadata exposure**: The LND host's IP address, SSH key, and connection metadata are visible to the VPS. * ⚠️ **Access control is coarse**: Without extra measures, any process on the VPS can access the forwarded service. * ⚠️ **No service-layer authentication**: Anyone reaching the exposed port can interact with LND, assuming the protocol is known. #### **VPNs (WireGuard/OpenVPN + iptables or socat)** * ⚠️ **Blurs the security boundary**: VPNs extend the network perimeter to remote clients. Misconfigured rules can inadvertently expose internal services. * ❌ **Allows lateral movement**: If the VPS is compromised, it may gain full access to the LND host’s network. * ✅ **Traffic is encrypted**, but requires correct firewalling and routing to be safe. * ⚠️ **Complexity**: These setups often involve manual iptables, port forwarding, and tight coupling of services. --- ### **Cloudflare Tunnel + Access (This Guide)** This solution uses **Cloudflared** on the LND host to initiate an outbound connection to Cloudflare, which then routes traffic through a secured, authenticated TCP tunnel via a VPS. * ✅ **No exposed ports on the LND host**. * ✅ **VPS cannot discover or access the LND IP**—only forwards TCP packets to Cloudflare. * ✅ **Service Token authentication** ensures only authorized clients can connect. * ⚠️ **Trust in Cloudflare** is required. While your LND host is protected from the internet, **Cloudflare can see metadata**, and potentially, inspect unencrypted traffic. * ❌ **Cloudflare is proprietary** infrastructure. You’re protected from attackers, but not necessarily from **Cloudflare** or governments. --- ### **Security & Privacy Comparison** | Feature | SSH Tunnel | VPN + socat/iptables | Cloudflare Tunnel + Access | | --------------------------------- | ------------------ | -------------------- | -------------------------- | | Encrypts traffic | ✅ | ✅ | ✅ | | Initiated from LND host | ✅ | ❌ | ✅ | | Prevents VPS from accessing LAN | ✅ | ❌ | ✅ | | Hides LND IP from VPS | ❌ | ❌ | ✅ | | Hides LND IP from tunnel provider | ❌ | ✅ | ❌ | | Proprietary infrastructure | ❌ | ❌ | ⚠️ (Cloudflare) | | Fine-grained access control | ⚠️ (manual) | ⚠️ (manual) | ✅ (Service Token) | | Susceptible to VPS compromise | ⚠️ (metadata only) | ❌ (full access) | ✅ (isolated forwarding) | --- ## **Tutorial: Step-by-Step Setup** --- ### **1. Set Up the Cloudflare Tunnel** 1. In your Cloudflare Zero Trust dashboard, navigate to **Access → Tunnels**. 2. Create a new tunnel (e.g., `lnd-tunnel`). 3. Choose **Use Token Authentication** and copy the token. 4. Add a **Public Hostname**: * **Hostname**: `lnd-external-access.mydomain.com` * **Service Type**: TCP * **URL**: `tcp://lnd:9735` *(This is the internal Docker hostname and port for LND.)* --- ### **2. Run Cloudflared on the LND Host** Assuming your LND node runs in Docker inside the `bitcoin-net` network: **`.env`** ```env TOKEN=your-cloudflare-tunnel-token ``` **`docker-compose.yml`** ```yaml version: "3.8" services: cloudflared: image: cloudflare/cloudflared:latest command: tunnel --no-autoupdate run --token ${TOKEN} restart: unless-stopped env_file: - .env networks: - bitcoin-net networks: bitcoin-net: external: true name: bitcoin-net ``` --- ### **3. Create the Cloudflare Service Token** 1. Go to **Access → Service Auth**. 2. Click **Create Service Token**. 3. Name it (e.g., `lnd-access-client`) and store both the **Token ID** and **Token Secret**—you’ll need these on the VPS and to configure access. --- ### **4. Define the Cloudflare Access Application** 1. Navigate to **Access → Applications → Add an Application**. 2. Choose **Self-hosted**. 3. Set: * **Application Name**: `lnd-external-access` * **Domain**: `lnd-external-access.mydomain.com` 4. In **Policies**: * Add a policy: * **Name**: `Allow via Service Token` * **Action**: `Service Auth` * **Include → Service Token**: select the token you just created --- ### **5. Deploy the Forwarding VPS** #### a. Configure firewall: ```bash sudo ufw allow ssh sudo ufw allow 9735/tcp sudo ufw enable ``` #### b. Set environment variables: **`.env`** ```env TOKEN_ID=your-service-token-id TOKEN_SECRET=your-service-token-secret HOSTNAME=lnd-external-access.mydomain.com LISTEN=tcp://0.0.0.0:9735 ``` #### c. Run Cloudflared: **`docker-compose.yml`** ```yaml version: "3.8" services: cloudflared: image: cloudflare/cloudflared:latest ports: - 9735:9735 command: > access tcp --service-token-id ${TOKEN_ID} --service-token-secret ${TOKEN_SECRET} --hostname ${HOSTNAME} --url ${LISTEN} --loglevel debug env_file: - .env restart: unless-stopped ``` --- ### **6. Configure DNS** In Cloudflare DNS: * Create an **A record**: * **Name**: `lnd` * **Type**: A * **Value**: `VPS_IP` * **Proxy status**: DNS only --- ### **7. Configure LND** Edit `lnd.conf` to include: ```ini externalip=lnd.mydomain.com ``` Restart LND to apply changes. --- ### **8. Test the Connection** From another LND node or client: ```bash lncli connect <pubkey>@lnd.mydomain.com:9735 ``` Check logs in LND and Cloudflared to confirm successful connection. --- ## **Final Notes** * This method **preserves your network perimeter**, even if the VPS is compromised. * All traffic is **authenticated with service tokens**, and **no direct access** is possible to your LND host. * You do **trust Cloudflare**, so weigh that risk in high-privacy environments.