🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
197 lines
5.7 KiB
Markdown
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
|