首页
📈统计
📬留言
💘关于
更多
💞友链
📺直播
🎠壁纸
Search
1
docker部署chromium
5 阅读
2
prometheus+alertmanager告警
2 阅读
3
minio部署以及使用挂载
2 阅读
4
typecho背景透明设置
2 阅读
5
httpd文件服务器
1 阅读
🎑Linux
centos
ubuntu
deepin
debian
🎉Typecho
🎻小程序
🍕生活
🍞其他
☸k8s
🤖监控配置
登录
Search
标签搜索
shell
脚本
文档
doc
存储
typecho
chromium
lazy-balancer
Typecho
累计撰写
57
篇文章
累计收到
37
条评论
首页
栏目
🎑Linux
centos
ubuntu
deepin
debian
🎉Typecho
🎻小程序
🍕生活
🍞其他
☸k8s
🤖监控配置
页面
📈统计
📬留言
💘关于
💞友链
📺直播
🎠壁纸
搜索到
7
篇与
的结果
2026-01-23
linux密钥登录脚本
{anote icon="fa-download" href="https://packages.emal.cc/package/softinstall/doc/sh/update_keygen.sh" type="info" content="点击下载脚本"/}linux密钥登录脚本vim update_keygen.sh#!/usr/bin/env bash # --------------------------- # 颜色定义 # --------------------------- YELLOW='\e[93m' # 黄色(信息提示) GREEN='\033[32m' # 绿色(成功提示) RED='\033[31m' # 红色(错误提示) RESET='\e[0m' # 重置颜色 YELLOWS='\033[1;33m' RESETS='\033[0m' # --------------------------- # 日志输出函数 # --------------------------- #黄色 inst_msg() { local msg="$1" local datetime=$(date +"%Y-%m-%d %H:%M:%S") echo -e "${YELLOW}INFO: [${datetime}] ${msg}${RESET}" } # infos_msg() { local msg="$1" local datetime=$(date +"%Y-%m-%d %H:%M:%S") echo -e "${YELLOWS}\033[5mINFO: [${datetime}] ${msg}\033[25m${RESETS}" } #绿色 info_msg() { local msg="$1" local datetime=$(date +"%Y-%m-%d %H:%M:%S") echo -e "${GREEN}INFO: [${datetime}] ${msg}${RESET}" } #红色 err_msg() { local msg="$1" local datetime=$(date +"%Y-%m-%d %H:%M:%S") echo -e "${RED}ERRO: [${datetime}] ${msg}${RESET}" >&2 #exit 1 } create_sshd() { local SSH_DIR="$HOME/.ssh" local AUTH_KEYS_FILE="$SSH_DIR/authorized_keys" # 1. 确保.ssh目录存在 mkdir -p "$SSH_DIR" chmod 700 "$SSH_DIR" # 2. 确保 authorized_keys 文件存在 touch "$AUTH_KEYS_FILE" chmod 600 "$AUTH_KEYS_FILE" # 3. 提示用户输入公钥 echo "请粘贴 id_rsa.pub 公钥内容(一行),按 Enter 结束输入:" echo "提示: 公钥格式为: ssh-rsa AAAA... comment" echo "或者以 ssh-ed25519、ecdsa-sha2-nistp256 开头" echo "按 Ctrl+D 退出输入" echo "----------------------------------------" # 读取公钥(支持多行,但实际上公钥通常是一行) local PUB_KEY PUB_KEY=$(cat) # 如果用户按 Ctrl+D 直接退出,PUB_KEY 可能为空 if [ -z "$PUB_KEY" ]; then read -r -p "未输入公钥,是否跳过? [y/N]: " SKIP_INPUT if [[ "${SKIP_INPUT:-n}" =~ ^[Yy]$ ]]; then info_msg "跳过公钥配置" return 0 else err_msg "公钥输入被取消" return 1 fi fi # 4. 清理公钥字符串(去除首尾空白,合并多行) # 公钥可能被粘贴成多行,需要合并成一行 PUB_KEY=$(echo "$PUB_KEY" | tr -d '\r' | sed ':a;N;$!ba;s/\n//g' | xargs) if [ -z "$PUB_KEY" ]; then err_msg "错误: 公钥内容无效或为空" return 1 fi # 5. 验证公钥格式 info_msg "正在验证公钥格式..." # 检查是否是有效的SSH公钥格式 local IS_VALID_KEY=false # SSH 公钥常见类型 if [[ "$PUB_KEY" =~ ^ssh-(rsa|dss|ed25519) ]]; then IS_VALID_KEY=true elif [[ "$PUB_KEY" =~ ^ecdsa-sha2-nistp ]]; then IS_VALID_KEY=true else # 尝试解析密钥类型 local KEY_TYPE KEY_TYPE=$(echo "$PUB_KEY" | awk '{print $1}') case "$KEY_TYPE" in ssh-rsa|ssh-dss|ssh-ed25519|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521) IS_VALID_KEY=true ;; *) # 如果不是标准格式,检查是否有三个字段(类型 密钥 注释) local FIELD_COUNT FIELD_COUNT=$(echo "$PUB_KEY" | wc -w) if [ "$FIELD_COUNT" -ge 2 ]; then # 至少有两个字段,可能是有效的 IS_VALID_KEY=true info_msg "检测到非标准格式,但继续处理..." fi ;; esac fi if [ "$IS_VALID_KEY" = false ]; then err_msg "错误: 无效的SSH公钥格式" echo "示例格式: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user@host" return 1 fi # 6. 提取公钥的关键部分用于查重(类型 + 密钥,不含注释) local KEY_FOR_CHECK KEY_FOR_CHECK=$(echo "$PUB_KEY" | awk '{print $1" "$2}') # 7. 检查公钥是否已存在 if [ -f "$AUTH_KEYS_FILE" ]; then # 检查是否已有相同密钥(不考虑注释) if grep -qF "$KEY_FOR_CHECK" "$AUTH_KEYS_FILE" 2>/dev/null; then # 获取已存在的完整行 local EXISTING_LINE EXISTING_LINE=$(grep -F "$KEY_FOR_CHECK" "$AUTH_KEYS_FILE" | head -1) info_msg "公钥已存在于 authorized_keys 文件中:" echo "$EXISTING_LINE" read -r -p "是否仍然添加? [y/N]: " ADD_ANYWAY if [[ ! "${ADD_ANYWAY:-n}" =~ ^[Yy]$ ]]; then info_msg "跳过添加重复公钥" return 0 fi fi fi # 8. 添加公钥 echo "$PUB_KEY" >> "$AUTH_KEYS_FILE" # 9. 确保文件权限正确 chmod 600 "$AUTH_KEYS_FILE" # 10. 显示添加结果 inst_msg "公钥已成功添加到 ~/.ssh/authorized_keys" info_msg "添加的公钥:" echo "$PUB_KEY" # 11. 显示统计信息 echo -e "\n----------------------------------------" info_msg "当前 authorized_keys 文件状态:" if [ -f "$AUTH_KEYS_FILE" ]; then local KEY_COUNT KEY_COUNT=$(grep -c -E '^(ssh-|ecdsa-)' "$AUTH_KEYS_FILE" 2>/dev/null || echo "0") info_msg "授权公钥总数: $KEY_COUNT" # 显示最后添加的几个密钥 if [ "$KEY_COUNT" -gt 0 ]; then info_msg "最近添加的公钥:" tail -5 "$AUTH_KEYS_FILE" | while read -r line; do echo " - $(echo "$line" | awk '{print $NF}')" done fi fi echo "----------------------------------------" return 0 } update_config(){ # 备份原始配置文件 cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak # 删除所有冲突的配置项 sed -i -E "/^(#\s*)?(PubkeyAuthentication|PasswordAuthentication|ChallengeResponseAuthentication|UsePAM|PermitRootLogin)/d" /etc/ssh/sshd_config # 添加新的安全配置 echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config echo "PasswordAuthentication no" >> /etc/ssh/sshd_config echo "ChallengeResponseAuthentication no" >> /etc/ssh/sshd_config echo "UsePAM no" >> /etc/ssh/sshd_config echo "PermitRootLogin without-password" >> /etc/ssh/sshd_config # 修改完配置文件后,需要重启 SSH 服务使配置生效 if systemctl restart sshd; then info_msg "SSH服务重启成功" else err_msg "SSH服务重启失败" return 1 fi } print_ssh_config_table() { # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' RESET='\033[0m' # 检查是否有root权限,因为需要读取/etc/ssh/sshd_config if [ "$(id -u)" -ne 0 ]; then echo -e "${RED}错误: 需要root权限运行此脚本。请使用sudo命令。${RESET}" exit 1 fi # 从配置文件获取数据 config_data=$(grep -E "^(PubkeyAuthentication|PasswordAuthentication|ChallengeResponseAuthentication|UsePAM|PermitRootLogin)" /etc/ssh/sshd_config) # 检查是否找到了配置项 if [ -z "$config_data" ]; then echo -e "${RED}错误: 在/etc/ssh/sshd_config中未找到匹配的配置项。${RESET}" exit 1 fi # 计算配置项和值的最大长度 max_key_length=0 max_value_length=0 while IFS= read -r line; do key=$(echo "$line" | awk '{print $1}') value=$(echo "$line" | awk '{print $2}') key_length=${#key} value_length=${#value} if [ $key_length -gt $max_key_length ]; then max_key_length=$key_length fi if [ $value_length -gt $max_value_length ]; then max_value_length=$value_length fi done <<< "$config_data" # 确保列宽足够显示标题 if [ $max_key_length -lt 6 ]; then max_key_length=6 fi if [ $max_value_length -lt 3 ]; then max_value_length=3 fi # 添加一些边距 max_key_length=$((max_key_length + 2)) max_value_length=$((max_value_length + 2)) # 计算表格总宽度 table_width=$((max_key_length + max_value_length + 3)) # 3个竖线 # 生成横线 hline=$(printf '%*s' "$table_width" '' | tr ' ' '-') # 打印表头 echo -e "\n${BLUE}SSH 安全配置信息:${RESET}" echo -e "${BLUE}+${hline}+${RESET}" printf "${YELLOW}| ${BLUE}%-${max_key_length}s${YELLOW} | ${BLUE}%-${max_value_length}s${YELLOW} |${RESET}\n" "配置项" "值" echo -e "${BLUE}+${hline}+${RESET}" # 打印每一行配置 while IFS= read -r line; do key=$(echo "$line" | awk '{print $1}') value=$(echo "$line" | awk '{print $2}') # 根据值设置颜色 if [ "$value" = "yes" ] || [ "$value" = "without-password" ]; then value_color="${GREEN}" else value_color="${RED}" fi # 打印行 printf "${YELLOW}| ${RESET}%-${max_key_length}s${YELLOW}| ${value_color}%-${max_value_length}s${YELLOW}|${RESET}\n" "$key" "$value" done <<< "$config_data" # 打印表尾 echo -e "${BLUE}+${hline}+${RESET}\n" | column -t } restore_root_password_login() { local SSHD_CONFIG="/etc/ssh/sshd_config" local BACKUP_FILE="${SSHD_CONFIG}.backup.$(date +%Y%m%d_%H%M%S)" # 1. 检查文件是否存在 if [ ! -f "$SSHD_CONFIG" ]; then err_msg "SSH 配置文件不存在: $SSHD_CONFIG" return 1 fi # 2. 备份原配置文件 info_msg "备份原配置文件..." if cp "$SSHD_CONFIG" "$BACKUP_FILE"; then inst_msg "配置文件已备份到: $BACKUP_FILE" else err_msg "备份失败,请检查权限" return 1 fi # 3. 显示当前配置 info_msg "当前 SSH 配置状态:" echo "----------------------------------------" grep -E "^(PermitRootLogin|PasswordAuthentication|ChallengeResponseAuthentication)" "$SSHD_CONFIG" | grep -v "^#" || echo "使用默认配置" echo "----------------------------------------" # 4. 修改配置 info_msg "正在修改 SSH 配置..." # 临时文件 local TMP_FILE=$(mktemp) # 处理配置项 cat "$SSHD_CONFIG" | while IFS= read -r line; do # 注释掉现有的相关配置 case "$line" in PermitRootLogin*) echo "# $line # 已禁用,由脚本修改" echo "PermitRootLogin yes" ;; PasswordAuthentication*) echo "# $line # 已禁用,由脚本修改" echo "PasswordAuthentication yes" ;; ChallengeResponseAuthentication*) echo "# $line # 已禁用,由脚本修改" echo "ChallengeResponseAuthentication yes" ;; *) echo "$line" ;; esac done > "$TMP_FILE" # 如果文件中没有这些配置项,则添加 if ! grep -q "^PermitRootLogin" "$TMP_FILE"; then echo "PermitRootLogin yes" >> "$TMP_FILE" fi if ! grep -q "^PasswordAuthentication" "$TMP_FILE"; then echo "PasswordAuthentication yes" >> "$TMP_FILE" fi if ! grep -q "^ChallengeResponseAuthentication" "$TMP_FILE"; then echo "ChallengeResponseAuthentication yes" >> "$TMP_FILE" fi # 5. 验证配置文件语法 info_msg "验证配置文件语法..." if sshd -t -f "$TMP_FILE" 2>/dev/null; then inst_msg "配置文件语法正确" else err_msg "配置文件语法错误,请检查" sshd -t -f "$TMP_FILE" rm -f "$TMP_FILE" return 1 fi # 6. 应用新配置 if cp "$TMP_FILE" "$SSHD_CONFIG"; then chmod 600 "$SSHD_CONFIG" inst_msg "新配置已写入" else err_msg "写入配置文件失败,请检查权限" rm -f "$TMP_FILE" return 1 fi rm -f "$TMP_FILE" # 7. 重启 SSH 服务 info_msg "重启 SSH 服务..." if systemctl restart sshd 2>/dev/null || service sshd restart 2>/dev/null || /etc/init.d/ssh restart 2>/dev/null; then inst_msg "SSH 服务重启成功" else err_msg "SSH 服务重启失败,请手动重启" info_msg "请执行: systemctl restart sshd 或 service sshd restart" fi # 8. 显示修改后的配置 echo -e "\n----------------------------------------" inst_msg "SSH 配置修改完成!" info_msg "修改后的关键配置:" grep -E "^(PermitRootLogin|PasswordAuthentication|ChallengeResponseAuthentication)" "$SSHD_CONFIG" | grep -v "^#" echo "----------------------------------------" # 9. 安全提示 echo -e "\n${YELLOW}⚠ 安全提示:${NC}" echo "1. 已启用 root 密码登录" echo "2. 请确保 root 密码足够复杂" echo "3. 建议使用强密码或定期更换密码" echo "4. 考虑使用 fail2ban 防止暴力破解" echo "5. 如需禁用,可执行: PermitRootLogin no" return 0 } func_ifs(){ if [ $? -eq 0 ]; then info_msg "SSH密钥登录设置成功" # 验证配置 inst_msg "验证配置:" echo -e "公钥认证: $(grep -q '^PubkeyAuthentication yes' /etc/ssh/sshd_config && echo -e "${GREEN}已启用${RESET}" || echo -e "${RED}未启用${RESET}")" echo -e "密码认证: $(grep -q '^PasswordAuthentication no' /etc/ssh/sshd_config && echo -e "${GREEN}已禁用${RESET}" || echo -e "${RED}未禁用${RESET}")" exit 0 else err_msg "SSH密钥登录设置失败" # 恢复备份 mv /etc/ssh/sshd_config.bak /etc/ssh/sshd_config systemctl restart sshd err_msg "已恢复原始SSH配置" exit 127 fi } echo -e "\n配置菜单: \n1、配置免密登录并禁用root登录\n2、配置免密登录不禁用root登录\n3、恢复ssh root登录\n4、不配置退出" read -r -p "选择配置[1-3]: " USERADDNAME if [ -z "${USERADDNAME}" ]; then err_msg "错误: 选择不能为空" exit 1 fi # 检查输入是否为数字 if ! [[ "${USERADDNAME}" =~ ^[0-9]+$ ]]; then err_msg "错误: 请输入数字(1-3)" exit 1 fi case "${USERADDNAME}" in 1) # 配置免密登录并禁用root登录 inst_msg "执行选项1: 配置免密登录并禁用root登录" # 这里调用你的函数 # create_sshd # update_config # print_ssh_config_table # func_ifs info_msg "正在配置免密登录并禁用root登录..." # 实际执行代码... ;; 2) # 配置免密登录不禁用root登录 inst_msg "执行选项2: 配置免密登录不禁用root登录" echo "请粘贴 id_rsa 私钥内容(支持多行),按两次 Ctrl+D 结束输入:" info_msg "提示: 粘贴以 '-----BEGIN OPENSSH PRIVATE KEY-----' 开头的内容" # 读取多行私钥 ID_RSANAME=$(cat) if [ -z "${ID_RSANAME}" ]; then err_msg "错误: 私钥内容不能为空" exit 1 fi # 验证私钥基本格式 if ! echo "${ID_RSANAME}" | grep -q "BEGIN.*PRIVATE KEY"; then echo -e "\n" info_msg "警告: 未检测到标准私钥开头标记,但继续处理..." fi echo -e "\n" info_msg "私钥已接收,长度: ${#ID_RSANAME} 字符" # 确保 ~/.ssh 目录存在 mkdir -p ~/.ssh chmod 700 ~/.ssh # 检查私钥文件是否存在 if [ -f ~/.ssh/id_rsa ]; then read -r -p "~/.ssh/id_rsa 文件已存在,是否替换它? [y/N]: " YES_RSA if [ -z "${YES_RSA}" ]; then YES_RSA="n" # 默认为不替换 fi if [[ "${YES_RSA}" =~ ^[Yy]$ ]]; then # 备份原文件 BACKUP_FILE="$HOME/.ssh/id_rsa.backup.$(date +%Y%m%d%H%M%S)" cp ~/.ssh/id_rsa "${BACKUP_FILE}" info_msg "原文件已备份到: ${BACKUP_FILE}" # 写入新私钥 echo "${ID_RSANAME}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa inst_msg "私钥文件已替换" # 可选: 生成公钥 # info_msg "正在生成公钥..." # ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub 2>/dev/null # if [ $? -eq 0 ]; then # inst_msg "公钥已生成: ~/.ssh/id_rsa.pub" # else # err_msg "警告: 公钥生成失败,请检查私钥格式" # fi else inst_msg "未替换私钥文件" exit 0 fi else # 文件不存在,直接创建 echo "${ID_RSANAME}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa inst_msg "私钥文件已创建: ~/.ssh/id_rsa" # 生成公钥 # info_msg "正在生成公钥..." # ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub 2>/dev/null # if [ $? -eq 0 ]; then # inst_msg "公钥已生成: ~/.ssh/id_rsa.pub" # else # err_msg "警告: 公钥生成失败,请检查私钥格式" # fi fi # 测试私钥有效性 info_msg "测试私钥有效性..." ssh-keygen -l -f ~/.ssh/id_rsa >/dev/null 2>&1 if [ $? -eq 0 ]; then inst_msg "私钥格式有效" else err_msg "警告: 私钥格式可能无效" fi create_sshd ;; 3) restore_root_password_login ;; 4) # 不配置退出 inst_msg "用户选择退出,即将退出!" exit 0 ;; *) err_msg "错误: 无效的选择,请输入 1、2、3、4" exit 1 ;; esac # 可选: 显示配置结果 echo -e "\n===============================" info_msg "配置完成!" if [ -f ~/.ssh/id_rsa ]; then info_msg "私钥文件: ~/.ssh/id_rsa" info_msg "权限: $(ls -l ~/.ssh/id_rsa | awk '{print $1}')" # 显示密钥指纹 if command -v ssh-keygen >/dev/null 2>&1; then info_msg "密钥指纹:" ssh-keygen -l -f ~/.ssh/id_rsa 2>/dev/null || err_msg "无法获取密钥指纹" fi fi echo "==============================="bash update_keygen.sh
2026年01月23日
0 阅读
0 评论
0 点赞
1
2