diff --git a/README.md b/README.md index 9b93392..4a55c8c 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ Turn a fresh Debian/Ubuntu/Arch VPS into a familiar workstation in one command. ```sh curl -fsSL | bash -# run everything non-interactively: -curl -fsSL | bash -s -- --yes # run a single step: curl -fsSL | bash -s -- --only packages +# run everything non-interactively and create a sudo user 'mk': +curl -fsSL | bash -s -- --yes --username mk ``` The shortener points at the **raw `install.sh`** in this repo, which clones the @@ -27,18 +27,50 @@ bash ~/.bootstrap/setup.sh --only hardening | # | step | what it does | |---|-------------|--------------------------------------------------------------------| -| 0 | preflight | verify distro + network + privileges | -| 1 | packages | git, byobu, ufw, mosh, btop, eza, fzf, ripgrep, bat, zoxide, jq, fd, tree, ncdu, lazygit, starship, … (+ `yay` on Arch) | -| 2 | docker | Docker engine + compose v2 plugin, `$USER` in `docker` group | -| 3 | angie | Angie (nginx fork) web server | -| 4 | shell-zsh | zsh + oh-my-zsh + plugins, set default shell, ship config | -| 5 | nvm | nvm → `~/.nvm` + Node LTS | -| 6 | nvim | clone `g.mk.fo/bootstrap/nvim-minimal` → `~/.config/nvim` | -| 7 | hardening | ssh (key-only root), ufw, updates, unattended-upgrades, tz, hostname, swapfile, locale, fail2ban, **angie config layout** | -| 8 | sanity | read-only report + recommended manual follow-ups | +| 0 | preflight | verify distro + network + privileges | +| 1 | create-user | (when direct root) create a passwordless sudo user, copy root's authorized_keys, retarget config at them | +| 2 | packages | git, byobu, ufw, mosh, btop, eza, fzf, ripgrep, bat, zoxide, jq, fd, tree, ncdu, lazygit, starship, … (+ `yay` on Arch) | +| 3 | docker | Docker engine + compose v2 plugin, `$TARGET_USER` in `docker` group | +| 4 | angie | Angie (nginx fork) web server | +| 5 | shell-zsh | zsh + oh-my-zsh + plugins, set default shell, ship config (to `~$TARGET_USER/.config/zsh`) | +| 6 | nvm | nvm → `~$TARGET_USER/.nvm` + Node LTS | +| 7 | nvim | clone `g.mk.fo/bootstrap/nvim-minimal` → `~$TARGET_USER/.config/nvim` | +| 8 | hardening | ssh (key-only root), ufw, updates, unattended-upgrades, tz, hostname, swapfile, locale, fail2ban, **angie config layout** | +| 9 | sanity | read-only report + recommended manual follow-ups | Every step is idempotent — re-running is safe. +## Sudo user (when running as direct root) + +Running the one-liner as **direct root** (no `SUDO_USER`) is the common +provider-provisioned-VPS case. The `create-user` step then: + +- **Arch**: auto-creates a non-root sudoer (AUR/`makepkg` can't run as root), + with a `y/N` confirm on the username (default `mk`). +- **Debian/Ubuntu**: asks `y/N` whether to create one (optional — apt works + as root). +- Always when sudoed-root (`SUDO_USER` set): uses that invoking user as the target, + syncing their sudoers + ssh keys instead of creating a new account. +- Never when not root: you're already a normal user; yourself is the target. + +Flags: +- `--create-user` force the prompt regardless of distro, +- `--username NAME` use that name and skip the name prompt. + +The created user: +- is added to `wheel` (Arch) or `sudo`+`adm` (Debian), shell set to zsh, +- has **no password** (`passwd -d`) — SSH key login only (you'll disable ssh + password auth in the hardening step), +- gets `/root/.ssh/authorized_keys` copied to `~user/.ssh/` (chmod 600/700), + with the fingerprints printed so you can sanity-check they're yours, +- gets `/etc/sudoers.d/`: `Defaults: !tty_tickets`, + `Defaults: timestamp_timeout=10080` (7-day cache), and + ` ALL=(ALL) NOPASSWD:ALL`. Validated with `visudo -c` before install. + +All later config steps (zsh/omz, nvim, nvm, docker group) target +`~$TARGET_USER`. After bootstrap, **test `ssh @` from a new +terminal before closing the root session.** + ## Zsh plugins enabled (oh-my-zsh) `git sudo command-not-found colored-man-pages extract copypath dirhistory`