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.

大功告成。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM