Files
pi-pm3/docs/CAPTIVE_PORTAL_DEPLOY.md
michael 4f35df1781 Initial commit - Phase 3/4
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:46:22 -08:00

197 lines
5.7 KiB
Markdown

# Captive Portal Deployment Notes
**Date**: 2026-01-06
**Status**: Ready to deploy on live Pi
## Summary
Added captive portal detection to nginx configuration. This enables automatic popup on devices when they connect to the Dangerous-Pi WiFi network.
## What Was Changed
### Files Modified
1. **pi-gen pipeline** (for future builds):
- `pi-gen/stageDangerousPi/01-Wireless-AP/00-run-chroot.sh`
2. **Local nginx config** (reference):
- `nginx/dangerous-pi.conf`
### Changes Made
Added OS connectivity check endpoints to nginx:
| Endpoint | OS/Browser | Response |
|----------|-----------|----------|
| `/generate_204` | Android/Chrome | 204 No Content |
| `/gen_204` | Android alternate | 204 No Content |
| `/connectivitycheck/gstatic/generate_204` | Google services | 204 No Content |
| `/hotspot-detect.html` | iOS/macOS | 200 + HTML |
| `/library/test/success.html` | iOS alternate | 200 + HTML |
| `/connecttest.txt` | Windows 10/11 | 200 + text |
| `/ncsi.txt` | Windows NCSI | 200 + text |
| `/success.txt` | Firefox | 200 + text |
| `/kindle-wifi/wifistub.html` | Kindle/Amazon | 200 + HTML |
## Deploy on Live Pi
### Option 1: Copy nginx config directly
```bash
# SSH into the Pi
ssh dt@dangerous-pi.local
# Backup existing config
sudo cp /etc/nginx/sites-available/dangerous-pi.conf /etc/nginx/sites-available/dangerous-pi.conf.bak
# Copy the new config (from your dev machine)
# On dev machine:
scp nginx/dangerous-pi.conf dt@dangerous-pi.local:/tmp/
# On Pi:
sudo cp /tmp/dangerous-pi.conf /etc/nginx/sites-available/dangerous-pi.conf
# Test nginx config
sudo nginx -t
# Reload nginx
sudo systemctl reload nginx
```
### Option 2: Manual edit on Pi
Add the following block to `/etc/nginx/sites-available/dangerous-pi.conf` **before** the `location /api/` block:
```nginx
# ===========================================
# CAPTIVE PORTAL DETECTION
# ===========================================
# These endpoints respond to OS connectivity checks.
# When a device connects to the AP, the OS checks these URLs.
# By responding correctly, we trigger the captive portal popup.
# Android / Chrome OS connectivity check
location = /generate_204 {
return 204;
}
# Additional Android check paths
location = /gen_204 {
return 204;
}
# Google connectivity check
location = /connectivitycheck/gstatic/generate_204 {
return 204;
}
# iOS / macOS captive portal detection
location = /hotspot-detect.html {
return 200 '<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>';
add_header Content-Type text/html;
}
# iOS alternate path
location = /library/test/success.html {
return 200 '<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>';
add_header Content-Type text/html;
}
# Windows 10/11 connectivity check
location = /connecttest.txt {
return 200 'Microsoft Connect Test';
add_header Content-Type text/plain;
}
# Windows NCSI check
location = /ncsi.txt {
return 200 'Microsoft NCSI';
add_header Content-Type text/plain;
}
# Firefox / Mozilla connectivity check
location = /success.txt {
return 200 'success';
add_header Content-Type text/plain;
}
# Kindle / Amazon devices
location = /kindle-wifi/wifistub.html {
return 200 '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"><html><head><title>Kindle</title></head><body>81ce4465-7167-4dcb-835b-dcc9e44c112a</body></html>';
add_header Content-Type text/html;
}
# ===========================================
# END CAPTIVE PORTAL DETECTION
# ===========================================
```
Then reload nginx:
```bash
sudo nginx -t && sudo systemctl reload nginx
```
## Testing
### Test from a mobile device
1. Forget the "Dangerous-Pi" network on your phone
2. Reconnect to "Dangerous-Pi" WiFi
3. You should see a captive portal popup automatically
4. Clicking it should open the Dangerous Pi web interface
### Test manually with curl
```bash
# Android check (should return empty 204)
curl -v http://192.168.4.1/generate_204
# iOS check (should return HTML)
curl -v http://192.168.4.1/hotspot-detect.html
# Windows check (should return "Microsoft Connect Test")
curl -v http://192.168.4.1/connecttest.txt
# Firefox check (should return "success")
curl -v http://192.168.4.1/success.txt
```
## How It Works
1. **DNS**: dnsmasq already redirects ALL DNS queries to 192.168.4.1 (`address=/#/192.168.4.1`)
2. **HTTP**: When the OS checks connectivity URLs, nginx now responds correctly
3. **Detection**: OS sees the expected response and knows internet is available
4. **Popup**: Because DNS resolved to the AP but responses are correct, OS triggers captive portal UI
## Troubleshooting
### No popup appears
1. Check nginx is running: `sudo systemctl status nginx`
2. Check nginx config: `sudo nginx -t`
3. Check dnsmasq is running: `sudo systemctl status dnsmasq`
4. Verify DNS redirect: `nslookup google.com` (should resolve to 192.168.4.1)
### Popup appears but shows error
1. Check frontend is running: `curl http://localhost:3000`
2. Check backend is running: `curl http://localhost:8000/api/health`
3. Check nginx logs: `sudo tail -f /var/log/nginx/error.log`
### Some devices don't show popup
Different devices use different detection URLs. The current config covers:
- Android (all versions)
- iOS / macOS
- Windows 10/11
- Firefox
- Kindle
If a specific device doesn't work, check its connectivity check URL and add it to nginx.
## Future Improvements
- [ ] Add Samsung-specific detection URLs if needed
- [ ] Consider adding a redirect for unknown hosts to `/` (requires `if` statement)
- [ ] Monitor nginx access logs to discover new detection URLs