通过ansible分发免密公钥、清理不再使用的公钥及验证公钥状态

1.分发公钥 :ansible使用authorized_key模块分发ansible控制机上的ssh公钥,文件是/root/.ssh/id_rsa.pub 公钥,分发到远端节点的authorized_keys 文件中,实现免密登录。

复制代码
---
- name: 为jenkins组节点配置root用户免密SSH登录
  hosts: jenkins  # 匹配inventory中jenkins组的节点
  remote_user: root  # 远程执行用户(建议用有sudo权限的普通用户,更安全)
  gather_facts: false  # 无需收集节点信息,加快执行速度
  tasks:
    - name: 将控制节点的公钥添加到目标节点root用户的authorized_keys
      ansible.builtin.authorized_key:
        user: root  # 目标节点的用户(要配置免密的用户)
        state: present  # 确保公钥存在(默认值,可省略)
        key: "{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"  # 读取控制节点的公钥文件
        exclusive: false  # 不删除其他已存在的公钥(重要,避免误删)
        manage_dir: true  # 自动创建.ssh目录并设置正确权限(700)
参数 作用 注意事项
hosts: jenkins 指定要执行的目标节点组(需在 Ansible inventory 文件中定义 jenkins 组) 确保 inventory 中 jenkins 组包含正确的节点 IP / 主机名
remote_user: root 远程登录目标节点的用户 生产环境建议用普通用户(如 ansible)+ sudo,避免直接用 root
authorized_key Ansible 内置模块,用于管理 SSH 授权密钥 比手动拷贝更安全,自动处理权限问题
user: root 目标节点上要配置免密的用户(这里是 root) 若要给普通用户配置,改为对应用户名(如 jenkins)
key: "{``{ lookup('file', ...) }}" 读取控制节点本地的公钥文件内容 确保控制节点存在/root/.ssh/id_rsa.pub文件,若不存在先执行ssh-keygen -t rsa生成
manage_dir: true 自动创建目标用户的~/.ssh 目录,权限设为 700 避免因目录不存在或权限错误导致免密失败
exclusive: false 保留目标节点已有的其他公钥 若设为 true,会删除该用户所有其他公钥,极其危险!

2.删除不再使用的公钥,通过ansible实现批量清理特定免密登录权限的目的

复制代码
---
- name: 从目标节点移除指定的SSH公钥
  hosts: jenkins  # 匹配两个组的所有节点
  become: yes  # 提权到root(确保有修改/root/.ssh的权限)
  gather_facts: false  # 无需收集节点信息,加快执行速度
  tasks:
    - name: 移除root用户下指定的SSH公钥
      ansible.builtin.authorized_key:
        user: root  # 目标用户(要清理公钥的用户)
        state: absent  # 标记为移除(核心参数)
        key: "ssh-rsa AAAAB3NzaC1yc2EddddBAQDAUvIWgBHxszilFFjKoAuHwSioRcvYTXPdm5o1kNlkb0P+hfu8IuQhzGUUqYOXAFk7d+PKF4FUVijYF52Mw2N/jG12SvzAKbJpAfXFYX3Y4Dpaq0wqEBnj4c2nXhySv3vfOOev+Cq0AYj8mvt0F0JPfQC5Qml4OfQDfH73p4ml2o83vVrlJVF9M6wUK7uRVGC8U2qTc9gddddddVT/Yy8dmx1sgdJxhkjVvNa60X29OsNw4s3jH5UIo5fIn/r1Up0Li+CkdLHGzLJWCiTe3vcZPLEEs4QCdddXuiC42LtVygoiUUVx test01"
        manage_dir: false  # 移除公钥时无需管理.ssh目录(避免误改目录权限)

3.更换公钥场景,可通过先添加新的,在移除老的,具体如下

复制代码
---
- name: 更新root用户的SSH公钥(先加新再删旧)
  hosts: 目标组名  # 替换为你的节点组
  become: yes
  gather_facts: false
  vars:
    # 定义旧公钥(要移除的)和新公钥(要添加的)
    old_ssh_key: "ssh-rsa AAAAB3NzaC1ycdddddAAABAQDAUvIWgBHxszilFFjKoAuHwSioRcvYTXPdm5o1kNlkb0P+hfu8IuQhzGUUqYOXAFk7d+PKF4FUVijYF52Mw2N/jG12SvzAKbJpAfXFYX3Y4Dpaq0wqvL8i8l0EBnj4c2nXhySv3vfOOev+Cq0AYj8mvt0F0JPfQC5Qml4OfQDfH73p4mdddd9M6wUK7uRVGC8U2qTc9gYFdrRuySyZodBVT/Yy8dmx1sgdJxhkjVvNa60X29OsNw4s3jH5UIo5fIn/r1Up0Li+CkdLHGzLJWCiTe3vcZPLEEs4QCheZMBE6siuim7nXuiC42LtVyddddfff test01"
    new_ssh_key: "{{ lookup('file', '/root/.ssh/new_id_rsa.pub') }}"  # 读取控制节点的新公钥文件
  tasks:
    - name: 第一步:添加新公钥
      ansible.builtin.authorized_key:
        user: root
        state: present
        key: "{{ new_ssh_key }}"
        manage_dir: true  # 自动创建/修复.ssh目录权限
        exclusive: false  # 保留其他已存在的公钥
    - name: 第二步:移除旧公钥
      ansible.builtin.authorized_key:
        user: root
        state: absent
        key: "{{ old_ssh_key }}"
        manage_dir: false  # 移除时无需管理目录

4.节点组的公钥状态,看是否添加或者删除

复制代码
---
- name: 批量验证SSH公钥更新结果
  hosts: jenkins  # 替换为你的目标节点组
  become: yes
  gather_facts: false
  vars:
    # 配置需要验证的关键信息
    old_ssh_key_comment: "test01"  # 旧公钥的注释(用于快速检索)
    new_ssh_key: "{{ lookup('file', '/root/.ssh/new_id_rsa.pub') }}"  # 新公钥内容
    new_ssh_key_fingerprint: "{{ new_ssh_key | regex_replace('ssh-rsa (.*) .*', '\\1') | hash('sha256') | regex_replace('^', 'SHA256:') }}"  # 自动生成新公钥指纹

  tasks:
    - name: 步骤1:检查旧公钥是否已移除
      ansible.builtin.shell: |
        grep -q "{{ old_ssh_key_comment }}" /root/.ssh/authorized_keys && echo "旧公钥未移除" || echo "旧公钥已移除"
      register: old_key_check
      changed_when: false  # 标记为非变更操作

    - name: 步骤2:检查新公钥是否已添加
      ansible.builtin.shell: |
        grep -q "{{ new_ssh_key }}" /root/.ssh/authorized_keys && echo "新公钥已添加" || echo "新公钥未添加"
      register: new_key_check
      changed_when: false

    - name: 步骤3:验证.ssh目录和文件权限(SSH强制要求)
      ansible.builtin.stat:
        path: "{{ item.path }}"
        get_checksum: false
      register: file_perm_check
      loop:
        - { path: "/root/.ssh", mode: "0700" }
        - { path: "/root/.ssh/authorized_keys", mode: "0600" }

    - name: 输出验证结果(汇总)
      ansible.builtin.debug:
        msg: |
          节点 {{ inventory_hostname }} 验证结果:
          1. 旧公钥状态:{{ old_key_check.stdout }}
          2. 新公钥状态:{{ new_key_check.stdout }}
          3. .ssh目录权限:{{ file_perm_check.results[0].stat.mode }} (预期:0700)
          4. authorized_keys权限:{{ file_perm_check.results[1].stat.mode }} (预期:0600)
          5. 新公钥指纹:{{ new_ssh_key_fingerprint }}
相关推荐
Apipi*6 小时前
30天速通Linux 第六章信号及信号处理
linux·运维·信号处理
天启HTTP7 小时前
爬虫防封核心原理:IP轮换机制与风控规避逻辑
linux·服务器·网络·爬虫·tcp/ip
运维行者_7 小时前
网络性能监控怎么做?从自动发现到根因分析的4个环节
运维·服务器·网络·人工智能·支持向量机
hz567899 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
广州浮点FLOATLIC9 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
优橙教育9 小时前
零基础学AI应用开发要多久?3个月能到什么水平
服务器·开发语言·网络·php
BLUcoding9 小时前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom
AIgorithmGEEK9 小时前
[Linux]从手写报头到内核套路:序列化、反序列化与自定义协议全链路
linux·运维·服务器·网络·序列化·反序列化
Nil20810 小时前
leetcode 139单词拆分
linux·运维·服务器
Starry-sky(jing)10 小时前
BUG: unable to handle kernel paging request 完整排查:dmesg 四要素与三路定罪
linux·运维·服务器·内核·排障