[29] in Hesiod
Status of Hesiod code development
daemon@ATHENA.MIT.EDU (Mark Rosenstein)
Tue May 22 16:05:03 1990
Date: Tue, 22 May 90 15:56:07 -0400
From: Mark Rosenstein <mar@MIT.EDU>
To: allen@ECF.NCSL.NIST.GOV
Cc: hesiod@ATHENA.MIT.EDU
In-Reply-To: "ALLEN, DAN"'s message of 17 May 90 15:23:00 EST <9005171934.AA12630@ATHENA.MIT.EDU>
We are making some use of the dynamic update code in named here, for
addresses rather than hesiod information. We do this in conjunction
with dynamic address assignment on workstations at installation/boot
time. So far this is just experimental, but we have gotten the update
code to work after fixing a few bugs from the way 4.8.1 was shipped.
We also added per-zone flags so that we can control which zones may be
dynamically updated. I can make these diffs available if there is
interest.
We also did some work here towards Kerberos-authenticated nameservice.
A prototype was written for the following spec, but we decided to can
the project before bringing the code up to production quality.
-Mark
A PROPOSAL FOR
AUTHENTICATED NAME SERVICE
Mark Rosenstein
31 MARCH 1989
DRAFT 1.3
Motivation
Authenticated name service is necessary if access control lists and other
authorization information are to be stored in the Hesiod name server. The
loading of the Hesiod database from Moira(The Athena Service Management System,
previously called SMS.) is already authenticated, but requests for Hesiod data
from a workstation are easily spoofed. In this case, the required
authentication is not of the user to the server as is usually done, but of the
server to the user so that the user is assured that the proper data was
returned.
Some people have also expressed a desire for authenticating the user to the
server, so that the server can enforce access control lists on which data may
be viewed by whom. Athena does not have interest in this functionality at this
time, but this proposal keeps this in mind for forward compatibility.
To add as little overhead to the existing Hesiod server as possible, the new
functionality is integrated into the existing Hesiod server. This mechanism is
optional, so that most name lookups need not be authenticated, but it is
possible to do an authenticated lookup of any data contained in the Hesiod
database. This authentication technique can be used for anything stored in the
domain name system, not just Hesiod.
Protocol Design
Authenticated name service will continue to use the internet standard domain
name service (DNS) protocol, as documented in RFC1034 and RFC1035. This
proposal assumes familiarity with those documents. The only change is to
provide authentication information in the ``additional records'' section of the
request and response packets. A nameserver which implements only the internet
standard DNS will simply ignore these additional records. However, our Hesiod
nameservers will be modified to scan the additional records section for a
resource record (RR) of type T_CRED(Eventually we need to get a official number
assigned to this. For now I've taken the number 105.). The class given to
these records does not matter and is ignored, although a legal class should be
assigned, such as C_HESIOD. This extra RR contains the credentials necessary
to perform authentication. To allow this scheme to be used at sites with
differing requirements and local authentication schemes, this RR always starts
with a 16 bit subtype field indicating which authentication scheme is being
used.
The request from the workstation to the Hesiod server will contain a credential
RR of subtype ST_KRB_WEAK_REQ (assigned a value of 1). This credentials record
contains an encrypted checksum and a Kerberos ticket. The checksum is an 8
byte DES encryption of the quad-checksum from the start of the domain packet up
to and including the byte preceding this RR. The ticket is for
``hesiod.server_name@realm_name'', and contains the session key which is used
to seed the quad-checksum routine and to key the DES encryption of that
checksum. It is not necessary to checksum any of the transport layer headers
since we don't care how the packet got here, as DNS runs over multiple
transport layers. This checksum prevents someone from modifying the request
before it gets to the nameserver.
RR-type 16 bit integer T_CRED = 105
RR-class 16 bit integer any (C_HESIOD = 3 recommended)
sub-type 16 bit integer ST_KRB_WEAK_REQ = 1
checksum 8 bytes DES encryption of quad_checksum
ticket rest of RR length encrypted Kerberos record
When the nameserver finds a credentials RR in a request, and can verify the
credentials, then it will also include credentials in the reply. Verification
of received credentials consists of successful decryption of the ticket,
extraction of the session key, and double-checking the cryptographic checksum.
If no credentials are found, or the authentication fails, then the nameserver
answers the request normally without including credentials in the reply.
The credentials RR in the reply is similar, although it is not necessary to
repeat the ticket. It contains a subtype of ST_KRB_WEAK_RESP (assigned a value
of 2), and a cryptographic checksum of the packet preceding this RR, as in the
request. The checksum makes use of the same session key that was in the
request.
RR-type 16 bit integer T_CRED = 105
RR-class 16 bit integer any (C_HESIOD = 3 recommended)
sub-type 16 bit integer ST_KRB_WEAK_RSP = 2
checksum 8 bytes DES encryption of quad_checksum
To verify this authenticator, the checksum is double-checked using the
remembered session key. This checksum is sufficient to verify that the
response has not been modified. Replays are not a problem as long as the
techniques for choosing session keys and packet Identifiers are reasonably
unique. A complete ticket is not included in this RR because space is at a
premium in Hesiod response packets.
The primary weakness of this protocol is finding the correct nameserver for the
request. This must be done through the DNS, which is inherently easy to spoof.
It is necessary to find the correct nameserver to know which instance to use
for the Kerberos ticket, and where to send the packet. This protocol cannot
rely on the usual forwarding mechanism of the DNS since all of the intermediate
servers might not understand the credentials RR and forward it on properly.
However, the danger is not too great for finding the incorrect nameserver,
since only an entity capable of decoding the authenticator can authenticate the
reply.
Implementation
There are basically two subsystems this new protocol would affect (plus any
applications which wish to use it). The first is the nameserver. All of the
changes there appear in one routine, ns_req() in ns_req.c. Where the request
is parsed at the beginning of the routine, it must look for the credentials RR,
verify it, and save the session key and the fact that this transaction is
authenticated. Then near the end of the routine where it sends back the
response, if the request was authenticated it must generate the necessary
credentials RR and append it to the response. This, and a new srvtab file for
the Hesiod server, are all that are needed on the server end.
The Hesiod library is where most of the changes take place. The user interface
to Hesiod is through hes_resolve(). A new routine, called hes_auth_resolve()
should be added with identical calling conventions. The first difference
between this routine and the regular hes_resolve() is that it starts by
scanning a local cache file for cached authenticated responses (see caching
discussion below). If a cached answer is found, it is returned, otherwise this
routine continues following a code path similar to that of the regular
hes_resolve() except for the routine which builds the DNS packet and parses the
response. The new version of this routine first makes a query for the target
data, with the PRIMARY_SERVER bit set. This will cause the local nameserver to
reply with a response containing the name of the primary server in the ``name
server'' section of the packet (unless the local host is the primary server).
Now we know the name of the server and can get a ticket for it, and set our DNS
resolver to send the next request directly to that host. The proper request is
sent, and the reply is scanned for a credentials RR in addition to an answer to
the query. If the authentication was not successful, then no data is returned,
and the Hesiod error state (retrievable through hes_error()) is set to a new
code, HES_ER_AUTH ``authentication failed''. If an authenticated answer is
found, it is also added to the local cache.
Caching is done in a local temporary file similar to they way Kerberos caches
tickets. The cache contains the name of the Kerberos principal that owns the
cache, and the time that person's ticket granting ticket expires. After this
time, the entire cache will be thrown out. Each entry in the cache consists of
the hesiod name and type, the answer, and a timeout. The timeout associated
with each piece of data is the minimum of the timeout of the data assigned by
the DNS and the expiration time of the ticket used to authenticate that data.
Before any access to the cache, a check will be made that the user owns the
cache file, and that the expiration time on the cache matches the expiration
time on the user's ticket granting ticket. If these times don't match, the
cache is cleared. Any operation that modifies the cache will lock the file
first. It is safe to leave the cache files in /tmp, since they contain no
secret information and it is possible to detect old cache files left there that
shouldn't be used.
The one client that should be provided immediately is an additional option to
hesinfo to get it to do authentication. This is useful both for testing and in
shell scripts.
Performance Issues
This will be an increase in the load on the name servers. The authentication
part of the protocol has been carefully examined so that the server need only
perform 3 DES encryptions: 1 to get the session key out of the ticket, 1 to
verify the request checksum, and 1 more to encode the checksum in the reply.
Without going to public key encryption, this is the minimum number of
encryptions necessary to guarantee the desired level of security.
The current version of the nameserver at Athena can respond to approximately
150 requests/second. A back-of-the-envelope calculation based on the vax DES
encryption time of 2ms implies that 105 authenticated queries/second should be
possible. Athena's average request rate on busy days is still under 1
request/second, although we don't have measurements for peak seconds.