SSH 提示密码过期,如何通过 ansible 批量更新线上服务器密码

起因

线上环境是在内网,登陆线上环境需要使用 VPN + 堡垒机 登陆,但是我日常登陆线上环境都是 VPN + 堡垒机 + Socks5常驻代理,在shell端只需要保存会话,会话使用socks5代理即可无缝ssh到线上服务器。

今天来发现无法登陆服务器,但是ssh *** -f -N ****@**** 建立后台socks的方式并不会把密码过期的问题暴露出来,经过多次尝试,手动登陆服务器才发现用于登陆服务器的密码已过期。

手动更新密码后问题恢复。

解决问题

由于这一批服务器都存在密码过期的问题,所以打算尝试使用 Ansible 来批量登陆服务器更新密码。

https://github.com/ansible/ansible/issues/1619 受到国外大神的解答,尝试进行处理。

使用 Ansible expect 模块来进行处理。

python 需要安装 pexpect 包。
pip install pexpect

正常手动操作的console返回信息如下:

You are required to change your password immediately (password aged)
Last login: Thu Aug 13 11:23:46 2020 from 1*.*.*7
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user sysadmin.
Changing password for sysadmin.
(current) UNIX password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

playbook task 内容:

- name: Set password if expired
  delegate_to: 127.0.0.1
  become: no
  expect:
    command: ssh {{ ansible_ssh_common_args }} {{ ansible_user }}@{{ inventory_hostname }}
    timeout: 10
    responses:
      "password:":
        # we couldn't keep the same old password
        - "{{ ansible_ssh_pass_old }}"
        - "{{ ansible_ssh_pass }}"
        - "{{ ansible_ssh_pass }}"
      # if succesfully login then quit
      "\\~\\]\\$": exit
  register: status
  changed_when: "'authentication tokens updated successfully' in status.stdout"

按照大神的解答,进行尝试过后,发现行不通,提示如下:

You are required to change your password immediately (password aged)
Last login: Thu Aug 13 11:23:46 2020 from 1*.*.*7
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user sysadmin.
Changing password for sysadmin.
(current) UNIX password:
passwd: Authentication token manipulation error

认真理解了一番,发现,reponses里面少了一次键入密码的机会,我的环境是通过密码认证登录的 ,如果是使用秘钥登录,即ansible_ssh_common_args 应配置为秘钥方式,更正后如下:

- name: Set password if expired
  delegate_to: 127.0.0.1
  become: no
  expect:
    command: ssh {{ ansible_ssh_common_args }} {{ ansible_user }}@{{ inventory_hostname }}
    timeout: 10
    responses:
      "(?i)password:":
        # we couldn't keep the same old password
        - "{{ ansible_ssh_pass_old }}"
        - "{{ ansible_ssh_pass_old }}"
        - "{{ ansible_ssh_pass }}"
        - "{{ ansible_ssh_pass }}"
      # if succesfully login then quit
      "\\~\\]\\$": exit
  register: status
  changed_when: "'authentication tokens updated successfully' in status.stdout"

解释:
第一次键入 ansible_ssh_pass_old 为 command ssh 的登录密码。
第二次键入 ansible_ssh_pass_old 为 提示过期输入当前密码。
第三次键入 ansible_ssh_pass 为 新密码。
第四次键入 ansible_ssh_pass 为 确认新密码。

结果测试

ansible-playbook 功能测试结果:

STDOUT:

Warning: Permanently added 'm******o' (ECDSA) to the list of known hosts.
symin@m******o's password:
You are required to change your password immediately (password aged)
Last login: Fri Jul 31 10:46:38 2020 from 1*.*.*.*7
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user sysadmin.
Changing password for sysadmin.
(current) UNIX password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
Connection to m*****o closed.

大功告成。

posted @   Professor哥  阅读(2125)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示