SSH-SETUP 自动化配置工具
2026/1/14大约 7 分钟
SSH-SETUP 自动化配置工具
一个交互式 SSH 配置脚本,用于自动化设置 SSH 密钥认证、服务器连接别名和免密登录。
一 工具概述
ssh-setup 是一个 Bash 脚本,旨在简化 SSH 服务器的配置过程。通过交互式引导,用户可以快速完成以下任务:
- 🔑 生成或选择 SSH 密钥
- 🌐 配置服务器连接信息
- 🔄 自动部署公钥到远程服务器
- 📝 更新 SSH 配置文件
- 🚀 创建便捷的 shell 别名
1.1 核心功能
- ✅ 密钥管理: 支持生成新密钥或使用现有密钥
- ✅ 交互式配置: 引导用户输入服务器信息
- ✅ 自动部署: 一键部署公钥到远程服务器
- ✅ 配置备份: 自动备份现有 SSH 配置
- ✅ 连接测试: 配置完成后自动测试连接
- ✅ 别名创建: 为每个服务器创建快捷别名
二 安装与配置
2.1 脚本位置
- 路径:
~/bin/ssh-setup - 权限: 可执行 (
-rwxrwxr-x) - 大小: 359 行代码
2.2 环境配置
- PATH 设置:
~/bin已添加到 PATH - Shell 别名: 已添加
ssh-setup别名到~/.bashrc - 配置文件更新:
~/.bashrc- 已优化 PATH 配置~/.profile- 已优化 PATH 配置
三 使用方法
3.1 启动方式
方法一:使用别名(推荐)
ssh-setup方法二:使用完整路径
~/bin/ssh-setup方法三:在新终端中
- 打开新终端窗口
- 直接运行:
ssh-setup
3.2 配置流程
运行 ssh-setup 后,按照提示输入:
- 服务器别名 - 如:
server1 - IP 地址 - 如:
10.6.220.216 - 端口 - 默认:
22,或输入如:10022 - 用户名 - 默认: 当前用户,或输入如:
sunri - 服务器密码 - 仅首次需要
3.3 配置完成后
- 连接方式:
ssh server1 - 快捷别名:
ssh-server1(需要重新加载 shell) - 配置文件:
~/.ssh/config自动更新
四 技术特性
4.1 安全功能
- ✅ SSH 密钥认证(不存储密码)
- ✅ 配置自动备份
- ✅ 输入验证和错误处理
- ✅ 失败重试机制
4.2 自动化功能
- ✅ 自动部署公钥到服务器
- ✅ 自动更新 SSH config
- ✅ 自动创建 shell 别名
- ✅ 自动测试连接
4.3 用户体验
- ✅ 彩色输出和进度提示
- ✅ 详细的错误信息
- ✅ 交互式输入引导
- ✅ 配置总结报告
五 立即使用
5.1 对于当前会话
# 1. 重新加载配置
source ~/.bashrc
# 2. 开始配置
ssh-setup5.2 对于新终端
- 打开新终端窗口
- 直接运行:
ssh-setup
六 验证配置
运行验证脚本检查配置:
~/verify-ssh-setup.sh七 故障排除
7.1 如果 ssh-setup 命令未找到
# 方案1: 使用完整路径
~/bin/ssh-setup
# 方案2: 手动设置 PATH
export PATH="$HOME/bin:$PATH"
ssh-setup
# 方案3: 重新加载配置
source ~/.bashrc
ssh-setup7.2 如果脚本权限问题
chmod +x ~/bin/ssh-setup八 功能实现确认
脚本已完全按照要求实现:
- ✅ 使用同一密钥
- ✅ 自动备份配置
- ✅ 服务器失败重试1次
- ✅ 密码错误直接提示用户
- ✅ 不支持批量导入
现在可以开始配置您的 SSH 连接了!
九 完整脚本代码
#!/bin/bash
# ssh-setup - 自动化 SSH 配置脚本
# 版本: 1.0
# 功能: 交互式配置 SSH 密钥认证和连接别名
set -euo pipefail
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查依赖
check_dependencies() {
log_info "检查系统依赖..."
local missing_deps=()
for cmd in ssh ssh-copy-id ssh-keygen; do
if ! command -v "$cmd" &> /dev/null; then
missing_deps+=("$cmd")
fi
done
if [ ${#missing_deps[@]} -gt 0 ]; then
log_error "缺少必要的依赖: ${missing_deps[*]}"
log_info "请安装: sudo apt install openssh-client"
exit 1
fi
log_success "所有依赖检查通过"
}
# 初始化环境
init_environment() {
log_info "初始化环境..."
# 确保 ~/.ssh 目录存在
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 设置默认密钥路径
DEFAULT_KEY="${HOME}/.ssh/id_ed25519"
log_success "环境初始化完成"
}
# 备份 SSH config
backup_ssh_config() {
local config_file="${HOME}/.ssh/config"
if [ -f "$config_file" ]; then
local backup_file="${config_file}.backup.$(date +%Y%m%d_%H%M%S)"
cp "$config_file" "$backup_file"
log_info "已备份 SSH config 到: $backup_file"
fi
}
# 收集服务器信息
collect_server_info() {
log_info "请输入服务器配置信息"
echo "----------------------------------------"
# 服务器别名
while true; do
read -p "服务器别名 (如: server1): " SERVER_ALIAS
SERVER_ALIAS=$(echo "$SERVER_ALIAS" | tr -d '[:space:]')
if [ -z "$SERVER_ALIAS" ]; then
log_error "别名不能为空"
continue
fi
# 检查别名是否已存在
if [ -f "${HOME}/.ssh/config" ]; then
if grep -q "^Host[[:space:]]*${SERVER_ALIAS}[[:space:]]*$" "${HOME}/.ssh/config"; then
log_warning "别名 '$SERVER_ALIAS' 已存在"
read -p "是否覆盖? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
break
else
continue
fi
fi
fi
break
done
# IP 地址
while true; do
read -p "服务器 IP 地址: " SERVER_IP
SERVER_IP=$(echo "$SERVER_IP" | tr -d '[:space:]')
if [[ "$SERVER_IP" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
break
else
log_error "请输入有效的 IP 地址 (如: 10.6.220.216)"
fi
done
# 端口
read -p "SSH 端口 [默认: 22]: " SERVER_PORT
SERVER_PORT=${SERVER_PORT:-22}
if ! [[ "$SERVER_PORT" =~ ^[0-9]+$ ]] || [ "$SERVER_PORT" -lt 1 ] || [ "$SERVER_PORT" -gt 65535 ]; then
log_error "端口号无效,使用默认值 22"
SERVER_PORT=22
fi
# 用户名
read -p "用户名 [默认: $(whoami)]: " SERVER_USER
SERVER_USER=${SERVER_USER:-$(whoami)}
log_success "服务器信息收集完成"
echo "----------------------------------------"
echo "别名: $SERVER_ALIAS"
echo "IP: $SERVER_IP"
echo "端口: $SERVER_PORT"
echo "用户: $SERVER_USER"
echo "----------------------------------------"
read -p "确认以上信息? (Y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
log_info "重新输入信息..."
collect_server_info
fi
}
# 选择 SSH 密钥
select_ssh_key() {
log_info "选择 SSH 密钥..."
# 检查默认密钥是否存在
if [ -f "$DEFAULT_KEY" ] && [ -f "${DEFAULT_KEY}.pub" ]; then
log_info "发现现有密钥: $DEFAULT_KEY"
read -p "使用现有密钥? (Y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
create_new_key
else
SSH_KEY="$DEFAULT_KEY"
log_success "使用现有密钥: $SSH_KEY"
fi
else
log_warning "未找到现有密钥"
create_new_key
fi
}
# 创建新密钥
create_new_key() {
log_info "创建新的 SSH 密钥..."
read -p "密钥类型 [默认: ed25519]: " KEY_TYPE
KEY_TYPE=${KEY_TYPE:-ed25519}
read -p "密钥注释 [默认: $(whoami)@$(hostname)]: " KEY_COMMENT
KEY_COMMENT=${KEY_COMMENT:-"$(whoami)@$(hostname)"}
SSH_KEY="${HOME}/.ssh/id_${KEY_TYPE}"
if [ -f "$SSH_KEY" ]; then
log_warning "密钥文件已存在: $SSH_KEY"
read -p "是否覆盖? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
log_info "请选择其他密钥名称"
create_new_key
return
fi
fi
log_info "正在生成密钥..."
ssh-keygen -t "$KEY_TYPE" -C "$KEY_COMMENT" -f "$SSH_KEY" -N ""
if [ $? -eq 0 ]; then
log_success "密钥创建成功: $SSH_KEY"
else
log_error "密钥创建失败"
exit 1
fi
}
# 部署公钥到服务器
deploy_public_key() {
log_info "部署公钥到服务器..."
local max_retries=1
local retry_count=0
while [ $retry_count -le $max_retries ]; do
echo "正在连接 ${SERVER_USER}@${SERVER_IP}:${SERVER_PORT}..."
# 使用 ssh-copy-id 部署公钥
if ssh-copy-id -p "$SERVER_PORT" -i "$SSH_KEY" "${SERVER_USER}@${SERVER_IP}"; then
log_success "公钥部署成功"
return 0
else
retry_count=$((retry_count + 1))
if [ $retry_count -le $max_retries ]; then
log_warning "部署失败,正在重试 (${retry_count}/${max_retries})..."
sleep 2
else
log_error "公钥部署失败,请检查:"
log_error "1. 服务器是否可达"
log_error "2. 用户名和密码是否正确"
log_error "3. 服务器 SSH 服务是否运行"
return 1
fi
fi
done
}
# 更新 SSH config
update_ssh_config() {
log_info "更新 SSH 配置文件..."
local config_file="${HOME}/.ssh/config"
# 创建或追加配置
{
echo ""
echo "# 自动配置: $SERVER_ALIAS - $(date)"
echo "Host $SERVER_ALIAS"
echo " HostName $SERVER_IP"
echo " Port $SERVER_PORT"
echo " User $SERVER_USER"
echo " IdentityFile $SSH_KEY"
echo " ServerAliveInterval 60"
echo " ServerAliveCountMax 3"
echo " ConnectTimeout 10"
echo ""
} >> "$config_file"
# 设置正确的权限
chmod 600 "$config_file"
log_success "SSH config 更新完成"
}
# 测试连接
test_connection() {
log_info "测试 SSH 连接..."
if ssh -o ConnectTimeout=5 -o BatchMode=yes "$SERVER_ALIAS" "echo 'SSH 密钥认证成功'" 2>/dev/null; then
log_success "连接测试成功"
return 0
else
log_warning "连接测试失败,但配置已保存"
log_info "您可能需要:"
log_info "1. 检查服务器防火墙设置"
log_info "2. 确认服务器 SSH 配置允许密钥认证"
log_info "3. 稍后手动测试: ssh $SERVER_ALIAS"
return 1
fi
}
# 创建 shell 别名
create_shell_alias() {
log_info "创建 shell 别名..."
local shell_rc
if [ -f "${HOME}/.zshrc" ]; then
shell_rc="${HOME}/.zshrc"
else
shell_rc="${HOME}/.bashrc"
fi
local alias_name="ssh-${SERVER_ALIAS}"
local alias_cmd="alias ${alias_name}='ssh ${SERVER_ALIAS}'"
# 检查别名是否已存在
if ! grep -q "^${alias_cmd}$" "$shell_rc" 2>/dev/null; then
echo "$alias_cmd" >> "$shell_rc"
log_success "别名已添加到 $shell_rc"
log_info "运行 'source $shell_rc' 或重新打开终端后可使用: $alias_name"
else
log_info "别名已存在: $alias_name"
fi
}
# 显示使用说明
show_usage() {
echo "使用方法:"
echo " 直接连接: ssh $SERVER_ALIAS"
echo " 使用别名: ssh-$SERVER_ALIAS (需要重新加载 shell 配置)"
echo ""
echo "配置位置:"
echo " SSH config: ~/.ssh/config"
echo " 密钥文件: $SSH_KEY"
}
# 主函数
main() {
echo "========================================"
echo " SSH 自动化配置工具 v1.0"
echo "========================================"
# 检查依赖
check_dependencies
# 初始化环境
init_environment
# 备份现有配置
backup_ssh_config
# 收集服务器信息
collect_server_info
# 选择密钥
select_ssh_key
# 部署公钥
if ! deploy_public_key; then
log_warning "公钥部署失败,跳过后续步骤"
exit 1
fi
# 更新配置
update_ssh_config
# 测试连接
test_connection
# 创建别名
create_shell_alias
echo "========================================"
log_success "配置完成!"
show_usage
echo "========================================"
}
# 运行主函数
main "$@"