TSALVIA技術メモ

CTFのWriteupや気になったツールについて書いていきます。また、このサイトはGoogle Analyticsを利用しています。

Ansibleでパスワードを一括変更する(Linux編)

はじめに

2019年7月4日、5日に開催されたHardening II SUという大会に参加してきました。

wasforum.jp

大会の中で、大量のユーザ(最低100アカウント)のパスワードを短時間で変更しなければならない機会がありました。 Ansibleを使えば、複数のPCのユーザを一括で変更することができます。 今回は、Andibleを使ったLinux系のPCのユーザを一括で変更する方法について紹介します。

環境構築

検証環境

f:id:tsalvia:20190708013840p:plain

Ansibleをインストールする

  1. Ansibleをインストールする
    $ sudo apt-get install ansible
    
  2. インストール完了確認
    $ ansible --version
    ansible 2.2.1.0
      config file = /etc/ansble/ansble.cfg
      configured module search path = Default w/o overrides
    

※ オフラインでインストールしたい場合は、下記のページを参考にしてください。

tsalvia.hatenablog.com

制御対象のPCに疎通確認をする

  1. Ansibleで管理するクライアントを登録する。
    今回は、linuxというグループ名で登録する。
    $ vi hosts
    [linux]
    192.168.10.2 ansible_ssh_user='{{ srv1[1].name }}' ansible_ssh_pass='{{ srv1[1].password }}' ansible_become_pass='{{ srv1[0].password }}'
    192.168.10.3 ansible_ssh_user='{{ srv2[1].name }}' ansible_ssh_pass='{{ srv2[1].password }}' ansible_become_pass='{{ srv2[0].password }}'
    
  2. パスワードリストを作成する。
    ansible-vault コマンドを使って作成すれば、パスワードを暗号化することができる。
    $ ansible-vault create current_user_password.yml
    srv1:
      # Become User
      - name: root
        password: P@ssw0rd1
      # Login User
      - name: user1
        password: P@ssw0rd1
      # Other Users
      - name: user2
        password: P@ssw0rd1
      - name: user3
        password: P@ssw0rd1
      - name: user4
        password: P@ssw0rd1
      - name: user5
        password: P@ssw0rd1
      - name: user6
        password: P@ssw0rd1
      - name: user7
        password: P@ssw0rd1
      - name: user8
        password: P@ssw0rd1
      - name: user9
        password: P@ssw0rd1
    srv2:
      # Become User
      - name: root
        password: P@ssw0rd1
      # Login User
      - name: user1
        password: P@ssw0rd1
      # Other Users
      - name: user2
        password: P@ssw0rd1
      - name: user3
        password: P@ssw0rd1
      - name: user4
        password: P@ssw0rd1
      - name: user5
        password: P@ssw0rd1
      - name: user6
        password: P@ssw0rd1
      - name: user7
        password: P@ssw0rd1
      - name: user8
        password: P@ssw0rd1
      - name: user9
        password: P@ssw0rd1
    
  3. linuxグループに登録したクライアント全体にPingを送信する。
    $ ansible -i hosts linux -m ping --ask-vault-pass -e@current_user_password.yml
    192.168.10.2 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    192.168.10.3 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    

