423 lines
15 KiB
PowerShell
423 lines
15 KiB
PowerShell
# Gitea SSH密钥设置脚本 (Windows PowerShell版本)
|
||
# 用途: 获取/生成SSH密钥并添加到Gitea
|
||
# 用法: .\setup_gitea_ssh_keys.ps1
|
||
|
||
param(
|
||
[string]$Help
|
||
)
|
||
|
||
# 配置信息(将通过用户输入获取)
|
||
$DEFAULT_USERNAME = ""
|
||
$DEFAULT_EMAIL = ""
|
||
$GITEA_TOKEN = ""
|
||
$GITEA_URL = "https://git.sanyitec.cc"
|
||
$SSH_PORT = 222
|
||
|
||
# 检查是否请求帮助
|
||
if ($Help -eq "--help" -or $Help -eq "-h") {
|
||
Write-Host "=== Gitea SSH密钥设置脚本 (Windows版) ===" -ForegroundColor Green
|
||
Write-Host "用途: 检查/生成SSH密钥并添加到Gitea"
|
||
Write-Host ""
|
||
Write-Host "用法:"
|
||
Write-Host " .\setup_gitea_ssh_keys.ps1 # 交互式配置"
|
||
Write-Host ""
|
||
Write-Host "功能:"
|
||
Write-Host " 1. 交互式输入Git用户信息和Gitea Token"
|
||
Write-Host " 2. 检查现有SSH密钥或生成新密钥"
|
||
Write-Host " 3. 自动添加公钥到Gitea"
|
||
Write-Host " 4. 配置Git用户信息"
|
||
Write-Host " 5. 配置SSH连接设置(端口222)"
|
||
Write-Host " 6. 测试Gitea SSH连接"
|
||
Write-Host ""
|
||
exit 0
|
||
}
|
||
|
||
Write-Host "=== Gitea SSH密钥设置脚本 (Windows版) ===" -ForegroundColor Green
|
||
Write-Host "将通过交互式配置检查现有SSH密钥或生成新密钥并添加到Gitea" -ForegroundColor Yellow
|
||
|
||
# 使用当前用户
|
||
$SSH_USERNAME = $env:USERNAME
|
||
Write-Host "当前用户: $SSH_USERNAME" -ForegroundColor Cyan
|
||
|
||
# 获取用户输入配置
|
||
function Get-UserConfiguration {
|
||
Write-Host "=== 配置信息输入 ===" -ForegroundColor Green
|
||
Write-Host "请输入以下配置信息:" -ForegroundColor Yellow
|
||
Write-Host ""
|
||
|
||
# 获取Git用户名
|
||
do {
|
||
$script:DEFAULT_USERNAME = Read-Host "请输入Git用户名"
|
||
if ([string]::IsNullOrWhiteSpace($script:DEFAULT_USERNAME)) {
|
||
Write-Host "❌ 用户名不能为空,请重新输入" -ForegroundColor Red
|
||
}
|
||
} while ([string]::IsNullOrWhiteSpace($script:DEFAULT_USERNAME))
|
||
|
||
# 获取Git邮箱
|
||
do {
|
||
$script:DEFAULT_EMAIL = Read-Host "请输入Git邮箱地址"
|
||
if ([string]::IsNullOrWhiteSpace($script:DEFAULT_EMAIL) -or $script:DEFAULT_EMAIL -notmatch "^[^@]+@[^@]+\.[^@]+$") {
|
||
Write-Host "❌ 请输入有效的邮箱地址" -ForegroundColor Red
|
||
}
|
||
} while ([string]::IsNullOrWhiteSpace($script:DEFAULT_EMAIL) -or $script:DEFAULT_EMAIL -notmatch "^[^@]+@[^@]+\.[^@]+$")
|
||
|
||
# 获取Gitea Token
|
||
do {
|
||
$script:GITEA_TOKEN = Read-Host "请输入Gitea访问Token" -AsSecureString
|
||
$script:GITEA_TOKEN = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($script:GITEA_TOKEN))
|
||
if ([string]::IsNullOrWhiteSpace($script:GITEA_TOKEN)) {
|
||
Write-Host "❌ Token不能为空,请重新输入" -ForegroundColor Red
|
||
}
|
||
} while ([string]::IsNullOrWhiteSpace($script:GITEA_TOKEN))
|
||
|
||
Write-Host ""
|
||
Write-Host "✓ 配置信息输入完成" -ForegroundColor Green
|
||
Write-Host "用户名: $script:DEFAULT_USERNAME" -ForegroundColor Cyan
|
||
Write-Host "邮箱: $script:DEFAULT_EMAIL" -ForegroundColor Cyan
|
||
Write-Host "Token: $('*' * $script:GITEA_TOKEN.Length)" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
}
|
||
|
||
# 检查必要工具
|
||
function Check-Dependencies {
|
||
Write-Host "正在检查依赖工具..." -ForegroundColor Yellow
|
||
|
||
$missingTools = @()
|
||
|
||
# 检查Git
|
||
try {
|
||
git --version | Out-Null
|
||
Write-Host "✓ Git已安装" -ForegroundColor Green
|
||
} catch {
|
||
$missingTools += "Git"
|
||
}
|
||
|
||
# 检查SSH
|
||
try {
|
||
ssh -V 2>$null | Out-Null
|
||
Write-Host "✓ SSH已安装" -ForegroundColor Green
|
||
} catch {
|
||
Write-Host "⚠ SSH未找到,将使用Windows内置OpenSSH" -ForegroundColor Yellow
|
||
}
|
||
|
||
if ($missingTools.Count -gt 0) {
|
||
Write-Host "❌ 缺少以下工具: $($missingTools -join ', ')" -ForegroundColor Red
|
||
Write-Host "请安装Git for Windows: https://git-scm.com/download/win" -ForegroundColor Yellow
|
||
exit 1
|
||
}
|
||
|
||
Write-Host "✓ 所有依赖工具检查完成" -ForegroundColor Green
|
||
}
|
||
|
||
# 检查或生成SSH密钥
|
||
function Check-OrGenerate-SSHKey {
|
||
Write-Host "正在检查SSH密钥..." -ForegroundColor Yellow
|
||
|
||
$sshDir = "$env:USERPROFILE\.ssh"
|
||
$privateKeyPath = "$sshDir\id_rsa"
|
||
$publicKeyPath = "$sshDir\id_rsa.pub"
|
||
|
||
# 检查是否已存在SSH密钥
|
||
if (Test-Path $publicKeyPath) {
|
||
Write-Host "✓ SSH密钥已存在" -ForegroundColor Green
|
||
return
|
||
}
|
||
|
||
Write-Host "正在生成SSH密钥..." -ForegroundColor Yellow
|
||
|
||
# 创建.ssh目录
|
||
if (!(Test-Path $sshDir)) {
|
||
New-Item -ItemType Directory -Path $sshDir -Force | Out-Null
|
||
}
|
||
|
||
# 生成SSH密钥
|
||
try {
|
||
ssh-keygen -t rsa -b 4096 -C $DEFAULT_EMAIL -f $privateKeyPath -N '""'
|
||
Write-Host "✓ SSH密钥生成成功" -ForegroundColor Green
|
||
} catch {
|
||
Write-Host "❌ SSH密钥生成失败: $($_.Exception.Message)" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
# 获取公钥
|
||
function Get-PublicKey {
|
||
Write-Host "正在获取公钥..." -ForegroundColor Yellow
|
||
|
||
$publicKeyPath = "$env:USERPROFILE\.ssh\id_rsa.pub"
|
||
|
||
if (Test-Path $publicKeyPath) {
|
||
$script:PUBLIC_KEY = Get-Content $publicKeyPath -Raw
|
||
$script:PUBLIC_KEY = $script:PUBLIC_KEY.Trim()
|
||
Write-Host "✓ 公钥获取成功" -ForegroundColor Green
|
||
Write-Host "公钥内容: $($script:PUBLIC_KEY.Substring(0, [Math]::Min(50, $script:PUBLIC_KEY.Length)))..." -ForegroundColor Cyan
|
||
} else {
|
||
Write-Host "❌ 公钥文件不存在" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
# 验证Gitea Token
|
||
function Verify-GiteaToken {
|
||
Write-Host "正在验证Gitea Token..." -ForegroundColor Yellow
|
||
|
||
try {
|
||
$headers = @{
|
||
"Authorization" = "token $GITEA_TOKEN"
|
||
"Accept" = "application/json"
|
||
}
|
||
|
||
# 忽略SSL证书验证
|
||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
|
||
|
||
$response = Invoke-RestMethod -Uri "$GITEA_URL/api/v1/user" -Headers $headers -Method Get
|
||
Write-Host "✓ Gitea Token验证成功,用户: $($response.login)" -ForegroundColor Green
|
||
} catch {
|
||
Write-Host "❌ Gitea Token验证失败: $($_.Exception.Message)" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
# 检查SSH密钥是否已存在于Gitea
|
||
function Check-KeyExistsOnGitea {
|
||
Write-Host "正在检查SSH密钥是否已存在于Gitea..." -ForegroundColor Yellow
|
||
|
||
# 获取当前公钥的指纹部分
|
||
$currentKeyContent = ($script:PUBLIC_KEY -split ' ')[1]
|
||
Write-Host "当前本地密钥指纹: $($currentKeyContent.Substring(0, [Math]::Min(50, $currentKeyContent.Length)))..." -ForegroundColor Cyan
|
||
|
||
try {
|
||
$headers = @{
|
||
"Authorization" = "token $GITEA_TOKEN"
|
||
"Accept" = "application/json"
|
||
}
|
||
|
||
$giteaKeys = Invoke-RestMethod -Uri "$GITEA_URL/api/v1/user/keys" -Headers $headers -Method Get
|
||
|
||
Write-Host "Gitea上现有的密钥:" -ForegroundColor Cyan
|
||
foreach ($key in $giteaKeys) {
|
||
$keyPreview = $key.key.Substring(0, [Math]::Min(50, $key.key.Length))
|
||
Write-Host " - $($key.title): $keyPreview..." -ForegroundColor Gray
|
||
}
|
||
|
||
# 检查是否有匹配的密钥
|
||
foreach ($key in $giteaKeys) {
|
||
if ($key.key -like "*$currentKeyContent*") {
|
||
Write-Host "✓ SSH密钥已存在于Gitea账户中" -ForegroundColor Green
|
||
Write-Host "现有密钥标题: $($key.title)" -ForegroundColor Cyan
|
||
return $true
|
||
}
|
||
}
|
||
|
||
Write-Host "⚠ 当前SSH密钥不存在于Gitea账户中,需要添加" -ForegroundColor Yellow
|
||
return $false
|
||
|
||
} catch {
|
||
Write-Host "❌ 检查Gitea密钥失败: $($_.Exception.Message)" -ForegroundColor Red
|
||
return $false
|
||
}
|
||
}
|
||
|
||
# 添加SSH密钥到Gitea
|
||
function Add-KeyToGitea {
|
||
# 先检查密钥是否已存在
|
||
if (Check-KeyExistsOnGitea) {
|
||
Write-Host "✓ 跳过添加,使用现有密钥" -ForegroundColor Green
|
||
return
|
||
}
|
||
|
||
Write-Host "正在添加SSH密钥到Gitea..." -ForegroundColor Yellow
|
||
|
||
# 生成密钥标题
|
||
$keyTitle = "$SSH_USERNAME@$env:COMPUTERNAME-$(Get-Date -Format 'yyyyMMdd_HHmmss')"
|
||
|
||
try {
|
||
$headers = @{
|
||
"Authorization" = "token $GITEA_TOKEN"
|
||
"Accept" = "application/json"
|
||
"Content-Type" = "application/json"
|
||
}
|
||
|
||
$body = @{
|
||
title = $keyTitle
|
||
key = $script:PUBLIC_KEY
|
||
} | ConvertTo-Json
|
||
|
||
$response = Invoke-RestMethod -Uri "$GITEA_URL/api/v1/user/keys" -Headers $headers -Method Post -Body $body
|
||
|
||
Write-Host "✓ SSH密钥已成功添加到Gitea" -ForegroundColor Green
|
||
Write-Host "密钥标题: $keyTitle" -ForegroundColor Cyan
|
||
if ($response.id) {
|
||
Write-Host "密钥ID: $($response.id)" -ForegroundColor Cyan
|
||
}
|
||
|
||
} catch {
|
||
$errorMessage = $_.Exception.Message
|
||
if ($errorMessage -like "*422*" -or $errorMessage -like "*already*") {
|
||
Write-Host "⚠ 这个SSH密钥已经存在于Gitea账户中" -ForegroundColor Yellow
|
||
Write-Host "✓ 可以继续使用现有密钥" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "❌ 添加SSH密钥失败: $errorMessage" -ForegroundColor Red
|
||
Write-Host "可能的原因:" -ForegroundColor Yellow
|
||
Write-Host "1. SSH密钥格式不正确" -ForegroundColor Yellow
|
||
Write-Host "2. Gitea Token权限不足" -ForegroundColor Yellow
|
||
Write-Host "3. 密钥已被其他账户使用" -ForegroundColor Yellow
|
||
Write-Host "4. 网络连接问题" -ForegroundColor Yellow
|
||
exit 1
|
||
}
|
||
}
|
||
}
|
||
|
||
# 配置Git用户信息
|
||
function Configure-Git {
|
||
Write-Host "正在配置Git用户信息..." -ForegroundColor Yellow
|
||
|
||
try {
|
||
git config --global user.name $DEFAULT_USERNAME
|
||
git config --global user.email $DEFAULT_EMAIL
|
||
|
||
Write-Host "✓ Git用户信息配置完成" -ForegroundColor Green
|
||
Write-Host "用户名: $(git config --global user.name)" -ForegroundColor Cyan
|
||
Write-Host "邮箱: $(git config --global user.email)" -ForegroundColor Cyan
|
||
} catch {
|
||
Write-Host "❌ Git配置失败: $($_.Exception.Message)" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
# 配置Gitea SSH
|
||
function Configure-GiteaSSH {
|
||
Write-Host "正在配置Gitea SSH..." -ForegroundColor Yellow
|
||
|
||
$sshDir = "$env:USERPROFILE\.ssh"
|
||
$configPath = "$sshDir\config"
|
||
|
||
# 创建SSH目录
|
||
if (!(Test-Path $sshDir)) {
|
||
New-Item -ItemType Directory -Path $sshDir -Force | Out-Null
|
||
}
|
||
|
||
# 从Gitea URL中提取主机名
|
||
$giteaHost = ($GITEA_URL -replace "https?://", "") -replace "/.*", ""
|
||
|
||
# 检查是否已有Gitea配置
|
||
$configExists = $false
|
||
if (Test-Path $configPath) {
|
||
$configContent = Get-Content $configPath -Raw
|
||
if ($configContent -like "*Host $giteaHost*") {
|
||
$configExists = $true
|
||
}
|
||
}
|
||
|
||
if (!$configExists) {
|
||
$sshConfig = @"
|
||
|
||
# Gitea SSH configuration
|
||
Host $giteaHost
|
||
Hostname $giteaHost
|
||
Port $SSH_PORT
|
||
User git
|
||
IdentityFile ~/.ssh/id_rsa
|
||
"@
|
||
Add-Content -Path $configPath -Value $sshConfig
|
||
Write-Host "✓ 已配置Gitea SSH" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "✓ Gitea SSH配置已存在" -ForegroundColor Green
|
||
}
|
||
}
|
||
|
||
# 测试Gitea SSH连接
|
||
function Test-GiteaConnection {
|
||
Write-Host "正在测试Gitea SSH连接..." -ForegroundColor Yellow
|
||
|
||
# 从Gitea URL中提取主机名
|
||
$giteaHost = ($GITEA_URL -replace "https?://", "") -replace "/.*", ""
|
||
|
||
Write-Host "尝试连接到 $giteaHost..." -ForegroundColor Cyan
|
||
|
||
try {
|
||
# 使用ssh命令测试连接
|
||
$testResult = ssh -T -o StrictHostKeyChecking=no -o ConnectTimeout=10 "git@$giteaHost" 2>&1
|
||
|
||
Write-Host "SSH测试输出: $testResult" -ForegroundColor Gray
|
||
|
||
if ($testResult -like "*Hi there*" -or $testResult -like "*successfully authenticated*" -or $testResult -like "*Welcome*" -or $testResult -like "*Hi $DEFAULT_USERNAME*") {
|
||
Write-Host "✓ Gitea SSH连接测试成功" -ForegroundColor Green
|
||
Write-Host "现在可以通过SSH访问Gitea仓库" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "⚠ Gitea SSH连接测试未完全成功" -ForegroundColor Yellow
|
||
Write-Host "测试结果: $testResult" -ForegroundColor Gray
|
||
|
||
if ($testResult -like "*Connection closed*" -or $testResult -like "*Connection refused*" -or $testResult -like "*Network is unreachable*") {
|
||
Write-Host "这可能是网络连接问题,但SSH密钥已成功添加到Gitea" -ForegroundColor Yellow
|
||
Write-Host "建议稍后手动测试: ssh -T git@$giteaHost" -ForegroundColor Yellow
|
||
} else {
|
||
Write-Host "可能的原因:" -ForegroundColor Yellow
|
||
Write-Host "1. SSH密钥未正确添加到Gitea" -ForegroundColor Yellow
|
||
Write-Host "2. 网络连接问题" -ForegroundColor Yellow
|
||
Write-Host "3. SSH配置问题" -ForegroundColor Yellow
|
||
Write-Host "4. Gitea服务暂时不可用" -ForegroundColor Yellow
|
||
Write-Host "建议稍后手动测试: ssh -T git@$giteaHost" -ForegroundColor Yellow
|
||
}
|
||
}
|
||
} catch {
|
||
Write-Host "⚠ SSH连接测试遇到问题: $($_.Exception.Message)" -ForegroundColor Yellow
|
||
Write-Host "但SSH密钥已成功添加到Gitea,建议稍后手动测试" -ForegroundColor Yellow
|
||
}
|
||
}
|
||
|
||
# 主执行流程
|
||
function Main {
|
||
Write-Host "开始Gitea SSH密钥设置过程..." -ForegroundColor Green
|
||
Write-Host ""
|
||
|
||
# 获取用户配置
|
||
Get-UserConfiguration
|
||
|
||
# 执行各个步骤
|
||
Check-Dependencies
|
||
Write-Host ""
|
||
|
||
Check-OrGenerate-SSHKey
|
||
Write-Host ""
|
||
|
||
Get-PublicKey
|
||
Write-Host ""
|
||
|
||
Verify-GiteaToken
|
||
Write-Host ""
|
||
|
||
Add-KeyToGitea
|
||
Write-Host ""
|
||
|
||
Configure-Git
|
||
Write-Host ""
|
||
|
||
Configure-GiteaSSH
|
||
Write-Host ""
|
||
|
||
Test-GiteaConnection
|
||
Write-Host ""
|
||
|
||
Write-Host "=== 设置完成 ===" -ForegroundColor Green
|
||
Write-Host "✓ Git已安装并配置完成" -ForegroundColor Green
|
||
Write-Host "✓ Git用户信息已设置: $DEFAULT_USERNAME <$DEFAULT_EMAIL>" -ForegroundColor Green
|
||
Write-Host "✓ SSH密钥已添加到Gitea" -ForegroundColor Green
|
||
Write-Host "✓ 用户 $SSH_USERNAME 现在可以通过SSH访问Gitea仓库" -ForegroundColor Green
|
||
Write-Host ""
|
||
Write-Host "测试命令:" -ForegroundColor Yellow
|
||
$giteaHost = ($GITEA_URL -replace "https?://", "") -replace "/.*", ""
|
||
Write-Host " git clone git@${giteaHost}:username/repository.git" -ForegroundColor Cyan
|
||
Write-Host " ssh -T git@$giteaHost" -ForegroundColor Cyan
|
||
Write-Host " git config --list # 查看git配置" -ForegroundColor Cyan
|
||
}
|
||
|
||
# 执行主函数
|
||
try {
|
||
Main
|
||
} catch {
|
||
Write-Host "❌ 脚本执行失败: $($_.Exception.Message)" -ForegroundColor Red
|
||
Write-Host "请检查网络连接和配置信息" -ForegroundColor Yellow
|
||
exit 1
|
||
}
|