Ubuntu

MIT Kerberos 在對 OpenSSH 進行身份驗證時不斷要求輸入密碼

  • June 20, 2017

我正在嘗試設置一個簡單的 Kerberos 環境,該環境由 Kerberos 伺服器 (KDC)、客戶端電腦和執行 OpenSSH 守護程序的伺服器電腦組成。在與伺服器機器建立 SSH 連接時,客戶端應該通過 Kerberos 進行身份驗證。

我要驗證的 Kerberos 使用者的名稱是krbuser. 此使用者存在於服務電腦上,並且具有 uid 1001。奇怪的是我用SSH登錄的時候需要輸入Kerberos使用者的密碼。每次我登錄。不僅是我的第一次連接。這看起來很奇怪,因為 Kerberos 的全部意義在於無需密碼即可進行身份驗證。

我在身份驗證過程中進行了 tcpdump,並註意到客戶端正在使用 cname 對 KDC 執行 AS-REQ root。這個 Kerberos 使用者名沒有,我知道客戶端為什麼使用這個名稱。正如預期的那樣,KDC 以eRR-C-PRINCIPAL-UNKNOWN消息響應,因為數據庫中沒有root使用者。

對我來說,主要問題似乎是客戶端嘗試以身份驗證root而不是krbuser.

我將在下面發布有關我目前配置的一些資訊。如果您需要任何其他資訊,請告訴我。

在 KDC 上:

/etc/krb5.conf

[logging]
   default = FILE:/usr/local/krb5/var/log/krb5lib.log 
   kdc = FILE:/usr/local/krb5/var/log/krb5kdc.log
   admin_server = FILE:/usr/local/krb5/var/log/kadmin.log

[libdefaults]
   default_realm = metz.prac.os3.nl
   rdns = false

# The following krb5.conf variables are only for MIT Kerberos.
   krb4_config = /etc/krb.conf
   krb4_realms = /etc/krb.realms
   kdc_timesync = 1
   ccache_type = 4
   forwardable = true
   proxiable = true

[realms]
   metz.prac.os3.nl = {
       kdc = krb-0.metz.prac.os3.nl
       admin_server = krb-0.metz.prac.os3.nl
   }

在服務機器上:

/etc/ssh/sshd config(摘錄)

# Kerberos options
KerberosAuthentication yes
# KerberosGetAFSToken no
# KerberosOrLocalPasswd no
# KerberosTicketCleanup yes

# GSSAPI options
GSSAPIAuthentication yes
# GSSAPICleanupCredentials yes

在 SSH 身份驗證期間擷取的日誌文件:

