在企业运维场景中,局域网内多台服务器的SSH登录凭据(用户名/密码)验证是高频需求——无论是新服务器部署后的凭据校验,还是定期安全巡检中的凭据有效性检查,手动逐台逐用户测试不仅效率低下,还容易出错。

  • 本文将从技术原理出发,详解如何通过Shell+Expect实现9台服务器(IP段192.168.1.3-11)、4个用户(root/dmadmin/oracle/was) 的SSH登录批量测试,并提供可直接落地的优化脚本与使用指南。

一、核心技术原理:为什么用Shell+Expect?

要实现SSH登录的批量自动化测试,需解决两个核心问题:非交互式输入密码批量循环调度。这正是Shell与Expect工具的协作优势所在:

1.1 Shell:批量调度的“总指挥”

Shell(本文使用Bash)作为Linux默认命令行解释器,负责:

  • 批量生成目标服务器IP:通过循环自动生成192.168.1.3至192.168.1.11的IP列表,无需手动逐个填写;
  • 多用户循环遍历:按顺序调度root、dmadmin、oracle、was四个用户的测试任务;
  • 日志输出管理:创建带时间戳的日志文件,统一记录每台服务器、每个用户的测试结果;
  • 依赖检查与错误处理:提前校验Expect工具是否安装、用户与密码配置是否匹配,避免脚本中途崩溃。

1.2 Expect:非交互式登录的“执行者”

SSH登录默认需要手动输入密码,而Expect是一款专门处理交互式命令的工具,其核心能力是:

  • 模拟用户输入:通过send命令自动发送密码,替代手动敲击键盘;
  • 精准匹配交互场景:通过expect命令监听SSH登录过程中的关键提示(如password:Permission denied),触发对应操作;
  • 超时控制:设置固定超时时间(如5秒),避免因网络故障导致脚本卡死。

举个简单的Expect交互逻辑示例(模拟单用户SSH登录):

# 启动SSH连接
spawn ssh user@192.168.1.3 exit
# 监听密码提示,发送密码
expect "*password:*" { send "user_password\r" }
# 监听登录结果,判断是否成功
expect {"*Permission denied*" { exit 1 }  # 密码错误eof { exit 0 }                    # 登录成功
}

1.3 整体协作流程

  1. Shell初始化配置(IP段、用户列表、密码、日志路径);
  2. Shell检查依赖(Expect是否安装)和配置合法性(用户与密码数量是否匹配);
  3. Shell循环生成目标服务器IP,对每台服务器执行下一步;
  4. 对当前服务器,Shell循环遍历4个用户,调用Expect脚本;
  5. Expect模拟SSH登录,返回结果码给Shell;
  6. Shell根据结果码判断登录状态(成功/密码错误/网络超时等),并写入日志;
  7. 所有服务器和用户测试完成后,Shell输出总结信息。

二、批量测试脚本实现:优化版代码详解

基于上述原理,我们设计了支持“IP自动生成+多用户循环+详细日志”的优化脚本。以下是完整代码及关键模块解析:

2.1 完整脚本代码

