Files
alexandre.pires 272ed647cf Refactor and enhance Ansible configurations for dev-02 and nginx proxy setup
- Updated host_vars for dev-02 to include login history settings and modified code server authentication.
- Adjusted opencode server configurations and reduced resource allocation.
- Introduced a new playbook for configuring nginx reverse proxy with TLS and OAuth2.
- Enhanced linux_dev_station role defaults and tasks, including package updates and service configurations.
- Removed unnecessary credential assertions in linux_dev_station tasks.
- Created nginx_proxy role with tasks for certbot, nginx installation, and oauth2-proxy setup.
- Added templates for nginx and oauth2-proxy configurations.
- Updated terraform configuration to reflect new DNS records for ide and agent services.
- Documented changes and configurations in linux_dev_station.md for clarity and future reference.
2026-07-11 19:29:50 -04:00

5.4 KiB

Linux Dev Station - dev-02.lab.alexpires.me

Overview

Provisioned dev-02.lab.alexpires.me (Fedora, 10.19.4.210) as a remote dev station mirroring the macOS setup. Includes code-server, opencode, and dev toolchain management. Exposed via nginx reverse proxy with TLS termination and OAuth2/OIDC SSO (Gitea as IdP).

Role: linux_dev_station

  • Location: ansible/roles/linux_dev_station/
  • Scope: Fedora only (ansible_facts['distribution'] == "Fedora")
  • Package manager: dnf for system packages; tool-managed (uv, rustup, fnm) for dev toolchains
  • Excludes: podman/container runtime management

Components

  • SSH hardening: Public key auth, password auth disabled, root login disabled
  • Users: devstation user with sudo, zsh shell, and required groups
  • Zsh: Oh My Zsh with agnoster theme, plugins, custom env vars, and zshrc management
  • Tooling:
    • uv - Python package manager
    • rustup - Rust toolchain
    • fnm + node - Node.js version manager
    • code-server - VS Code remote on 127.0.0.1:3000
    • opencode - AI coding assistant (HTTP server on 127.0.0.1:4096)
  • Firewall: firewalld with fw_allowed_ports (22, 443)
  • Systemd services: code-server, opencode

Opencode Details

  • Repo: anomalyco/opencode (not opencode-ai)
  • Version: 1.17.18
  • Binary: opencode-linux-x64.tar.gz
  • Mode: HTTP server (serve), binds to 127.0.0.1
  • Install strategy: Versioned directories (~/.local/lib/tool-vX.Y.Z) + symlinks for idempotent upgrades

Oh My Zsh Plugins (Linux)

git, fzf, common-aliases, sudo, tmux, extract, colored-man-pages, history-substring-search, kubectl, microk8s, docker, docker-compose, ansible, aws, golang, dnf, bgnotify

macOS Role Updates

  • Location: ansible/roles/macos_dev_station/
  • Synced Oh My Zsh fixes: sourcing, theme, plugins, extra env vars
  • Oh My Zsh Plugins (macOS): git, fzf, common-aliases, sudo, tmux, extract, colored-man-pages, history-substring-search, kubectl, docker, docker-compose, ansible, aws, golang, brew, bgnotify

TLS + OAuth2/OIDC SSO (nginx_proxy role)

  • Location: ansible/roles/nginx_proxy/ — standalone, generic role not tied to linux_dev_station
  • Playbook: ansible/playbook_nginx_proxy.yml targets [nginx] group
  • Architecture: nginx (:443, TLS) → oauth2-proxy (:4180, session mgmt) → backends (127.0.0.1 only)
  • Certificate: SAN cert for ide.lab.alexpires.me + agent.lab.alexpires.me via certbot DNS-01 (cloudns plugin), auto-renewal cron
  • SSO cookie: Scoped to .lab.alexpires.me
  • IdP: Gitea (code.alexpires.me), OAuth2 app lab-services (confidential client, scopes: openid, profile, email)
  • oauth2-proxy: v7.15.3, config format: oidc_issuer_url, http_address, upstreams array, cookie_domains array, proxy_websockets = true, reverse_proxy = true
  • Services exposed:
    • https://ide.lab.alexpires.me → code-server (127.0.0.1:3000)
    • https://agent.lab.alexpires.me → opencode (127.0.0.1:4096)
  • Nginx fixes applied: types_hash_bucket_size 64;, ssl_ciphers single line, http2 separate directive, SAN cert shared via first site directory, POST auth_request body fix (proxy_set_header Content-Length "";), proxy_buffer_size for oauth2 callback

Defaults

  • nginx_proxy_oauth2_proxy_version: "7.15.3"
  • nginx_proxy_cloudns_nameserver: "109.201.133.111"
  • nginx_proxy_sites — list of site configs with server_name, upstream, websocket toggle

Secrets

  • OAUTH2_PROXY_COOKIE_SECRET — 32-byte random, stored in vault
  • OAUTH2_PROXY_CLIENT_ID / OAUTH2_PROXY_CLIENT_SECRET — from Gitea OAuth2 app
  • CLOUDNS_AUTH_ID / CLOUDNS_PASSWORD — DNS credentials for certbot

Infrastructure Changes

  • DNS:
    • Added A record for dev-02.lab.alexpires.me (10.19.4.210)
    • Added A records for ide and agent10.19.4.210 (in terraform/apps/dev-01/config.tf)
  • Inventory: Added [nginx] group with dev-02.lab.alexpires.me; dev-02 removed from [certbot] group
  • Host vars: ansible/host_vars/dev-02.lab.alexpires.me.yml with nginx_proxy_sites, bind_to_localhost: true, firewall rules (22, 443), OAuth2 credentials via lookup('env', ...)
  • dev-01 cleanup: Removed opencode/vscode CNAME records and proxy_services entries (no longer proxying to dev-02)

Service Bindings

Service Binding
code-server 127.0.0.1:3000
opencode 127.0.0.1:4096
oauth2-proxy 127.0.0.1:4180
nginx 0.0.0.0:443

Firewall

Port Access
22 10.19.4.0/24 + VPN (10.5.5.5/32)
443 10.19.4.0/24 + VPN (10.5.5.5/32)
3000/4096 Closed (nginx handles all external access)

SELinux

  • http_port_t extended to include 4180 (oauth2-proxy)
  • httpd_can_network_connect enabled
  • /etc/letsencrypt context set to httpd_cert_t

Known Issues & Workarounds

  • ssh-agent systemd: Removed due to SELinux blocking transitions; managed via .zshrc startup instead
  • ACL issue: allow_world_readable_tmpfiles = True required in ansible.cfg for macOS→Fedora become_user compatibility

Required Credentials

  • GITEA_APP_TOKEN
  • OPEN_WEBUI_API_KEY
  • CLOUDNS_AUTH_ID / CLOUDNS_PASSWORD (for certbot DNS-01)
  • OAUTH2_PROXY_COOKIE_SECRET / CLIENT_ID / CLIENT_SECRET (for nginx_proxy role)

Ansible.cfg Fix

Added allow_world_readable_tmpfiles = True under [defaults] to fix become_user failures on Fedora when running from macOS.