Files
railiance-infra/workplans/RAIL-HO-WP-0001-hosteurope-bootstrap.md
tegwick 703c57d91c chore(rename): railiance-hosts → railiance-infra
Update all operational references to reflect the new repo name per
ADR-003 (OAS S1 Infrastructure Substrate). Historical text in ADRs
and state-hub-inbox files preserved as-is. Gitea remote URL updated
locally (Gitea repo rename is a manual step).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 00:34:18 +01:00

6.0 KiB

id, type, title, domain, repo, status, owner, topic_slug, repo_goal_id, state_hub_workstream_id, created, updated, completed, handoff_note
id type title domain repo status owner topic_slug repo_goal_id state_hub_workstream_id created updated completed handoff_note
RAIL-HO-WP-0001 workplan Secure Single-Server Bootstrap at HostEurope railiance railiance-infra completed railiance railiance 9e835b82-acca-493a-943f-2553ffe0bf54 bf40b47e-be5b-4930-a7d2-362e76b943bb 2026-03-08 2026-03-09 2026-03-09 T01 and T02 (inventory entry and SSH tunnel setup) are prerequisites to run T03 onwards from the HostEurope server itself. The ansible work previously done in railiance-bootstrap (harden.yml, bootstrap.yml) is superseded by the roles/base and roles/sops_agent structure in this repo. The HostEurope server IP is 92.205.62.239 (hosts.ini is gitignored — recreate from inventory/servers.yaml when working on the host).

Secure Single-Server Bootstrap at HostEurope

Goal

Provision and converge the HostEurope server so that it becomes a secure, hardened node ready to join the ThreePhoenix Kubernetes cluster. This workplan covers everything from establishing SSH access and tunnel connectivity through a fully converged, verified server — all secrets managed via SOPS/age, all services secured from the start.

Scope is deliberately narrow: one server, secure from day one. Automated provisioning of additional server resources and the full three-node setup are deferred.

Boundary conditions

  • Ubuntu 24.04 LTS at HostEurope (92.205.62.239), manually provisioned
  • All remote access key-based only (no password auth)
  • Firewall active before k3s is installed
  • Secrets managed via SOPS/age — nothing committed in plaintext
  • This workplan is run from the HostEurope server via SSH, not from WSL

Remote execution setup

This repo is intended to run from the HostEurope server itself. To retain State Hub connectivity during Claude sessions on that server, set up an SSH reverse tunnel from your local machine before connecting:

# On your local machine — forward local state-hub to the remote
ssh -R 8000:127.0.0.1:8000 <user>@92.205.62.239

Then Claude on the remote host can reach http://127.0.0.1:8000 as normal. See also: the tunnel setup note in CLAUDE.md.


Tasks

T01 — Add HostEurope host to inventory

id: T01
status: done
completed: "2026-03-08"
priority: high
state_hub_task_id: "9b2222a3-0f9f-4543-9321-e4cd5f87a457"

Add the HostEurope host to inventory/servers.yaml under a hosteurope group. Create ansible/hosts.ini from the inventory (gitignored — recreate on each new working machine):

python3 ansible/inventory_from_yaml.py > ansible/hosts.ini
# or add manually: [hosteurope]\n92.205.62.239 ansible_user=...

Verify connectivity:

ansible -i ansible/hosts.ini hosteurope -m ping

Done when: ping succeeds from a control node with network access to the host.


T02 — Set up SSH tunnel for State Hub access

id: T02
status: done
completed: "2026-03-09"
priority: high
state_hub_task_id: "e4dda416-19bc-4672-b9ba-8ddb1b9e9659"

On your local machine, establish a reverse tunnel before SSH-ing to the HostEurope server so the State Hub MCP server is reachable from Claude sessions on that host:

make tunnel   # reads host from inventory/servers.yaml

Or manually:

ssh -R 8000:127.0.0.1:8000 tegwick@92.205.62.239

Verify the tunnel is working from the remote:

curl http://127.0.0.1:8000/state/health

Done when: make tunnel target implemented; procedure documented.


T03 — Extend base role with security hardening

id: T03
status: done
completed: "2026-03-08"
priority: high
state_hub_task_id: "6eda6875-1301-4794-a07e-3e13ff1d92bf"

Extend ansible/roles/base/tasks/main.yml to cover security hardening that must run before any service installation:

  • Disable root SSH login (PermitRootLogin no)
  • Disable password authentication (PasswordAuthentication no)
  • Enable and configure UFW: deny all inbound, allow SSH (22), k3s API (6443), Flannel VXLAN (8472/UDP)
  • Install and enable fail2ban with SSH jail
  • Set HISTCONTROL=ignorespace in /etc/profile.d/

Verify with:

ansible-playbook -i ansible/hosts.ini -l hosteurope ansible/playbooks/bootstrap.yaml --check

Done when: dry-run produces no errors and hardening tasks are visible in the play recap.


T04 — Run bootstrap on the HostEurope host

id: T04
status: done
completed: "2026-03-08"
priority: high
state_hub_task_id: "77921431-3a45-45b2-a0b0-cf0c43262205"

Execute the full bootstrap playbook from the HostEurope server (tunnel must be active per T02):

ansible-playbook -i ansible/hosts.ini -l hosteurope ansible/playbooks/bootstrap.yaml

Done when:

  • Playbook completes with no failed tasks
  • UFW is active and SSH still works after the run
  • SOPS agent role applied successfully

T05 — Smoke test and record

id: T05
status: done
completed: "2026-03-08"
priority: medium
state_hub_task_id: "c573c200-bf22-49d1-86f9-dca1fc71743c"

Verify the converged state:

# Confirm UFW active
ansible -i ansible/hosts.ini hosteurope -m shell -a "ufw status"
# Confirm fail2ban running
ansible -i ansible/hosts.ini hosteurope -m shell -a "systemctl is-active fail2ban"
# Confirm SSH hardening applied
ansible -i ansible/hosts.ini hosteurope -m shell -a "sshd -T | grep -E 'permitrootlogin|passwordauthentication'"

Add docs/hosteurope-bootstrap.md recording:

  • Server specs (vCPU, RAM, disk)
  • Public IP (no credentials)
  • Date bootstrapped
  • Roles applied

Log completion to the State Hub:

add_progress_event(summary="HostEurope server bootstrapped and hardened",
    event_type="milestone", workstream_id="bf40b47e-be5b-4930-a7d2-362e76b943bb")

Done when: all checks pass and the progress event is logged.


References

  • Repo goal: 9e835b82-acca-493a-943f-2553ffe0bf54
  • Domain goal: 6f96c712-60e6-4ea9-ab06-168878eafbce (Three-Phoenix Secure Kubernetes Infrastructure)
  • Previous ansible work: railiance-bootstrap/ansible/ (harden.yml, bootstrap.yml — superseded by this repo's role structure)