Quick Reference — Key Addresses & Log Files
Blue Triangle (Cloud Hub)
ssh root@100.113.114.32
docker ps
docker logs -f amp-dashboard
docker logs -f amp-bridge
curl http://100.113.114.32:5001
Spoke Nodes (Hawaii Pis)
ssh pi@<tailscale-ip-of-spoke>
cat /etc/amp-serial
tail -20 /var/log/amp-heartbeat.log
tail -30 /var/log/amp-firstboot.log
sudo tailscale status
| Node | Location | Node ID | Tailscale Tag | Find Tailscale IP |
| Blue Triangle | DigitalOcean NYC1 | N/A | tag:blue-triangle | 100.113.114.32 (fixed) |
| Node 20 | Leonard · Kent HQ (Founder) | 20 | tag:exit-node | tailscale status on BT or laptop |
| Node 21 | Mom · Waimea | 21 | tag:exit-node | tailscale status on BT or laptop |
| Node 22 | Charla · Nanakuli | 22 | tag:exit-node | tailscale status on BT or laptop |
| Node 23 | Tammy · Waianae | 23 | tag:exit-node | tailscale status on BT or laptop |
1 — Spoke Node Issues (Hawaii Pis)
🔴Telegram alert received: "Node Offline" — node hasn't checked in for 10+ minutes
- Check if it's a power issue — ask the family member if the Pi's LEDs are on. Green LED = running; no lights = unplugged or dead power supply.
- Check Tailscale from your laptop — if the node is still in the mesh, it has internet:
tailscale status
- If Tailscale shows online but heartbeat is still missing — SSH in and check the cron:
ssh pi@<tailscale-ip>
crontab -l
cat /var/log/amp-heartbeat.log | tail -20
sudo /usr/local/bin/amp-heartbeat.sh
- If the node is truly unreachable — have the family member unplug it, wait 15 seconds, plug back in. The heartbeat cron will resume automatically. Alert will auto-clear when BT receives the next heartbeat.
Alert auto-clears when heartbeat resumes. No manual database cleanup needed — the alert.py script handles recovery detection automatically.
🔑Can't SSH into a spoke node
- Confirm you're on a Tailscale-connected network (your laptop must be on the mesh).
- Find the node's Tailscale IP:
tailscale status — look for the AMP hostname.
- Try Tailscale SSH directly:
tailscale ssh pi@AMPxxxxxxxx
- If that fails, check Tailscale service on the spoke: ask family to reboot the Pi, which restarts tailscaled automatically.
- If still unreachable — the Pi is likely powered off or lost internet. See "Node Offline" scenario above.
Password auth is disabled. Only SSH keys work (Leonard's key + BT deploy key). Never share SSH passwords — there are none.
🌐Tailscale is not connected on the spoke
- SSH in via local network if possible (connect to family's WiFi) or ask them to hold the Pi near the router.
- Check Tailscale status and logs:
sudo systemctl status tailscaled
sudo tailscale status
sudo journalctl -u tailscaled -n 50
- If "needs login" or "not authorized" — the auth key expired. Generate a new reusable auth key at
tailscale.com/admin/settings/keys and re-authenticate:
sudo tailscale up \
--authkey=tskey-auth-xxxxx \
--advertise-exit-node \
--advertise-tags=tag:exit-node
- If tailscaled won't start:
sudo systemctl restart tailscaled — then re-run step 3.
⏰Heartbeat cron is not sending (log is old or missing)
- Check if the cron entry exists:
crontab -l (should show */5 * * * * /usr/local/bin/amp-heartbeat.sh)
- Check if cron service is running:
sudo systemctl status cron
- Test the heartbeat script manually:
sudo /usr/local/bin/amp-heartbeat.sh
- If
/etc/amp-serial is missing or empty, the heartbeat can't identify itself. Re-run first-boot if needed (see below).
- Reinstall cron entry if missing:
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/local/bin/amp-heartbeat.sh") | crontab -
2 — First-Boot Problems
🥾First boot didn't complete — node has no serial, no Tailscale, no heartbeat
- SSH in locally (connect to family's WiFi, or use default
pi/raspberry credentials if it's a fresh image). Check the log:
cat /var/log/amp-firstboot.log
- Check if the guard file exists — if it does, the script thinks it already ran:
ls -la /etc/amp-firstboot-done
- If the script stopped at Tailscale setup — the auth key file was missing or wrong:
ls /boot/amp-tailscale.key
echo "tskey-auth-xxxxx" | sudo tee /boot/amp-tailscale.key
- To re-run first-boot completely (resets everything):
sudo rm /etc/amp-firstboot-done
sudo bash /usr/local/bin/first-boot.sh
Removing the guard file and rebooting is safe for a fresh Pi — it won't create a duplicate serial if the MAC isn't registered yet. If it IS already registered, the API returns 200 OK (idempotent).
💥Registration returned 409 CONFLICT — serial collision detected
- This means the MAC address was already registered under a different serial — usually because the SD card was re-flashed and the Pi booted fresh, generating a new salt.
- Check the audit_logs table on Blue Triangle:
ssh root@100.113.114.32
docker exec -it amp-db psql -U amp -d ampdb -c \
"SELECT * FROM audit_logs WHERE hardware_mac = '<MAC>' ORDER BY timestamp DESC LIMIT 10;"
- Decide: do you want to keep the old serial or accept the new one?
- Keep old serial: Delete the new record from gateways and reinstall the original serial file on the Pi:
echo "AMPXXXXXXXX" | sudo tee /etc/amp-serial
- Accept new serial: Update the gateways row with the new serial. Update /etc/amp-serial on the Pi to match.
3 — Blue Triangle (Cloud Hub) Issues
🔴Blue Triangle API unreachable — spokes can't register or send heartbeats
- SSH into BT (you must be on Tailscale):
ssh root@100.113.114.32
- If SSH fails, BT may be down. Open DigitalOcean console in browser → Power → Power cycle the droplet.
- Once SSH works, check Docker containers:
docker ps -a
docker start amp-dashboard
docker start amp-db
cd /opt/amp && docker compose up -d
- Check if the API is responding locally on BT:
curl http://127.0.0.1:5000/api/health
docker logs --tail=50 amp-dashboard
- Check Tailscale on BT is still connected:
tailscale status
🐳Docker container is down or crashing in a restart loop
docker ps -a
docker logs --tail=100 <container>
docker inspect <container> | grep -A5 '"State"'
- amp-db failing: Check disk space (
df -h). Postgres needs free space to operate. If low, clean up: docker system prune -f
- amp-dashboard failing: Usually a missing environment variable. Check
/opt/amp/.env has all required keys (DATABASE_URL, TELEGRAM_CLAUDE_TOKEN, etc.)
- amp-bridge failing: Check Anthropic API key is valid. Check both Telegram bot tokens in
.env.
cd /opt/amp && docker compose down && docker compose up -d
🌊Telegram war room flooded with hundreds of tailscale_restart / reboot alerts after BT recovery
This happens when BT has been offline for hours — pukas queue events locally and flush everything at once when BT comes back, overwhelming the API's 2 Gunicorn workers.
- Snooze puka alerts immediately (works via aikai over LAN, no Tailscale needed):
ssh -i ~/.ssh/id_ed25519 bullaz@10.0.0.105
python3 -c "import json,time; open('/tmp/amp-snooze.json','w').write(json.dumps({'snoozed':True,'until_ts':int(time.time())+7200,'until':'2h from now'}))"
- Block Telegram outbound from BT to stop the spam immediately:
ssh root@100.113.114.32
iptables -I FORWARD -d 149.154.160.0/20 -j DROP
iptables -I FORWARD -d 91.108.4.0/22 -j DROP
- Clear event queues on all pukas to stop new events being sent:
for IP in 100.110.69.51 100.116.250.85 100.86.244.86 100.73.221.51; do
ssh -i ~/.ssh/amp-deploy pi@$IP "sudo rm -f /tmp/amp-events-queue"
done
- Wait for API to clear (poll for HTTP 200), then unblock Telegram:
until curl -s --max-time 5 http://172.19.0.3:5000/api/gateways -o /dev/null -w '%{http_code}' | grep -q 200; do sleep 10; done
iptables -D FORWARD -d 149.154.160.0/20 -j DROP
iptables -D FORWARD -d 91.108.4.0/22 -j DROP
If puka processes are stuck mid-flush (SSH to pukas also timing out), wait it out — they will drain naturally in 15–30 min. The event queue is finite.
📊Hōʻike (hoike.alamalu.com:5000) returns connection timeout / HTTP 000
- Check if the API is responding at all:
ssh root@100.113.114.32
curl -s --max-time 8 http://172.19.0.3:5000/api/gateways -o /dev/null -w '%{http_code}'
- If API is overwhelmed (usually after event flood) — check logs and restart:
docker logs amp-api --tail=20
cd /opt/amp/blue-triangle && docker compose restart api
sleep 15 && curl -s --max-time 8 http://172.19.0.3:5000/api/gateways -o /dev/null -w '%{http_code}'
- If Docker containers can't reach internet after any iptables flush — rebuild Docker NAT rules:
systemctl restart docker
- If Hōʻike loads but shows stale data — check heartbeats are flowing:
docker exec amp-db psql -U amp -d amp -c "SELECT node_id, last_telemetry_seen FROM gateways ORDER BY node_id"
🔗wg_aikai failover tunnel won't establish handshake with aikai
- Check BT's wg_aikai config has
Table = off (CRITICAL — without it, all BT outbound traffic routes through aikai, breaking internet for all Docker containers):
cat /etc/wireguard/wg_aikai.conf | grep -E 'Table|Address|ListenPort'
- Verify aikai's endpoint uses BT's PUBLIC IP (not Tailscale) — Tailscale ACLs block UDP 51845:
ssh -i ~/.ssh/id_ed25519 bullaz@10.0.0.105
sudo grep Endpoint /etc/wireguard/wg_failover.conf
sudo systemctl restart wg-quick@wg_failover
- Verify UDP 51845 is open in DO cloud firewall (Networking → Firewalls → amp-no-front-door).
- Check handshake on both sides:
wg show wg_aikai latest-handshakes
ssh bullaz@10.0.0.105 "sudo wg show wg_failover latest-handshakes"
4 — Telegram Bridge Not Responding (Ala-C / Ala-G silent)
✈Sent a Telegram message and got no response from Ala-C or Ala-G
- Quick health check — if this returns anything other than
{"status":"up"}, the bridge is down:
curl http://100.113.114.32:5001
ssh root@100.113.114.32 "curl http://127.0.0.1:5001"
- Check bridge container status and restart it:
ssh root@100.113.114.32
docker ps | grep bridge
docker logs --tail=50 amp-bridge
docker restart amp-bridge
- If the bridge logs show "403 Forbidden" from Telegram — a bot token has expired or been revoked. Generate a new token in BotFather and update
/opt/amp/.env, then restart.
- If the bridge logs show Anthropic API errors — check your API key balance/status at
console.anthropic.com
- If the bridge is running but only ONE bot responds — one bot token is bad. Check which one is failing in the logs and fix that token.
/clear in the group chat resets the in-memory conversation history. Useful if the bots are giving confused or looping responses.
5 — Family Device / Subscriber Issues
📱Family member's device isn't routing through the exit node — no privacy protection
- On their phone/laptop — open the Tailscale app. Check that:
- Tailscale is connected (toggle is ON)
- "Use exit node" is selected, and their home Pi is chosen (e.g., AMP56F020949F)
- Confirm the Pi itself is advertising as an exit node:
ssh pi@<spoke-tailscale-ip>
sudo tailscale status
sudo tailscale up --advertise-exit-node --advertise-tags=tag:exit-node
- On the Tailscale admin console (
tailscale.com/admin) — confirm the exit node is "Approved". New exit node advertisements must be manually approved.
- Verify internet is routing through the Pi: have the family member visit
api.ipify.org — their IP should match the Pi's WAN IP shown in the dashboard.
🐢Internet is slow when connected through the exit node
- Check the Pi's load and temperature (they're fanless — heat causes throttling):
ssh pi@<spoke-tailscale-ip>
vcgencmd measure_temp
top -bn1 | head -5
cat /proc/net/dev
- If temperature is high (>75°C) — Pi is throttling. Check that the Argon NEO case heatsink is properly seated and the unit has airflow around it. Avoid placing in enclosed spaces.
- Test the Pi's own internet speed (eliminates the home ISP as the bottleneck):
curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python3 -
- If Pi speed is fine but VPN is slow — check Tailscale relay vs. direct connection:
sudo tailscale ping <client-tailscale-ip>
🌐Can't reach puka.alamalu.com or setup.alamalu.com
- Check NPM (Nginx Proxy Manager) is running on BT:
docker ps | grep proxy
- Check NPM proxy host configuration at
http://100.113.114.32:81 (NPM admin UI)
- Check DNS:
nslookup puka.alamalu.com — should point to Blue Triangle's public IP
- Check SSL cert status in NPM — expired certs will show certificate errors. Use NPM to renew Let's Encrypt certs.
ssh root@100.113.114.32
docker logs --tail=30 amp-proxy
docker restart amp-proxy
6 — Nessus Scan Issues
🔬Nessus scan fails to reach the Pi or returns incomplete results
- Nessus runs on Blue Triangle at
https://100.113.114.32:8834 — must be on Tailscale to access.
- The scan target is the Pi's local IP (on Kent Lab network during burn-in). Ensure Pi is on the same network as BT's scan range or use Tailscale IP as target.
- If Nessus says "Host unreachable" — check that the Pi is on (LEDs), has internet, and you can ping it from BT:
ssh root@100.113.114.32
ping <pi-ip-or-tailscale-ip> -c 3
- If Nessus service itself is down on BT:
ssh root@100.113.114.32
sudo systemctl status nessusd
sudo systemctl start nessusd
7 — Nuclear Recovery Procedures
☢Blue Triangle droplet is completely unreachable — cannot SSH, Tailscale shows offline
- Step 1 — netplan fix (try this first). Most likely cause after account suspension/reactivation: netplan vs. legacy ifupdown conflict. Use DO web console (Actions → Web Console) and run:
netplan --debug generate
netplan --debug apply
- If web console shows "timed out waiting for handshake" — file a DO support ticket: "SSH listening on 0.0.0.0:22, no firewall, netplan apply run, connections still time out. Please reset backend networking."
- SSH key check — after restoring connectivity, verify
~/.ssh/authorized_keys contains the amp-deploy key. If missing, add it (or enable password auth temporarily):
cat ~/.ssh/authorized_keys
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA92/nhiyYQqT16MEumPW+3mRMXtLZXCNqBOdxvYS8S6 amp-deploy" >> ~/.ssh/authorized_keys
echo 'PasswordAuthentication yes' > /etc/ssh/sshd_config.d/70-enable-password.conf && systemctl restart ssh
- After reboot, Tailscale should auto-reconnect. If auth expired:
tailscale up --authkey=tskey-auth-xxxxx --advertise-tags=tag:blue-triangle --ssh
- Once SSH works — restart Docker stack and verify:
cd /opt/amp/blue-triangle && docker compose up -d
docker ps
systemctl restart docker
- If the entire droplet is gone — rebuild from scratch using
DR/README.md in the repo (full rebuild runbook including event flood warning).
Pukas stay operational even when BT is offline — they use direct Telegram alerts as fallback. Family internet access is unaffected. Use /snooze 120 in the war room to silence alert noise during recovery.
💾Need to rebuild a spoke node from scratch (SD card corrupted / Pi replaced)
- Flash a fresh Raspberry Pi OS Bullseye image to a new SD card.
- Add to
/boot: empty ssh file + amp-tailscale.key with a valid reusable auth key.
- Ensure
first-boot.sh is installed as systemd one-shot service in the image.
- Boot Pi — first-boot runs automatically. It will re-register with BT API using the new MAC.
- If same MAC as before: gets same serial back (idempotent) ✓
- If new hardware (different MAC): gets new serial, new node_id — update gateways table to reassign to correct subscriber
- Check the first-boot log to confirm success:
tail -30 /var/log/amp-firstboot.log
8 — Symptom Quick-Lookup
| What You See | Most Likely Cause | First Command to Run | Page |
| 🔴 Telegram "Node Offline" alert |
Pi unplugged or lost internet |
tailscale status on laptop |
P.1 |
| Telegram bots not responding |
Bridge container down |
curl http://100.113.114.32:5001 |
P.2 |
| SSH to spoke refused |
Tailscale disconnected on spoke |
tailscale status on laptop |
P.1 |
| Heartbeat log is stale |
Cron not running or missing |
crontab -l on spoke |
P.1 |
| First boot log stops mid-way |
Missing Tailscale key file |
ls /boot/amp-tailscale.key |
P.2 |
| 409 CONFLICT at registration |
SD re-flashed, MAC already registered |
Check audit_logs table in Postgres |
P.2 |
| Docker containers showing Exited |
BT rebooted without auto-start set |
docker compose up -d on BT |
P.2 |
| Internet slow through exit node |
Pi thermal throttle or DERP relay |
vcgencmd measure_temp on spoke |
P.3 |
| Exit node not showing in Tailscale app |
Not approved in Tailscale admin |
Approve at tailscale.com/admin |
P.3 |
| puka.alamalu.com unreachable |
NPM down or SSL cert expired |
docker ps | grep proxy on BT |
P.3 |
| Blue Triangle SSH unreachable |
Tailscale down on BT or droplet frozen |
Use DigitalOcean web console |
P.3 |
| Telegram flooded with 100s of alerts after BT recovery |
Pukas flushing 11-day backlog of queued events |
/snooze 120 in war room, then clear puka queues |
P.2 |
| Hōʻike port 5000 times out / HTTP 000 |
Gunicorn workers overwhelmed by event flood |
docker compose restart api on BT |
P.2 |
| All BT outbound broken after wg_aikai up |
wg_aikai missing Table = off — hijacks default route |
wg-quick down wg_aikai, add Table = off, bring back up |
P.2 |
| wg_aikai handshake stuck at 0 (never connects) |
aikai endpoint uses Tailscale IP — blocked by ACLs |
Change endpoint to 159.65.218.220:51845 in wg_failover.conf |
P.2 |
| Docker containers can't reach internet |
iptables/nftables flushed — Docker NAT rules wiped |
systemctl restart docker on BT |
P.2 |
| Nessus won't start |
nessusd service not running |
sudo systemctl start nessusd |
P.3 |
Required Environment Variables — /opt/amp/.env on Blue Triangle
| Variable | Used By | Where to Get / Check |
DATABASE_URL | Dashboard API, Alert script | Postgres connection string on BT: postgresql://amp:<pass>@amp-db/ampdb |
TELEGRAM_CLAUDE_TOKEN | Alert script, Telegram bridge (Ala-C bot) | BotFather → Ala-C bot token |
TELEGRAM_GEMINI_TOKEN | Telegram bridge (Ala-G bot) | BotFather → Ala-G bot token |
TELEGRAM_GROUP_CHAT_ID | Alert script, Telegram bridge | War Room group chat ID (negative number) |
ANTHROPIC_API_KEY | Telegram bridge | console.anthropic.com → API Keys |
If any key is missing or wrong, the container will crash on startup. Check with: docker logs amp-bridge --tail=20 for KeyError or authentication error messages.