AnsibleでOpenLDAP環境構築 -⑤ldapユーザをssh鍵認証でログインするための設定まで終わったら、いよいよ大詰めldapユーザにssh鍵認証設定。
LDAP構築 まとめの例にならい、
パスフレーズ(ssh鍵認証用パスワード)⇒ sshmanager
ssh秘密鍵/公開鍵生成 ⇒ ssh-keygenコマンドを実行
とした。
■ssh鍵認証設定用playbook
以下の内容でplaybookを作成してみた。
[root@ansible_sv ~]# vi/etc/ansible/yml/6_setPubkey.yml 1- hosts: ldap_sv 2 remote_user: root 3 4 vars: 5 gid: "ldapmanager" 6 uid: "user01" 7 gidnum: "1001" 8 uidnum: "1001" 9 keypass: "sshmanager" 10 11 tasks: 12 - name: execute su 13 shell: > 14 su {{ uid }} 15 16 - name: create .ssh directory 17 file: 18 path=/home/{{ uid }}/.ssh 19 state=directory 20 owner={{ uid }} 21 group={{ gid }} 22 mode=0700 23 24 - name: create sshPublickey 25 shell: > 26 ssh-keygen -t ed25519 -f /home/{{ uid }}/.ssh/id_ed25519 -N "{{ keypass }}" 27 28 - name: chmod id_ed25519* 29 file: 30 path=/home/{{ uid }}/.ssh/{{ item }} 31 state=file 32 owner={{ uid }} 33 group={{ gid }} 34 mode=0600 35 with_items: 36 - 'id_ed25519' 37 - 'id_ed25519.pub' 38 39 - name: rename authorized_keys 40 shell: > 41 mv /home/{{ uid }}/.ssh/id_ed25519.pub /home/{{ uid }}/.ssh/authorized_keys 42 43 - name: userdel 44 ldap_entry: 45 dn: uid={{ uid }},cn={{ gid }},ou=Group,dc=abc,dc=def,dc=com 46 state: absent 47 server_uri: ldap://localhost/ 48 bind_dn: cn=Manager,dc=abc,dc=def,dc=com 49 bind_pw: manager 50 51 - name: stdout slappasswd 52 shell: slappasswd -s ldapuser01 53 register: user01pass 54 55 - name: stdout sshPublickey 56 shell: cat /home/{{ uid }}/.ssh/authorized_keys 57 register: pubkey 58 59 - name: re-exec useradd 60 ldap_entry: 61 dn: uid={{ uid }},cn={{ gid }},ou=Group,dc=abc,dc=def,dc=com 62 state: present 63 server_uri: ldap://localhost/ 64 bind_dn: cn=Manager,dc=abc,dc=def,dc=com 65 bind_pw: "manager" 66 objectClass: 67 - top 68 - posixAccount 69 - account 70 - ldapPublickey 71 attributes: 72 gecos: ldapsystem manager 73 cn: "{{ gid }}" 74 uid: "{{ uid }}" 75 uidNumber: "{{ uidnum }}" 76 gidNumber: "{{ gidnum }}" 77 homeDirectory: /home/{{ uid }} 78 loginShell: /bin/bash 79 userPassword: "{{ user01pass.stdout }}" 80 sshPublicKey: "{{ pubkey.stdout }}"
以下、各モジュールの説明。
hosts:(1行目)
処理を実行する対象ホストを指定。「ldap_sv」は/etc/ansible/hostsに記述したホスト名となる。
remote_user:(2行目)
hosts:で指定したホストで処理を実行する際に、どのユーザで処理を実行するかを指定。上記の例では先頭の階層に記述しているため、それ以降の全階層において適用される。
vars:(4行目)
変数を宣言するモジュール。変数の宣言は1行だけでなく複数可。またこの場合一番上位のhostsモジュールと同じ階層に位置されているので、それ以下のすべての階層に有効となる。言うまでもないかもしれないが、ここで変数を使う理由として、ldapユーザが後々追加になった場合に、playbookを使いまわすのにいちいちファイルの内容全部をチェックして修正箇所を網羅するのは非効率なので、ldapユーザ追加時に、主に変更が発生しそうな箇所はあらかじめ変数にして、追加が発生した場合にその変数1箇所だけを修正するようにしたかった。
tasks:(10行目)
処理の内容を、tasks:以降に記述する。tasks:を記述しないとエラーになるので注意。
name:(12、16、24、28、39、43、51、55、59行目)
ansible-playbookコマンドを実行した際に、実行結果に出力させる文字列を指定する。
shell:(13、25、40、52、56、行目)
linuxコマンドを直接指定できる。類似モジュールで「command:」もあるが、shellは複数行記述できる。
file:(17、29行目)
ファイルやディレクトリの作成、アクセス権限の指定ができるモジュール。複数のモジュール引数が存在するので、以下の表に示す。
モジュール引数 | 条件 | 説明 |
---|---|---|
path= | ディレクトリやファイル、シンボリックリンクの位置をフルパスで指定する。 | |
state= | file | pathで指定した既存のファイルを示す。もしファイルがない場合はcopyモジュールやtemplateモジュールが発動する。 |
link | pathで指定したシンボリックリンクを示す。 | |
directory | pathで指定した既存のディレクトリを示す。ディレクトリがない場合はサブディレクトリとして作成され、アクセス権限は上位ディレクトリから継承される。 | |
hard | ハードリンクを指定する。 | |
touch | pathで指定したファイルを空の状態で作成する。linuxコマンドのtouchコマンドに相当する。 | |
absent | pathで指定したファイルやディレクトリ、シンボリックリックを削除する。 | |
owner= | ファイルのオーナーを指定する。lsコマンド等で表示されるオーナーの部分に当たる。 | |
group= | ファイルのグループを指定する。lsコマンド等で表示されるグループの部分に当たる。 | |
mode= | ファイルのアクセス権限を指定する。chmodコマンドに相当する。 |
with_items:(35行目)
「item」と記述したところに入る文字列を指定する。文字列は複数指定することができる。
実はここでも行頭に「-」が記述されているが、yml形式においては、ひとつのモジュールに対して複数の処理を当てはめる場合にこのような記述になるらしい。
上記例でも「task:」の中に複数の「- name:」があるのと同じ考えといったところだろうか。
ldap_entry:(44、60行目)
ldap関連モジュール。ldap_attrやldap_sert,ldap_searchがある。詳細はansible公式ページのldap関連もしくはGitHubを参照。
モジュール引数 | 条件 | 説明 |
---|---|---|
dn: | 登録するベースDN(本稿ではdc=abc,dc=def,dc=com)を指定する。 | |
state: | present | ベースDN/組織/グループ/ユーザを設定するときに指定する。 |
absent | ベースDN/組織/グループ/ユーザを削除するときに指定する。 | |
server_uri: | OpenLDAPサーバのURLを「ldap://<OpenLDAPサーバのIPアドレス>」という記述で指定する。 | |
bind_dn: | 設定/削除する際にバインド(認証)する管理者DN(本稿では「cn=Manager,dc=abc,dc=def,dc=com」)を指定する。 | |
bind_pw: | 設定/削除する際にバインド(認証)する管理者パスワード(本稿では「manager」)を指定する。 | |
objectClass: | ベースDN/組織/グループ/ユーザに対し、設定/削除するオブジェクトクラスを指定する。オブジェクトクラスの記述の前に「‐」をつけて、複数指定することも可能。その際にオブジェクトクラスや属性の継承関係やスキーマの有無などは事前に確認すべし。 | |
attributes: | ベースDN/組織/グループ/ユーザに対し、設定/削除する属性を指定する。属性は「dc:」「o:」のように、実際にスキーマに登録されているものを指定する。 |
ldap系モジュールを使用するにあたって
事前に開発パッケージをインストールしておく必要がある。詳細はAnsibleでOpenLDAP環境構築 -③組織(ou)/グループ(cn)の設定を参照。
register:(53、57行目)
直前で実行したモジュールの標準出力結果を、指定した変数に代入してくれる。※ここで注意することは、registerで得た文字列は「<registerモジュールで指定した変数名>.stdout」と記述しているように、.stdoutをつけて使用すること。
■補足
上記playbookの内容を少し説明すると。。。
・14行目
suコマンドを実行するように仕掛けているが、ansibleではsuコマンドを推奨していないらしく、warningが出てしまう。エラーではないので気にはしないが、ldapユーザが初回ログインした時に、oddjobサービスによってちゃんとホームディレクトリが作成されるか、念のため動作確認の意味を含めている。
・29~37行
「path=/home/{{ uid }}/.ssh/{{ item }}」と記述している。itemという変数を使って、with_itemsでid_ed25519とid_ed25519.pubの2つのファイルに対してアクセス権限を変更している。
・44~49行目
「state: absent」と記述し、一旦ldapユーザを削除している。60行以降でsshPublicKeyモジュールを付け加えてユーザ再登録を行うため。
■ansible-playbookコマンドでplaybookを実行
いよいよansibleの実行。コマンドは
# ansible-playbook <playbook名(フルパス)>
[root@ansible_sv ~]# ansible-playbook /etc/ansible/yml/6_setPubkey.yml SSH password: PLAY [ldap_sv] *************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************* ok: [192.168.3.6] TASK [execute su] ************************************************************************************************************************************ [WARNING]: Consider using 'become', 'become_method', and 'become_user' rather than running su changed: [192.168.3.6] TASK [create .ssh directory] ************************************************************************************************************************* changed: [192.168.3.6] TASK [create sshPublickey] *************************************************************************************************************************** changed: [192.168.3.6] TASK [chmod id_ed25519*] ***************************************************************************************************************************** changed: [192.168.3.6] => (item=id_ed25519) changed: [192.168.3.6] => (item=id_ed25519.pub) TASK [rename authorized_keys] ************************************************************************************************************************ changed: [192.168.3.6] TASK [userdel] *************************************************************************************************************************************** changed: [192.168.3.6] TASK [stdout slappasswd] ***************************************************************************************************************************** changed: [192.168.3.6] TASK [stdout sshPublickey] *************************************************************************************************************************** changed: [192.168.3.6] TASK [re-exec useradd] ******************************************************************************************************************************* changed: [192.168.3.6] PLAY RECAP ******************************************************************************************************************************************* 192.168.3.6 : ok=10 changed=9 unreachable=0 failed=0 [root@ansible_sv ~]#
suコマンドをたたいているところは、案の定ピンク文字。([WARNING]: Consider using ‘become’, ‘become_method’, and ‘become_user’ rather than running su)ホームディレクトリの作成は必要な作業なので、やむなし。
無事成功\(^o^)/
実行結果の説明はAnsibleでOpenLDAP環境構築 -①OpenLDAPサーバ関連のパッケージインストールを参照。
■OpenLDAPサーバで事後確認
念のためansible-playbookコマンドで実行したplaybookの内容がOpenLDAPサーバにちゃんと反映されたか確認。
ここで事後確認するポイントは、playbookに沿って以下。
・/etc/<ldapユーザ名>/.ssh及び、その配下のid_ed25519、authorized_keysのアクセス権限が期待値どおりであること。
(/etc/<ldapユーザ名>/.ssh⇒0700、id_ed25519/authorized_keys⇒0600)
・ldapユーザがsshPublicKey属性つきで登録されていること。(ldapsearchコマンドで確認)
[root@ldapmanager ~]# ls -l /home 合計 0 drwx------. 3 user01 ldapmanager 74 1月 25 13:53 user01 [root@ldapmanager ~]# ls -l /home/user01/.ssh 合計 8 -rw-------. 1 user01 ldapmanager 98 1月 25 13:53 authorized_keys -rw-------. 1 user01 ldapmanager 464 1月 25 13:53 id_ed25519 [root@ldapmanager ~]#
アクセス権限は大丈夫のようだ。
[root@ldapmanager ~]# ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b 'dc=abc,dc=def,dc=com' 'uid=*' SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 dn: uid=user01,cn=ldapmanager,ou=Group,dc=abc,dc=def,dc=com cn: ldapmanager objectClass: top objectClass: posixAccount objectClass: account objectClass: ldapPublicKey loginShell: /bin/bash userPassword:: e1NTSEF9MWNXYXloRmlkV0F4aGdTY3ZudUw3eElQNE5LMERPOWk= uidNumber: 1001 gidNumber: 1001 gecos: ldapsystem manager homeDirectory: /home/user01 sshPublicKey: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP9SdWAQw736AdPnGnvHfGEPRZSe UflZVEqbFyqgM0AM root@ldapmanager uid: user01 [root@ldapmanager ~]#
sshPublicKey属性ありました\(^o^)/
playbook成功!!