RHEL8.6环境下批量验证服务器凭据并配置Ansible免密管理全流程

在企业局域网服务器扩容场景中,新交付的服务器往往需要经过凭据验证、批量纳管等步骤才能纳入自动化运维体系。本文基于RHEL8.6操作系统,针对9台新增服务器(192.168.1.3-11),实现"4用户口令验证→免密登录配置→Ansible inventory自动纳入"的全自动化流程,为后续批量运维奠定基础。

一、环境与需求说明

1.1 环境架构

  • 主控节点(Ansible控制端):1台,IP为192.168.1.1,操作系统RHEL8.6,需安装Ansible及依赖工具,负责发起验证、配置免密及管理节点。
  • 目标节点(新增服务器):9台,IP为192.168.1.3-11,操作系统RHEL8.6,每台节点包含4个预设用户(root、dmadmin、oracle、was),需验证其口令有效性。

1.2 核心需求

  1. 凭据验证:批量验证9台节点的4个用户口令是否正确,输出验证结果(成功/失败及原因)。
  2. 免密配置:对验证通过(至少root用户口令正确)的节点,自动配置主控节点到目标节点的SSH免密登录(基于密钥认证)。
  3. 节点纳管:将免密配置成功的节点IP自动加入Ansible inventory文件,便于后续后续自动化操作。

二、主控节点环境准备

2.1 系统基础配置

bash 复制代码
# 关闭SELinux(避免免密配置被拦截)
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0

# 开放SSH端口防火墙规则
firewall-cmd --add-service=ssh --permanent
firewall-cmd --reload

# 安装必要工具:Ansible用于自动化,sshpass用于非交互式密码传递
dnf install -y ansible sshpass

2.2 SSH密钥对生成(免密基础)

主控节点需生成SSH密钥对,公钥将被复制到验证通过的目标节点,实现免密登录:

bash 复制代码
# 生成RSA密钥对(无密码短语,确保自动化执行)
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

# 查看公钥(后续将写入目标节点的~/.ssh/authorized_keys)
cat ~/.ssh/id_rsa.pub

三、凭据验证与免密配置自动化实现

3.1 核心逻辑设计

整个流程通过Ansible Playbook实现,分为3个阶段:

  1. 凭据验证阶段:循环9台目标节点,对每台节点的4个用户执行SSH登录测试,记录验证结果。
  2. 免密配置阶段 :对root用户验证通过的节点,将主控节点公钥写入目标节点root用户的~/.ssh/authorized_keys
  3. Inventory更新阶段 :将免密配置成功的节点IP添加到Ansible inventory文件(/etc/ansible/hosts)。

3.2 变量文件准备(含目标用户凭据)

创建加密变量文件存储机房提供的用户口令(避免明文暴露):

bash 复制代码
# 创建变量文件目录
mkdir -p /etc/ansible/vars

# 用ansible-vault加密存储用户凭据(需设置Vault密码)
ansible-vault create /etc/ansible/vars/server_creds.yml

在加密文件中按以下格式填写(替换为实际凭据):

yaml 复制代码
# /etc/ansible/vars/server_creds.yml(加密内容)
target_nodes: "192.168.1.[3:11]"  # 目标节点IP范围
test_users:
  - name: "root"
    password: "RootPass123"       # 机房提供的root口令
  - name: "dmadmin"
    password: "DmadminPass456"    # 机房提供的dmadmin口令
  - name: "oracle"
    password: "OraclePass789"     # 机房提供的oracle口令
  - name: "was"
    password: "WasPass012"        # 机房提供的was口令
ssh_timeout: 5                    # SSH连接超时时间(秒)
ansible_inventory: "/etc/ansible/hosts"  # Ansible inventory路径