debug1: rekey after 4294967296 blocks [preauth]
debug1: SSH2_MSG_NEWKEYS received [preauth]
debug1: KEX done [preauth]
debug1: userauth-request for user root service ssh-connection method none [preauth]
debug1: attempt 0 failures 0 [preauth]
debug1: PAM: initializing for "root"
debug1: PAM: setting PAM_RHOST to "218.65.30.30"
debug1: PAM: setting PAM_TTY to "ssh"
debug1: userauth-request for user root service ssh-connection method password [preauth]
debug1: attempt 1 failures 0 [preauth]
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: restore_uid: 0/0
debug1: Kerberos password authentication failed: Client 'root@metz.prac.os3.nl' not found in Kerberos database
debug1: krb5_cleanup_proc called
debug1: inetd sockets after dupping: 5, 5
Connection from 145.100.110.115 port 51946 on 145.100.110.116 port 22
debug1: Client protocol version 2.0; client software version OpenSSH_7.2p2 Ubuntu-4ubuntu2.2
debug1: match: OpenSSH_7.2p2 Ubuntu-4ubuntu2.2 pat OpenSSH* compat 0x04000000
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2
debug1: permanently_set_uid: 106/65534 [preauth]
debug1: list_hostkey_types: ssh-rsa,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519 [preauth]
debug1: SSH2_MSG_KEXINIT sent [preauth]
debug1: SSH2_MSG_KEXINIT received [preauth]
debug1: kex: algorithm: curve25519-sha256@libssh.org [preauth]
debug1: kex: host key algorithm: ecdsa-sha2-nistp256 [preauth]
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none [preauth]
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none [preauth]
debug1: expecting SSH2_MSG_KEX_ECDH_INIT [preauth]
debug1: rekey after 134217728 blocks [preauth]
debug1: SSH2_MSG_NEWKEYS sent [preauth]
debug1: expecting SSH2_MSG_NEWKEYS [preauth]
debug1: rekey after 134217728 blocks [preauth]
debug1: SSH2_MSG_NEWKEYS received [preauth]
debug1: KEX done [preauth]
debug1: userauth-request for user krbuser service ssh-connection method none [preauth]
debug1: attempt 0 failures 0 [preauth]
debug1: PAM: initializing for "krbuser"
debug1: PAM: setting PAM_RHOST to "145.100.110.115"
debug1: PAM: setting PAM_TTY to "ssh"
debug1: userauth-request for user krbuser service ssh-connection method gssapi-with-mic [preauth]
debug1: attempt 1 failures 0 [preauth]
debug1: PAM: password authentication failed for root: Authentication failure
Failed password for root from 218.65.30.30 port 18460 ssh2
debug1: userauth-request for user root service ssh-connection method password [preauth]
debug1: attempt 2 failures 1 [preauth]
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: restore_uid: 0/0
debug1: Kerberos password authentication failed: Client 'root@metz.prac.os3.nl' not found in Kerberos database
debug1: krb5_cleanup_proc called
debug1: PAM: password authentication failed for root: Authentication failure
Failed password for root from 218.65.30.30 port 18460 ssh2
debug1: userauth-request for user root service ssh-connection method password [preauth]
debug1: attempt 3 failures 2 [preauth]
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: restore_uid: 0/0
debug1: Kerberos password authentication failed: Client 'root@metz.prac.os3.nl' not found in Kerberos database
debug1: krb5_cleanup_proc called
debug1: PAM: password authentication failed for root: Authentication failure
Failed password for root from 218.65.30.30 port 18460 ssh2
debug1: userauth-request for user krbuser service ssh-connection method password [preauth]
debug1: attempt 2 failures 0 [preauth]
debug1: temporarily_use_uid: 1001/1001 (e=0/0)
debug1: restore_uid: 0/0
debug1: temporarily_use_uid: 1001/1001 (e=0/0)
debug1: restore_uid: 0/0
debug1: do_pam_account: called
Accepted password for krbuser from 145.100.110.115 port 51946 ssh2
debug1: monitor_child_preauth: krbuser has been authenticated by privileged process
debug1: monitor_read_log: child log fd closed
debug1: temporarily_use_uid: 1001/1001 (e=0/0)
debug1: ssh_gssapi_storecreds: Not a GSSAPI mechanism
debug1: restore_uid: 0/0
debug1: PAM: establishing credentials
User child is on pid 20617
debug1: SELinux support disabled
debug1: PAM: establishing credentials
debug1: permanently_set_uid: 1001/1001
debug1: rekey after 134217728 blocks
debug1: rekey after 134217728 blocks
debug1: ssh_packet_set_postauth: called
debug1: Entering interactive session for SSH2.
debug1: server_init_dispatch_20
debug1: server_input_channel_open: ctype session rchan 0 win 1048576 max 16384
debug1: input_session_request
debug1: channel 0: new [server-session]
debug1: session_new: session 0
debug1: session_open: channel 0
debug1: session_open: session 0: link with channel 0
debug1: server_input_channel_open: confirm session
debug1: server_input_global_request: rtype no-more-sessions@openssh.com want_reply 0
debug1: server_input_channel_req: channel 0 request pty-req reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req pty-req
debug1: Allocating pty.
debug1: session_new: session 0
debug1: SELinux support disabled
debug1: session_pty_req: session 0 alloc /dev/pts/2
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request shell reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req shell
Starting session: shell on pts/2 for krbuser from 145.100.110.115 port 51946 id 0
debug1: Setting controlling tty using TIOCSCTTY.
debug1: userauth-request for user root service ssh-connection method password [preauth]
debug1: attempt 4 failures 3 [preauth]
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: restore_uid: 0/0
debug1: Kerberos password authentication failed: Client 'root@metz.prac.os3.nl' not found in Kerberos database
debug1: krb5_cleanup_proc called
debug1: PAM: password authentication failed for root: Authentication failure
Failed password for root from 218.65.30.30 port 18460 ssh2
debug1: userauth-request for user root service ssh-connection method password [preauth]
debug1: attempt 5 failures 4 [preauth]
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: restore_uid: 0/0
debug1: Kerberos password authentication failed: Client 'root@metz.prac.os3.nl' not found in Kerberos database
debug1: krb5_cleanup_proc called
debug1: PAM: password authentication failed for root: Authentication failure
Failed password for root from 218.65.30.30 port 18460 ssh2
debug1: userauth-request for user root service ssh-connection method password [preauth]
debug1: attempt 6 failures 5 [preauth]
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: restore_uid: 0/0
debug1: Kerberos password authentication failed: Client 'root@metz.prac.os3.nl' not found in Kerberos database
debug1: krb5_cleanup_proc called
debug1: PAM: password authentication failed for root: Authentication failure
Failed password for root from 218.65.30.30 port 18460 ssh2
maximum authentication attempts exceeded for root from 218.65.30.30 port 18460 ssh2 [preauth]
Disconnecting: Too many authentication failures [preauth]
debug1: do_cleanup [preauth]
debug1: monitor_read_log: child log fd closed
debug1: do_cleanup
debug1: PAM: cleanup
debug1: Killing privsep child 20604
debug1: audit_event: unhandled event 12
debug1: inetd sockets after dupping: 5, 5
Connection from 218.65.30.30 port 58146 on 145.100.110.116 port 22
debug1: Client protocol version 2.0; client software version nsssh2_4.0.0032 NetSarang Computer, Inc.
debug1: no match: nsssh2_4.0.0032 NetSarang Computer, Inc.
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2
debug1: permanently_set_uid: 106/65534 [preauth]
debug1: list_hostkey_types: ssh-rsa,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519 [preauth]
debug1: SSH2_MSG_KEXINIT sent [preauth]
debug1: SSH2_MSG_KEXINIT received [preauth]
debug1: kex: algorithm: diffie-hellman-group14-sha1 [preauth]
debug1: kex: host key algorithm: ssh-rsa [preauth]
debug1: kex: client->server cipher: aes128-ctr MAC: hmac-sha1 compression: none [preauth]
debug1: kex: server->client cipher: aes128-ctr MAC: hmac-sha1 compression: none [preauth]
debug1: expecting SSH2_MSG_KEXDH_INIT [preauth]

