8

我无法从我的 ansible 主机通过 AD 向 Windows 机器进行身份验证。我有一张有效的 kerberos 票 -

klist
Credentials cache: FILE:/tmp/krb5cc_1000
        Principal: ansible@SOMEDOMAIN.LOCAL

  Issued                Expires               Principal
Mar 10 09:15:27 2017  Mar 10 19:15:24 2017  krbtgt/SOMEDOMAIN.LOCAL@SOMEDOMAIN.LOCAL

我的 kerberos 配置对我来说看起来不错 -

cat /etc/krb5.conf
[libdefaults]
        default_realm = SOMEDOMAIN.LOCAL
#       dns_lookup_realm = true
#       dns_lookup_kdc = true
#       ticket_lifetime = 24h
#       renew_lifetime = 7d
#       forwardable = true

# The following krb5.conf variables are only for MIT Kerberos.
#       kdc_timesync = 1
#       forwardable = true
#       proxiable = true

# The following encryption type specification will be used by MIT Kerberos
# if uncommented.  In general, the defaults in the MIT Kerberos code are
# correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
#
# Thie only time when you might need to uncomment these lines and change
# the enctypes is if you have local software that will break on ticket
# caches containing ticket encryption types it doesn't know about (such as
# old versions of Sun Java).

#       default_tgs_enctypes = des3-hmac-sha1
#       default_tkt_enctypes = des3-hmac-sha1
#       permitted_enctypes = des3-hmac-sha1

# The following libdefaults parameters are only for Heimdal Kerberos.
#       v4_instance_resolve = false
#       v4_name_convert = {
#               host = {
#                       rcmd = host
#                       ftp = ftp
#               }
#               plain = {
#                       something = something-else
#               }
#       }
#       fcc-mit-ticketflags = true

[realms]
        SOMEDOMAIN.LOCAL = {
                kdc = prosperitydc1.somedomain.local
                kdc = prosperitydc2.somedomain.local
                default_domain = somedomain.local
                admin_server = somedomain.local
        }
[domain_realm]
        .somedomain.local = SOMEDOMAIN.LOCAL
        somedomain.local = SOMEDOMAIN.LOCAL

运行测试命令时 - ansible windows -m win_ping -vvvvv我得到

'Server not found in Kerberos database'.
     ansible windows -m win_ping -vvvvv
    Using /etc/ansible/ansible.cfg as config file
    Loading callback plugin minimal of type stdout, v2.0 from /usr/lib/python2.7/dist-packages/ansible/plugins/callback/__init__.pyc
    Using module file /usr/lib/python2.7/dist-packages/ansible/modules/core/windows/win_ping.ps1
    <kerberostest.somedomain.local> ESTABLISH WINRM CONNECTION FOR USER: ansible@SOMEDOMAIN.LOCAL on PORT 5986 TO kerberostest.somedomain.local
    <kerberostest.somedomain.local> WINRM CONNECT: transport=kerberos endpoint=https://kerberostest.somedomain.local:5986/wsman
    <kerberostest.somedomain.local> WINRM CONNECTION ERROR: authGSSClientStep() failed: (('Unspecified GSS failure.  Minor code may provide more information', 851968), ('Server not found in Kerberos database', -1765328377))
    Traceback (most recent call last):
      File "/usr/lib/python2.7/dist-packages/ansible/plugins/connection/winrm.py", line 154, in _winrm_connect
        self.shell_id = protocol.open_shell(codepage=65001)  # UTF-8
      File "/home/prosperity/.local/lib/python2.7/site-packages/winrm/protocol.py", line 132, in open_shell
        res = self.send_message(xmltodict.unparse(req))
      File "/home/prosperity/.local/lib/python2.7/site-packages/winrm/protocol.py", line 207, in send_message
        return self.transport.send_message(message)
      File "/home/prosperity/.local/lib/python2.7/site-packages/winrm/transport.py", line 181, in send_message
        prepared_request = self.session.prepare_request(request)
      File "/home/prosperity/.local/lib/python2.7/site-packages/requests/sessions.py", line 407, in prepare_request
        hooks=merge_hooks(request.hooks, self.hooks),
      File "/home/prosperity/.local/lib/python2.7/site-packages/requests/models.py", line 306, in prepare
        self.prepare_auth(auth, url)
      File "/home/prosperity/.local/lib/python2.7/site-packages/requests/models.py", line 543, in prepare_auth
        r = auth(self)
      File "/home/prosperity/.local/lib/python2.7/site-packages/requests_kerberos/kerberos_.py", line 308, in __call__
        auth_header = self.generate_request_header(None, host, is_preemptive=True)
      File "/home/prosperity/.local/lib/python2.7/site-packages/requests_kerberos/kerberos_.py", line 148, in generate_request_header
        raise KerberosExchangeError("%s failed: %s" % (kerb_stage, str(error.args)))
    KerberosExchangeError: authGSSClientStep() failed: (('Unspecified GSS failure.  Minor code may provide more information', 851968), ('Server not found in Kerberos database', -1765328377))

    kerberostest.somedomain.local | UNREACHABLE! => {
        "changed": false,
        "msg": "kerberos: authGSSClientStep() failed: (('Unspecified GSS failure.  Minor code may provide more information', 851968), ('Server not found in Kerberos database', -1765328377))",
        "unreachable": true
    }

我能够 ssh 到目标机器

 ssh -v1 kerberostest.somedomain.local -p 5986
