feat(install): mirror this machine's apt packages
gitleaks, web stack (mariadb-server, imagemagick, unversioned php-* modules), ubuntu-desktop-minimal before the RDP setup, and a lspci-gated install_nvidia_driver() that runs ubuntu-drivers install. README + TODO updated.
This commit is contained in:
@@ -60,3 +60,12 @@ Branch: feature/security-baseline (off develop). Scope approved: fail2ban, unatt
|
|||||||
- [x] README.md (table, step 13, packages) + CLAUDE.md layout
|
- [x] README.md (table, step 13, packages) + CLAUDE.md layout
|
||||||
- [x] shellcheck + bash -n; stub harness harden_sshd (accept / reject paths); configparser check of jail file
|
- [x] shellcheck + bash -n; stub harness harden_sshd (accept / reject paths); configparser check of jail file
|
||||||
- [x] commit; registries (BDR-013, LRN-012); runbook. No finish without explicit signal.
|
- [x] commit; registries (BDR-013, LRN-012); runbook. No finish without explicit signal.
|
||||||
|
|
||||||
|
## Feature — install.sh mirrors this machine's apt packages (2026-09-28)
|
||||||
|
Branch: feature/apt-packages (off develop). Source: apt-mark showmanual + /var/log/apt/history.log diffed against install.sh.
|
||||||
|
- [x] gitleaks in the base list (backs the pre-commit hook)
|
||||||
|
- [x] web stack group: mariadb-server imagemagick + unversioned php-* modules (approved: base list, not an offer)
|
||||||
|
- [x] ubuntu-desktop-minimal before setup_remote_desktop (approved)
|
||||||
|
- [x] install_nvidia_driver(): lspci vendor 10de gate + ubuntu-drivers install (approved: no version pin)
|
||||||
|
- [x] README steps 11 + packages; shellcheck + bash -n; stub run of the NVIDIA helper
|
||||||
|
- [x] commit on the feature branch. No finish without explicit signal.
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ What it does:
|
|||||||
8. Copies the `bin/` scripts (`dt`, `dtach-router`, `claude-provider`) into `~/.local/bin`. The dtach session-resume menu ships in the deployed `bashrc-linux`, so every interactive shell offers it — including VS Code Remote-SSH terminals, which are non-login and never read `~/.profile`. The installer also strips any older dtach block left in `~/.profile` so a plain SSH login doesn't prompt twice.
|
8. Copies the `bin/` scripts (`dt`, `dtach-router`, `claude-provider`) into `~/.local/bin`. The dtach session-resume menu ships in the deployed `bashrc-linux`, so every interactive shell offers it — including VS Code Remote-SSH terminals, which are non-login and never read `~/.profile`. The installer also strips any older dtach block left in `~/.profile` so a plain SSH login doesn't prompt twice.
|
||||||
9. On Linux, installs `etc/profile.d/disk-usage-warning.sh` to `/etc/profile.d/` (needs `sudo`) so each login warns when `/` or `/home` cross 85% usage.
|
9. On Linux, installs `etc/profile.d/disk-usage-warning.sh` to `/etc/profile.d/` (needs `sudo`) so each login warns when `/` or `/home` cross 85% usage.
|
||||||
10. On Linux, installs **code-server** (VS Code in the browser) via its vendor script — skipped if already present — and enables the `code-server@$USER` systemd service.
|
10. On Linux, installs **code-server** (VS Code in the browser) via its vendor script — skipped if already present — and enables the `code-server@$USER` systemd service.
|
||||||
11. On Linux, sets up **RDP remote login** via `gnome-remote-desktop` (Wayland-native): installs the daemon + `openssl`, generates a self-signed TLS cert once, and prompts interactively for shared "gate" credentials (skipped when no terminal is attached, or already set). Disables `xrdp` if present; opens UFW port `3389` only when UFW is already active.
|
11. On Linux, installs **`ubuntu-desktop-minimal`** (GDM + GNOME Shell, ~1.5 GB): the RDP remote login below hands out a GNOME session, which a bare server install does not have. Then sets up **RDP remote login** via `gnome-remote-desktop` (Wayland-native): installs the daemon + `openssl`, generates a self-signed TLS cert once, and prompts interactively for shared "gate" credentials (skipped when no terminal is attached, or already set). Disables `xrdp` if present; opens UFW port `3389` only when UFW is already active. Finally, when `lspci` sees an NVIDIA GPU, runs `ubuntu-drivers install` to put on the driver the distro recommends for the card (no version pinned; loads at the next reboot). Skipped on machines without an NVIDIA GPU.
|
||||||
12. On Linux, installs the **`cloudpex`** NAS mount helper to `/usr/local/bin` via `cloudpex/install.sh`, which prompts for the NAS host, share name, SMB user, mount point and SMB version and writes them to `/etc/cloudpex.conf` (root, `0600`; an existing config is shown and kept unless you say `n`; skipped when no terminal is attached). Nothing is mounted, no password stored, see [`cloudpex/README.md`](cloudpex/README.md).
|
12. On Linux, installs the **`cloudpex`** NAS mount helper to `/usr/local/bin` via `cloudpex/install.sh`, which prompts for the NAS host, share name, SMB user, mount point and SMB version and writes them to `/etc/cloudpex.conf` (root, `0600`; an existing config is shown and kept unless you say `n`; skipped when no terminal is attached). Nothing is mounted, no password stored, see [`cloudpex/README.md`](cloudpex/README.md).
|
||||||
13. On Linux, installs the **security baseline**, always, no prompt: **fail2ban** (+ `nftables`) with `etc/fail2ban/jail.d/local.conf` (sshd jail reading the journal, bans the offending IP on every port so the SSH port does not matter, 5 failures in 10 min → 1 h ban, loopback and private LAN ranges never banned); **unattended-upgrades** enabled through `etc/apt/apt.conf.d/20auto-upgrades`; and the **sshd drop-in** `etc/ssh/sshd_config.d/20-hardening.conf` (`PermitRootLogin no`, `MaxAuthTries 3`, `LoginGraceTime 20`), checked with `sshd -t` and removed again if sshd rejects it, then `reload ssh`. Authentication methods, port and user lists are left as they are.
|
13. On Linux, installs the **security baseline**, always, no prompt: **fail2ban** (+ `nftables`) with `etc/fail2ban/jail.d/local.conf` (sshd jail reading the journal, bans the offending IP on every port so the SSH port does not matter, 5 failures in 10 min → 1 h ban, loopback and private LAN ranges never banned); **unattended-upgrades** enabled through `etc/apt/apt.conf.d/20auto-upgrades`; and the **sshd drop-in** `etc/ssh/sshd_config.d/20-hardening.conf` (`PermitRootLogin no`, `MaxAuthTries 3`, `LoginGraceTime 20`), checked with `sshd -t` and removed again if sshd rejects it, then `reload ssh`. Authentication methods, port and user lists are left as they are.
|
||||||
14. On Linux, at the very end, **offers** (`[y/N]`, skipped when no terminal is attached) to move **`/tmp` to disk**: Ubuntu mounts `/tmp` as a RAM-backed tmpfs capped at 50% of RAM, which agent runs fill, halving the RAM and breaking every shell with "No space left on device". Accepting masks `tmp.mount` and installs `etc/tmpfiles.d/tmp.conf` (wipe at boot, 10-day purge). Effective at the next reboot.
|
14. On Linux, at the very end, **offers** (`[y/N]`, skipped when no terminal is attached) to move **`/tmp` to disk**: Ubuntu mounts `/tmp` as a RAM-backed tmpfs capped at 50% of RAM, which agent runs fill, halving the RAM and breaking every shell with "No space left on device". Accepting masks `tmp.mount` and installs `etc/tmpfiles.d/tmp.conf` (wipe at boot, 10-day purge). Effective at the next reboot.
|
||||||
@@ -75,12 +75,14 @@ What it does:
|
|||||||
|
|
||||||
### Packages installed (apt)
|
### Packages installed (apt)
|
||||||
|
|
||||||
- **Build / VCS / C dev**: `vim git git-lfs git-filter-repo gcc make pkg-config dkms valgrind shellcheck`
|
- **Build / VCS / C dev**: `vim git git-lfs git-filter-repo gitleaks gcc make pkg-config dkms valgrind shellcheck gh`
|
||||||
- **Net / security / transport**: `curl gnupg ca-certificates apt-transport-https net-tools openssh-server cifs-utils lftp ftp`
|
- **Net / security / transport**: `curl gnupg ca-certificates apt-transport-https net-tools openssh-server cifs-utils lftp ftp`
|
||||||
- **Shell tooling**: `unzip tree tmux fzf dtach`
|
- **Shell tooling**: `unzip tree tmux fzf dtach`
|
||||||
- **Runtimes**: `nodejs python3-pip pipx php-cli`
|
- **Runtimes**: `nodejs python3-pip pipx php-cli`
|
||||||
|
- **Web stack (local WordPress/LAMP)**: `mariadb-server imagemagick php-mysql php-gd php-imagick php-mbstring php-xml php-intl php-curl` (unversioned `php-*` metapackages, so they follow the distro's PHP)
|
||||||
- **Media / doc CLI**: `ffmpeg weasyprint poppler-utils qpdf webp libavif-bin`
|
- **Media / doc CLI**: `ffmpeg weasyprint poppler-utils qpdf webp libavif-bin`
|
||||||
- **Docker**: `docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin` (via Docker's repo)
|
- **Docker**: `docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin` (via Docker's repo)
|
||||||
|
- **Desktop / GPU**: `ubuntu-desktop-minimal` (always, Linux) + the distro-recommended NVIDIA driver via `ubuntu-drivers install` (only when an NVIDIA GPU is detected)
|
||||||
- **Remote access**: `gnome-remote-desktop openssl` (apt) + `code-server` (via its vendor install script, not apt) — RDP remote login + browser VS Code
|
- **Remote access**: `gnome-remote-desktop openssl` (apt) + `code-server` (via its vendor install script, not apt) — RDP remote login + browser VS Code
|
||||||
- **pipx**: `PyMuPDF` (`pymupdf`), `Markdown` (`markdown_py`)
|
- **pipx**: `PyMuPDF` (`pymupdf`), `Markdown` (`markdown_py`)
|
||||||
- **Security baseline (Linux, always)**: `fail2ban nftables unattended-upgrades`
|
- **Security baseline (Linux, always)**: `fail2ban nftables unattended-upgrades`
|
||||||
|
|||||||
+33
-3
@@ -27,6 +27,25 @@ install_docker() {
|
|||||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# NVIDIA driver: only when an NVIDIA GPU is on the PCI bus (vendor id 10de), so the
|
||||||
|
# script stays hardware-agnostic elsewhere. ubuntu-drivers picks the driver the distro
|
||||||
|
# recommends for the card (595-open on the RTX 3060 Ti this was written on) instead of
|
||||||
|
# pinning a version that ages. Idempotent: a no-op when the recommended driver is in.
|
||||||
|
# The driver loads at the next reboot. Ubuntu-only (ubuntu-drivers-common).
|
||||||
|
install_nvidia_driver() {
|
||||||
|
if ! command -v ubuntu-drivers >/dev/null 2>&1; then
|
||||||
|
echo "ubuntu-drivers not found — skipping NVIDIA driver" >&2
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [ -z "$(lspci -d 10de: 2>/dev/null)" ]; then
|
||||||
|
echo "No NVIDIA GPU detected — skipping NVIDIA driver"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "NVIDIA GPU detected — installing the recommended driver"
|
||||||
|
sudo ubuntu-drivers install
|
||||||
|
echo "NVIDIA driver loads at the next reboot."
|
||||||
|
}
|
||||||
|
|
||||||
# RDP "gate" credentials: a shared username/password that unlocks the GDM
|
# RDP "gate" credentials: a shared username/password that unlocks the GDM
|
||||||
# login screen (each user then logs into GDM with his own account). Required —
|
# login screen (each user then logs into GDM with his own account). Required —
|
||||||
# without it the RDP server rejects every connection (mstsc error 0x904). It is
|
# without it the RDP server rejects every connection (mstsc error 0x904). It is
|
||||||
@@ -259,14 +278,18 @@ if command -v apt-get >/dev/null 2>&1; then
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get upgrade -y
|
sudo apt-get upgrade -y
|
||||||
|
|
||||||
# Build + version control + C dev tooling.
|
# Build + version control + C dev tooling (gitleaks backs the pre-commit hook).
|
||||||
|
# Web stack: MariaDB + PHP modules for local WordPress/LAMP work; the php-* metapackages
|
||||||
|
# follow the distro's PHP version instead of pinning php8.x-*.
|
||||||
sudo apt-get install -y \
|
sudo apt-get install -y \
|
||||||
vim git git-lfs git-filter-repo gcc make pkg-config dkms valgrind shellcheck \
|
vim git git-lfs git-filter-repo gitleaks gcc make pkg-config dkms valgrind shellcheck \
|
||||||
curl gnupg ca-certificates apt-transport-https \
|
curl gnupg ca-certificates apt-transport-https \
|
||||||
unzip tree tmux fzf dtach net-tools \
|
unzip tree tmux fzf dtach net-tools \
|
||||||
openssh-server cifs-utils lftp ftp \
|
openssh-server cifs-utils lftp ftp \
|
||||||
nodejs python3-pip pipx php-cli \
|
nodejs python3-pip pipx php-cli \
|
||||||
ffmpeg weasyprint poppler-utils qpdf webp libavif-bin gh
|
ffmpeg weasyprint poppler-utils qpdf webp libavif-bin gh \
|
||||||
|
mariadb-server imagemagick \
|
||||||
|
php-mysql php-gd php-imagick php-mbstring php-xml php-intl php-curl
|
||||||
|
|
||||||
# Docker (separate repo).
|
# Docker (separate repo).
|
||||||
install_docker
|
install_docker
|
||||||
@@ -277,9 +300,16 @@ if command -v apt-get >/dev/null 2>&1; then
|
|||||||
fi
|
fi
|
||||||
sudo systemctl enable --now "code-server@$USER"
|
sudo systemctl enable --now "code-server@$USER"
|
||||||
|
|
||||||
|
# GNOME desktop (GDM + Shell): the RDP remote login below needs a GNOME session
|
||||||
|
# to hand out; a bare server install has none. Ubuntu-only metapackage.
|
||||||
|
sudo apt-get install -y ubuntu-desktop-minimal
|
||||||
|
|
||||||
# Remote desktop (gnome-remote-desktop — see the function header for why not xrdp).
|
# Remote desktop (gnome-remote-desktop — see the function header for why not xrdp).
|
||||||
setup_remote_desktop
|
setup_remote_desktop
|
||||||
|
|
||||||
|
# NVIDIA driver, only when an NVIDIA GPU is present.
|
||||||
|
install_nvidia_driver
|
||||||
|
|
||||||
# Low-disk login warning (system-wide profile.d snippet).
|
# Low-disk login warning (system-wide profile.d snippet).
|
||||||
install_disk_warning
|
install_disk_warning
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user