Files changed: .gitignore CLAUDE.md credentials engine/.embcache.json engine/changelog.md engine/config.yaml engine/lib/__pycache__/agent.cpython-312.pyc engine/lib/agent.py engine/lib/lint.py engine/lint-report.md engine/sweep-full.log engine/sweep.sh vault/.obsidian/graph.json vault/.obsidian/workspace.json vault/INDEX.md vault/archive/projects/mmud/last-ember-chronicle.html vault/archive/projects/mmud/last-ember-howto.html vault/archive/projects/mmud/last-ember.html vault/archive/projects/mmud/mmud-phase5-prompt.md vault/archive/projects/mmud/mmud-phase6-prompt.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/01-update-planned.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/02-npc-nodes.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/03-darkcragg.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/04-dcrg-node.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/05-phase5.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/06-phase6.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/README.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/mmud-project.md vault/docs/hardware/environment.md vault/docs/hardware/ip-allocation.md vault/docs/matrix/archivist.md vault/docs/matrix/matrix_host.md vault/docs/matrix/mautrix_signal.md vault/docs/matrix/synapse.md vault/docs/matrix/synapse_retention_discovery.md vault/docs/navi/cc-rules.md vault/docs/navi/deployment.md vault/docs/navi/themes.md vault/docs/services/ots-setup.md vault/docs/services/services.md vault/docs/services/usenet.md vault/docs/software/authentik.md vault/docs/software/caddy.md vault/docs/software/dns.md vault/docs/software/geo-tools.md vault/docs/software/recon.md vault/docs/software/searxng.md vault/glossary.md vault/notes/echo6-landing-page-data-export.md vault/notes/ia-download-queue.md vault/plans/vaultwarden-plan.md vault/projects/advbbs-project.md vault/projects/argus.md vault/projects/deploy-livesync.md vault/projects/matrix-synapse-deployment.md vault/projects/meshtastic-headscale-runbook.md vault/projects/mmud-project.md vault/runbooks/add-peertube-channel.md vault/runbooks/authentik-access-groups.md vault/runbooks/authentik-create-invitation.md vault/runbooks/authentik-oidc-application.md vault/runbooks/authentik-upgrade.md vault/runbooks/ct-runbook.md vault/runbooks/edge2-access-reference.md vault/runbooks/expose-service-contabo.md vault/runbooks/expose-service-edge2.md vault/runbooks/expose-service-home.md vault/runbooks/headscale-onboard-node.md vault/runbooks/ia-cli-reference.md vault/runbooks/ia-download-mirror.md vault/runbooks/idahomesh-bridge-setup.md vault/runbooks/idahomesh-vpn-device-setup.md vault/runbooks/lxc-service-migration.md vault/runbooks/mailcow-create-mailbox.md vault/runbooks/meshmonitor-password-reset.md vault/runbooks/meshtastic-sidecar-node.md vault/runbooks/meshtasticd-sim-nodes-runbook.md vault/runbooks/nordvpn-lxc.md vault/runbooks/peertube-remote-runner.md vault/runbooks/pg-backup.md vault/runbooks/pi-nas-omv-runbook.md vault/runbooks/pipeline-patterns.md vault/runbooks/proxmox-create-ubuntu-vm.md vault/runbooks/proxmox-onboard-node.md vault/runbooks/recon-operations.md vault/runbooks/recon-service-integration.md vault/runbooks/syncthing-add-node.md vault/session-resume/SESSION-HANDOFF-meshai-test.md
313 lines
6.8 KiB
Markdown
313 lines
6.8 KiB
Markdown
---
|
|
title: IdahoMesh VPN — Device Setup
|
|
type: runbook
|
|
tags:
|
|
- mesh
|
|
aliases: []
|
|
related:
|
|
- [[idahomesh-bridge-setup]]
|
|
- [[meshtastic-headscale-runbook]]
|
|
- [[meshtastic-sidecar-node]]
|
|
- [[headscale-onboard-node]]
|
|
- [[caddy]]
|
|
updated: 2026-06-18
|
|
---
|
|
# IdahoMesh VPN — Device Setup
|
|
|
|
Join a device to the IdahoMesh tailnet (Meshtastic mesh network VPN).
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
| Item | Value |
|
|
|------|-------|
|
|
| Headscale URL | `https://vpn.idahomesh.com` |
|
|
| Tailnet prefix | 100.100.0.0/16 |
|
|
| MagicDNS domain | mesh.local |
|
|
| Supported platforms | Linux (x86/ARM), Windows, macOS, Android, iOS |
|
|
|
|
### Users
|
|
|
|
| User | Purpose | Key type |
|
|
|------|---------|----------|
|
|
| malice | Echo6 infrastructure (bridge LXC) | Short-lived, single-use |
|
|
| sidpatchy | Sidpatchy's devices | Short-lived, single-use |
|
|
| nebra | Nebra CM3 gateways (field devices) | Long-lived, reusable |
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
Before starting, you need:
|
|
|
|
1. **A preauthkey** — generated by the IdahoMesh Headscale admin (see [Generating Keys](#generating-preauthkeys) below)
|
|
2. **Internet access** on the device (to reach vpn.idahomesh.com)
|
|
3. **Root/admin access** on the device
|
|
|
|
---
|
|
|
|
## Linux (Debian/Ubuntu/Raspberry Pi OS)
|
|
|
|
### Install Tailscale
|
|
|
|
```bash
|
|
curl -fsSL https://tailscale.com/install.sh | sh
|
|
```
|
|
|
|
### Join the IdahoMesh tailnet
|
|
|
|
```bash
|
|
tailscale up \
|
|
--login-server=https://vpn.idahomesh.com \
|
|
--authkey=<YOUR_PREAUTHKEY> \
|
|
--hostname=<DEVICE_NAME>
|
|
```
|
|
|
|
Replace:
|
|
- `<YOUR_PREAUTHKEY>` — the key provided to you
|
|
- `<DEVICE_NAME>` — short, lowercase hostname (e.g., `burley-butte`, `sid-laptop`)
|
|
|
|
### Verify
|
|
|
|
```bash
|
|
tailscale status
|
|
tailscale ip -4
|
|
ping -c 3 100.100.0.1 # Ping another node on the tailnet
|
|
```
|
|
|
|
You should see a `100.100.x.x` IP assigned.
|
|
|
|
---
|
|
|
|
## Nebra CM3 Gateway (ARM/Raspberry Pi)
|
|
|
|
Same as Linux above. The install script auto-detects ARM.
|
|
|
|
```bash
|
|
# Install
|
|
curl -fsSL https://tailscale.com/install.sh | sh
|
|
|
|
# Join — use the reusable nebra preauthkey
|
|
tailscale up \
|
|
--login-server=https://vpn.idahomesh.com \
|
|
--authkey=<NEBRA_PREAUTHKEY> \
|
|
--hostname=<GATEWAY_NAME>
|
|
```
|
|
|
|
**Naming convention for Nebra gateways:**
|
|
|
|
| Gateway | Hostname |
|
|
|---------|----------|
|
|
| Burley Butte | `burley-butte` |
|
|
| Picabo | `picabo` |
|
|
| AIDA-NEBRA | `aida-nebra` |
|
|
|
|
### Enable Tailscale on boot
|
|
|
|
Tailscale installs as a systemd service and starts on boot automatically. Confirm:
|
|
|
|
```bash
|
|
systemctl is-enabled tailscaled
|
|
# Should output: enabled
|
|
```
|
|
|
|
---
|
|
|
|
## Windows
|
|
|
|
### Install
|
|
|
|
Download and install Tailscale from: https://tailscale.com/download/windows
|
|
|
|
### Join
|
|
|
|
Open **PowerShell as Administrator:**
|
|
|
|
```powershell
|
|
tailscale up --login-server=https://vpn.idahomesh.com `
|
|
--authkey=<YOUR_PREAUTHKEY> `
|
|
--hostname=<DEVICE_NAME>
|
|
```
|
|
|
|
### Verify
|
|
|
|
```powershell
|
|
tailscale status
|
|
tailscale ip -4
|
|
```
|
|
|
|
---
|
|
|
|
## macOS
|
|
|
|
### Install
|
|
|
|
Download and install Tailscale from: https://tailscale.com/download/mac
|
|
|
|
Or via Homebrew:
|
|
|
|
```bash
|
|
brew install tailscale
|
|
```
|
|
|
|
### Join
|
|
|
|
```bash
|
|
tailscale up \
|
|
--login-server=https://vpn.idahomesh.com \
|
|
--authkey=<YOUR_PREAUTHKEY> \
|
|
--hostname=<DEVICE_NAME>
|
|
```
|
|
|
|
### Verify
|
|
|
|
```bash
|
|
tailscale status
|
|
tailscale ip -4
|
|
```
|
|
|
|
---
|
|
|
|
## Android
|
|
|
|
1. Install Tailscale from **F-Droid** (recommended — supports custom servers) or Google Play
|
|
2. Open Tailscale → tap the three-dot menu → **Use custom coordination server**
|
|
3. Enter: `https://vpn.idahomesh.com`
|
|
4. Authenticate (it will open a browser if no authkey is used)
|
|
|
|
> **Note:** The Google Play version may not support custom coordination servers. Use the F-Droid build if the option is missing.
|
|
|
|
---
|
|
|
|
## iOS
|
|
|
|
1. Install Tailscale from the App Store
|
|
2. Open Tailscale → Settings → **Use Alternate Server**
|
|
3. Enter: `https://vpn.idahomesh.com`
|
|
4. Authenticate via browser
|
|
|
|
> **Note:** iOS support for custom Headscale servers can be limited. If the option is unavailable, use the CLI on another device and share connectivity via subnet routing.
|
|
|
|
---
|
|
|
|
## Verification Checklist
|
|
|
|
Run from the newly joined device:
|
|
|
|
```bash
|
|
echo "=== IdahoMesh VPN Check ==="
|
|
echo "Hostname: $(hostname)"
|
|
echo "Tailscale IP: $(tailscale ip -4 2>/dev/null || echo 'N/A')"
|
|
echo "Status: $(tailscale status --self 2>/dev/null | head -1 || echo 'NOT CONNECTED')"
|
|
echo "Login server: $(tailscale debug prefs 2>/dev/null | grep -o 'ControlURL:[^ ]*' || echo 'unknown')"
|
|
```
|
|
|
|
Expected: a `100.100.x.x` IP and connected status.
|
|
|
|
### Test connectivity to other nodes
|
|
|
|
```bash
|
|
# List all visible peers
|
|
tailscale status
|
|
|
|
# Ping another node by MagicDNS name
|
|
tailscale ping <OTHER_HOSTNAME>
|
|
|
|
# Or by IP
|
|
ping 100.100.0.x
|
|
```
|
|
|
|
---
|
|
|
|
## Generating Preauthkeys
|
|
|
|
**Admin only** — run on the IdahoMesh Headscale server (CT 106, 192.168.1.106):
|
|
|
|
```bash
|
|
# For a human user (single-use, expires in 24h)
|
|
headscale preauthkeys create --user <USERNAME> --expiration 24h
|
|
|
|
# For a human user (single-use, longer window)
|
|
headscale preauthkeys create --user <USERNAME> --expiration 72h
|
|
|
|
# For Nebra gateways (reusable, long-lived)
|
|
headscale preauthkeys create --user nebra --reusable --expiration 8760h
|
|
|
|
# List existing keys
|
|
headscale preauthkeys list --user <USERNAME>
|
|
```
|
|
|
|
Users: `malice` (ID 4), `sidpatchy` (ID 2), `nebra` (ID 3)
|
|
|
|
> **Note:** Headscale v0.28.0 `--user` flag requires user IDs (integers), not names.
|
|
|
|
---
|
|
|
|
## Removing a Device
|
|
|
|
**Admin only:**
|
|
|
|
```bash
|
|
# List all nodes
|
|
headscale nodes list
|
|
|
|
# Delete a node by ID
|
|
headscale nodes delete -i <NODE_ID>
|
|
```
|
|
|
|
On the device itself:
|
|
|
|
```bash
|
|
tailscale logout
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### "connection refused" or timeout on join
|
|
|
|
- Confirm the device has internet access: `curl -I https://vpn.idahomesh.com`
|
|
- Check [[dns]] resolution: `dig vpn.idahomesh.com`
|
|
- Verify the preauthkey hasn't expired
|
|
|
|
### "key expired" or "invalid key"
|
|
|
|
- Preauthkeys are time-limited. Ask the admin for a new one
|
|
- Nebra keys are reusable but still expire — check with `headscale preauthkeys list --user nebra`
|
|
|
|
### Device shows "offline" in node list
|
|
|
|
- Check if tailscaled is running: `systemctl status tailscaled`
|
|
- Restart: `systemctl restart tailscaled`
|
|
- Force re-auth: `tailscale up --login-server=https://vpn.idahomesh.com --force-reauth`
|
|
|
|
### Can't reach other nodes
|
|
|
|
- Confirm both devices show as "online" in `tailscale status`
|
|
- Check ACL policy — the admin may need to add rules for your user group
|
|
- Try direct IP ping before MagicDNS names
|
|
|
|
### MagicDNS not resolving
|
|
|
|
- Confirm `--accept-dns=true` (this is the default)
|
|
- Check: `tailscale debug prefs | grep CorpDNS`
|
|
- Restart tailscaled
|
|
|
|
---
|
|
|
|
## Quick Reference
|
|
|
|
| Item | Value |
|
|
|------|-------|
|
|
| Headscale URL | `https://vpn.idahomesh.com` |
|
|
| Tailnet prefix | 100.100.0.0/16 |
|
|
| MagicDNS domain | mesh.local |
|
|
| Headscale server | CT 106 on utility (192.168.1.106) |
|
|
| Admin access | SSH to 192.168.1.106 or via utility Proxmox |
|
|
| ACL policy | `/etc/headscale/acl.json` on CT 106 |
|
|
|
|
---
|
|
|
|
*Last updated: 2026-02-11*
|