272ed647cf
- 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.
5.4 KiB
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:
devstationuser 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 managerrustup- Rust toolchainfnm+node- Node.js version managercode-server- VS Code remote on127.0.0.1:3000opencode- AI coding assistant (HTTP server on127.0.0.1:4096)
- Firewall: firewalld with
fw_allowed_ports(22, 443) - Systemd services: code-server, opencode
Opencode Details
- Repo:
anomalyco/opencode(notopencode-ai) - Version:
1.17.18 - Binary:
opencode-linux-x64.tar.gz - Mode: HTTP server (
serve), binds to127.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 tolinux_dev_station - Playbook:
ansible/playbook_nginx_proxy.ymltargets[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.mevia certbot DNS-01 (cloudns plugin), auto-renewal cron - SSO cookie: Scoped to
.lab.alexpires.me - IdP: Gitea (
code.alexpires.me), OAuth2 applab-services(confidential client, scopes:openid,profile,email) - oauth2-proxy: v7.15.3, config format:
oidc_issuer_url,http_address,upstreamsarray,cookie_domainsarray,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 vaultOAUTH2_PROXY_CLIENT_ID/OAUTH2_PROXY_CLIENT_SECRET— from Gitea OAuth2 appCLOUDNS_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
ideandagent→10.19.4.210(interraform/apps/dev-01/config.tf)
- Added A record for
- Inventory: Added
[nginx]group withdev-02.lab.alexpires.me; dev-02 removed from[certbot]group - Host vars:
ansible/host_vars/dev-02.lab.alexpires.me.ymlwithnginx_proxy_sites,bind_to_localhost: true, firewall rules (22, 443), OAuth2 credentials vialookup('env', ...) - dev-01 cleanup: Removed
opencode/vscodeCNAME records andproxy_servicesentries (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/letsencryptcontext set tohttpd_cert_t
Known Issues & Workarounds
- ssh-agent systemd: Removed due to SELinux blocking transitions; managed via
.zshrcstartup instead - ACL issue:
allow_world_readable_tmpfiles = Truerequired inansible.cfgfor macOS→Fedorabecome_usercompatibility
Required Credentials
GITEA_APP_TOKENOPEN_WEBUI_API_KEYCLOUDNS_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.