在客戶端機器上:

kinitklist認證之前:

$ kinit -p krbuser
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: krbuser@metz.prac.os3.nl

Valid starting     Expires            Service principal
06/15/17 00:24:05  06/15/17 10:24:05  krbtgt/metz.prac.os3.nl@metz.prac.os3.nl
   renew until 06/16/17 00:23:56

/etc/ssh/ssh config(摘錄):

   GSSAPIAuthentication yes
   GSSAPIDelegateCredentials yes
#   GSSAPIKeyExchange no
#   GSSAPITrustDNS no

最後是 SSH 身份驗證:

$ ssh krbuser@service-0.metz.prac.os3.nl -vvv
...
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug2: resolving "service-0.metz.prac.os3.nl" port 22
debug2: ssh_connect_direct: needpriv 0
debug1: Connecting to service-0.metz.prac.os3.nl [145.***.***.***] port 22.
debug1: Connection established.
debug1: key_load_public: No such file or directory
debug1: identity file /home/client/.ssh/id_rsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/client/.ssh/id_rsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/client/.ssh/id_dsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/client/.ssh/id_dsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/client/.ssh/id_ecdsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/client/.ssh/id_ecdsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/client/.ssh/id_ed25519 type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/client/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.2p2 Ubuntu-4ubuntu2.2
...
debug1: Found key in /home/client/.ssh/known_hosts:3
debug3: send packet: type 21
debug2: set_newkeys: mode 1
debug1: rekey after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug3: receive packet: type 21
debug2: set_newkeys: mode 0
debug1: rekey after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS received
debug2: key: /home/client/.ssh/id_rsa ((nil))
debug2: key: /home/client/.ssh/id_dsa ((nil))
debug2: key: /home/client/.ssh/id_ecdsa ((nil))
debug2: key: /home/client/.ssh/id_ed25519 ((nil))
debug3: send packet: type 5
debug3: receive packet: type 7
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<rsa-sha2-256,rsa-sha2-512>
debug3: receive packet: type 6
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug3: send packet: type 50
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug3: start over, passed a different list publickey,gssapi-keyex,gssapi-with-mic,password
debug3: preferred gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive,password
debug3: authmethod_lookup gssapi-keyex
debug3: remaining preferred: gssapi-with-mic,publickey,keyboard-interactive,password
debug3: authmethod_is_enabled gssapi-keyex
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug2: we did not send a packet, disable method
debug3: authmethod_lookup gssapi-with-mic
debug3: remaining preferred: publickey,keyboard-interactive,password
debug3: authmethod_is_enabled gssapi-with-mic
debug1: Next authentication method: gssapi-with-mic
debug3: send packet: type 50
debug2: we sent a gssapi-with-mic packet, wait for reply
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug3: send packet: type 50
debug2: we sent a gssapi-with-mic packet, wait for reply
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug3: send packet: type 50
debug2: we sent a gssapi-with-mic packet, wait for reply
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug3: send packet: type 50
debug2: we sent a gssapi-with-mic packet, wait for reply
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug2: we did not send a packet, disable method
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
...
debug1: Next authentication method: password
krbuser@service-0.metz.prac.os3.nl's password: <entering PW of Kerberos user> !!!
debug3: send packet: type 50
debug2: we sent a password packet, wait for reply
debug3: receive packet: type 52
debug1: Authentication succeeded (password).
Authenticated to service-0.metz.prac.os3.nl ([145.***.***.***]:22).
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open
debug3: send packet: type 90
debug1: Requesting no-more-sessions@openssh.com
debug3: send packet: type 80
debug1: Entering interactive session.
debug1: pledge: network
debug3: receive packet: type 80
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug3: receive packet: type 91
debug2: callback start
debug2: fd 3 setting TCP_NODELAY
debug3: ssh_packet_set_tos: set IP_TOS 0x10
debug2: client_session2_setup: id 0
debug2: channel 0: request pty-req confirm 1
debug3: send packet: type 98
...
debug3: Ignored env _
debug2: channel 0: request shell confirm 1
debug3: send packet: type 98
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug3: receive packet: type 99
debug2: channel_input_status_confirm: type 99 id 0
debug2: PTY allocation request accepted on channel 0
debug2: channel 0: rcvd adjust 2097152
debug3: receive packet: type 99
debug2: channel_input_status_confirm: type 99 id 0
debug2: shell request accepted on channel 0
Last login: Thu Jun 15 00:28:57 2017

