The service step called `systemctl enable --now`, which aborts under
`set -e` when systemd is not PID 1. On MX Linux (SysVinit) this meant sshd
was never started and the firewall and admin-key steps were never reached.
Detect systemd via /run/systemd/system; otherwise fall back to
`update-rc.d`/`chkconfig` + `service <name> start`, failing with a clear
message if the service cannot be started.
Found on the first real-machine run (ThinkCentre M71e, MX Linux 25.2).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Final whole-branch review pass before merge:
1. sshinstall.ps1: #Requires -RunAsAdministrator doesn't enforce under
`irm ... | iex` (piping into Invoke-Expression). Add an explicit
WindowsPrincipal/IsInRole elevation check before anything else runs,
so a non-elevated run fails fast instead of silently falling through
Get-WindowsCapability's -ErrorAction SilentlyContinue into the
unsupported-OS branch.
2. sshinstall.ps1: drop the Windows 8 portable Win32-OpenSSH fallback —
it depends on Expand-Archive (PS 5.0+) and implicit TLS 1.2, neither
present on stock Windows 8's PS 3.0/4.0, so the one path that existed
for Windows 8 was guaranteed to fail on Windows 8. Replaced with a
clear unsupported-OS failure. Windows support is now 10 (1809+)/11
only; README table updated to match.
3. sshinstall.sh: guarantee a trailing newline before appending the
admin key to authorized_keys, so a pre-existing file without one
doesn't get its last line glued to the new key (which also defeats
the grep -qF idempotency check on every future run). Added the
equivalent guard to sshinstall.ps1's Add-Content path too — its
WriteLine only guarantees a trailing newline after what it writes,
not before, so a hand-edited or externally-written
administrators_authorized_keys has the same exposure.
4. sshinstall.sh: pacman -Sy -> -S (drop the partial-upgrade footgun,
matches apps.sh's install-vs-explicit-update convention); chown -R
now sets both user and group explicitly (matches apps.sh/
netdrivelink.sh convention).
5. sshinstall.ps1: rename the firewall rule this script creates to
OpenSSH-Server-In-TCP-sshinstall — the previous name collided with
the exact rule name Microsoft's own Add-WindowsCapability OpenSSH
install uses, so a disabled Microsoft-created rule of that name
would cause New-NetFirewallRule to throw under
$ErrorActionPreference = "Stop" and kill the script before the key
was deployed.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
- Fix ACL idempotency: check if ACLs already locked down before running
icacls; use Write-Skip if no broader groups present, else re-lock
- Harden SID check: explicit SecurityIdentifier construction vs string coercion
- Add explicit New-Item for Move-Item destination in Win8 fallback
Co-Authored-By: Claude Haiku 4.5 <[email protected]>