Skip Menu |
 

From: James Ralston <ralston@pobox.com>
Date: Wed, 18 Apr 2018 14:03:34 -0400
Subject: RFE: [realms] should support an "always_use_preauth" option
To: krb5-bugs@mit.edu
Download (untitled) / with headers
text/plain 3.7KiB
Anyone who has watched the MIT Kerberos library speak to a Microsoft
Active Directory KDC knows that performing a simple kinit requires a
13-packet exchange:

---------------------------------------------------------
packet TCP Kerberos
number who proto options protocol
---------------------------------------------------------
1 C UDP AS-REQ (no preauth)
2 S UDP KRB5KDC_PREAUTH_REQUIRED
3 C UDP AS-REQ (with preauth)
4 S UDP KRB5KRB_ERR_RESPONSE_TOO_BIG
5 C TCP SYN
6 S TCP SYN/ACK
7 C TCP ACK
8 C TCP PSH/ACK AS-REQ (with preauth)
9 S TCP PSH/ACK AS-REP
10 C TCP ACK
11 C TCP FIN/ACK
12 S TCP ACK
13 S TCP RST/ACK
---------------------------------------------------------

The first (UDP-based) exchange fails because the MIT Kerberos library
doesn't use preauth. The second exchange fails because virtually all
responses from a Microsoft Active Directory KDC will include a PAC,
and thus will be unable to fit within a UDP packet.

There is a [libdefaults] option, udp_preference_limit, that can be
used to tell the MIT Kerberos library to always use TCP instead of
UDP. But when speaking to an Active Directory KDC, setting that
option to 0 (to always force TCP) in fact makes the exchange *worse*,
not better:

---------------------------------------------------------
packet TCP Kerberos
number who proto options protocol
---------------------------------------------------------
1 C TCP SYN
2 S TCP SYN/ACK
3 C TCP ACK
4 C TCP PSH/ACK AS-REQ (no preauth)
5 S TCP PSH/ACK KRB5KDC_PREAUTH_REQUIRED
6 C TCP ACK
7 C TCP FIN/ACK
8 S TCP ACK
9 S TCP RST/ACK
10 C TCP SYN
11 S TCP SYN/ACK
12 C TCP ACK
13 C TCP PSH/ACK AS-REQ (with preauth)
14 S TCP PSH/ACK AS-REP
15 C TCP ACK
16 C TCP FIN/ACK
17 S TCP ACK
18 S TCP RST/ACK
---------------------------------------------------------

Rather than taking 2 UDP packets to discover that preauth is required,
it takes 9 TCP packets.

If there were a [realms]-specific option for the administrator to tell
the MIT Kerberos library that a specific realm *always* requires
preauth, then the useless KRB5KDC_PREAUTH_REQUIRED exchange (2 UDP
packets or 9 TCP packets) could be avoided. Combined with setting
udp_preference_limit, this could meaningfully reduce the packet
exchange count required for an initial kinit:

---------------------------------------------------------
packet TCP Kerberos
number who proto options protocol
---------------------------------------------------------
1 C TCP SYN
2 S TCP SYN/ACK
3 C TCP ACK
4 C TCP PSH/ACK AS-REQ (with preauth)
5 S TCP PSH/ACK AS-REP
6 C TCP ACK
7 C TCP FIN/ACK
8 S TCP ACK
9 S TCP RST/ACK
---------------------------------------------------------

Therefore, please consider adding a [realms]-specific option to force
the MIT Kerberos libraries to always use preauth when talking to the
KDCs for the realm in question.
Download (untitled) / with headers
text/plain 1.5KiB
(Sorry for the long delay. I somehow didn't see this in the krb5-
bugs moderation queue until today.)

What you are asking for is called "optimistic pre-authentication."
The problem with doing it usefully for this scenario is that the
PREAUTH_REQUIRED error doesn't just convey a need to do preauth; it
also conveys:

1. The types of pre-authentication supported by the KDC.
2. The encryption type of at least one password-derived key that the
KDC can validate.
3. The salt to be used for the string-to-key operation.
4. (Rarely) any other string-to-key parameters which should affect
the password-derived key.

I think for user accounts in a Windows domain which don't use PKINIT
it might generally work to try with the first requested enctype
(assuming that would be aes256-sha1 and the server is reasonably
modern) and the default salt, and then retry if we get back an error
indicating the wrong key. But it could easily make things worse if
any of the assumptions change.

The ideal implementation of optimistic encrypted timestamp would
cache the preauth type and etype-info parameters (items 2-4 above)
per client principal name, so that a retry is only needed if one of
those parameters changes. We could perhaps keep such a cache in the
user home directory if configuration explicitly requests it (doing it
by default would create problems for NFS-mounted home directories and
has privacy implications), but it would add a non-trivial amount of
code complexity.

We haven't gotten many requests to implement optimistic preauth, so I
will leave this open as an enhancement request in case that changes.