介绍
Ava 更换了工作室旧笔记本电脑。两台准备好的主机仍接受旧设备密钥,以及她当前和备用的密钥。只移除旧设备授权,同时保留账户与原始笔记。
这个独立单元以前一实验“为同事开通访问”中的用户、公钥、lookup 和循环练习为基础。它有自己的训练密钥和预建账户,不继承上一 VM 的文件或连接。
移除一把旧设备密钥
本步骤将在两台工作室主机撤销 Ava 的旧设备密钥,证明新连接被拒绝,并保留当前钥、备用钥和原有工作。
本单元有自己的全新环境。Ava 已在两台目标拥有账户和工作。每个账户当前接受三把训练密钥:当前、备用和旧设备。你只移除旧授权。删除密钥会阻止用它进行新的认证,不会终止已经认证的连接。本实验测试新连接,不宣称终止已有会话。
打开 Controller 并进入项目目录。若误切换目录,这条命令也可恢复:
cd /home/labex/project
阅读准备好的输入和客户端别名:
cat approved-staff.json
cat clients.conf
批准的课程账户是 studio_ava。待撤销密钥为 training-keys/ava-old.pub;training-keys/ava.pub 和 training-keys/ava-backup.pub 继续获准。以 .pub 结尾的是公钥,对应私钥保留在训练客户端。别名选择主机、用户和确切密钥。-F clients.conf 使用这份固定了信任的项目配置;每次 ssh 调用都建立新连接。保持清单、客户端设置、主机信任与训练密钥不变。
修改访问之前,先观察正常行为。单引号内,远端 shell 先运行 id,再运行 cat,二者以分号分隔:
ssh -F clients.conf web1-ava 'id -un; cat work/briefing.txt'
ssh -F clients.conf web2-ava 'id -un; cat work/briefing.txt'
两处身份都是 studio_ava,但 Riverside 与 Hill 笔记不同。也验证备用钥:
ssh -F clients.conf web1-ava-backup 'id -un'
ssh -F clients.conf web2-ava-backup 'id -un'
此时旧设备仍被接受:
ssh -F clients.conf web1-ava-old 'id -un'
ssh -F clients.conf web2-ava-old 'id -un'
仅从“待添加密钥列表”删除一把钥匙,并不等于请求移除它。用空添加列表安全观察这个差别。here-document 写入整个控制端文件:> 替换该文件,带引号的 YAML 防止 shell 展开。结束分隔符须单独位于一行开头。若 shell 因缺少结束分隔符仍在等待,按 Ctrl+C 取消未完成输入,再从正常提示符重跑完整块。[] 是空 YAML 列表,对它循环时没有可执行的条目。
cat > additions.yml <<'YAML'
- name: Add listed keys without removing other grants
hosts: all
become: true
gather_facts: false
vars:
keys_to_add: []
tasks:
- name: Add a listed key
ansible.posix.authorized_key:
user: studio_ava
key: "{{ lookup('file', item) }}"
state: present
loop: "{{ keys_to_add }}"
YAML
ansible-playbook additions.yml
两台主机均跳过密钥任务,未发生变更。该任务并没有检查所有可能授权并移除列表之外的密钥。旧设备仍能连接:
ssh -F clients.conf web1-ava-old 'id -un'
现在表达真正的撤销。group_vars/all.yml 把这份列表提供给两台清单主机,不会改动准备好的批准文件。每个对象指定课程用户和控制端公钥路径。若文件块有误,重跑即可替换那个控制端文件,不需要重置 VM。
cat > group_vars/all.yml <<'YAML'
revoked_keys:
- name: studio_ava
key_file: training-keys/ava-old.pub
YAML
使用已教过的密钥模块及 state: absent,只移除此钥,保留账户和其他授权。循环处理列出的每项撤销。双花括号解析当前条目,lookup 读取控制端公钥。collection 已为本项目离线安装。不要使用独占替换、删除主目录、锁定密码或修改平台 SSH 服务。
cat > revoke.yml <<'YAML'
- name: Revoke only the approved old device keys
hosts: all
become: true
gather_facts: false
tasks:
- name: Remove each listed old public key
ansible.posix.authorized_key:
user: "{{ item.name }}"
key: "{{ lookup('file', item.key_file) }}"
state: absent
loop: "{{ revoked_keys }}"
YAML
检查语法。若有 YAML 错误,读指定行,与完整块比较缩进和引号,只重写对应控制端文件。
ansible-playbook revoke.yml --syntax-check
这些账户已经存在,因此受支持的 check mode 可以预测移除密钥。--diff 会在输出显示公钥行,本次预览不需要这些内容。使用 --check:
ansible-playbook revoke.yml --check
两台主机都应预测有变更。check mode 尚未撤销真实授权。现在应用:
ansible-playbook revoke.yml
两台主机都须没有不可达或失败任务。接下来的两次连接预期失败,显示 Permission denied (publickey),退出状态为 255:
ssh -F clients.conf web1-ava-old 'id -un'
ssh -F clients.conf web2-ava-old 'id -un'
超时、连接被拒绝或主机密钥警告不能证明撤销。服务器必须仍可用,获准密钥必须仍有效。用当前钥和备用钥建立新连接,读取两个原始文件:
ssh -F clients.conf web1-ava 'id -un; cat work/briefing.txt'
ssh -F clients.conf web2-ava 'id -un; cat work/briefing.txt'
ssh -F clients.conf web1-ava-backup 'id -un; cat work/briefing.txt'
ssh -F clients.conf web2-ava-backup 'id -un; cat work/briefing.txt'
四次都须以 studio_ava 成功登录,显示对应原始笔记。保留文件字节、所有者和模式 0640;账户主目录/工作目录保持 0750,.ssh 保持 0700,authorized_keys 保持 0600。文件属于 studio_ava 及其主组。已有密钥模块会保留这些准备好的安全权限。
重复实际声明,再运行预测:
ansible-playbook revoke.yml
ansible-playbook revoke.yml --check
两行摘要均应为 changed=0、unreachable=0、failed=0。正确撤销是对实际授权的选择性修改,而非仅有成功摘要或空控制端列表。若选错密钥路径,先修正控制端数据;用之前教过的 state: present 恢复误删的合法钥,再重新应用正确的定向移除。不要通过清空整个密钥文件或将它设为所有人可写来恢复。
总结
你区分了省略添加与显式撤销,用 state absent 移除一项公钥授权,验证了真实的新连接拒绝,并保留当前/备用登录及两个原始工作文件。原样声明收敛,没有不必要的变更。