OpenSSH_7.3p1 Ubuntu-1, OpenSSL 1.0.2g  1 Mar 2016
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to kerberostest.somedomain.local [10.10.20.84] port 5986.
debug1: Connection established.

我还可以用它们的主机名 ping 所有主机。我很茫然:(

这是ansible主机文件-

sudo cat /etc/ansible/hosts               
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

# Ex 1: Ungrouped hosts, specify before any group headers.

## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10

# Ex 2: A collection of hosts belonging to the 'webservers' group

## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110

# If you have multiple hosts following a pattern you can specify
# them like this:

## www[001:006].example.com

# Ex 3: A collection of database servers in the 'dbservers' group

## [dbservers]
## 
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57

# Here's another example of host ranges, this time there are no
# leading 0s:

## db-[99:101]-node.example.com
[monitoring-servers]
#nagios
10.10.20.75 ansible_connection=ssh ansible_user=nagios

[windows]
#fileserver.somedomain.local#this machine isnt joined to the domain yet.
kerberostest.SOMEDOMAIN.LOCAL


[windows:vars]
#the following works for windows local account authentication
#ansible_ssh_user = prosperity
#ansible_ssh_pass = *********
#ansible_connection = winrm
#ansible_ssh_port = 5986
#ansible_winrm_server_cert_validation = ignore

#vars needed to authenticate on the windows domain using kerberos
ansible_user = ansible@SOMEDOMAIN.LOCAL
ansible_connection = winrm
ansible_winrm_scheme = https
ansible_winrm_transport = kerberos
ansible_winrm_server_cert_validation = ignore

我还尝试使用 realmd 成功连接到域,但运行 ansible 命令产生了相同的结果。

4

2 回答 2

4

这看起来像是缺少 SPN 的情况。

这是相关的错误片段:

<kerberostest.prosperityerp.local> ESTABLISH WINRM CONNECTION FOR USER: ansible@PROSPERITYERP.LOCAL on PORT 5986 TO kerberostest.prosperityerp.local
    <kerberostest.prosperityerp.local> WINRM CONNECT: transport=kerberos endpoint=https://kerberostest.prosperityerp.local:5986/wsman
    <kerberostest.prosperityerp.local> WINRM CONNECTION ERROR: authGSSClientStep() failed: (('Unspecified GSS failure.  Minor code may provide more information', 851968), ('Server not found in Kerberos database', -1765328377))

这是基于我在您的 Ansible 配置文件中注意到的内容:

[windows]
#fileserver.prosperityerp.local#this machine isnt joined to the domain yet.
kerberostest.PROSPERITYERP.LOCAL

我认为该this machine isnt joined to the domain yet文件中的行很好地表明了 SPN HTTP/kerberostest.prosperityerp.local在 Active Directory 中不存在,这将导致“ server not found”消息。您可以通过 SSH 连接到kerberostest.prosperityerp.local,可能是因为它存在于 DNS 或客户端计算机的 Hosts 文件中,但除非并且直到在 Active Directory 中创建 SPN HTTP/kerberostest.prosperityerp.local ,否则您将继续得到它错误信息。此时正确添加该 SPN 将是另一个讨论主题。

  1. 您可以使用这样的命令来测试您是否定义了该 SPN:

    setspn -Q HTTP/kerberostest.prosperityerp.local

SPN 的存在是为了向 Kerberos 客户端表示在哪里可以找到网络上该服务的服务实例。

  1. 同时运行:

nslookup kerberostest.prosperityerp.local

在至少两台客户端计算机上确保运行 Kerberized 的 IP 主机的 FQDN 存在 DNS。DNS 是 Kerberos 在网络中正常运行的必要条件。

  1. 最后,您可以在客户端上使用 Wireshark 进行进一步分析,使用过滤器kerberos仅突出显示 kerberos 流量。
于 2017-03-11T06:25:04.543 回答
0

在我的情况下,Server not found in Kerberos database错误是由于目标 Windows 机器的 DNS 名称没有映射到正确的领域,正如Microsoft Technet 文章的这一行中所暗示的那样:

错误“在 Kerberos 数据库中找不到服务器”很常见并且可能会产生误导,因为它经常在服务主体不丢失时出现。该错误可能是由域/领域映射问题引起的,也可能是由于未正确构建服务主体名称的 DNS 问题造成的。服务器日志和网络跟踪可用于确定实际请求的服务主体。

我有剧本whoami.yaml

- hosts: windows-machine.mydomain.com
  tasks:
  - name: Run 'whoami' command
    win_command: whoami

主机文件:

[windows]
windows-machine.mydomain.com

[windows:vars]
ansible_connection=winrm
ansible_winrm_transport=kerberos
ansible_user=user@FOO.BAR.MYDOMAIN.COM
ansible_password=<password>
ansible_port=5985

由于 DNS 名称是windows-machine.mydomain.com,但AD 领域FOO.BAR.MYDOMAIN.COM我必须/etc/krb5.conf在我的 Ansible 主机上的文件中修复映射:

不正确

这不适用于我们的案例,因为此映射规则不适用于windows-machine.mydomain.com

[domain_realm]
    foo.bar.mydomain.com = FOO.BAR.MYDOMAIN.COM

正确的

这将正确映射windows-machine.mydomain.com到领域FOO.BAR.MYDOMAIN.COM

[domain_realm]
    .mydomain.com = FOO.BAR.MYDOMAIN.COM
于 2018-04-04T21:02:29.590 回答