diff --git a/docs/broadcaster.md b/docs/broadcaster.md index 1408e27..238f011 100644 --- a/docs/broadcaster.md +++ b/docs/broadcaster.md @@ -5,7 +5,7 @@ User: grace Hostname: portal.local 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 @@ -99,35 +99,122 @@ WantedBy=multi-user.target 3. sudo systemctl enable icecast2 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: -- **ddclient** - Updates your domain's IP address automatically -- **Configuration file** - Pre-configured for Namecheap at `/etc/ddclient.conf` -- **Systemd service** - Runs ddclient as a background service -- **Icecast on port 80** - Eliminates need for router port forwarding +- **cloudflared** - Creates secure tunnel to Cloudflare edge servers +- **Configuration file** - Pre-configured tunnel settings at `/etc/cloudflared/config.yml` +- **Systemd service** - Runs cloudflared as a background service +- **Nginx reverse proxy** - Proxies port 80 to icecast port 8000 (no root privileges needed) #### Manual steps required after installation: -1. **In Namecheap account**: Enable Dynamic DNS for blackportaldetroit.com -2. **Add DNS record**: Create an "A + Dynamic DNS" record for "@" (root domain) -3. **Get password**: Note the Dynamic DNS password from Namecheap -4. **Update config**: Edit `/etc/ddclient.conf` and replace `REPLACE_WITH_NAMECHEAP_DDNS_PASSWORD` -5. **Start service**: Run `sudo systemctl start ddclient` -6. **No router setup needed** - icecast runs directly on port 80 +1. **Transfer domain**: Move blackportaldetroit.com nameservers to Cloudflare (if not already done) +2. **Authenticate**: Run `cloudflared tunnel login` when prompted +3. **Create tunnel**: Run `cloudflared tunnel create blackportal` +4. **Add DNS record**: Create CNAME record in Cloudflare dashboard pointing to tunnel +5. **Start service**: Tunnel starts automatically via systemd -#### Verify Dynamic DNS is working: +#### Verify Cloudflare Tunnel is working: ```bash -# Check ddclient status -sudo systemctl status ddclient +# Check tunnel status +sudo systemctl status cloudflared -# View ddclient logs -sudo journalctl -u ddclient -f +# View tunnel logs +sudo journalctl -u cloudflared -f # Test DNS resolution 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 diff --git a/docs/how-to-turn-it-on.md b/docs/how-to-turn-it-on.md index 5fbb4eb..f976fa1 100644 --- a/docs/how-to-turn-it-on.md +++ b/docs/how-to-turn-it-on.md @@ -1,14 +1,15 @@ # 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: ## Requirements -- Modem and internet plan (no static IP required - uses Dynamic DNS). -- Provisioned [broadcaster](broadcaster.md) with Dynamic DNS configured +- Modem and internet plan (no static IP required - uses Cloudflare Tunnel) +- Provisioned [broadcaster](broadcaster.md) with Cloudflare Tunnel configured - Provisioned [listener](listener.md) +- Domain transferred to Cloudflare (blackportaldetroit.com) ## 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 4. Plug the power into the broadcaster (this is how you turn it on) -### Networking (Simplified with Dynamic DNS) - ### Networking -6. Log into the 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. +1. Either configure cloudlfare tunnel, ddns or setup a static ip and forward from your router ### Turn on listener @@ -37,7 +33,36 @@ Make sure to do the following steps in the order they are listed: ### Important notes -* 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. -* Dynamic DNS automatically keeps blackportaldetroit.com pointed to your current IP address -* No router port forwarding required - icecast runs directly on port 80 +- 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. +- SSL certificates are handled automatically by Cloudflare +- 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 +``` diff --git a/docs/readme.md b/docs/readme.md index a3fc275..b224be4 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -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. -## 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 -- Namecheap integration for seamless domain management -- Icecast running directly on port 80 (no router port forwarding needed) +- Secure tunnel bypassing router/firewall restrictions +- Automatic SSL certificate management +- Built-in DDoS protection and global CDN +- Works with any internet connection type (LTE, cable, DSL, fiber) ## 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. diff --git a/setup/broadcaster/cloudflare-tunnel-setup.sh b/setup/broadcaster/cloudflare-tunnel-setup.sh new file mode 100644 index 0000000..bc98d52 --- /dev/null +++ b/setup/broadcaster/cloudflare-tunnel-setup.sh @@ -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 \ No newline at end of file diff --git a/setup/broadcaster/install.sh b/setup/broadcaster/install.sh index 52e091c..df86bdc 100644 --- a/setup/broadcaster/install.sh +++ b/setup/broadcaster/install.sh @@ -19,10 +19,10 @@ ver="1.0" marker="0.0.0" 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 -sed -i 's/8000<\/port>/80<\/port>/g' /etc/icecast2/icecast.xml +# Keep icecast on port 8000 (can't bind to port 80 without root) +# Nginx will proxy port 80 to icecast port 8000 cp ./darkice.cfg /etc/ cp ./darkice.service /lib/systemd/system/ @@ -31,30 +31,29 @@ systemctl daemon-reload systemctl enable darkice systemctl start darkice -# Configure ddclient for Namecheap Dynamic DNS -cat > /etc/ddclient.conf << EOF -# Namecheap Dynamic DNS configuration -daemon=300 # Check every 5 minutes -syslog=yes # Log to syslog -pid=/var/run/ddclient.pid # PID file location -ssl=yes # Use SSL +# Configure nginx to proxy port 80 to icecast port 8000 +cat > /etc/nginx/sites-available/blackportaldetroit.com << EOF +server { + listen 80; + server_name blackportaldetroit.com; -# How to get IP address -use=web, web=dynamicdns.park-your-domain.com/getip - -# Namecheap settings -protocol=namecheap -server=dynamicdns.park-your-domain.com -login=blackportaldetroit.com -password=REPLACE_WITH_NAMECHEAP_DDNS_PASSWORD -@ # Update root domain + location / { + proxy_pass http://127.0.0.1:8000; + proxy_buffering off; + } +} EOF -# Set proper permissions for ddclient config -chmod 600 /etc/ddclient.conf +# Enable the nginx site and disable default +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) -systemctl enable ddclient +echo "" +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)" diff --git a/setup/broadcaster/nginx.conf b/setup/broadcaster/nginx.conf new file mode 100644 index 0000000..c2017fa --- /dev/null +++ b/setup/broadcaster/nginx.conf @@ -0,0 +1,9 @@ +server { + listen 80; + server_name blackportaldetroit.com; + + location / { + proxy_pass http://127.0.0.1:8000; + proxy_buffering off; + } +} \ No newline at end of file