#!/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