SSH 免密是自动化运维的基础,Ansible远程管控、脚本自动执行都得靠它。用大白话讲清免密核心原理,拆解3个核心步骤,内容极简、好懂、能直接用。
一、SSH 免密核心原理
SSH 免密靠非对称加密,全程无明文密码传输,控制端Rsync(172.16.0.61)免密控制被控制端NFS/DataBase(172.16.0.41),核心就3点:
- 控制端生成密钥对:私钥(id_rsa)留本地,相当于「个人身份证」,绝不能泄露;公钥(id_rsa.pub)可公开,相当于「免密授权函」。
- 把控制端的公钥,放到被控制端的「免密白名单」(/root/.ssh/authorized_keys)里。
- 控制端连被控制端时,用私钥做身份验证,被控制端用白名单里的公钥验证,匹配上就直接连接,不用输密码。
二、你的实战Playbook
实现172.16.0.61 免密控制 172.16.0.41的极简Playbook,也是我个人环境的写法,重复执行不报错:
- name: 实现SSH免密登录
hosts: 172.16.0.61 # 控制端(生成密钥的机器)
remote_user: root
tasks:
# 步骤1:控制端生成密钥对,已存在则跳过
- name: 生成密钥
command: ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa
args:
creates: /root/.ssh/id_rsa
# 步骤2:读取控制端公钥,注册为变量
- name: 读取公钥
slurp:
src: /root/.ssh/id_rsa.pub
register: id_rsa_pub
# 步骤3:把公钥写入被控制端41的免密白名单
- name: 免密控制41
authorized_key:
user: root
key: "{{ id_rsa_pub.content | b64decode }}"
delegate_to: 172.16.0.41
三、3 步拆解:每一步做什么?为什么这么做?
步骤 1:控制端生成密钥对
核心作用:给控制端生成「身份证+授权函」,命令ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa:
-t rsa:用最常用的 RSA 加密算法,安全又兼容;-N "":密钥无密码,自动化场景必须加,否则会弹窗输密码中断任务;creates: /root/.ssh/id_rsa:关键!如果密钥已存在,直接跳过,避免重复生成提示覆盖文件。
执行结果:控制端/root/.ssh/下生成 2 个文件 ——id_rsa(私钥,权限 600,严禁泄露)、id_rsa.pub(公钥,可自由传输)。
步骤 2:读取公钥并注册变量
核心作用:把公钥内容读出来,供后续步骤使用。
- 用
slurp模块而非简单的cat命令:自动对内容做Base64编码,跨机传输不丢内容、无编码问题; register: id_rsa_pub:把编码后的公钥存到变量里,后续直接调用就行。
步骤 3:写入被控制端免密白名单
核心作用:把控制端的「授权函」,放到被控制端41的白名单里,实现免密。
authorized_key:Ansible专用管理免密白名单的模块,自动校验公钥格式,避免重复写入,比手动敲命令安全;{{ id_rsa_pub.content | b64decode }}:把步骤2编码的公钥解码为原始内容,正常写入白名单;delegate_to: 172.16.0.41:核心指令!把这个任务的执行目标,从控制端61切换到被控制端41,不用手动登录41操作;user: root:公钥写入41服务器root用户的白名单,控制端后续以root身份免密连接41。
四、一键验证:免密是否生效?
在控制端61执行以下命令,不用输密码就能连接41,说明配置成功: 运行
ssh root@172.16.0.41
五、快速扩展:一键免密多台服务器
如果需要同时免密41、31,只需把步骤3改成遍历IP,一行搞定多台:
- name: 免密控制多台服务器
authorized_key:
user: root
key: "{{ id_rsa_pub.content | b64decode }}"
delegate_to: "{{ item }}"
with_items:
- 172.16.0.41
- 172.16.0.31
总结
- SSH免密核心:控制端生密钥对,公钥写入被控制端的 /root/.ssh/authorized_keys;
- Ansible实现3步:生成密钥→读取公钥→写入远端白名单,全程自动化,重复执行不报错;
- 关键要点:
creates防重复生成、slurp保公钥完整、delegate_to切执行目标,这是生产环境规范写法。