はじめに
CentOS6上のAnsibleから、Windows2012Serverに対してアクティブディレクトリユーザーで接続(Kerberos認証)をしようとした際に"plaintext: 401 Unauthorized. basic auth failed"のエラーでハマリましたので備忘も含めて記事にします。
本記事について、長文かつ、なんだかまとまりがなくなってしまったのでどこかでリライトするかもしれません。
事象
公式サイトのWindows Supportの通りCentOS6上で以下Kerberos関連の設定を行い、Windows2012Serverへ接続するplaybookを実行すると"plaintext: 401 Unauthorized. basic auth failed"
と
Kerberos認証ではなくパスワード認証で接続NG(401エラー)となっていました。
# WinRM 及び Kerberos関連のモジュール等をインストール
pip install "pywinrm>=0.1.1"
# Installing python-kerberos dependencies
yum -y install python-devel krb5-devel krb5-libs krb5-workstation
# Installing python-kerberos
pip install kerberos
# Configuring Kerberos
# /etc/krb5.conf を自環境の値に変更
[realms]
MY.DOMAIN.COM = {
kdc = domain-controller1.my.domain.com
kdc = domain-controller2.my.domain.com
}
[domain_realm]
.my.domain.com = MY.DOMAIN.COM
# Testing a kerberos connection
kinit -C user@MY.DOMAIN.COM
klist
# Inbentoryhost
[windows]
winserver1.example.com
winserver2.example.com
[windows:vars]
ansible_user=Administrator@
ansible_password=SecretPasswordGoesHere
ansible_port=5985
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
原因
- CentOS6では、Kerberos認証モジュールが動作していませんでした。
- 具体的にはCentOS6のPython Ver.2.6ではpipでインストールしたKerberosのモジュールがうまく動作していない(import等に失敗)ことが分かりました。
対策
以下いずれかの方法でPythonのバージョンを2.7.xに上げてからpip install kerberos
を行います。
- AnsibleホストをCentOS6(Python Ver.2.6)ではなく、CentOS7(Python Ver.2.7.5)にする。
- CentOS7で公式サイトのWindows Supportの通り設定を行ったところ、問題なくKerberos認証がうまくいきました。
- CentOS6上でpynevを使いPython Ver.を2.7.8以降(注1)にする。
- CentOS6にて、2.7系のPythonを別途インストールしたのですが、pipとの依存関係等でAnsible含めてうまく動作させることができなかったのでpyenvを利用しました。
- 注1:当初CentOS7と同じバージョン2.7.5をインストールしましたが、Ansibleで必要なparamiko(pythonモジュール)がこのバージョンのpyenvではインストールできないことが分かったため、2.7.8をいれています。
- こちらにpyenvをインストール・設定するAnsible playbookのQiita記事を書きましたので参考まで。
おまけ
/etc/krb5.conf
やインベントリファイルの設定例
klist
の結果Default principal:
に両ファイルを合わせるのコツです。
特に.LOCALなど大文字小文字区別されます。
以下kinit , /etc/krb5.conf , インベントリファイルの設定例
[root@AnsibleSV krbs_test]# kinit foo@MYDOMAIN.local
Password for foo@MYDOMAIN.local:
kinit: KDC reply did not match expectations while getting initial credentials
[root@AnsibleSV krbs_test]# kinit -C foo@MYDOMAIN.local
Password for foo@MYDOMAIN.local:
[root@AnsibleSV krbs_test]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: foo@MYDOMAIN.LOCAL
Valid starting Expires Service principal
06/01/16 17:30:17 06/02/16 03:30:18 krbtgt/MYDOMAIN.LOCAL@MYDOMAIN.LOCAL
renew until 06/08/16 17:30:17
[root@AnsibleSV krbs_test]# cat /etc/krb5.conf
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = MYDOMAIN.LOCAL
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
MYDOMAIN.LOCAL = {
kdc = 192.168.200.1
admin_server = 192.168.200.1
}
[domain_realm]
.mydomain.local = MYDOMAIN.LOCAL
mydomain.local = MYDOMAIN.LOCAL
[root@AnsibleSV krbs_test]# cat krbs_host
[win]
win01.MYDOMAIN.LOCAL
win02.MYDOMAIN.LOCAL
[win:vars]
ansible_user=foo@MYDOMAIN.LOCAL
ansible_password=SecretPassword
ansible_port=5985
ansible_connection=winrm
ansible_winrm_transport=kerberos
ansible_winrm_server_cert_validation=ignore
トラブルシュート方法
- python kerberosモジュールが動作するか試す一例としては、Ansible Serverへコマンドライン上で以下コマンドの結果としてなにもエラーがでなければ、おそらくインストールはうまくいっているので、krb5.confやインベントリファイルの設定の問題の可能性が高いです。
以下エラーの例。
# python
Python 2.6.6 (r266:84292, Jul 23 2015, 15:22:56)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import kerberos
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /usr/lib64/python2.6/site-packages/kerberos.so: undefined symbol: PyCapsule_CheckExact
>>>
# Ctrl + d でpythonを終了
ちなみに上記エラー状態でpip list
やpip freeze
を行った結果が以下です。
# pip list | grep kerberos
DEPRECATION: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of pip will drop support for Python 2.6
kerberos (1.2.4)
# pip freeze | grep kerberos
DEPRECATION: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of pip will drop support for Python 2.6
kerberos==1.2.4
-
kinit -C user@MY.DOMAIN.COM
やklist
でAnsibleServerとWindows間でKerberos認証ができるか確認します。Ansible/pythonとの切り分け。- なお、チケットには有効期限(
krb5.conf
のticket_lifetime
で設定 また、klist
結果のExpiresで確認可能)があるので注意。有効期限が切れた場合は、再度チケットを発行。
- なお、チケットには有効期限(
-
デフォルトでは、接続ユーザー名に@が入っている場合、kerberos認証を試し、エラーの場合、パスワード認証を行うようです。エラー内容がパスワード認証のままの場合は、インベントリファイルに
ansible_winrm_transport=kerberos
を追加して、明示的にkerberos認証のみで接続を試みるとエラーメッセージがkerberos認証のもに変わるのでメッセージに沿った対応(python kerberosモジュールのインストール問題かkrb5.confやインベントリファイルの設定の問題かどうかがわかります)をします。
参考
環境
サーバ種別 | 種類 | ver. |
---|---|---|
Ansible Server1 | OS | CentOS 6.7 |
Ansible | ansible 2.0.2.0 yum install | |
Python | Python 2.6.6 → pyenv 2.7.8 | |
pip 8.1.2 (python 2.6) → pip 8.1.2 (python 2.7.8) | ||
Ansible Server2 | OS | CentOS 7 |
Ansible | epel yum install | |
Python | 2.7.5 | |
pip 8.1.2 (python 2.7.5) | ||
Ansible Client | OS | Windows2012 |
OS | Windows2012R2 |
実行結果エラー時
テスト用プレイブック
[root@AnsibleSV krbs_test]# cat krbs_test.yml
---
- hosts: win
gather_facts: no
vars:
CMD:
- cmd: CMD /c "dir"
tasks:
- name: "CMD TEST"
raw: "{{ item.cmd }}"
register: CMD_RESULT
with_items: '{{ CMD }}'
- name: "debug: output CMD results"
debug: var=CMD_RESULT.results
"plaintext: 401 Unauthorized. basic auth failed"
エラー
ansible_winrm_transport=kerberos
指定なし 、 Python Ver.2.6
[root@AnsibleSV krbs_test]# ansible-playbook -i krbs_host krbs_test.yml
PLAY [win] *********************************************************************
TASK [CMD TEST] ****************************************************************
fatal: [win01.MYDOMAIN.LOCAL]: FAILED! => {"failed": true, "msg": "plaintext: 401 Unauthorized. basic auth failed"}
fatal: [win02.MYDOMAIN.LOCAL]: FAILED! => {"failed": true, "msg": "plaintext: 401 Unauthorized. basic auth failed"}
NO MORE HOSTS LEFT *************************************************************
to retry, use: --limit @krbs_test.retry
PLAY RECAP *********************************************************************
win01.MYDOMAIN.LOCAL : ok=0 changed=0 unreachable=0 failed=1
win02.MYDOMAIN.LOCAL : ok=0 changed=0 unreachable=0 failed=1
[root@AnsibleSV krbs_test]#
"kerberos: the python kerberos library is not installed"エラー
インベントリファイルへansible_winrm_transport=kerberos
を追加して
明示的にkerberos認証のエラーメッセージを出力。
[root@AnsibleSV krbs_test]# ansible-playbook -i krbs_host krbs_test.yml
PLAY [win] *********************************************************************
TASK [CMD TEST] ****************************************************************
fatal: [win02.MYDOMAIN.LOCAL]: FAILED! => {"failed": true, "msg": "kerberos: the python kerberos library is not installed"}
fatal: [win01.MYDOMAIN.LOCAL]: FAILED! => {"failed": true, "msg": "kerberos: the python kerberos library is not installed"}
NO MORE HOSTS LEFT *************************************************************
to retry, use: --limit @krbs_test.retry
PLAY RECAP *********************************************************************
win01.MYDOMAIN.LOCAL : ok=0 changed=0 unreachable=0 failed=1
win02.MYDOMAIN.LOCAL : ok=0 changed=0 unreachable=0 failed=1
[root@AnsibleSV krbs_test]#