cloudflare_tunnel_guide.md - tphakala/birdnet-go GitHub Wiki
Exposing BirdNET-Go to the Internet with Cloudflare Tunnel
This guide explains how to securely expose your BirdNET-Go installation to the internet using Cloudflare Tunnel (cloudflared), which is the recommended method for remote access.
Why Use Cloudflare Tunnel?
Cloudflare Tunnel provides several significant advantages over traditional port forwarding:
- Enhanced Security: No need to open ports on your router/firewall, eliminating attack vectors
- End-to-End Encryption: Traffic is encrypted from your server to Cloudflare, and from Cloudflare to users' browsers
- DDoS Protection: Cloudflare's infrastructure shields your server from direct attacks
- Performance Optimization: Static content like spectrograms and audio clips are cached at Cloudflare's edge network
- Simple Setup: No need for complex networking configuration or dynamic DNS solutions
- Free Tier Available: Basic functionality is available on Cloudflare's free plan
Prerequisites
- A Cloudflare account (free tier is sufficient)
- A domain name added to your Cloudflare account
- BirdNET-Go running on your system (any installation method is compatible)
The cloudflared client can be found in the official cloudflared GitHub repository.
Setup Instructions
Using Docker Compose (Recommended for Docker installations)
If you're using Docker Compose with BirdNET-Go, setting up Cloudflare Tunnel is straightforward:
-
Create a Cloudflare Tunnel:
- Log in to the Cloudflare Zero Trust dashboard
- Navigate to Access > Tunnels
- Click "Create a tunnel"
- Give your tunnel a name (e.g., "BirdNET-Go")
- Copy the provided tunnel token
-
Configure Environment Variables:
- In your
.env
file (in the same directory as your docker-compose.yml), add:CLOUDFLARE_TUNNEL_TOKEN=your-tunnel-token
- In your
-
Update Docker Compose Configuration:
- Edit your docker-compose.yml to include the cloudflared service:
cloudflared: image: cloudflare/cloudflared:latest container_name: birdnet-cloudflared restart: unless-stopped command: tunnel run environment: - TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN} depends_on: - birdnet-go
- Alternatively, use the premade docker-compose.yml which already includes this configuration (commented out)
- Edit your docker-compose.yml to include the cloudflared service:
-
Start the Services:
docker-compose up -d
-
Configure Public Hostname in Cloudflare Dashboard:
- Go back to your tunnel in the Cloudflare Zero Trust dashboard
- Add a public hostname (e.g.,
birdnet.yourdomain.com
) - Set the service to
http://birdnet-go:8080
- Save the configuration
Your BirdNET-Go instance will now be accessible at https://birdnet.yourdomain.com
from anywhere.
Using Standard Docker Install
If you're using the standard Docker installation method:
-
Create a Cloudflare Tunnel (same as above)
-
Download and Run Cloudflared:
# Create a directory for configuration mkdir -p ~/cloudflared # Run cloudflared in a container docker run -d --name cloudflared \ --restart unless-stopped \ -e TUNNEL_TOKEN=your-tunnel-token \ cloudflare/cloudflared:latest \ tunnel run
-
Configure Public Hostname (same as above)
Using Binary Installation (Non-Docker)
If you're running BirdNET-Go directly on your system (not using Docker):
-
Install cloudflared:
- Download the appropriate binary for your system from the cloudflared GitHub releases page
- Or use your system's package manager:
# Debian/Ubuntu curl -L https://pkg.cloudflare.com/cloudflare-main.gpg | sudo apt-key add - echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list sudo apt update sudo apt install cloudflared # macOS brew install cloudflare/cloudflare/cloudflared # Windows (using Scoop) scoop install cloudflared
-
Create a Cloudflare Tunnel:
- Log in to the Cloudflare Zero Trust dashboard
- Create a tunnel and copy the token
-
Run cloudflared:
cloudflared tunnel run --token your-tunnel-token
-
Configure Public Hostname in the Cloudflare dashboard (same as above)
Quick Tunnels with TryCloudflare
If you want to quickly test exposing your BirdNET-Go instance without configuring a domain or creating a permanent tunnel, you can use Cloudflare's "quick tunnels" feature:
# For Docker installations
docker run --name cloudflared \
--network=host \
cloudflare/cloudflared:latest \
tunnel --no-autoupdate run --url http://localhost:8080
# For binary installations
cloudflared tunnel --no-autoupdate run --url http://localhost:8080
This will create a temporary public URL that you can use to access your BirdNET-Go instance. The output will show the random hostname assigned to your tunnel, such as https://randomly-generated-hostname.trycloudflare.com
.
Important limitations of quick tunnels:
- The hostname is randomly generated each time you start the tunnel
- The tunnel is temporary and will be deleted when the cloudflared process stops
- Quick tunnels do not support custom domains or advanced configuration
- Not recommended for permanent installations, but useful for testing
For more information on quick tunnels, see the TryCloudflare documentation.
Enabling Authentication
When exposing BirdNET-Go to the internet, it's strongly recommended to enable authentication.
Security Implications of Not Enabling Authentication
Without authentication, your BirdNET-Go instance is completely open to anyone who has the URL. This creates significant security and privacy risks:
-
Full Administrative Access: Anyone can access all administrative functions, including:
- Changing configuration settings (audio sources, detection parameters, etc.)
- Deleting detection records from the database
- Viewing your configured location coordinates (privacy concern)
- Accessing all audio recordings of detected birds
-
Potential for Abuse:
- Malicious users could deliberately misconfigure your system
- Someone could wipe your detection history and audio clips
- Your data could be scraped or downloaded without your knowledge
- An attacker could use your system as an entry point to other services
-
Privacy Concerns:
- Your exact location is visible in the settings
- Personal information might be inferred from detection patterns and setup
- Audio clips could potentially contain background human voices
Even with Cloudflare Tunnel's security benefits, exposing an unauthenticated BirdNET-Go instance to the internet is equivalent to leaving your front door wide open. The tunnel provides secure access, but without authentication, anyone who finds your URL has complete control over your BirdNET-Go installation.
Setting Up Authentication
There are several authentication methods available in BirdNET-Go:
-
Edit your config.yaml file to enable one of the authentication methods:
security: # Required for OAuth methods host: "birdnet.yourdomain.com" # Your Cloudflare domain # Option 1: Basic Password Authentication basicauth: enabled: true password: "your_password" # Will be automatically hashed # Option 2: Google OAuth (requires Google Cloud account) googleauth: enabled: true clientid: "your_client_id" # From Google Cloud Console clientsecret: "your_client_secret" userid: "[email protected]" # Option 3: GitHub OAuth githubauth: enabled: true clientid: "your_client_id" # From GitHub developer settings clientsecret: "your_client_secret" userid: "your_github_username" # Optional: Allow local network access without auth allowsubnetbypass: enabled: true subnet: "192.168.1.0/24,10.0.0.0/8" # Your local network ranges
-
Restart BirdNET-Go for the changes to take effect
Authentication Method Comparison
- Basic Password Authentication: Simplest to set up, but offers the least security. Good for personal use.
- OAuth (Google/GitHub): More secure, requires fewer passwords to remember, and offers better protection against brute force attacks. Recommended for most users.
- Subnet Bypass: Optional feature that allows unauthenticated access from your local network while requiring authentication from the internet. Useful for mixed home/remote usage.
If you're sharing your BirdNET-Go instance with family or friends, consider using OAuth which makes it easier to control who has access without sharing passwords.
Advanced Configuration
Using a Configuration File (Alternative to Token)
For more advanced setups, you can use a config file instead of a token:
-
Create configuration files:
mkdir -p ~/cloudflared
-
Add config.yml:
# ~/cloudflared/config.yml tunnel: your-tunnel-id credentials-file: /etc/cloudflared/credentials.json ingress: - hostname: birdnet.yourdomain.com service: http://birdnet-go:8080 - service: http_status:404
-
Add credentials file obtained from Cloudflare dashboard to
~/cloudflared/credentials.json
-
Run with Docker Compose:
cloudflared: image: cloudflare/cloudflared:latest container_name: birdnet-cloudflared restart: unless-stopped command: tunnel --config /etc/cloudflared/config.yml run volumes: - ./cloudflared:/etc/cloudflared depends_on: - birdnet-go
Securing Multiple Services
If you run multiple services on your network, you can expose them all through a single Cloudflare Tunnel:
- Expand your ingress rules:
ingress: - hostname: birdnet.yourdomain.com service: http://birdnet-go:8080 - hostname: otherservice.yourdomain.com service: http://otherservice:80 - service: http_status:404
Troubleshooting
- Connection refused errors: Verify that the BirdNET-Go container is accessible from the cloudflared container. They should be on the same Docker network.
- Tunnel not connecting: Check logs with
docker logs birdnet-cloudflared
to ensure the token is valid. - Cannot access web interface: Verify that your DNS settings in Cloudflare are properly configured for your domain.
- Authentication issues: If using OAuth, ensure the
security.host
matches your public domain exactly.
For more help, see the Cloudflare Tunnel documentation.