#!/bin/bash
##############################################################################
# 脚本名称:ssh_multi_user_batch_test.sh
# 功能描述:批量测试局域网内多服务器多用户的SSH登录凭据有效性
# 测试范围:IP段 192.168.1.3-11(共9台),用户 root/dmadmin/oracle/was
# 输出日志:带时间戳的log文件(如 ssh_login_test_20250826_163000.log)
############################################################################### ========================== 配置参数(需根据实际环境修改)==========================
BASE_IP="192.168.1."       # IP前三位(局域网统一前缀)
START_SUFFIX=3             # IP最后一位起始值(含)
END_SUFFIX=11              # IP最后一位结束值(含)
USERS=("root" "dmadmin" "oracle" "was")  # 需测试的用户列表
# 对应用户的密码(顺序必须与USERS数组一致!)
PASSWORDS=("your_root_password"    # root用户实际密码"your_dmadmin_password" # dmadmin用户实际密码"your_oracle_password"  # oracle用户实际密码"your_was_password"     # was用户实际密码
)
LOG_FILE="ssh_login_test_$(date +%Y%m%d_%H%M%S).log"  # 日志文件(带时间戳)
TIMEOUT=5                  # SSH连接超时时间(秒),建议5-10秒
# ==================================================================================# ========================== 初始化日志与前置检查 ==========================
# 1. 初始化日志文件,写入测试摘要
echo "==================================== 多用户SSH登录批量测试报告 ===================================" > "$LOG_FILE"
echo "测试启动时间:$(date +'%Y-%m-%d %H:%M:%S')" >> "$LOG_FILE"
echo "测试IP范围:${BASE_IP}${START_SUFFIX} ~ ${BASE_IP}${END_SUFFIX}(共$((END_SUFFIX - START_SUFFIX + 1))台服务器)" >> "$LOG_FILE"
echo "测试用户列表:${USERS[*]}" >> "$LOG_FILE"
echo "连接超时时间:${TIMEOUT}秒" >> "$LOG_FILE"
echo "==================================================================================================" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"# 2. 检查用户与密码数组长度是否一致(避免配置错误)
if [ ${#USERS[@]} -ne ${#PASSWORDS[@]} ]; thenecho "【错误】用户列表与密码列表长度不匹配!请检查USERS和PASSWORDS配置" | tee -a "$LOG_FILE"exit 1
fi# 3. 检查Expect工具是否安装(脚本依赖)
if ! command -v expect &> /dev/null; thenecho "【错误】未检测到expect工具,脚本无法运行!" | tee -a "$LOG_FILE"echo "       请先安装expect:" | tee -a "$LOG_FILE"echo "       - CentOS/RHEL:sudo yum install expect -y" | tee -a "$LOG_FILE"echo "       - Debian/Ubuntu:sudo apt install expect -y" | tee -a "$LOG_FILE"exit 1
fi# 4. 自动生成服务器IP列表(从START_SUFFIX到END_SUFFIX)
SERVERS=()
for ((i=START_SUFFIX; i<=END_SUFFIX; i++)); doSERVERS+=("${BASE_IP}${i}")
done
echo "【信息】已生成服务器列表:${SERVERS[*]}" | tee -a "$LOG_FILE"
echo "【信息】开始批量测试(每台服务器测试${#USERS[@]}个用户)..." | tee -a "$LOG_FILE"
echo "------------------------------------------------------------------------------------------" >> "$LOG_FILE"
echo ""# ========================== 核心测试逻辑:循环测试服务器与用户 ==========================
for server in "${SERVERS[@]}"; do# 打印当前测试的服务器信息(控制台+日志)echo -e "\n=== 正在测试服务器:$server ==="echo -e "=== 测试服务器:$server ===" >> "$LOG_FILE"# 对当前服务器,循环测试所有用户for index in "${!USERS[@]}"; douser=${USERS[$index]}       # 当前测试用户password=${PASSWORDS[$index]} # 当前用户密码echo -n "  → 测试用户 $user@$server:"# 调用Expect执行非交互式SSH登录测试(核心模块)# 说明:-o StrictHostKeyChecking=no 跳过主机密钥检查;-o UserKnownHostsFile=/dev/null 不写入known_hostsexpect -c "set timeout $TIMEOUT  # 设置超时时间spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $user@$server exitexpect {# 场景1:出现密码提示,发送密码\"*assword:*\" {send \"$password\r\"expect {# 子场景1.1:密码错误(Permission denied/Authentication failed){*Permission denied*} { exit 1 }{*Authentication failed*} { exit 1 }# 子场景1.2:登录成功(退出SSH,获取eof)eof { exit 0 }}}# 场景2:网络不可达(No route to host)\"*No route to host*\" { exit 2 }# 场景3:SSH服务未启动(Connection refused)\"*Connection refused*\" { exit 3 }# 场景4:连接超时timeout { exit 4 }# 场景5:其他未知错误default { exit 99 }}"# 捕获Expect返回的结果码,判断测试结果result_code=$?case $result_code in0)result="登录成功"echo -e "\033[32m$result\033[0m"  # 绿色输出成功信息;;1)result="登录失败(用户名或密码错误)"echo -e "\033[31m$result\033[0m"  # 红色输出失败信息;;2)result="网络错误(无法到达主机,可能是IP错误或路由问题)"echo -e "\033[33m$result\033[0m"  # 黄色输出警告信息;;3)result="连接被拒绝(目标服务器SSH服务未启动或端口被占用)"echo -e "\033[33m$result\033[0m";;4)result="连接超时(超过${TIMEOUT}秒,可能是网络延迟或防火墙拦截)"echo -e "\033[33m$result\033[0m";;*)result="未知错误(返回码:$result_code)"echo -e "\033[31m$result\033[0m";;esac# 将结果写入日志(带时间戳)echo "  $(date +'%H:%M:%S') - $user@$server$result" >> "$LOG_FILE"done# 服务器测试结束,写入分隔符echo -e "=== 服务器 $server 测试完成 ==="echo "------------------------------------------------------------------------------------------" >> "$LOG_FILE"
done# ========================== 测试完成总结 ==========================
echo -e "\n【信息】所有服务器测试完成!"
echo "" >> "$LOG_FILE"
echo "==================================== 测试总结 ===================================" >> "$LOG_FILE"
echo "测试结束时间:$(date +'%Y-%m-%d %H:%M:%S')" >> "$LOG_FILE"
echo "测试服务器总数:$((END_SUFFIX - START_SUFFIX + 1))台" >> "$LOG_FILE"
echo "测试用户总数:${#USERS[@]}个" >> "$LOG_FILE"
echo "测试结果日志:$(pwd)/$LOG_FILE" >> "$LOG_FILE"
echo "==================================================================================" >> "$LOG_FILE"echo "【信息】测试结果已保存至日志文件:$(pwd)/$LOG_FILE"

2.2 关键模块解析

(1)配置参数模块:灵活适配实际环境

脚本开头的配置参数部分是核心可修改区域,需根据局域网环境调整:

  • BASE_IP:局域网IP统一前缀(如192.168.0.或10.0.5.);
  • START_SUFFIX/END_SUFFIX:IP最后一位的范围(本文3-11,共9台服务器);
  • USERS/PASSWORDS:需测试的用户列表与对应密码(顺序必须严格一致,避免密码错乱);
  • TIMEOUT:超时时间(建议5-10秒,太短易误判,太长影响效率)。
(2)前置检查模块:规避脚本运行风险
  • 用户密码匹配检查:通过${#USERS[@]} -ne ${#PASSWORDS[@]}判断数组长度是否一致,避免“用户多密码少”或“密码多用户少”的配置错误;
  • Expect依赖检查:通过command -v expect判断工具是否安装,若未安装则输出对应系统的安装命令,降低运维门槛。
(3)IP自动生成模块:减少手动配置

通过for ((i=START_SUFFIX; i<=END_SUFFIX; i++))循环,自动生成192.168.1.3至192.168.1.11的IP列表,无需手动填写9个IP,尤其适合IP段连续的场景。

(4)Expect交互模块:精准处理登录场景

这是脚本的核心,通过expect -c "..."嵌入Expect脚本,覆盖5种常见场景:

  1. 密码提示:监听*password:*(兼容大小写,如Password:),发送密码;
  2. 密码错误:匹配Permission deniedAuthentication failed,返回码1;
  3. 网络不可达:匹配No route to host,返回码2;
  4. SSH服务未启动:匹配Connection refused,返回码3;
  5. 连接超时:超过TIMEOUT时间无响应,返回码4。
(5)结果输出模块:控制台+日志双记录
  • 控制台输出:用颜色区分结果(绿色成功、红色失败、黄色警告),便于实时查看;
  • 日志输出:写入带时间戳的log文件,包含测试摘要、每台服务器每个用户的详细结果、总结信息,便于后续追溯和问题定位。

三、脚本使用指南:从部署到执行

3.1 环境准备

脚本需在Linux系统(如CentOS 7/8、Ubuntu 20.04+)上运行,且需满足:

  1. 安装Expect工具
    • CentOS/RHEL:sudo yum install expect -y
    • Debian/Ubuntu:sudo apt install expect -y
  2. 执行用户权限:无需root权限,但需确保执行用户可正常调用sshexpect命令;
  3. 网络连通性:执行脚本的机器需能ping通目标服务器(192.168.1.3-11),且目标服务器开放22端口(SSH默认端口)。

3.2 脚本部署与修改

  1. 创建脚本文件
    vi ssh_multi_user_batch_test.sh
    
  2. 粘贴完整代码:将上文的脚本代码复制粘贴到文件中;
  3. 修改配置参数:重点修改PASSWORDS数组中的密码(替换为实际凭据),并确认BASE_IP是否与局域网匹配。

3.3 执行脚本与查看结果

  1. 赋予执行权限
    chmod +x ssh_multi_user_batch_test.sh
    
  2. 执行脚本
    ./ssh_multi_user_batch_test.sh
    
  3. 实时查看进度:控制台会按“服务器→用户”的顺序输出测试结果,颜色区分状态(绿色成功、红色失败);
  4. 查看日志文件:测试完成后,当前目录会生成带时间戳的log文件(如ssh_login_test_20250826_163000.log),可通过catless查看详细结果:
    cat ssh_login_test_20250826_163000.log
    

四、常见问题与优化建议

4.1 常见问题排查

  1. “用户列表与密码列表长度不匹配”

    • 原因:USERS数组和PASSWORDS数组元素数量不一致;
    • 解决:检查两个数组,确保每个用户对应一个密码(顺序一致)。
  2. “连接被拒绝”

    • 原因:目标服务器SSH服务未启动(systemctl status sshd查看),或22端口被防火墙拦截;
    • 解决:在目标服务器执行systemctl start sshd启动服务,或开放22端口(firewall-cmd --add-port=22/tcp --permanent)。
  3. “连接超时”

    • 原因:目标服务器IP错误、网络路由不通,或防火墙拦截ICMP/SSH流量;
    • 解决:先通过ping 192.168.1.3测试网络连通性,再通过telnet 192.168.1.3 22测试端口是否开放。

4.2 脚本优化方向

  1. 支持自定义SSH端口:若目标服务器SSH端口非22,可在spawn ssh命令中添加-p 端口号,并新增SSH_PORT配置参数;
  2. 密码加密存储:当前脚本密码明文存储存在安全风险,可通过openssl加密密码,脚本运行时解密(需额外配置密钥);
  3. 并行测试:当前脚本按顺序测试服务器,可通过xargs -P&实现并行测试,提升效率(适合服务器数量多的场景);
  4. 结果统计:在日志总结中增加“成功次数/失败次数/错误类型统计”,便于快速掌握整体情况。

五、总结

本文通过“原理讲解→脚本实现→使用指南”的逻辑,详细介绍了局域网多服务器多用户SSH登录批量测试的技术方案。核心是利用Shell的批量调度能力和Expect的非交互式处理能力,解决了手动测试效率低、易出错的痛点。

脚本已针对“IP段192.168.1.3-11+4个用户”的场景优化,只需修改配置参数即可直接落地。同时,文中提供的问题排查和优化方向,也为后续扩展功能提供了思路,适合企业运维人员日常使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/94672.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/94672.shtml
英文地址,请注明出处:http://en.pswp.cn/web/94672.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

专题:2025人工智能2.0智能体驱动ERP、生成式AI经济现状落地报告|附400+份报告PDF、原数据表汇总下载

原文链接&#xff1a;https://tecdat.cn/?p43713 2025年&#xff0c;人工智能正从技术概念快速渗透到产业实操层面——大模型推理能力的突破让复杂任务自动化成为可能&#xff0c;AI代理的规模化应用重构企业效率边界&#xff0c;而AI企业“天生全球化”的特性更是打破了传统创…

机器学习--支持向量机

目录 一、为什么需要 SVM&#xff1f;先解决 “怎么分才好” 的问题 二、SVM 的核心&#xff1a;什么是 “最好的超平面”&#xff1f;用 “间隔” 说话 1. 先搞懂两个关键概念 2. 目标&#xff1a;把 “间隔” 拉到最大 三、从 “想要最大间隔” 到 “解数学问题”&#…

Multi-output Classification and Multi-label Classification|多输出分类和多标签分类

----------------------------------------------------------------------------------------------- 这是我在我的网站中截取的文章&#xff0c;有更多的文章欢迎来访问我自己的博客网站rn.berlinlian.cn&#xff0c;这里还有很多有关计算机的知识&#xff0c;欢迎进行留言或…

【目标检测】论文阅读5

Small-object detection based on YOLOv5 in autonomous driving systems 发表期刊&#xff1a;Pattern Recognition Letters&#xff1b;发表时间&#xff1a;2023年 论文地址 摘要 随着自动驾驶领域的快速发展&#xff0c;对更快、更准确的目标检测框架的需求已经成为必要。…

Playwright进阶指南 (6) | 自动化测试实战

2025企业级测试解决方案&#xff1a;从单测到千级并发&#xff0c;打造高可用测试体系一、为什么传统自动化测试难以落地&#xff1f;根据2025年最新行业调研&#xff0c;测试项目失败的三大核心原因&#xff1a;失败原因占比典型表现维护成本过高45%选择器频繁失效&#xff0c…

uv 简单使用

二进制安装 powershell -ExecutionPolicy Bypass -c "irm https://ghproxy.cn/https://github.com/astral-sh/uv/releases/download/0.8.13/uv-installer.ps1 | iex"版本号&#xff1a;0.8.13&#xff0c;自行更改github加速前缀&#xff1a;https://ghproxy.cn/ 配置…

Linux程序管理

目录 一、Linux程序与进程 1、程序,进程,线程的概念 2、程序和进程的区别 3、进程和线程的区别 二、Linux进程基础(生命周期) 1、进程生命周期 2、父子进程的关系 三、程序管理 1、课程目标 2、常见的软件包类型 3、安装方法 使用独立的rpm包安装 rpm包的命名方法…

Linux-进程替换exec

文章目录进程替换exec 函数族使用说明查看命令的路径 which测试 execl测试 execlp测试 execv测试 execvp进程替换 概述 在 Windows 平台下&#xff0c;我们可以通过双击运行可执行程序&#xff0c;让这个可执行程序成为一个进程&#xff1b;而在 Linux 平台&#xff0c;我们可…

Seaborn数据可视化实战:Seaborn数据可视化实战入门

Seaborn数据可视化实战&#xff1a;从数据到图表的完整旅程 学习目标 通过本课程的学习&#xff0c;你将能够掌握使用Seaborn进行数据可视化的完整流程&#xff0c;从数据准备到图表设计&#xff0c;再到最终的图表呈现。本课程将通过一个具体的项目案例&#xff0c;帮助你全面…

控制系统仿真之时域分析(二)

一、时域分析法时域分析法是从传递函数出发直接在时域上研究控制系统性能的方法&#xff0c;实质上是研究系统在某典型输入信号下随时间变化的曲线&#xff0c;从而分析系统性能。控制系统的时域响应决定于系统本身的参数和结构&#xff0c;还有系统的初始状态&#xff0c;以及…

PDF 表单创建与分发

PDF 表单是一种交互式文档&#xff0c;允许用户填写信息、做出选择并提交数据。与静态 PDF 不同&#xff0c;PDF 表单包含可交互的字段元素&#xff0c;如文本框、复选框、单选按钮等。#mermaid-svg-sZe9We4UG0yKymyl {font-family:"trebuchet ms",verdana,arial,san…

Guava 简介:让 Java 开发更高效

Guava 简介&#xff1a;让 Java 开发更高效 Guava 是由 Google 开源的 Java 库&#xff0c;旨在为开发者提供一系列实用的工具类&#xff0c;以提高开发效率。它包含了集合类、缓存、并发工具、字符串处理等实用方法。 Guava 的常用场景 集合处理&#xff1a;Guava 提供了多种扩…

「ECG信号处理——(24)基于ECG和EEG信号的多模态融合疲劳分析」2025年8月23日

目录 一、引言 二、核心原理 2.1 心电 HRV 疲劳关联原理 2.2 脑电 EEG 疲劳关联原理 2.3 疲劳综合指数 三、数据处理流程 四、结果展示与分析 参考文献 一、引言 针对作业安全&#xff08;如驾驶、精密操作&#xff09;场景下的疲劳状态实时监测需求&#xff0c;本文提…

EXCEL自动调整列宽适应A4 A3 A2

Public xlPaperA2%Sub 填满页面排版()xlPaperA2 66 A2编号66Dim ws As Worksheet: Set ws ActiveSheetDim FirstCol As Long, LastCol As Long, LastRow As LongDim TargetRange As RangeDim UsablePageWidth As DoubleDim CurrentWidth As DoubleDim StartFontSize As Doubl…

Linux系统性能优化全攻略:从CPU到网络的全方位监控与诊断

引言 在Linux系统运维和开发过程中&#xff0c;系统性能优化是一个永恒的话题。无论是服务器负载过高&#xff0c;还是应用程序响应缓慢&#xff0c;准确快速地定位问题根源至关重要。本文将全面介绍Linux系统中常用的性能诊断工具和方法&#xff0c;帮助您从CPU、内存、磁盘I/…

uniapp+vue+uCharts开发常见问题汇总

项目结构&#xff1a;uniapp vue2 uni-ui uCharts 1、chunk-vendors.js:2765[Vue warn]: Invalid prop: custom validator check failed for prop "navigationBarTextStyle". 检索发现原因&#xff1a; 在 pages.json 文件中&#xff0c;navigationBarTextStyle 属…

【甲烷数据集】EPA-美国2012-2020年网格化甲烷清单

目录 数据概述 数据特征 数据版本与年份 排放源类型(示例) 时间变化处理 数据下载 参考 根据美国环保署(EPA)官网 《U.S. Gridded Methane Emissions》页面 的内容,以下是对 美国网格化甲烷清单(Gridded Methane GHGI) 的详细介绍。 数据概述 EPA-U.S. Gridded Methan…

【温室气体数据集】NOAA CCGG 飞机观测温室气体

目录 数据集概述 采样方式 测量气体 数据用途 观测站点 NOAA CCGG 飞机观测站点信息 项目特色 数据访问 参考 NOAA 全球监测实验室(Global Monitoring Laboratory, GML)提供的 Carbon Cycle Greenhouse Gases Aircraft Program 数据集是一个关于温室气体在大气中垂直分布的观…

FreeRTOS,互斥量 (Mutex)

1. 信号量 (Semaphore) 通俗理解&#xff1a;信号量就像停车场的空位计数器。当有车进入时&#xff0c;计数器减1&#xff1b;当有车离开时&#xff0c;计数器加1。如果计数器为0&#xff0c;新车必须等待直到有空位。 #include "FreeRTOS.h" #include "semphr.…

SQL查询-设置局部变量(PostgreSQL、MySQL)

&#x1f60b;博主在工作中编写复杂SQL语句时&#xff0c;经常需要替换查询值进行测试。所以需要用到局部变量设置&#xff0c;可以减轻测试时的压力。 目录使用场景1.常规写法2.局部变量写法&#xff08;1&#xff09;PostgreSQL示例注意事项&#xff08;2&#xff09;MySQL示…