ansible playbook批量改ssh配置文件,遠程用戶Permission denied


 最近手里的數百台服務器需要改/etc/ssh/sshd_config的參數,禁止root直接登陸,也就是說

[root@t0 ~]# cat /etc/ssh/sshd_config | grep Root
#PermitRootLogin yes

得改成

[root@t1 ~]# cat /etc/ssh/sshd_config| grep ^PermitRoot
PermitRootLogin no

一台台登上去改簡直要死,ansible自動化運維工具聽說還不錯,之前就會用命令直接使用shell模塊執行sed 替換配置文件里面的參數

[root@t0 ansible]# ansible all -b --become-method=su --become-user=root -m shell -a "sed 's/PermitRootLogin yes/PermitRootLogin no/g' /etc/ssh/sshd_config" | grep -E "Root|10.0"
 [WARNING]: Consider using the replace, lineinfile or template module rather than running sed.  If you need to use
command because replace, lineinfile or template is insufficient you can add warn=False to this command task or set
command_warnings=False in ansible.cfg to get rid of this message.
10.0.0.52 | CHANGED | rc=0 >>
#    $OpenBSD: sshd_config,v 1.93 2014/01/10 05:59:19 djm Exp $
PermitRootLogin no
# the setting of "PermitRootLogin without-password".
10.0.0.53 | CHANGED | rc=0 >>
#    $OpenBSD: sshd_config,v 1.93 2014/01/10 05:59:19 djm Exp $
PermitRootLogin no
# the setting of "PermitRootLogin without-password".

大概看個效果,這樣做不僅效率低,而且你不能保證每台服務器的配置文件都是

#PermitRootLogin yes

也有可能是PermitRootLogin yes

所以不一定能達到自己的要求

然后根據提示信息,我看到了
replace, lineinfile template這三個模塊
感興趣的朋友可以自行研究一下
我今天用的是playbook用正則表達式匹配要更改的項
首先自己寫一個playbook
[root@t0 playbook]# cat change_ssh.yml 
---
- hosts: test
  gather_facts: false
#  become: yes
#  become_method: su
  remote_user: root
  tasks:
  - name: "change file"
    lineinfile:
      path: /etc/ssh/sshd_config
      regexp: '^PermitRootLogin'
      line: 'PermitRootLogin yes'
      state: present
#    notify: restart sshd
#      handlers:
#        - name: restart sshd
#            service: name=sshd state=restarted
 
        

之前寫的是沒有注釋的那些,注釋的內容是我后來加上去的,待會再解釋注釋的意思

然后我的hosts文件

[root@t0 playbook]# cat ../hosts 
#[localhost]
#127.0.0.1
[test]
10.0.0.52
10.0.0.53
[test:vars]
ansible_ssh_pass=123456
ansible_ssh_user=test
ansible_become_pass=123456

執行以下命令

[root@t0 playbook]# ansible-playbook change_ssh.yml 

PLAY [test] ************************************************************************************************************