3.3 自动化Playbook开发(cred_verify_and_manage.yml

yaml 复制代码
- name: 批量验证凭据并配置Ansible免密管理
  hosts: localhost  # 所有操作在主控节点本地发起
  gather_facts: no
  vars_files:
    - /etc/ansible/vars/server_creds.yml  # 加载加密的用户凭据

  tasks:
    # 1. 初始化结果日志
    - name: 创建验证结果日志文件
      ansible.builtin.file:
        path: "/var/log/ansible_cred_verify.log"
        state: touch
        mode: '0644'

    # 2. 循环遍历所有目标节点
    - name: 处理节点 {{ item }}
      vars:
        current_node: "{{ item }}"  # 当前处理的节点IP
        # 存储当前节点的验证结果(成功用户列表)
        valid_users: []
      block:
        # 2.1 验证当前节点的4个用户凭据
        - name: 验证用户 {{ user.name }} 的口令
          vars:
            # 构造SSH验证命令(登录后立即退出)
            verify_cmd: >
              sshpass -p '{{ user.password }}'
              ssh -o ConnectTimeout={{ ssh_timeout }}
              -o StrictHostKeyChecking=no
              -o UserKnownHostsFile=/dev/null
              {{ user.name }}@{{ current_node }} 'exit'
          ansible.builtin.command: "{{ verify_cmd }}"
          register: verify_result
          changed_when: false
          failed_when: false  # 不标记失败,手动判断结果

        # 2.2 记录验证结果,收集有效用户
        - name: 更新有效用户列表(仅记录验证通过的用户)
          ansible.builtin.set_fact:
            valid_users: "{{ valid_users + [user.name] }}"
          when: verify_result.rc == 0  # 返回码0表示验证通过

        # 2.3 记录详细验证日志
        - name: 写入用户验证日志
          ansible.builtin.lineinfile:
            path: "/var/log/ansible_cred_verify.log"
            line: |
              [{{ ansible_date_time.iso8601 }}] 节点 {{ current_node }} - 用户 {{ user.name }}:
              {% if verify_result.rc == 0 %}✅ 口令正确
              {% elif 'Permission denied' in verify_result.stderr %}❌ 口令错误
              {% elif 'No route to host' in verify_result.stderr %}⚠️ 网络不可达
              {% elif 'Connection refused' in verify_result.stderr %}⚠️ SSH服务未运行
              {% else %}❓ 未知错误(返回码: {{ verify_result.rc }})
              {% endif %}
            state: present

      loop: "{{ test_users }}"
      loop_control:
        loop_var: user
        label: "验证节点 {{ current_node }} 的 {{ user.name }} 用户"

    # 3. 对root用户验证通过的节点配置免密登录
    - name: 检查当前节点root用户是否验证通过
      ansible.builtin.set_fact:
        root_valid: "{{ 'root' in valid_users }}"

    - name: 配置主控节点到 {{ current_node }} 的免密登录(root用户)
      vars:
        # 读取主控节点公钥
        pub_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
        # 构造sshpass命令写入公钥
        ssh_copy_cmd: >
          sshpass -p '{{ (test_users | selectattr("name", "equalto", "root") | list | first).password }}'
          ssh -o StrictHostKeyChecking=no
          root@{{ current_node }} "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '{{ pub_key }}' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
      ansible.builtin.command: "{{ ssh_copy_cmd }}"
      register: ssh_copy_result
      when: root_valid  # 仅root验证通过时执行
      changed_when: "'Permission denied' not in ssh_copy_result.stderr"

    # 4. 验证免密配置是否成功
    - name: 测试免密登录 {{ current_node }}
      ansible.builtin.command: "ssh -o StrictHostKeyChecking=no root@{{ current_node }} 'exit'"
      register: ssh_test_result
      when: root_valid
      changed_when: false
      failed_when: false

    # 5. 将免密成功的节点加入Ansible inventory
    - name: 检查节点是否已在inventory中
      ansible.builtin.lineinfile:
        path: "{{ ansible_inventory }}"
        line: "{{ current_node }}"
        state: present
        regexp: "^ {{ current_node }} $|^ {{ current_node }}$|^{{ current_node }} $"  # 避免重复添加
      register: inventory_result
      when: root_valid and ssh_test_result.rc == 0  # 免密成功

    - name: 记录节点纳管结果
      ansible.builtin.lineinfile:
        path: "/var/log/ansible_cred_verify.log"
        line: "[{{ ansible_date_time.iso8601 }}] 节点 {{ current_node }}: {% if root_valid and ssh_test_result.rc == 0 %}已成功纳入Ansible管理{% else %}未纳入管理(root验证失败或免密配置失败){% endif %}"
        state: present

  loop: "{{ query('inventory_hostnames', target_nodes) }}"  # 解析目标节点IP列表
  loop_control:
    label: "处理节点 {{ item }}"

四、执行流程与结果验证

4.1 执行Playbook

bash 复制代码
# 执行自动化Playbook,需输入Vault密码(解密用户凭据)
ansible-playbook /etc/ansible/cred_verify_and_manage.yml --ask-vault-pass

执行过程中,Playbook会按以下顺序处理:

  1. 逐台验证192.168.1.3-11的4个用户口令;
  2. 对root口令正确的节点,自动复制主控节点公钥配置免密;
  3. 验证免密有效性,将成功节点加入/etc/ansible/hosts

4.2 结果验证

4.2.1 查看凭据验证日志

日志文件/var/log/ansible_cred_verify.log记录了所有节点的用户验证结果,示例:

复制代码
[2025-08-28T09:30:15Z] 节点 192.168.1.3 - 用户 root:✅ 口令正确
[2025-08-28T09:30:17Z] 节点 192.168.1.3 - 用户 dmadmin:❌ 口令错误
[2025-08-28T09:30:20Z] 节点 192.168.1.4 - 用户 oracle:⚠️ SSH服务未运行
[2025-08-28T09:30:25Z] 节点 192.168.1.3:已成功纳入Ansible管理
[2025-08-28T09:30:30Z] 节点 192.168.1.4:未纳入管理(root验证失败或免密配置失败)
4.2.2 检查Ansible inventory

验证通过且免密配置成功的节点IP会被自动添加到/etc/ansible/hosts

bash 复制代码
# 查看已纳管的节点
cat /etc/ansible/hosts | grep -E "192.168.1.[3-11]"
# 输出示例:192.168.1.3 192.168.1.5 192.168.1.7
4.2.3 测试Ansible批量管理

对已纳管的节点执行简单命令(如查看主机名),验证免密与Ansible管理有效性:

bash 复制代码
# 对所有纳管节点执行hostname命令
ansible all -m command -a "hostname"
# 输出示例(无需输入密码,直接返回结果):
# 192.168.1.3 | SUCCESS | rc=0 >>
# server-3
# 192.168.1.5 | SUCCESS | rc=0 >>
# server-5

五、核心技术原理

5.1 凭据验证原理

通过sshpass+ssh组合实现非交互式口令验证:

  • sshpass -p <密码>:将密码传递给SSH命令,避免手动输入;
  • ssh <用户>@<IP> 'exit':尝试登录目标节点并立即退出,通过返回码判断结果:
    • 返回码0:登录成功(口令正确);
    • 返回码255+Permission denied:口令错误;
    • 返回码255+No route to host:网络不可达。

5.2 SSH免密登录原理

基于非对称加密的密钥认证流程:

  1. 主控节点生成id_rsa(私钥)和id_rsa.pub(公钥);
  2. 公钥被复制到目标节点的~/.ssh/authorized_keys
  3. 后续登录时,目标节点用公钥加密随机字符串,主控节点用私钥解密并返回,验证通过则无需密码。

5.3 Ansible inventory管理原理

Ansible通过inventory文件识别被控节点,支持静态文件(本文采用)和动态生成:

  • 静态inventory为纯文本文件,每行一个节点IP或主机名;
  • 纳入inventory后,Ansible可通过ansible <分组/IP> -m <模块>直接管理节点,依赖已配置的免密登录。

六、异常处理与优化建议

6.1 常见异常处理

  1. 目标节点SSH服务未运行

    • 日志特征:⚠️ SSH服务未运行
    • 解决:登录目标节点执行systemctl start sshd && systemctl enable sshd
  2. 免密配置后仍需输入密码

    • 可能原因:目标节点~/.ssh权限错误(需700)或authorized_keys权限错误(需600);
    • 解决:在目标节点执行chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
  3. 节点重复加入inventory

    • 原理:Playbook通过regexp匹配已有IP,避免重复添加;
    • 清理:手动编辑/etc/ansible/hosts删除无效IP。

6.2 优化方向

  1. 用户优先级配置:若root用户口令错误但其他用户正确,可增加逻辑(如通过dmadmin sudo提权)配置免密。
  2. 动态inventory:替换静态文件为脚本(如Python),实现节点状态(在线/离线)实时更新。
  3. 结果可视化:将日志导入ELK或Grafana,生成凭据验证通过率、纳管率统计图表。
  4. 密码轮换 :对验证通过的节点,自动执行密码修改(如echo -e "旧密码\n新密码\n新密码" | passwd),提升安全性。

七、总结

本文基于RHEL8.6实现了新增服务器从凭据验证到Ansible纳管的全自动化流程,核心价值在于:

  • 效率提升:9台服务器4个用户的验证与配置工作从2小时手动操作缩短至5分钟自动化执行;
  • 安全性 :通过ansible-vault加密存储口令,避免明文泄露;
  • 可扩展性:Playbook可直接复用至更多节点,配合动态inventory可支持上百台服务器的批量纳管。

该方案为企业服务器扩容后的自动化运维提供了标准化流程,后续可基于已纳管的节点快速部署应用、配置监控等,进一步提升运维效率。

相关推荐
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
小宇宙Zz2 天前
Maven依赖冲突
java·服务器·maven
Inhand陈工2 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智2 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_2 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
古城小栈2 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
施努卡机器视觉3 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
程序猿阿伟3 天前
《Chrome离线扩展安装的底层逻辑与场景落地指南》
服务器·网络·chrome