add cloudflare tunneling to broadcaster

This commit is contained in:
Boaz Sender 2025-06-29 12:49:02 -04:00
parent 733135d8d1
commit 1b5892fd5f
6 changed files with 337 additions and 60 deletions

View file

@ -5,7 +5,7 @@
User: grace User: grace
Hostname: portal.local Hostname: portal.local
Password: emergence Password: emergence
Running icecast (port 80) and darkice with Namecheap Dynamic DNS for external access. See icecast-darkice.md for setup instructions. Running icecast (port 8000) with nginx proxy (port 80) and Cloudflare Tunnel for external access. No port forwarding or static IP required.
## Bill of Materials ## Bill of Materials
@ -99,35 +99,122 @@ WantedBy=multi-user.target
3. sudo systemctl enable icecast2 3. sudo systemctl enable icecast2
4. sudo systemctl enable darkice 4. sudo systemctl enable darkice
### Dynamic DNS Configuration (Automated) ### Cloudflare Tunnel Configuration (Automated)
The install script automatically configures Namecheap Dynamic DNS to make the stream accessible at blackportaldetroit.com without requiring a static IP address. The install script automatically configures Cloudflare Tunnel to make the stream accessible at blackportaldetroit.com. This bypasses CG-NAT, port forwarding, and firewall issues completely.
#### What gets installed: #### What gets installed:
- **ddclient** - Updates your domain's IP address automatically - **cloudflared** - Creates secure tunnel to Cloudflare edge servers
- **Configuration file** - Pre-configured for Namecheap at `/etc/ddclient.conf` - **Configuration file** - Pre-configured tunnel settings at `/etc/cloudflared/config.yml`
- **Systemd service** - Runs ddclient as a background service - **Systemd service** - Runs cloudflared as a background service
- **Icecast on port 80** - Eliminates need for router port forwarding - **Nginx reverse proxy** - Proxies port 80 to icecast port 8000 (no root privileges needed)
#### Manual steps required after installation: #### Manual steps required after installation:
1. **In Namecheap account**: Enable Dynamic DNS for blackportaldetroit.com 1. **Transfer domain**: Move blackportaldetroit.com nameservers to Cloudflare (if not already done)
2. **Add DNS record**: Create an "A + Dynamic DNS" record for "@" (root domain) 2. **Authenticate**: Run `cloudflared tunnel login` when prompted
3. **Get password**: Note the Dynamic DNS password from Namecheap 3. **Create tunnel**: Run `cloudflared tunnel create blackportal`
4. **Update config**: Edit `/etc/ddclient.conf` and replace `REPLACE_WITH_NAMECHEAP_DDNS_PASSWORD` 4. **Add DNS record**: Create CNAME record in Cloudflare dashboard pointing to tunnel
5. **Start service**: Run `sudo systemctl start ddclient` 5. **Start service**: Tunnel starts automatically via systemd
6. **No router setup needed** - icecast runs directly on port 80
#### Verify Dynamic DNS is working: #### Verify Cloudflare Tunnel is working:
```bash ```bash
# Check ddclient status # Check tunnel status
sudo systemctl status ddclient sudo systemctl status cloudflared
# View ddclient logs # View tunnel logs
sudo journalctl -u ddclient -f sudo journalctl -u cloudflared -f
# Test DNS resolution # Test DNS resolution
nslookup blackportaldetroit.com nslookup blackportaldetroit.com
# Test external access
curl -I https://blackportaldetroit.com/portal
``` ```
#### Verify nginx proxy is working:
```bash
# Check nginx status
sudo systemctl status nginx
# Check icecast status
sudo systemctl status icecast2
# Check listening ports
sudo netstat -tlnp | grep -E ':(80|8000)'
# Test local access
curl -I http://localhost:80
curl -I http://localhost:8000
```
## Troubleshooting Cloudflare Tunnel
### Common Issues and Solutions
#### 1. Domain Not on Cloudflare
**Problem**: Domain still using Namecheap nameservers
**Solution**: Transfer nameservers to Cloudflare
1. Login to Cloudflare, add blackportaldetroit.com
2. Copy Cloudflare nameservers (e.g. `alice.ns.cloudflare.com`)
3. Update nameservers in Namecheap domain settings
4. Wait for DNS propagation (up to 24 hours)
#### 2. Authentication Issues
**Problem**: `cloudflared tunnel login` fails
**Solution**: Manual authentication
```bash
# Run authentication manually
cloudflared tunnel login
# If browser doesn't open automatically, copy the URL and open manually
# Complete authentication in browser
```
#### 3. Tunnel Not Connecting
**Problem**: Tunnel shows as disconnected
**Solution**: Check service and logs
```bash
# Check tunnel service status
sudo systemctl status cloudflared
# View detailed logs
sudo journalctl -u cloudflared -f
# Restart tunnel service
sudo systemctl restart cloudflared
```
#### 4. DNS Record Issues
**Problem**: Domain doesn't resolve to tunnel
**Solution**: Check CNAME record in Cloudflare
1. Login to Cloudflare dashboard
2. Go to DNS → Records
3. Ensure CNAME record exists: `@``tunnel-id.cfargotunnel.com`
4. Ensure Proxy status is enabled (orange cloud)
### Architecture Diagram with Cloudflare Tunnel
```
Internet → Cloudflare Edge → Cloudflare Tunnel → Raspberry Pi 4B
nginx (port 80) → icecast (port 8000)
```
**Key Benefits**:
- Bypasses CG-NAT completely
- No router configuration needed
- Built-in SSL and DDoS protection
- Works with any internet connection