Connection established

現在klist顯示以下票證:

$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: krbuser@metz.prac.os3.nl

Valid starting     Expires            Service principal
06/15/17 00:24:05  06/15/17 10:24:05  krbtgt/metz.prac.os3.nl@metz.prac.os3.nl
   renew until 06/16/17 00:23:56
06/15/17 00:27:37  06/15/17 10:24:05  host/service-0.metz.prac.os3.nl@
   renew until 06/16/17 00:23:56
06/15/17 00:27:37  06/15/17 10:24:05  host/service-0.metz.prac.os3.nl@metz.prac.os3.nl
   renew until 06/16/17 00:23:56

因此,總結一下:客戶端上的 Kerberos 使用者可以通過輸入其 Kerberos (!) 密碼來建立與伺服器的 SSH 會話。不是它的 UNIX 密碼。tcpdump 顯示客戶端驗證為root不是 Kerberos 使用者,我不知道為什麼它使用此使用者名而不是krbuser. 這是我與kinit命令一起使用的那個。

**誰能告訴我為什麼此身份驗證無法正常工作?**如果您需要更多資訊,請告訴我。我試圖保持簡短。

根登錄

從您提供的日誌文件來看,我會說嘗試的 root 登錄不是您的問題。請注意,所有以 root 身份進行的身份驗證嘗試都來自218.65.30.30,一個簡單的whois命令告訴我們這是來自中國的 IP。成功參與此身份驗證的其他 IP145.100.110.11{5,6}都來自同一個(大學管理的)網路塊。我假設這些是您感興趣的機器。我也非常推薦安裝類似的東西fail2ban來阻止試圖暴力破解你的 IP。

