瀏覽代碼

feat: support configurable SSH user (root and non-root)

Inventory ansible_user is now a placeholder instead of hardcoded root.
Non-root users work via become/sudo. Documented in README.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
kotoyuuko 3 周之前
父節點
當前提交
4eaba0c038

+ 9 - 1
README.md

@@ -23,7 +23,7 @@ Client → Relay (SS) → Internet                       # relay only
 
 ### 1. Configure inventory
 
-Edit `inventory/hosts.yml` with your server IPs:
+Edit `inventory/hosts.yml` with your server IPs and SSH user:
 
 ```yaml
 all:
@@ -32,12 +32,20 @@ all:
       hosts:
         relay-server:
           ansible_host: "1.2.3.4"
+          ansible_user: "ubuntu"   # or "root"
     landing:
       hosts:
         landing-server:
           ansible_host: "5.6.7.8"
+          ansible_user: "ubuntu"   # or "root"
 ```
 
+**SSH user options:**
+- **Root**: Set `ansible_user: "root"` — connects directly as root
+- **Non-root**: Set `ansible_user: "ubuntu"` (or any user) — requires passwordless sudo on the server. If sudo requires a password, add `--ask-become-pass` when running the playbook
+
+Make sure your SSH key is already configured for the specified user on both servers.
+
 ### 2. Configure variables
 
 Edit `group_vars/landing.yml`:

+ 3 - 2
inventory/hosts.yml

@@ -4,9 +4,10 @@ all:
       hosts:
         relay-server:
           ansible_host: "YOUR_RELAY_IP"
-          ansible_user: root
+          # SSH user: set to "root" or a non-root user with passwordless sudo (e.g., "ubuntu")
+          ansible_user: "YOUR_SSH_USER"
     landing:
       hosts:
         landing-server:
           ansible_host: "YOUR_LANDING_IP"
-          ansible_user: root
+          ansible_user: "YOUR_SSH_USER"

+ 2 - 0
openspec/changes/archive/2026-04-22-configurable-ssh-user/.openspec.yaml

@@ -0,0 +1,2 @@
+schema: spec-driven
+created: 2026-04-22

+ 35 - 0
openspec/changes/archive/2026-04-22-configurable-ssh-user/design.md

@@ -0,0 +1,35 @@
+## Context
+
+Current inventory hardcodes `ansible_user: root`. The `ansible.cfg` already has `become = True` with `become_method = sudo`, which handles privilege escalation for non-root users. The main changes are updating the inventory placeholder, ensuring sshd config is compatible, and documenting the workflow.
+
+## Goals / Non-Goals
+
+**Goals:**
+- Support both root and non-root SSH users out of the box
+- SSH key is pre-configured by the user (not managed by Ansible)
+- Clear documentation for SSH user setup
+
+**Non-Goals:**
+- SSH key deployment or management by Ansible
+- Creating users on the server (user must exist beforehand)
+- sudo password prompts (assume passwordless sudo for the configured user)
+
+## Decisions
+
+### 1. Inventory uses placeholder with comment, no default user
+
+Change `ansible_user` to `"YOUR_SSH_USER"` with comments explaining both root and non-root options. Users fill in their actual username.
+
+### 2. sshd_config allows root login with key only
+
+Keep `PermitRootLogin prohibit-password` — this allows root SSH with key auth, which is fine for users who choose to connect as root. For non-root users, root SSH access becomes irrelevant since they use `become` for privilege escalation.
+
+### 3. ansible.cfg become settings remain as-is
+
+Current config already has `become = True` globally. This works correctly:
+- As root: become is a no-op (already root)
+- As non-root: `sudo` escalation kicks in
+
+## Risks / Trade-offs
+
+- **[Passwordless sudo required]** → Non-root users must have passwordless sudo. If not, they need `--ask-become-pass`. Mitigation: documented in README.

+ 25 - 0
openspec/changes/archive/2026-04-22-configurable-ssh-user/proposal.md