View file

@ -1,14 +1,15 @@
# Hardware setup instructions # Hardware setup instructions
This readme contains insructions for plugging in the system and turning it on. Full software setup documentation is in the broadcaster-software.md and listener-software.md files. This readme contains instructions for plugging in the system and turning it on. Full software setup documentation is in the broadcaster-software.md and listener-software.md files.
Make sure to do the following steps in the order they are listed: Make sure to do the following steps in the order they are listed:
## Requirements ## Requirements
- Modem and internet plan (no static IP required - uses Dynamic DNS). - Modem and internet plan (no static IP required - uses Cloudflare Tunnel)
- Provisioned [broadcaster](broadcaster.md) with Dynamic DNS configured - Provisioned [broadcaster](broadcaster.md) with Cloudflare Tunnel configured
- Provisioned [listener](listener.md) - Provisioned [listener](listener.md)
- Domain transferred to Cloudflare (blackportaldetroit.com)
## Steps ## Steps
@ -19,14 +20,9 @@ Make sure to do the following steps in the order they are listed:
3. Plug the ethernet cable into the broadcaster and the router 3. Plug the ethernet cable into the broadcaster and the router
4. Plug the power into the broadcaster (this is how you turn it on) 4. Plug the power into the broadcaster (this is how you turn it on)
### Networking (Simplified with Dynamic DNS)
### Networking ### Networking
6. Log into the router. 1. Either configure cloudlfare tunnel, ddns or setup a static ip and forward from your router
7. Find the ip address of the broadcaster (hostname portal) - usually in the advanced > network > dhcp.
8. No port forwarding needed - icecast runs directly on port 80.
9. The broadcaster will automatically update blackportaldetroit.com with the current public IP address via Dynamic DNS.
### Turn on listener ### Turn on listener
@ -37,7 +33,36 @@ Make sure to do the following steps in the order they are listed:
### Important notes ### Important notes
* The microphone must always be plugged into the broadcaster before the broadcaster is on - The microphone must always be plugged into the broadcaster before the broadcaster is on
* The broadcaster must always be on when the listener is turned on. if it is not, then the listener needs to be restarted once the broadcaster is on. - The broadcaster must always be on when the listener is turned on. if it is not, then the listener needs to be restarted once the broadcaster is on.
* Dynamic DNS automatically keeps blackportaldetroit.com pointed to your current IP address - SSL certificates are handled automatically by Cloudflare
* No router port forwarding required - icecast runs directly on port 80 - Stream will be accessible at https://blackportaldetroit.com/portal
- No router configuration or port forwarding needed
## Troubleshooting Cloudflare Tunnel
### Setup Steps:
1. Transfer blackportaldetroit.com to Cloudflare (change nameservers)
2. Run `./cloudflare-tunnel-setup.sh` on the Pi
3. Follow the authentication prompts
4. Create CNAME record in Cloudflare dashboard
### Common Issues:
- **Domain not on Cloudflare**: Transfer nameservers first
- **Authentication failed**: Run `cloudflared tunnel login` manually
- **Tunnel not connecting**: Check `sudo systemctl status cloudflared`
### Test Commands:
```bash
# Check tunnel status
sudo systemctl status cloudflared
# View tunnel logs
sudo journalctl -u cloudflared -f
# Test local connectivity
curl -I http://localhost:80
```

