Files
public/setup_gitea_ssh_keys_interactive.sh
2025-07-06 06:47:55 +08:00

422 lines
13 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Gitea SSH密钥设置脚本 (交互式版本)
# 用途: 获取/生成SSH密钥并添加到Gitea
# 用法: ./setup_gitea_ssh_keys_interactive.sh
set -e # 遇到错误立即退出
# 配置信息(将通过用户输入获取)
DEFAULT_USERNAME=""
DEFAULT_EMAIL=""
GITEA_TOKEN=""
GITEA_URL="https://git.sanyitec.cc"
SSH_PORT=222
# 检查是否请求帮助
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo "=== Gitea SSH密钥设置脚本 (交互式版本) ==="
echo "用途: 检查/生成SSH密钥并添加到Gitea (交互式配置)"
echo
echo "用法:"
echo " $0 # 交互式配置"
echo
echo "功能:"
echo " 1. 交互式输入Git用户信息和Gitea Token"
echo " 2. 检查现有SSH密钥或生成新密钥"
echo " 3. 自动添加公钥到Gitea"
echo " 4. 配置Git用户信息"
echo " 5. 配置SSH连接设置端口222"
echo " 6. 测试Gitea SSH连接"
echo
exit 0
fi
echo "=== Gitea SSH密钥设置脚本 (交互式版本) ==="
echo "将通过交互式配置检查现有SSH密钥或生成新密钥并添加到Gitea"
# 使用当前用户
SSH_USERNAME="${SSH_USERNAME:-$(whoami)}"
SSH_HOST="localhost"
echo "当前用户: $SSH_USERNAME"
# 获取用户输入配置
get_user_configuration() {
echo "=== 配置信息输入 ==="
echo "请输入以下配置信息:"
echo
# 获取Git用户名
while true; do
read -p "请输入Git用户名: " DEFAULT_USERNAME
if [ -n "$DEFAULT_USERNAME" ]; then
break
else
echo "❌ 用户名不能为空,请重新输入"
fi
done
# 获取Git邮箱
while true; do
read -p "请输入Git邮箱地址: " DEFAULT_EMAIL
if [[ "$DEFAULT_EMAIL" =~ ^[^@]+@[^@]+\.[^@]+$ ]]; then
break
else
echo "❌ 请输入有效的邮箱地址"
fi
done
# 获取Gitea Token
while true; do
read -s -p "请输入Gitea访问Token: " GITEA_TOKEN
echo # 换行
if [ -n "$GITEA_TOKEN" ]; then
break
else
echo "❌ Token不能为空请重新输入"
fi
done
echo
echo "✓ 配置信息输入完成"
echo "用户名: $DEFAULT_USERNAME"
echo "邮箱: $DEFAULT_EMAIL"
echo "Token: $(echo "$GITEA_TOKEN" | sed 's/./*/g')"
echo
}
# 检查必要工具
check_dependencies() {
echo "正在检查依赖工具..."
local missing_tools=()
if ! command -v git &> /dev/null; then
missing_tools+=("git")
fi
if ! command -v curl &> /dev/null; then
missing_tools+=("curl")
fi
if ! command -v jq &> /dev/null; then
missing_tools+=("jq")
fi
if [ ${#missing_tools[@]} -gt 0 ]; then
echo "正在安装缺失的工具: ${missing_tools[*]}"
# 检查网络连接
if ! ping -c 1 8.8.8.8 &>/dev/null; then
echo "❌ 网络连接失败,无法安装依赖工具"
echo "请手动安装以下工具: ${missing_tools[*]}"
echo "命令: sudo apt update && sudo apt install -y ${missing_tools[*]}"
exit 1
fi
sudo apt update -qq
for tool in "${missing_tools[@]}"; do
sudo apt install -y "$tool"
done
echo "✓ 依赖工具安装完成"
else
echo "✓ 所有依赖工具已安装"
fi
}
# 检查或生成SSH密钥
check_or_generate_ssh_key() {
echo "正在检查本地SSH密钥..."
# 检查是否已存在SSH密钥
if [ -f ~/.ssh/id_rsa.pub ]; then
echo "✓ 本地已存在SSH密钥"
return 0
fi
echo "正在生成SSH密钥..."
# 生成SSH密钥
mkdir -p ~/.ssh && chmod 700 ~/.ssh
ssh-keygen -t rsa -b 4096 -C "$DEFAULT_EMAIL" -f ~/.ssh/id_rsa -N ''
if [ $? -eq 0 ]; then
echo "✓ SSH密钥生成成功"
else
echo "❌ SSH密钥生成失败"
exit 1
fi
}
# 获取公钥
get_public_key() {
echo "正在获取本地公钥..."
if [ -f ~/.ssh/id_rsa.pub ]; then
PUBLIC_KEY=$(cat ~/.ssh/id_rsa.pub)
echo "✓ 公钥获取成功"
echo "公钥内容: ${PUBLIC_KEY:0:50}..."
return 0
else
echo "❌ 本地公钥文件不存在"
exit 1
fi
}
# 验证Gitea Token
verify_gitea_token() {
echo "正在验证Gitea Token..."
local response=$(curl -s -k -w "%{http_code}" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Accept: application/json" \
"$GITEA_URL/api/v1/user")
local http_code="${response: -3}"
local response_body="${response%???}"
if [ "$http_code" = "200" ]; then
local username=$(echo "$response_body" | jq -r '.login // empty')
echo "✓ Gitea Token验证成功用户: $username"
return 0
else
echo "❌ Gitea Token验证失败 (HTTP $http_code)"
echo "响应: $response_body"
echo "请检查Gitea Token是否正确且具有足够权限"
exit 1
fi
}
# 检查SSH密钥是否已存在于Gitea
check_key_exists_on_gitea() {
echo "正在检查SSH密钥是否已存在于Gitea..."
# 获取当前公钥的指纹部分去掉ssh-rsa前缀和邮箱后缀
local current_key_content=$(echo "$PUBLIC_KEY" | awk '{print $2}')
echo "当前本地密钥指纹: ${current_key_content:0:50}..."
# 获取Gitea上的所有密钥
local gitea_keys=$(curl -s -k \
-H "Authorization: token $GITEA_TOKEN" \
-H "Accept: application/json" \
"$GITEA_URL/api/v1/user/keys")
# 显示Gitea上现有的密钥
echo "Gitea上现有的密钥:"
echo "$gitea_keys" | jq -r '.[] | " - \(.title): \(.key[0:50])..."'
# 检查是否有匹配的密钥
if echo "$gitea_keys" | jq -r '.[].key' | grep -q "$current_key_content"; then
echo "✓ SSH密钥已存在于Gitea账户中"
local existing_title=$(echo "$gitea_keys" | jq -r '.[] | select(.key | contains("'$current_key_content'")) | .title')
echo "现有密钥标题: $existing_title"
return 0
else
echo "⚠ 当前SSH密钥不存在于Gitea账户中需要添加"
return 1
fi
}
# 添加SSH密钥到Gitea
add_key_to_gitea() {
# 先检查密钥是否已存在
if check_key_exists_on_gitea; then
echo "✓ 跳过添加,使用现有密钥"
return 0
fi
echo "正在添加SSH密钥到Gitea..."
# 生成密钥标题(包含服务器信息和时间戳)
local key_title="$SSH_USERNAME@$SSH_HOST-$(date +%Y%m%d_%H%M%S)"
# 构建JSON数据
local json_data=$(jq -n \
--arg title "$key_title" \
--arg key "$PUBLIC_KEY" \
'{title: $title, key: $key}')
# 发送请求到Gitea API
local response=$(curl -s -k -w "%{http_code}" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d "$json_data" \
"$GITEA_URL/api/v1/user/keys")
# 提取HTTP状态码
local http_code="${response: -3}"
local response_body="${response%???}"
if [ "$http_code" = "201" ]; then
echo "✓ SSH密钥已成功添加到Gitea"
echo "密钥标题: $key_title"
# 解析响应获取密钥ID
local key_id=$(echo "$response_body" | jq -r '.id // empty')
if [ -n "$key_id" ]; then
echo "密钥ID: $key_id"
fi
elif [ "$http_code" = "422" ]; then
# 检查是否是密钥已存在的错误
local error_message=$(echo "$response_body" | jq -r '.message // empty')
local errors=$(echo "$response_body" | jq -r '.errors[]?.message // empty' 2>/dev/null | tr '\n' '; ')
echo "❌ Gitea API验证失败 (HTTP 422)"
echo "错误信息: $error_message"
if [ -n "$errors" ]; then
echo "详细错误: $errors"
fi
echo "完整响应: $response_body"
# 检查各种可能的错误情况
if echo "$error_message" | grep -qi "key is already in use\|already exists"; then
echo "⚠ 这个SSH密钥已经存在于Gitea账户中"
echo "✓ 可以继续使用现有密钥"
return 0 # 返回成功,因为密钥已存在
elif echo "$response_body" | grep -qi "key is already in use\|already exists"; then
echo "⚠ 这个SSH密钥已经存在于Gitea账户中"
echo "✓ 可以继续使用现有密钥"
return 0 # 返回成功,因为密钥已存在
else
echo "可能的原因:"
echo "1. SSH密钥格式不正确"
echo "2. Gitea Token权限不足"
echo "3. 密钥已被其他账户使用"
echo "4. 网络连接问题"
exit 1
fi
else
echo "❌ 添加SSH密钥失败 (HTTP $http_code)"
echo "响应: $response_body"
exit 1
fi
}
# 配置Git用户信息
configure_git() {
echo "正在配置Git用户信息..."
git config --global user.name "$DEFAULT_USERNAME"
git config --global user.email "$DEFAULT_EMAIL"
echo "✓ Git用户信息配置完成"
echo "用户名: $(git config --global user.name)"
echo "邮箱: $(git config --global user.email)"
}
# 配置Gitea SSH
configure_gitea_ssh() {
echo "正在配置Gitea SSH..."
# 创建SSH配置文件
mkdir -p ~/.ssh
# 从Gitea URL中提取主机名
local gitea_host=$(echo "$GITEA_URL" | sed 's|https\?://||' | sed 's|/.*||')
# 检查是否已有Gitea配置
if ! grep -q "Host $gitea_host" ~/.ssh/config 2>/dev/null; then
echo "" >> ~/.ssh/config
echo "# Gitea SSH configuration" >> ~/.ssh/config
echo "Host $gitea_host" >> ~/.ssh/config
echo " Hostname $gitea_host" >> ~/.ssh/config
echo " Port $SSH_PORT" >> ~/.ssh/config
echo " User git" >> ~/.ssh/config
echo " IdentityFile ~/.ssh/id_rsa" >> ~/.ssh/config
chmod 600 ~/.ssh/config
echo "✓ 已配置Gitea SSH (端口: $SSH_PORT)"
else
echo "✓ Gitea SSH配置已存在"
fi
}
# 测试Gitea SSH连接
test_gitea_connection() {
echo "正在测试Gitea SSH连接..."
# 从Gitea URL中提取主机名
local gitea_host=$(echo "$GITEA_URL" | sed 's|https\?://||' | sed 's|/.*||')
echo "尝试连接到 $gitea_host:$SSH_PORT..."
local test_result=$(ssh -T -o StrictHostKeyChecking=no -o ConnectTimeout=10 git@$gitea_host 2>&1 || true)
echo "SSH测试输出: $test_result"
if echo "$test_result" | grep -q "Hi there\|successfully authenticated\|Welcome"; then
echo "✓ Gitea SSH连接测试成功"
echo "现在可以通过SSH访问Gitea仓库"
return 0
elif echo "$test_result" | grep -q "Hi $DEFAULT_USERNAME"; then
echo "✓ Gitea SSH连接测试成功"
echo "现在可以通过SSH访问Gitea仓库"
return 0
else
echo "⚠ Gitea SSH连接测试未完全成功"
echo "测试结果: $test_result"
# 检查是否是网络连接问题
if echo "$test_result" | grep -q "Connection closed by remote host\|Connection refused\|Network is unreachable\|kex_exchange_identification"; then
echo "这可能是网络连接问题但SSH密钥已成功添加到Gitea"
echo "建议稍后手动测试: ssh -T git@$gitea_host"
return 0 # 不视为失败,因为密钥已添加成功
else
echo "可能的原因:"
echo "1. SSH密钥未正确添加到Gitea"
echo "2. 网络连接问题"
echo "3. SSH配置问题"
echo "4. Gitea服务暂时不可用"
echo "建议稍后手动测试: ssh -T git@$gitea_host"
return 0 # 改为返回成功,因为主要任务(添加密钥)已完成
fi
fi
}
# 主执行流程
main() {
echo "开始Gitea SSH密钥设置过程..."
echo
# 获取用户配置
get_user_configuration
# 执行各个步骤
check_dependencies
echo
check_or_generate_ssh_key
echo
get_public_key
echo
verify_gitea_token
echo
add_key_to_gitea
echo
configure_git
echo
configure_gitea_ssh
echo
test_gitea_connection
echo
echo "=== 设置完成 ==="
echo "✓ Git已安装并配置完成"
echo "✓ Git用户信息已设置: $DEFAULT_USERNAME <$DEFAULT_EMAIL>"
echo "✓ SSH密钥已添加到Gitea"
echo "✓ 用户 $SSH_USERNAME 现在可以通过SSH访问Gitea仓库"
echo
echo "测试命令:"
echo " git clone git@$(echo "$GITEA_URL" | sed 's|https\?://||' | sed 's|/.*||'):username/repository.git"
echo " ssh -T git@$(echo "$GITEA_URL" | sed 's|https\?://||' | sed 's|/.*||')"
echo " git config --list # 查看git配置"
}
# 执行主函数
main