422 lines
13 KiB
Bash
Executable File
422 lines
13 KiB
Bash
Executable File
#!/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
|