今回は構成管理のデファクトスタンダードであるOSSのAnsibleを使って、
sudoパスワードの暗号化、Playbookを使ってのコマンド実行、PlaybookからAnsibleのroleに変更、Roleを使ってのユーザ作成を行ってみます。
ディストリビューションによって違いがないかUbuntu18.04,20.04,22.04、Debin9,10、CentOS7、AlmaLinux8,9、RockyLinux8,9、RHEL8と11種類のOSを用意して実行していきます。
準備
Debianでsudoが実行できるよう準備
Debianを最小でインストールした場合はsudoがインスト
sudoをインストールして、
$ apt -y install sudo
$ usermod -aG sudo xxxxxx
パスワードなしでのSSHログイン準備
後でAnsibleでのパスワードログインもやっていきますが
通常のシーケンスである鍵交換をしていきます。
まず、サーバー側のSSH鍵を作成します。
$ cd ~/.ssh
$ ssh-keygen -t rsa -f id_rsa
$ chmod 600 ~/.ssh/id_rsa
$ chmod 700 ~/.ssh
鍵配布を行っていきます、
ここからクライアントの数だけループを行います。
$ ssh-copy-id 192.168.1.50
$ ssh 192.168.1.50
$ ssh-copy-id 192.168.1.51
$ ssh 192.168.1.51
.........................................
Playbookでの実行
Playbookの準備
現時点ではロールを使いませんが
Ansbileのロールを作成します。
$ ansible-galaxy init --offline test
$ tree test
test
├── README.md
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
鍵を登録したクライアントを記載します。
$ vi test/inventory
[yum]
192.168.1.55
[dnf]
localhost
192.168.1.56
192.168.1.57
192.168.1.58
192.168.1.59
[apt]
192.168.1.50
192.168.1.51
192.168.1.52
192.168.1.53
192.168.1.54
登録したホストが認識されているか確認します。
$ ansible-inventory --graph -i test/inventory
@all:
|--@apt:
| |--192.168.1.50
| |--192.168.1.51
| |--192.168.1.52
| |--192.168.1.53
| |--192.168.1.54
|--@dnf:
| |--192.168.1.56
| |--192.168.1.57
| |--192.168.1.58
| |--192.168.1.59
| |--localhost
|--@yum:
| |--192.168.1.55
|--@ungrouped:
Ansible Vaultでパスワードを暗号化します
sudoに必要なパスワードを変数ansible_sudo_passに登録します。
複数の環境設定ファイルが使いやすいようvars/main.ymlではなくvars/main/*.ymlで設定します。
$ cd test
$ rm -rf vars/main.yml
$ mkdir vars/main
$ vi vars/main/sudo_pass.yml
ansible_sudo_pass: hogehoge
暗号化用のパスワードを記載します。
場所はどこでもいいのですが、.
$ vi ~/.ssh/sudo_pass
ansible-vaultでsudo_pass.
@の前のsudoがvault-idになり、
@の後のファイル名がパスワード格納ファイルになります。
$ ansible-vault encrypt --vault-id sudo@~/.ssh/sudo_pass vars/main/sudo_pass.yml
Encryption successful
sudo_pass.ymlが暗号化されたことを確認します。
$ cat vars/main/sudo_pass.yml
$ANSIBLE_VAULT;1.2;AES256;sudo
36633337366438316536346238633862666431653066303537663836666236626232376631306262
3239643862663036323232306238356232663836363430640a343137373135376262386436353033
65393763363963346232656536326136353239353435336565343530633964306464623432663661
3730643661613862370a326631613933343531306433616138343139363836633538323234643861
30303930373165316231623136326465343430313366656161383131666139363863383931356363
3936343530306432666337386135303630646564633064313261
Playbookの作成と実行(SSH鍵認証、sudoパスワード入力不要)
まずロールではなく単独のPlaybookで操作を行っていきます。
各サーバにSSH鍵でログインして、sudoしてwhoamiを実行するPlaybookを作成します。
また、ログが表示できるようhandlerで捕捉します。
xxxxは任意のユーザに変えてください
$ vi test.yml
---
- name: test
hosts: all
user: xxxxxx
become: true
gather_facts: false
vars_files:
- vars/main/sudo_pass.yml
tasks:
- name: whoami
command: whoami
notify: handler
register: result
handlers:
- name: handler
debug: var="result"
実行します。
$ ansible-playbook --vault-id sudo@~/.ssh/sudo_pass test.yml -i inventory
fatal: [192.168.0.53]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"ansible.legacy.setup": {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "failed": true, "module_stderr": "Shared connection to 192.168.0.53 closed.\r\n", "module_stdout": "/bin/sh: 1: sudo: not found\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 127}}, "msg": "The following modules failed to execute: ansible.legacy.setup\n"}
fatal: [192.168.0.54]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"ansible.legacy.setup": {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "failed": true, "module_stderr": "Shared connection to 192.168.0.54 closed.\r\n", "module_stdout": "/bin/sh: 1: sudo: not found\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 127}}, "msg": "The following modules failed to execute: ansible.legacy.setup\n"}
Python3の実行エラー回避
対象のDebianのサーバで確認した所
原因は/usr/bin/python3が存在しないようです。
$ whereis python
python: /usr/bin/python /usr/bin/python3.7 /usr/bin/python3.7m /usr/bin/python2.7 /usr/lib/python3.7 /usr/lib/python2.7 /etc/python /etc/python3.7 /etc/python2.7 /usr/local/lib/python3.7 /usr/local/lib/python2.7 /usr/share/python /usr/share/man/man1/python.1.gz
$ whereis python
python: /usr/bin/python3.9 /usr/lib/python2.7 /usr/lib/python3.9 /etc/python3.9 /usr/local/lib/pyth
inventoryにPythonのパスを記載します。
$ vi inventory
[dnf]
localhost
192.168.1.55
192.168.1.56
192.168.1.57
192.168.1.58
192.168.1.59
[apt]
192.168.1.50
192.168.1.51
192.168.1.52
192.168.1.53 ansible_python_interpreter=/usr/bin/python3.7
192.168.1.54 ansible_python_interpreter=/usr/bin/python3.9
再度実行します。エラーが起きないはずです。
$ ansible-playbook --vault-id sudo@~/.ssh/sudo_pass test.yml -i inventory
–vault-idを省略できるようにします。
実行ディレクトリにansible.cfgを記載してデフォルトを上書きします。
まずはvault-id抜きでエラーが出ることを確認します。
$ ansible-playbook test.yml -i inventory
ERROR! Attempting to decrypt but no vault secrets found
$ vi ansible.cfg
[defaults]
vault_identity_list: sudo@~/.ssh/sudo_pass
vault_id_match: true
再度実行してみます。
$ ansible-playbook test.yml -i inventory
RoleでのAnsible実行
RoleでのPlaybookの作成(ログインパスワード平文、sudoパスワード平文))
今度はsudoが可能なスポットの作業用ユーザを作成します。
また、ロール化も行います。
今回はパスワードログインで行ってみます。
また、sudoができるようディストリビューションごとに異なるグループに所属させます。
特にエラー処理していないため実行ごとにパスワードハッシュが変わり常にchangedになります。
処理部分を記載
$ vi tasks/main.yml
---
# tasks file for test
- name: RedHat Create User
user:
user: test1
group: wheel
password: "{{ 'hogehoge'|password_hash('sha512') }}"
when:
- ansible_distribution != "Ubuntu"
- ansible_distribution != "Debian"
- name: Debian Ubuntu Create User
user:
user: test1
group: sudo
password: "{{ 'hogehoge'|password_hash('sha512') }}"
when:
- ansible_distribution == "Ubuntu" or ansible_distribution == "Debian"
- name: User Check
command: "id test1"
notify: handler
register: result
ハンドラーを記載します。
$ vi handlers/main.yml
---
# handlers file for test
- name: handler
debug: var="result"
ロールを実行するPlaybookを記載します。
$ cd ../
$ vi test.yml
---
- name: test
hosts: all
become: true
gather_facts: true
roles:
- test
ansible.cfgは実行ディレクトリに置く必要があるため再度記載します。
$ vi ansible.cfg
[defaults]
vault_identity_list: sudo@~/.ssh/sudo_pass
vault_id_match: true
RoleでのPlaybookの実行(SSHパスワード平文、sudoパスワード平文)
inventoryにログイン情報とsudoパスワードを記載して、実行を行います。
$ vi test/inventory
[RHEL]
localhost
192.168.1.55
192.168.1.56
192.168.1.57
192.168.1.58
192.168.1.59
[Ubuntu]
192.168.1.50
192.168.1.51
192.168.1.52
[Debian]
192.168.1.53
192.168.1.54
[all:vars]
ansible_ssh_pass=hogehoge
ansible_sudo_pass=hogehoge
$ ansible-playbook test.yml -i test/inventory
ログインとsudoで昇格できるか先程のPlaybookでは確認していないため
必要に応じてログインしてsudoでスーパーユーザになれるか確
最初のPlaybookの実行ユーザをtest1に書き換えます。
$ cd test
$ vi test.yml
---
- name: test
hosts: all
user: test1
become: true
gather_facts: false
tasks:
- name: whoami
command: whoami
notify: handler
register: result
handlers:
- name: handler
debug: var="result"
実行します。
$ ansible-playbook test.yml -i inventory