#requires -RunAsAdministrator # Windows SSH Server 公钥认证完整配置脚本 # 基于 codex 分析的一次性解决方案 Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" Write-Host "=== Windows SSH Server 公钥认证配置 ===" -ForegroundColor Cyan Write-Host "" $PublicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCm/leXfpZ1Ycm7uL3sXYU1Hp5TO42EqUnD5H7SwveTIusF14e5oZf5P72fttGLIxQMFgGdXzu4+coWPmpGsUHjqm4g0FbeL+mjM+0cnqeggoueoFm3dk9y+9jaogjuR2VY9oqbdOvD+L0IfvS+t6WJrYif1MdXOYnH5MfNYtrLb/MWCDiTT4w/Cw0QKSSB3S3+nvYqxD1Ep+wdLrd+SfgiMi2qU/bO7ccEgXwjqiI/4LDHh2r5oajkvdRSuQ75PLSRdFfR+aq/NcV/NJE3YOcb8wVhvVjZZSXQyy8PlqLn6N58qckharwAj6vRxC9CbWB+XDrLOMWOtdq7T7iBPJmy1wVDDyva9wEnKiprdXf+2F/Q57SJjcbPTCt6TqXggQ0hVf7tOK6Wefk5dwPW0P3mdzPTp91s9iU96kM+9VSY0dhKEnim+6IncxEK+hnbAbGOX66MuRmK9u7dYlsjhFq345rNXmkXIIY3VU2GuCBLB4bk88pNubrd8y9S03JbZIU= root@vps21249823.hosteons.com" $sshdConfig = Join-Path $env:ProgramData "ssh\sshd_config" $adminKeys = Join-Path $env:ProgramData "ssh\administrators_authorized_keys" if (!(Test-Path $sshdConfig)) { throw "错误: 找不到 $sshdConfig,请先安装 OpenSSH Server" } Write-Host "步骤 1/5: 写入公钥到 administrators_authorized_keys" -ForegroundColor Yellow $keyLine = ($PublicKey -replace "`r","" -replace "`n","").Trim() if ($keyLine -notmatch "^(ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp256)\s+") { throw "错误: 公钥格式不正确" } [System.IO.File]::WriteAllBytes($adminKeys, [System.Text.Encoding]::ASCII.GetBytes($keyLine + "`n")) Write-Host "✓ 公钥已写入 (ASCII 无 BOM)" -ForegroundColor Green Write-Host "" Write-Host "步骤 2/5: 设置文件权限" -ForegroundColor Yellow & icacls $adminKeys /inheritance:r | Out-Null & icacls $adminKeys /grant "SYSTEM:F" "Administrators:F" | Out-Null & icacls $adminKeys /remove "Users" "Authenticated Users" "Everyone" 2>$null | Out-Null & icacls $adminKeys /setowner "Administrators" | Out-Null Write-Host "✓ ACL 权限已设置 (仅 SYSTEM + Administrators)" -ForegroundColor Green Write-Host "" Write-Host "步骤 3/5: 备份 sshd_config" -ForegroundColor Yellow Copy-Item $sshdConfig "$sshdConfig.backup-$(Get-Date -Format 'yyyyMMdd-HHmmss')" Write-Host "✓ 已备份到 $sshdConfig.backup-*" -ForegroundColor Green Write-Host "" Write-Host "步骤 4/5: 修改 sshd_config" -ForegroundColor Yellow $config = Get-Content $sshdConfig -Raw # 启用公钥认证 $config = [regex]::Replace($config, '(?im)^\s*#?\s*PubkeyAuthentication\s+\S+.*$', 'PubkeyAuthentication yes') if ($config -notmatch '(?im)^\s*PubkeyAuthentication\s+') { $config += "`r`nPubkeyAuthentication yes`r`n" } # 禁用密码认证(可选,避免误导) $config = [regex]::Replace($config, '(?im)^\s*#?\s*PasswordAuthentication\s+\S+.*$', 'PasswordAuthentication no') if ($config -notmatch '(?im)^\s*PasswordAuthentication\s+') { $config += "`r`nPasswordAuthentication no`r`n" } # 启用详细日志 $config = [regex]::Replace($config, '(?im)^\s*#?\s*LogLevel\s+\S+.*$', 'LogLevel VERBOSE') if ($config -notmatch '(?im)^\s*LogLevel\s+') { $config += "`r`nLogLevel VERBOSE`r`n" } # 添加 Match Group administrators 配置块 $config += @" # Force Administrators to use the global authorized_keys file Match Group administrators AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys "@ Set-Content -Path $sshdConfig -Value $config -Encoding ascii Write-Host "✓ sshd_config 已更新" -ForegroundColor Green Write-Host " - PubkeyAuthentication yes" -ForegroundColor Gray Write-Host " - PasswordAuthentication no" -ForegroundColor Gray Write-Host " - LogLevel VERBOSE" -ForegroundColor Gray Write-Host " - Match Group administrators" -ForegroundColor Gray Write-Host "" Write-Host "步骤 5/5: 重启 SSH Server" -ForegroundColor Yellow Set-Service sshd -StartupType Automatic Restart-Service sshd -Force Write-Host "✓ SSH Server 已重启" -ForegroundColor Green Write-Host "" Write-Host "=== 验证配置 ===" -ForegroundColor Cyan Write-Host "authorized_keys 内容:" Get-Content $adminKeys Write-Host "" Write-Host "文件权限:" & icacls $adminKeys Write-Host "" Write-Host "=== 配置完成!===" -ForegroundColor Green Write-Host "" Write-Host "下一步:在服务器端测试连接" -ForegroundColor Yellow Write-Host " ssh -vvv -p 26002 -o PreferredAuthentications=publickey Administrator@localhost" -ForegroundColor Gray