パスワードを一括変更する

  1. 新パスワード用のパスワードリストを作成する。
    ansible-vault コマンドを使って作成すれば、パスワードを暗号化することができる。
    $ ansible-vault create new_user_password.yml
    new_srv1:
      # Become User
      - name: root
        password: HvXGiYp843fH
      # Login User
      - name: user1
        password: iddxgw4UPWHV
      # Other Users
      - name: user2
        password: LfNRawjwdWFz
      - name: user3
        password: qyWfmgYBNE4h
      - name: user4
        password: u7E6JV9GJrsa
      - name: user5
        password: ew85Uji6hJbY
      - name: user6
        password: 5qumZFn9Bfdr
      - name: user7
        password: ra9ampz3Khur
      - name: user8
        password: FqV7fKsSzfKC
      - name: user9
        password: zv2Ld32zFJBM
    new_srv2:
      # Become User
      - name: root
        password: thdEMxG5hFLY
      # Login User
      - name: user1
        password: QXDpkbJdZh4K
      # Other Users
      - name: user2
        password: t7JQmQFwbWFx
      - name: user3
        password: qRuPadS9sLTN
      - name: user4
        password: U8QHRabhjdyQ
      - name: user5
        password: XGLGvX8h9z22
      - name: user6
        password: BLrDZfcCWVSU
      - name: user7
        password: S6sYCFDe9Y66
      - name: user8
        password: Rf2i4zJ3AhU7
      - name: user9
        password: kj6hQUjFnheN
    
  2. パスワード変更用のPlaybookを作成する。
    • パスワード変更手順
      1. rootのパスワードだけ変更する。
      2. becomeで権限を変更する際に使用するパスワードを新しいパスワードに置き換える。
      3. root以外のユーザのパスワードを変更する。
    • 各キーの意味
      • become:yesにすると、権限を変更してくれる。
      • become_method:権限変更のメソッドを選択する(su もしくは sudo)
      • no_log:yesにすると、変更されたパスワードがログに残らないようになる。
      • vars_files:外部ファイル(パスワードリスト)を指定する。
      • user:ユーザの管理ができる
      • set_fact:fact(ansible_xxx形式のもの)値の書換えができる
    $ vi change_password.yml
    - hosts: 192.168.10.2
      become: yes
      become_method: su
      no_log: yes
      vars_files:
        - new_user_password.yml
      tasks:
        - name: change root's password
          user:
            name: "{{ new_srv1[0].name }}"
            password: "{{ new_srv1[0].password | password_hash('sha256') }}"
        - name: set new root's password
          set_fact:
            ansible_become_pass: "{{ new_srv1[0].password }}"
        - name: change password
          user:
            name: "{{ item.name }}"
            password: "{{ item.password | password_hash('sha256') }}"
          when: item.name != "{{ new_srv1[0].name }}"
          with_items:
            - "{{ new_srv1 }}"
    - hosts: 192.168.10.3
      become: yes
      become_method: su
      no_log: yes
      vars_files:
        - new_user_password.yml
      tasks:
        - name: change root's password
          user:
            name: "{{ new_srv2[0].name }}"
            password: "{{ new_srv2[0].password | password_hash('sha256') }}"
        - name: set new root's password
          set_fact:
            ansible_become_pass: "{{ new_srv2[0].password }}"
        - name: change password
          user:
            name: "{{ item.name }}"
            password: "{{ item.password | password_hash('sha256') }}"
          when: item.name != "{{ new_srv2[0].name }}"
          with_items:
            - "{{ new_srv2 }}"
    
  3. Playbookの実行結果
    $ ansible-playbook -i hosts change_password.yml --ask-vault-pass -e@current_user_password.yml
    
    PLAY [192.168.10.2] ************************************************************
    
    TASK [setup] *******************************************************************
    ok: [192.168.10.2]
    
    TASK [change root's password] **************************************************
    changed: [192.168.10.2]
    
    TASK [set new root's password] *************************************************
    ok: [192.168.10.2]
    
    TASK [change password] *********************************************************
    skipping: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    
    PLAY [192.168.10.3] ************************************************************
    
    TASK [setup] *******************************************************************
    ok: [192.168.10.3]
    
    TASK [change root's password] **************************************************
    changed: [192.168.10.3]
    
    TASK [set new root's password] *************************************************
    ok: [192.168.10.3]
    
    TASK [change password] *********************************************************
    skipping: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    
    PLAY RECAP *********************************************************************
    192.168.10.2               : ok=4    changed=2    unreachable=0    failed=0
    192.168.10.3               : ok=4    changed=2    unreachable=0    failed=0
    

おわりに

今回は、Ansibleを使ったLinux系のPCのユーザを一括で変更する方法について紹介しました。 Ansibleは、パスワード変更だけでなく、FWの設定やアップデートなど様々な自動化が行える構成管理ツールです。 Hardeningでも役に立った便利なツールなので、ぜひ試してみてください。

参考にしたサイト