TASK [change file] *****************************************************************************************************
fatal: [10.0.0.53]: FAILED! => {"changed": false, "module_stderr": "Shared connection to 10.0.0.53 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n  File \"/home/test/.ansible/tmp/ansible-tmp-1555555638.07-154814815296297/AnsiballZ_lineinfile.py\", line 113, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/test/.ansible/tmp/ansible-tmp-1555555638.07-154814815296297/AnsiballZ_lineinfile.py\", line 105, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/home/test/.ansible/tmp/ansible-tmp-1555555638.07-154814815296297/AnsiballZ_lineinfile.py\", line 48, in invoke_module\r\n    imp.load_module('__main__', mod, module, MOD_DESC)\r\n  File \"/tmp/ansible_lineinfile_payload_1q9ATP/__main__.py\", line 524, in <module>\r\n  File \"/tmp/ansible_lineinfile_payload_1q9ATP/__main__.py\", line 515, in main\r\n  File \"/tmp/ansible_lineinfile_payload_1q9ATP/__main__.py\", line 257, in present\r\nIOError: [Errno 13] Permission denied: '/etc/ssh/sshd_config'\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
fatal: [10.0.0.52]: FAILED! => {"changed": false, "module_stderr": "Shared connection to 10.0.0.52 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n  File \"/home/test/.ansible/tmp/ansible-tmp-1555555638.06-7599860498373/AnsiballZ_lineinfile.py\", line 113, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/test/.ansible/tmp/ansible-tmp-1555555638.06-7599860498373/AnsiballZ_lineinfile.py\", line 105, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/home/test/.ansible/tmp/ansible-tmp-1555555638.06-7599860498373/AnsiballZ_lineinfile.py\", line 48, in invoke_module\r\n    imp.load_module('__main__', mod, module, MOD_DESC)\r\n  File \"/tmp/ansible_lineinfile_payload_5xlcxo/__main__.py\", line 524, in <module>\r\n  File \"/tmp/ansible_lineinfile_payload_5xlcxo/__main__.py\", line 515, in main\r\n  File \"/tmp/ansible_lineinfile_payload_5xlcxo/__main__.py\", line 257, in present\r\nIOError: [Errno 13] Permission denied: '/etc/ssh/sshd_config'\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
    to retry, use: --limit @/etc/ansible/playbook/change_ssh.retry

PLAY RECAP *************************************************************************************************************
10.0.0.52                  : ok=0    changed=0    unreachable=0    failed=1   
10.0.0.53                  : ok=0    changed=0    unreachable=0    failed=1   

結果是失敗的,根據報錯信息

IOError: [Errno 13] Permission denied: '/etc/ssh/sshd_config'

懷疑是權限的問題,因為根據我的hosts文件,默認是普通用戶test去執行,所以在playbook里面加上兩行

#  become: yes
#  become_method: su

意思就是,我ansible遠程操作的時候,用戶使用的時管理員的權限,然后再次執行

[root@t0 playbook]# ansible-playbook change_ssh.yml 

PLAY [test] ************************************************************************************************************

TASK [change file] *****************************************************************************************************
changed: [10.0.0.52]
changed: [10.0.0.53]

PLAY RECAP *************************************************************************************************************
10.0.0.52                  : ok=1    changed=1    unreachable=0    failed=0   
10.0.0.53                  : ok=1    changed=1    unreachable=0    failed=0   

查看遠程主機的配置文件

[root@t1 ~]# cat /etc/ssh/sshd_config| grep ^PermitRoot
PermitRootLogin no

說明已經改成功了,但是如果配置文件有其他的設置,我們還需要其他的正則,而且sshd的配置文件改完之后需要重啟才能生效,所以需要一個觸發器,playbook需要做一下調整

---
#- hosts: 'test:!c2'
- hosts: c2
#- hosts: "`hosts`" gather_facts: false become: yes become_method: su remote_user: root tasks: - name: 'change sshd_config' lineinfile: dest: /etc/ssh/sshd_config regexp: "{{ item.regexp }}" line: "{{ item.line }}" state: present with_items: #In this way # - { regexp: "^#PermitRootLogin yes",line: "PermitRootLogin no" } #or # - regexp: "^#PermitRootLogin yes" # line: "PermitRootLogin no" #Both methods have the same effect - { regexp: "PermitRootLogin yes",line: "PermitRootLogin no" } notify: restart sshd handlers: - name: restart sshd service: name=sshd state=restarted

 

 

總結:1. ansible如果hosts文件寫的ansible_user時普通用戶的時候,遠程操作需要管理員權限,需要become的

  become: yes
  become_method: su

或者是

  become: yes
  become_method: sudo
  remote_user: test

   2. 執行完操作之后,利用觸發器notify重啟sshd服務

  3. 需要繼續學習,謝謝


免責聲明!

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



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