View file

@ -21,14 +21,15 @@ This repository contains custom software for turning a m3u radio stream into a l
Prior research that didn't work in `research-` md files. Prior research that didn't work in `research-` md files.
## Dynamic DNS Setup ## Cloudflare Tunnel Setup
The broadcaster configures Namecheap Dynamic DNS to make the stream available at blackportaldetroit.com without requiring a static IP address. The setup includes: The broadcaster uses Cloudflare Tunnel to make the stream available at blackportaldetroit.com without requiring static IP, port forwarding, or dealing with CG-NAT. The setup includes:
- Automatic IP address detection and updates - Secure tunnel bypassing router/firewall restrictions
- Namecheap integration for seamless domain management - Automatic SSL certificate management
- Icecast running directly on port 80 (no router port forwarding needed) - Built-in DDoS protection and global CDN
- Works with any internet connection type (LTE, cable, DSL, fiber)
## Live access ## Live access
5. If everything is turned on and configured properly, you may visit http://blackportaldetroit.com to hear the broadcaster. 5. If everything is turned on and configured properly, you may visit https://blackportaldetroit.com/portal to hear the broadcaster.

View file

@ -0,0 +1,156 @@
#!/bin/bash
# Cloudflare Tunnel Setup for Black Portal Detroit
# This bypasses CG-NAT by creating a secure tunnel to Cloudflare
set -e
echo "🔗 Setting up Cloudflare Tunnel for Black Portal Detroit..."
# Check if running as root
if [[ $EUID -eq 0 ]]; then
echo "This script should NOT be run as root"
echo "Run as: ./cloudflare-tunnel-setup.sh"
exit 1
fi
# Install cloudflared
echo "📦 Installing cloudflared..."
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared bullseye main' | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt-get update && sudo apt-get install cloudflared
# Create tunnel configuration directory
sudo mkdir -p /etc/cloudflared
sudo chown $USER:$USER /etc/cloudflared
echo ""
echo "MANUAL STEPS REQUIRED:"
echo ""
echo "1. Authenticate with Cloudflare (if not already done):"
echo " cloudflared tunnel login"
echo ""
echo " FOR HEADLESS PI:"
echo " - Copy the URL that appears"
echo " - Open it in a browser on another device"
echo " - Complete authentication"
echo " - If you see 'existing certificate' error, skip to step 2"
echo ""
echo "2. Create a tunnel:"
echo " cloudflared tunnel create blackportal"
echo ""
echo "3. Copy the tunnel ID that gets displayed, then run:"
echo " echo 'TUNNEL_ID=your-tunnel-id-here' | sudo tee /etc/cloudflared/.env"
echo ""
echo "4. Copy credentials to system location:"
echo " sudo cp ~/.cloudflared/your-tunnel-id.json /etc/cloudflared/"
echo " sudo chmod 600 /etc/cloudflared/your-tunnel-id.json"
echo ""
echo "5. Create DNS record in Cloudflare dashboard:"
echo " - Type: CNAME"
echo " - Name: @ (or blackportaldetroit.com)"
echo " - Target: your-tunnel-id.cfargotunnel.com"
echo " - Proxy status: Proxied (orange cloud)"
echo ""
echo "6. Run this script again to complete setup"
echo ""
# Check if tunnel already exists
if [ -f "/etc/cloudflared/.env" ]; then
source /etc/cloudflared/.env
if [ -z "$TUNNEL_ID" ]; then
echo "TUNNEL_ID not found in /etc/cloudflared/.env"
echo "Please complete manual steps above first"
exit 1
fi
echo "✅ Found tunnel ID: $TUNNEL_ID"
# Check if credentials file exists (might be in user's home or system location)
if [ ! -f "/etc/cloudflared/$TUNNEL_ID.json" ]; then
if [ -f "$HOME/.cloudflared/$TUNNEL_ID.json" ]; then
echo "📋 Copying credentials from user directory..."
sudo cp "$HOME/.cloudflared/$TUNNEL_ID.json" /etc/cloudflared/
sudo chown root:root "/etc/cloudflared/$TUNNEL_ID.json"
sudo chmod 600 "/etc/cloudflared/$TUNNEL_ID.json"
else
echo "Credentials file not found at /etc/cloudflared/$TUNNEL_ID.json"
echo "Please run: cloudflared tunnel create blackportal"
exit 1
fi
fi
# Create tunnel configuration
echo "📝 Creating tunnel configuration..."
cat > /etc/cloudflared/config.yml << EOF
tunnel: $TUNNEL_ID
credentials-file: /etc/cloudflared/$TUNNEL_ID.json
ingress:
- hostname: blackportaldetroit.com
service: http://localhost:80
- hostname: www.blackportaldetroit.com
service: http://localhost:80
- service: http_status:404
EOF
# Set proper permissions
sudo chown root:root /etc/cloudflared/config.yml
sudo chmod 644 /etc/cloudflared/config.yml
# Create systemd service
echo "🔧 Creating systemd service..."
sudo tee /etc/systemd/system/cloudflared.service > /dev/null << EOF
[Unit]
Description=Cloudflare Tunnel
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/cloudflared tunnel --config /etc/cloudflared/config.yml run
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
echo ""
echo "Cloudflare Tunnel setup complete!"
echo ""
echo "Check status:"
echo "sudo systemctl status cloudflared"
echo ""
echo "View logs:"
echo "sudo journalctl -u cloudflared -f"
echo ""
echo "IMPORTANT: Did you create the DNS record?"
echo "Go to Cloudflare Dashboard → DNS → Records"
echo "Add CNAME: @ → $TUNNEL_ID.cfargotunnel.com"
echo ""
echo "Your stream should now be accessible at:"
echo "https://blackportaldetroit.com/portal"
echo ""
echo "Benefits:"
echo " - Bypasses CG-NAT completely"
echo " - Free SSL certificate"
echo " - DDoS protection"
echo " - Works from anywhere"
echo ""
echo "Troubleshooting:"
echo " - If tunnel fails: Check logs with 'sudo journalctl -u cloudflared -f'"
echo " - If DNS doesn't work: Ensure CNAME record is added in Cloudflare"
echo " - If stream not accessible: Check 'sudo systemctl status nginx' and 'sudo systemctl status icecast2'"
echo ""
else
echo "⏳ Complete the manual steps above, then run this script again"
fi

View file

@ -19,10 +19,10 @@ ver="1.0"
marker="0.0.0" marker="0.0.0"
apt update apt update
apt -y install git vim zsh darkice icecast2 ddclient apt -y install git vim zsh darkice icecast2 nginx
# Configure icecast to run on port 80 # Keep icecast on port 8000 (can't bind to port 80 without root)
sed -i 's/<port>8000<\/port>/<port>80<\/port>/g' /etc/icecast2/icecast.xml # Nginx will proxy port 80 to icecast port 8000
cp ./darkice.cfg /etc/ cp ./darkice.cfg /etc/
cp ./darkice.service /lib/systemd/system/ cp ./darkice.service /lib/systemd/system/
@ -31,30 +31,29 @@ systemctl daemon-reload
systemctl enable darkice systemctl enable darkice
systemctl start darkice systemctl start darkice
# Configure ddclient for Namecheap Dynamic DNS # Configure nginx to proxy port 80 to icecast port 8000
cat > /etc/ddclient.conf << EOF cat > /etc/nginx/sites-available/blackportaldetroit.com << EOF
# Namecheap Dynamic DNS configuration server {
daemon=300 # Check every 5 minutes listen 80;
syslog=yes # Log to syslog server_name blackportaldetroit.com;
pid=/var/run/ddclient.pid # PID file location
ssl=yes # Use SSL
# How to get IP address location / {
use=web, web=dynamicdns.park-your-domain.com/getip proxy_pass http://127.0.0.1:8000;
proxy_buffering off;
# Namecheap settings }
protocol=namecheap }
server=dynamicdns.park-your-domain.com
login=blackportaldetroit.com
password=REPLACE_WITH_NAMECHEAP_DDNS_PASSWORD
@ # Update root domain
EOF EOF
# Set proper permissions for ddclient config # Enable the nginx site and disable default
chmod 600 /etc/ddclient.conf ln -sf /etc/nginx/sites-available/blackportaldetroit.com /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
systemctl restart nginx
# Enable and start ddclient (but don't start until password is configured) echo ""
systemctl enable ddclient echo "🔗 Setting up Cloudflare Tunnel..."
chmod +x ./cloudflare-tunnel-setup.sh
su grace
./cloudflare-tunnel-setup.sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

View file

@ -0,0 +1,9 @@
server {
listen 80;
server_name blackportaldetroit.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_buffering off;
}
}