updated ssh setup

This commit is contained in:
LeonL committed 2026-11-06 10:18:02 -08:00
1 parent 044de4e730
commit 2e8e3faff0
2 files changed
+110 -9

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
@echo off
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0git-ssh-setup.ps1" %*
pause
+107 -9
View File
@@ -1,9 +1,9 @@
<#
.SYNOPSIS
Sets up SSH for Git on Windows: creates a key in ~/.ssh, loads it into the
Windows ssh-agent, adds a host entry to ~/.ssh/config, and points Git at
Windows ssh-agent, adds a host entry to ~/.ssh/config, points Git at
Windows' OpenSSH so pushes (and Git LFS) use the agent instead of asking
for the passphrase every time.
for the passphrase every time, and signs Gitea's key-verification token.
.DESCRIPTION
Safe to re-run: an existing key is reused (unless -Force), a key already in
@@ -13,14 +13,22 @@
Run it as your normal user, NOT "Run as administrator". It asks for admin
rights (UAC prompt) only if the ssh-agent service needs to be enabled.
.EXAMPLE
powershell -ExecutionPolicy Bypass -File .\setup-git-ssh.ps1
Execution policy: start it through powershell.exe with -ExecutionPolicy
Bypass as in the examples, or double-click git-ssh-setup.cmd. Either way the
bypass applies to this one run only; the system setting is not changed.
.EXAMPLE
powershell -ExecutionPolicy Bypass -File .\setup-git-ssh.ps1 -Comment "you@example.com"
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1
.EXAMPLE
powershell -ExecutionPolicy Bypass -File .\setup-git-ssh.ps1 -HostName github.com -KeyName id_ed25519_github
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1 -Comment "you@example.com"
.EXAMPLE
# Verify the key later: click Verify next to it in Gitea and pass the token it shows.
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1 -NoTest -Token d0d4b8e7...
.EXAMPLE
powershell -NoProfile -ExecutionPolicy Bypass -File .\git-ssh-setup.ps1 -HostName github.com -KeyName id_ed25519_github -NoVerify
#>
[CmdletBinding()]
param(
@@ -41,9 +49,15 @@ param(
[ValidateNotNullOrEmpty()]
[string]$Comment = "$env:USERNAME@$env:COMPUTERNAME",
# Token from Gitea's Verify button. If omitted, the script asks for it.
[string]$Token,
# Replace an existing key with the same name instead of reusing it.
[switch]$Force,
# Skip the Gitea key-verification step.
[switch]$NoVerify,
# Skip the connection test at the end.
[switch]$NoTest
)
@@ -56,6 +70,32 @@ function Stop-Setup([string]$Message) {
exit 1
}
# Signs $Text exactly as given and returns the armored signature, or $null if
# ssh-keygen failed. The text is written to a file with no trailing newline and
# no BOM: piping it into ssh-keygen from PowerShell would add a newline and
# change what gets signed.
function Get-SshSignature([string]$Text, [string]$Keygen, [string]$KeyFile, [string]$Namespace = 'gitea') {
$file = Join-Path ([IO.Path]::GetTempPath()) ("gitea-verify-" + [guid]::NewGuid().ToString('N'))
$sigFile = "$file.sig"
try {
[IO.File]::WriteAllText($file, $Text, (New-Object Text.UTF8Encoding($false)))
# A .pub key file makes ssh-keygen sign through ssh-agent (no passphrase prompt).
& $Keygen -Y sign -n $Namespace -f $KeyFile $file | Out-Host
if ($LASTEXITCODE -eq 0 -and (Test-Path $sigFile)) {
return (Get-Content -Path $sigFile -Raw).Trim()
}
return $null
} finally {
Remove-Item -LiteralPath $file, $sigFile -Force -ErrorAction SilentlyContinue
}
}
# Accept the token with stray spaces or quotes, but nothing that isn't hex.
$Token = "$Token" -replace '[\s''"]', ''
if ($Token -and $Token -notmatch '^[0-9a-fA-F]+$') {
Stop-Setup "-Token should be just the hex string from Gitea's Token box."
}
$openSshDir = Join-Path $env:WINDIR 'System32\OpenSSH'
$sshExe = Join-Path $openSshDir 'ssh.exe'
$keygenExe = Join-Path $openSshDir 'ssh-keygen.exe'
@@ -210,10 +250,68 @@ try {
}
Write-Host " Add it in Gitea: your avatar > Settings > SSH / GPG Keys > Add Key"
# --- 7. Test -----------------------------------------------------------------
# --- 7. Verify the key in Gitea (optional) -----------------------------------
# Gitea's Verify button shows a token. Signing it with this key proves you own
# the key, and Gitea then marks the key as verified.
if (-not $NoVerify) {
Write-Step "Verifying the key in Gitea (optional)"
if (-not $Token) {
Write-Host " 1. Add the key in Gitea first (it's on your clipboard)."
Write-Host " 2. Click Verify next to the key and copy the token Gitea shows."
while ($true) {
$Token = "$(Read-Host ' Paste the token here, or press Enter to skip')" -replace '[\s''"]', ''
if (-not $Token -or $Token -match '^[0-9a-fA-F]+$') { break }
Write-Note "That doesn't look like a token. Paste only the hex string from the Token box."
}
}
if (-not $Token) {
Write-Note "Skipped. To verify later, click Verify in Gitea and re-run with -NoTest -Token <token>."
} else {
$signature = Get-SshSignature -Text $Token -Keygen $keygenExe -KeyFile $pubPath
if (-not $signature) {
# Windows OpenSSH older than 8.1 has no 'ssh-keygen -Y'; Git for Windows ships a newer one.
$gitKeygen = $null
$gitCmd = Get-Command git -ErrorAction SilentlyContinue
if ($gitCmd) {
$dir = Split-Path $gitCmd.Source
foreach ($i in 1..3) {
if (-not $dir) { break }
$candidate = Join-Path $dir 'usr\bin\ssh-keygen.exe'
if (Test-Path $candidate) { $gitKeygen = $candidate; break }
$dir = Split-Path $dir
}
}
if ($gitKeygen) {
Write-Note "Retrying with Git for Windows' ssh-keygen (it may ask for the key's passphrase)."
$signature = Get-SshSignature -Text $Token -Keygen $gitKeygen -KeyFile $keyPath
}
}
if ($signature) {
Write-Host "`n$signature`n"
try {
Set-Clipboard -Value $signature
Write-Ok "Signature copied to the clipboard."
} catch {
Write-Note "Couldn't copy to the clipboard - copy the block above."
}
Write-Host " Paste it into Gitea's 'Armored SSH signature' box and click Verify."
Write-Note "The token only stays valid for a short time. If Gitea rejects the signature,"
Write-Note "click Verify again for a new token and re-run with -NoTest -Token <new token>."
} else {
Write-Note "Couldn't sign the token, so the key wasn't verified. Everything else is set up."
}
}
}
# --- 8. Test -----------------------------------------------------------------
if ($HostName -and -not $NoTest) {
Write-Host ""
Read-Host "Press Enter once the key is added to test the connection (Ctrl+C to skip)" | Out-Null
Write-Step "Testing the connection to $HostName"
if ($NoVerify) {
Read-Host "Press Enter once the key is added in Gitea (Ctrl+C to skip)" | Out-Null
}
& $sshExe -T -p $Port "$User@$HostName"
Write-Host ""
Write-Note "A 'Hi there, <name>! You've successfully authenticated' message means it worked."