@@ -0,0 +1,25 @@
+## Why
+
+The inventory currently hardcodes `ansible_user: root`. Many server providers create a non-root user by default (e.g., `ubuntu`, `debian`), and users may prefer to SSH as a non-root user with sudo privileges. The SSH key is pre-configured by the user before running the playbook.
+
+## What Changes
+
+- Change `ansible_user` in inventory to a configurable placeholder instead of hardcoded `root`
+- Ensure `ansible.cfg` privilege escalation settings work for both root and non-root users
+- Update the `sshd_config` template: when connecting as root, allow `prohibit-password`; when connecting as non-root, the user doesn't need root SSH access at all
+- Update README to document SSH user configuration
+
+## Capabilities
+
+### New Capabilities
+
+(none)
+
+### Modified Capabilities
+- `server-base`: SSH configuration must work for both root and non-root `ansible_user`
+
+## Impact
+
+- `inventory/hosts.yml` updated with configurable user placeholder
+- `roles/base/templates/sshd_config.j2` adjusted for flexibility
+- `README.md` updated with SSH user configuration instructions

+ 16 - 0
openspec/changes/archive/2026-04-22-configurable-ssh-user/specs/server-base/spec.md

@@ -0,0 +1,16 @@
+## MODIFIED Requirements
+
+### Requirement: Ansible inventory defines relay and landing server groups
+The inventory SHALL define two host groups: `relay` and `landing`, each containing the respective server's connection details (IP, SSH user, SSH key). The `ansible_user` SHALL be a configurable placeholder supporting both root and non-root users.
+
+#### Scenario: Inventory is valid
+- **WHEN** the inventory file is parsed by Ansible
+- **THEN** two groups `relay` and `landing` are available, each with at least one host
+
+#### Scenario: Non-root user with sudo
+- **WHEN** `ansible_user` is set to a non-root user (e.g., `ubuntu`)
+- **THEN** Ansible connects as that user and uses `become` for privilege escalation
+
+#### Scenario: Root user
+- **WHEN** `ansible_user` is set to `root`
+- **THEN** Ansible connects as root directly and `become` is a no-op

+ 8 - 0
openspec/changes/archive/2026-04-22-configurable-ssh-user/tasks.md

@@ -0,0 +1,8 @@
+## 1. Inventory & Configuration
+
+- [x] 1.1 Update `inventory/hosts.yml` — change `ansible_user` from `root` to `"YOUR_SSH_USER"` with comments documenting root vs non-root options
+- [x] 1.2 Verify `ansible.cfg` become settings are correct for both root and non-root (already set, just confirm)
+
+## 2. Documentation
+
+- [x] 2.1 Update `README.md` — add SSH user configuration section explaining root vs non-root, passwordless sudo requirement, and `--ask-become-pass` option

+ 9 - 1
openspec/specs/server-base/spec.md

@@ -1,12 +1,20 @@
 ## ADDED Requirements
 
 ### Requirement: Ansible inventory defines relay and landing server groups
-The inventory SHALL define two host groups: `relay` and `landing`, each containing the respective server's connection details (IP, SSH user, SSH key).
+The inventory SHALL define two host groups: `relay` and `landing`, each containing the respective server's connection details (IP, SSH user, SSH key). The `ansible_user` SHALL be a configurable placeholder supporting both root and non-root users.
 
 #### Scenario: Inventory is valid
 - **WHEN** the inventory file is parsed by Ansible
 - **THEN** two groups `relay` and `landing` are available, each with at least one host
 
+#### Scenario: Non-root user with sudo
+- **WHEN** `ansible_user` is set to a non-root user (e.g., `ubuntu`)
+- **THEN** Ansible connects as that user and uses `become` for privilege escalation
+
+#### Scenario: Root user
+- **WHEN** `ansible_user` is set to `root`
+- **THEN** Ansible connects as root directly and `become` is a no-op
+
 ### Requirement: Base packages are installed on all servers
 The base role SHALL install essential packages: `curl`, `wget`, `vim`, `htop`, `unzip`, `ufw`, `fail2ban`, `unattended-upgrades`.