SSH

現在讓我們著手解決您的 Kerberos 問題。我最近建立了一個 Kerberos 環境,這充滿了困難,所以我感到你的痛苦!您的 SSH 配置看起來不錯,因此我們可以排除這種情況。GSSAPIDelegateCredentials yes儘管從安全形度來看,您可能需要考慮,但 /etc/ssh/ssh_config實際上是否需要設置?雖然方便,但此選項會將您的 TGT 公開給您通過 SSH 連接的任何機器。

Keberos 警告

kerberos 設置對時間偏差和名稱解析很敏感的兩個主要問題。我認為時間偏差不太可能是您的問題。不過,使用您的 kerberos 日誌更容易確認這一點。大多數現代 GNU/Linux 發行版都已經設置了網路時間。您可以使用類似的東西來驗證這一點timedatectl。您還應該確保為您環境中的每台主機正確設置了正向和反向 DNS。

關於領域的旁白——雖然並不總是嚴格要求,但慣例是讓您的領域保持大寫。當您在混合 GNU/Linux 和 Windows 環境中工作時,這是絕對必須的,有時這會導致完全無法工作。如果您總體上堅持這一點,您將使自己的生活更輕鬆。

主機名是否匹配 DNS 名稱和 keytab 名稱?

對我來說最突出的主要事情是您擁有的空域服務票,即來自 SPN 的服務票host/service-0.metz.prac.os3.nl@。對我來說,這聽起來像是您的網路設置正在發生一些時髦的事情。看起來您default_realm的設置正確,所以我認為最終主機有問題。要對此進行調試,我建議使用額外的日誌記錄 ( sudo /usr/sbin/sshd -p 9001 -D -dd) 在服務上啟動一個新的 sshd 實例,然後嘗試從客戶端連接 ( ssh -p 9001 -vv krbuser@service-0.metz.prac.os3.nl)。這將從雙方准確地向您展示身份驗證期間發生的情況以及實際使用了哪些 SPN。

我最近遇到了一個問題,因為我連接的服務不知道它自己的 FQDN(即服務試圖找到 keytab 條目host/service-0@REALM而不是host/service-0.rest.of.domain@REALM),所以身份驗證失敗。您可以使用 進行檢查hostname --fqdn,如果這不返回系統的完整 DNS 名稱,那麼您可以編輯/etc/hosts確保輸出hostname --fqdn與 DNS 中的內容匹配

最後,確保每個具有正確 SPN 的主機都有一個 keytab 文件。這應該看起來像host/service-0.rest.of.domain@REALM。您可以使用 . 檢查 keytab 文件的內容klist -k /path/to/keytab。調試愉快!我知道 Kerberos 有多麼令人沮喪。

核選項

如果您仍處於設置階段的早期階段,那麼用火殺死設置並從頭開始可能會更容易:)。從長遠來看,牢記所有這些並遵循良好的指南可能會為您節省一些時間。

引用自:https://serverfault.com/questions/855859