fix: final review fixes for sshinstall (elevation guard, Win8 drop, authorized_keys newline, style)
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]>
This commit is contained in:
1 parent
93d9ead905
commit
337a209713
3 files changed
+32
-19
No files matched your search
@@ -29,7 +29,7 @@ irm https://git.edemilov.ru/edemilov/scripts/raw/branch/master/sshinstall.ps1 |
|
||||
| `netdrivelink.sh` | Mount vanga Samba shares + 2nd drive symlinks | Same |
|
||||
| `apps.ps1` | Windows equivalent via winget + map network drives | Windows 10/11 |
|
||||
| `sshinstall.sh` | Install/enable SSH server + deploy admin key | Arch, Debian, Ubuntu, RHEL, Fedora |
|
||||
| `sshinstall.ps1` | Windows equivalent | Windows 8, 10, 11 |
|
||||
| `sshinstall.ps1` | Windows equivalent | Windows 10, 11 |
|
||||
| `gitea-ct-setup.sh` | Create CT116 with Gitea on Proxmox host | Proxmox 8+ |
|
||||
|
||||
## Samba shares (vanga — 10.0.99.100)
|
||||
|
||||
+25
-16
@@ -16,6 +16,16 @@ function Write-Success { param($t) Write-Host "[✓] $t" -ForegroundColor Green
|
||||
function Write-Skip { param($t) Write-Host "[~] $t (already done)" -ForegroundColor Magenta }
|
||||
function Write-Warn { param($t) Write-Host "[!] $t" -ForegroundColor Yellow }
|
||||
|
||||
# ── Require elevation ────────────────────────────────────────────
|
||||
# #Requires -RunAsAdministrator above does not enforce under
|
||||
# `irm ... | iex` (piping into Invoke-Expression is widely reported not to
|
||||
# trigger the #Requires check), so this explicit check is the real guard.
|
||||
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
|
||||
if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||||
Write-Warn "Must be run as Administrator — re-run PowerShell as Administrator"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$AdminKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH/hWD8YgjVzA/9V364W4w2HiEpuPjKMQ/Id3SRlyriM edemilov@laptop"
|
||||
|
||||
Write-Host ""
|
||||
@@ -38,21 +48,8 @@ if ($capability -and $capability.State -eq "Installed") {
|
||||
} elseif (Test-Path $sshdPath) {
|
||||
Write-Skip "OpenSSH Server (portable install found at $sshdPath)"
|
||||
} else {
|
||||
Write-Warn "Windows capability not available (likely Windows 8) — falling back to portable Win32-OpenSSH install"
|
||||
$zipUrl = "https://github.com/PowerShell/Win32-OpenSSH/releases/latest/download/OpenSSH-Win64.zip"
|
||||
$zipPath = "$env:TEMP\OpenSSH-Win64.zip"
|
||||
$installDir = "$env:ProgramFiles\OpenSSH"
|
||||
Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath
|
||||
Expand-Archive -Path $zipPath -DestinationPath $env:ProgramFiles -Force
|
||||
if (Test-Path "$env:ProgramFiles\OpenSSH-Win64") {
|
||||
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
|
||||
Move-Item "$env:ProgramFiles\OpenSSH-Win64\*" $installDir -Force
|
||||
Remove-Item "$env:ProgramFiles\OpenSSH-Win64" -Recurse -Force
|
||||
}
|
||||
Push-Location $installDir
|
||||
& "$installDir\install-sshd.ps1"
|
||||
Pop-Location
|
||||
Write-Success "Portable OpenSSH Server installed to $installDir"
|
||||
Write-Warn "OpenSSH Server capability is not available on this Windows version. This script supports Windows 10 (1809+) and Windows 11 only."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ── Enable + start service ────────────────────────────────────────
|
||||
@@ -77,7 +74,7 @@ if ($rule) {
|
||||
Write-Skip "Inbound firewall rule for port 22"
|
||||
} else {
|
||||
Write-Info "Adding inbound firewall rule for port 22..."
|
||||
New-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -DisplayName "OpenSSH Server (sshinstall)" -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 | Out-Null
|
||||
New-NetFirewallRule -Name "OpenSSH-Server-In-TCP-sshinstall" -DisplayName "OpenSSH Server (sshinstall)" -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 | Out-Null
|
||||
Write-Success "Firewall rule added"
|
||||
}
|
||||
|
||||
@@ -95,6 +92,18 @@ $keyDir = Split-Path $keyFile
|
||||
if (-not (Test-Path $keyDir)) { New-Item -ItemType Directory -Path $keyDir -Force | Out-Null }
|
||||
if (-not (Test-Path $keyFile)) { New-Item -ItemType File -Path $keyFile -Force | Out-Null }
|
||||
|
||||
# Add-Content resumes writing at the file's current end-of-file position and only
|
||||
# guarantees a trailing newline after what IT writes — it does not fix up a pre-existing
|
||||
# last line that lacks one (e.g. a hand-edited or externally-written file). Without this
|
||||
# guard that can glue the new key onto the end of the last existing line, corrupting both,
|
||||
# same as the bash >> case this fix wave addresses.
|
||||
if ((Get-Item $keyFile).Length -gt 0) {
|
||||
$existingRaw = Get-Content -Path $keyFile -Raw
|
||||
if ($existingRaw.Length -gt 0 -and $existingRaw[-1] -ne "`n") {
|
||||
Add-Content -Path $keyFile -Value ""
|
||||
}
|
||||
}
|
||||
|
||||
$existing = Get-Content $keyFile -ErrorAction SilentlyContinue
|
||||
if ($existing -contains $AdminKey) {
|
||||
Write-Skip "admin key in $keyFile"
|
||||
|
||||
+6
-2
@@ -55,7 +55,7 @@ case $FAMILY in
|
||||
skip "openssh"
|
||||
else
|
||||
info "Installing openssh..."
|
||||
pacman -Sy --noconfirm --needed openssh
|
||||
pacman -S --noconfirm --needed openssh
|
||||
success "openssh installed"
|
||||
fi
|
||||
;;
|
||||
@@ -130,7 +130,11 @@ mkdir -p "$SSH_DIR"
|
||||
chmod 700 "$SSH_DIR"
|
||||
touch "$AUTH_KEYS"
|
||||
chmod 600 "$AUTH_KEYS"
|
||||
chown -R "$REAL_USER" "$SSH_DIR"
|
||||
chown -R "$REAL_USER:$REAL_USER" "$SSH_DIR"
|
||||
|
||||
if [[ -s "$AUTH_KEYS" ]] && [[ -n "$(tail -c1 "$AUTH_KEYS")" ]]; then
|
||||
echo >> "$AUTH_KEYS"
|
||||
fi
|
||||
|
||||
if grep -qF "$ADMIN_KEY" "$AUTH_KEYS" 2>/dev/null; then
|
||||
skip "admin key in $AUTH_KEYS"
|
||||
|
||||
Reference in new issue
Block a user