Document HAOS on PVE VM 180 (LAN55) with verified SSH access, network details, and cross-links from lan-overview, inventory, and AGENTS quick map.
9.8 KiB
VPS Agent Ops Hub
This repo is the agent ops handbook + fact source for maintaining personal VPS hosts. Prefer verifying live state over assuming docs are complete.
Also readable as agent.md (symlink → this file).
How to work
- Read
inventory/hosts.mdfor the machine list. - Open the matching
hosts/<name>.mdfor SSH, roles, paths, and quirks. - For common tasks, follow a runbook under
runbooks/. - Prefer read-only checks first; change only after confirming current state.
- For routine checks and approved service reconciliation, run the matching
Ansible playbook from
ansible/; see routine Ansible operations. - Default SSH access (
ssh -4 windy@<host>) is for focused diagnostics, imperative upstream procedures, and incident work. Prefer IPv4 from this WSL client (AAAA often exists but IPv6 route does not). - Record each material VPS operation, incident, configuration change, or
verification outcome in the corresponding Linear
vpsproject. Include scope, action, verification, and remaining follow-up; never put passwords, tokens, private keys, recovery keys, or private room IDs in Linear.
Active hosts (quick map)
| Host | Role | SSH | Facts |
|---|---|---|---|
| mx2.windy.me | mailcow (/opt/mail, project cow) |
ssh -4 windy@mx2.windy.me |
hosts/mx2.windy.me.md |
| us2.wsvc.info | Vaultwarden + Traefik (+ Soft Serve, …) | ssh -4 windy@us2.wsvc.info |
hosts/us2.wsvc.info.md |
| hk2.chans.xyz | PowerDNS auth ns1 (/opt/pdns) |
ssh -4 windy@hk2.chans.xyz |
hosts/hk2.chans.xyz.md |
| synapse.chans.xyz | Matrix ESS (Synapse + MAS + Element) on K3s | ssh -4 windy@synapse.chans.xyz |
hosts/synapse.chans.xyz.md |
| dns.windy.lan | AdGuard Home LAN DNS + Mihomo explicit proxy | ssh -4 windy@192.168.66.36 |
hosts/dns.windy.lan.md |
| gfw.windy.lan | OpenWrt LAN gateway / OpenClash | ssh -4 root@192.168.66.1 |
hosts/gfw.windy.lan.md |
| gw | EdgeRouter X primary LAN gateway | ssh -4 zhiqiang@192.168.66.254 |
hosts/gw.md |
| ubnt | UniFi Network Controller | ssh -4 windy@192.168.66.46 |
hosts/ubnt.md |
| hass.windy.lan | Home Assistant (HAOS, LAN55) | ssh hassio@hass.windy.lan |
hosts/hass.windy.lan.md |
Public services
| URL / endpoint | Backend host | Notes |
|---|---|---|
| https://mx2.windy.me | mx2 | mailcow UI / SOGo |
SMTP mx2.windy.me:587 (STARTTLS) or :465 |
mx2 | client submission; full email + mailbox password — runbook |
IMAP mx2.windy.me:993 |
mx2 | same mailbox credentials |
| https://auth.wsvc.info | us2 (/opt/vaultwarden) |
Vaultwarden (Postgres, operational) — client Server URL |
repo.windy.me:2222 |
us2 (/opt/soft-serve) |
Soft Serve (stub details) |
DNS ns1.wsvc.info:53 |
hk2 (/opt/pdns, Auth 5.0.6) |
PowerDNS auth — zones windy.me, wsvc.info, chans.xyz |
| https://pdns.wsvc.info | hk2 (poweradmin) |
Poweradmin UI |
| https://pgweb.wsvc.info | hk2 (pgweb) |
PowerDNS Postgres browser |
| https://chat.chans.xyz | synapse (ess, ESS chart 26.7.2) |
Element Web (Matrix client) |
| https://synapse.chans.xyz | synapse | Synapse Client-Server + Federation API |
| https://account.chans.xyz | synapse | Matrix Authentication Service (local passwords) |
| https://admin.chans.xyz | synapse | Element Admin console (MAS admin auth) |
Upstream docs
Vaultwarden: Before changing config, read docs/vaultwarden-upstream.md. Live DB is Postgres (DATABASE_URL); vw-data/config.json from /admin overrides .env (including SMTP password — keep it synced with .env / .smtp-credentials). After recreating the VW container, restart Traefik if https://auth.wsvc.info returns 404. SMTP health needs AUTH, not TCP-only — see vaultwarden-health.
PowerDNS: Before changing /opt/pdns on hk2, read docs/pdns-upstream.md. Auth pin 5.0.6; primary + also-notify/only-notify= + DNSSEC OK. Deferred: rotate weak API/DB credentials and TSIG (TSIG-ALLOW-AXFR bypasses IP ACL). Health: pdns-health.
Matrix (ESS on synapse): Matrix homeserver running on synapse.chans.xyz via the official ESS (Element Server Suite) Helm chart with Synapse + MAS + Element Web + Admin. DNS zone chans.xyz managed by hk2 PowerDNS. Before changing config, read docs/matrix-upstream.md and hosts/synapse.chans.xyz.md. K3s cluster on this node has hostPort 80/443 for Traefik (no ServiceLB). Health: matrix-health.
RustDesk: Self-hosted RustDesk server on hk2.chans.xyz (/opt/rustdesk, containers hbbs/hbbr, image pinned 1.1.14). The hbbs -r relay hostname must resolve to the host's public IP 154.36.174.161 — use hk2.chans.xyz (never hk2.wsvc.info, which has no DNS record). Health: rustdesk-health.
Runbooks & scripts
| Task | Path |
|---|---|
| mailcow health | runbooks/mailcow-health.md |
| mailcow update | runbooks/mailcow-update.md |
| mailcow SMTP/IMAP client | runbooks/mailcow-smtp-client.md |
| Vaultwarden health | runbooks/vaultwarden-health.md |
| Vaultwarden SQLite→PG migrate | runbooks/vaultwarden-sqlite-to-postgres.md |
| Vaultwarden upstream refs | docs/vaultwarden-upstream.md |
| PowerDNS health (hk2) | runbooks/pdns-health.md |
| PowerDNS upstream refs | docs/pdns-upstream.md |
| Matrix health | runbooks/matrix-health.md |
| RustDesk health (hk2) | runbooks/rustdesk-health.md |
| AdGuard Home health | runbooks/adguard-home-health.md |
| Matrix upstream refs | docs/matrix-upstream.md |
| Hermes Agent Matrix channel | docs/hermes-matrix.md |
| UniFi local-service proxy bypass | docs/unifi-openclash-localhost.md |
| UniFi SSO login setting (Ansible) | cd ansible && ansible-playbook playbooks/unifi-sso.yml --limit unifi |
| Routine Ansible operations | runbooks/ansible-operations.md |
Routine mailcow health: cd ansible && ansible-playbook playbooks/health-report.yml --limit mailcow. The local stub resolver is flaky; DNS probes use 1.1.1.1 / 8.8.8.8.
Agent skills
Issue tracker
Issues are tracked in Linear and created/updated via the Linear MCP (vps project). See docs/agents/issue-tracker.md.
Triage labels
Default triage labels: needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix. See docs/agents/triage-labels.md.
Domain docs
Single-context layout: CONTEXT.md + docs/adr/ at the repo root. See docs/agents/domain.md.
Safety
- Never commit secrets: passwords, API keys, private keys,
.env,mailcow.confDB passwords, VaultwardenADMIN_TOKEN/.smtp-credentials. - Secrets live only on the servers (e.g.
/opt/vaultwarden/.env). Do not copy them from Obsidian into this repo. - Ask before destructive actions:
docker compose down -v, DB drops, DNS changes, force-push, disk wipes. - Ansible reconciliation is intentionally allowlisted and requires an explicit confirmation variable; it is not a general remote-command facility.
- Do not modify local
~/.ssh/configor git config unless explicitly asked.
SSH access safety — mandatory change procedure
Treat any SSH authentication or authorization change as a lockout-risk change. This includes sshd_config / drop-in edits, PasswordAuthentication, PermitRootLogin, AuthorizedKeysFile, Match blocks, SSH keys, accounts, groups, chroots, firewalls, and SSH ports.
Before disabling an existing access method or reloading sshd, all of the following are mandatory:
- Keep the current verified SSH management session open as the rollback path; do not use it to run the validation connection.
- Install the intended management public key from a verified local source. Never assume a public-key file exists on the target host or copy a remote path without checking it first.
- Validate the candidate configuration with
sshd -tbefore reloading the service. - From a separate local terminal, prove the new key-only login works using the exact target account, hostname, and key (
BatchMode=yes, password authentication disabled), and verify needed sudo access. - Only after step 4 succeeds may password login, root login, the old key, or another existing access route be disabled.
- Keep the original management session open until the final effective SSH configuration and a fresh key-only login have both been verified.
If the new key-based login cannot be proven first, stop immediately: do not reload an access-restricting configuration. Provider web/serial console access must be confirmed before any SSH access-policy change, but it is a recovery path—not a substitute for the validation steps above.
Obsidian
Bills, rough notes, and personal clutter stay in the Obsidian vault. This repo holds actionable facts and runbooks only.
Layout
AGENTS.md / agent.md # this entry (agent.md → AGENTS.md)
inventory/hosts.md # machine index
hosts/ # per-host facts
runbooks/ # step-by-step ops
docs/ # upstream doc indexes / design notes