<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Felipe Alfaro Solana &#187; Kerberos</title>
	<atom:link href="http://www.felipe-alfaro.org/blog/category/kerberos/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.felipe-alfaro.org/blog</link>
	<description>A little bit of technology, security and networking with Linux, FreeBSD and Mac OS X, plus some personal opinions.</description>
	<lastBuildDate>Sun, 23 Oct 2011 16:46:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Kerberizing Leopard&#8217;s Remote Login (built-in SSH) service</title>
		<link>http://www.felipe-alfaro.org/blog/2007/12/07/kerberizing-leopards-ssh/</link>
		<comments>http://www.felipe-alfaro.org/blog/2007/12/07/kerberizing-leopards-ssh/#comments</comments>
		<pubDate>Thu, 06 Dec 2007 20:31:29 +0000</pubDate>
		<dc:creator>Felipe Alfaro Solana</dc:creator>
				<category><![CDATA[Kerberos]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.felipe-alfaro.org/blog/2007/12/07/kerberizing-leopards-built-in-openssh-server/</guid>
		<description><![CDATA[0. Introduction Enabling Kerberos/GSSAPI support in Leopard&#8217;s Remote Login (SSH) service is straightforward. As Leopard&#8217;s Remote Login is built using OpenSSH, most of what is described here applies perfectly to other flavors of UNIX. Kerberos/GSSAPI authentication allows for Single Sign-On capabilities in OpenSSH in such a way that it makes very convenient to work with [...]]]></description>
			<content:encoded><![CDATA[<h2>0. Introduction</h2>
<p>Enabling Kerberos/GSSAPI support in Leopard&#8217;s Remote Login (SSH) service is straightforward. As Leopard&#8217;s Remote Login is built using <a href="http://www.openssh.org/">OpenSSH</a>, most of what is described here applies perfectly to other flavors of UNIX.</p>
<p>Kerberos/GSSAPI authentication allows for Single Sign-On capabilities in <a href="http://www.openssh.org/">OpenSSH</a> in such a way that it makes very convenient to work with or manage multiple machines while only having to authenticate to the network every certain amount (Kerberos uses a form of cached credentials that expire within hours, typically). In this document I describe how to enable support for Kerberos/GSSAPI authentication to Leopard&#8217;s implementation of <a href="http://www.openssh.org/">OpenSSH</a>. Leopard includes many of the tools from the <a href="http://web.mit.edu/Kerberos/">MIT&#8217;s implementation of Kerberos</a>, so this makes the whole process even easier.</p>
<p>The process consists on:</p>
<ol>
<li>Creating the Kerberos principal</li>
<li>Creating <code>/etc/krb5.conf</code></li>
<li>Adding the Kerberos principal to the keytab file</li>
<li>Reconfiguring OpenSSH to support Kerberos authentication</li>
<li>Restarting OpenSSH</li>
<li>Enabling Kerberos authentication on OpenSSH clients</li>
<li>Testing</li>
</ol>
<h2>1. Creating the Kerberos principal</h2>
<p>When a Kerberized SSH client tries to authenticate to a Kerberized OpenSSH service, the client will request a Kerberos service ticket for that specific OpenSSH service. The Kerberos service ticket contains, among other things, a shared secret (for example, a 3DES private key) that has to be distributed to both the client and the server, called K<>client,server. The KDC will generate such shared secret and will encrypt it twice. Once, with a shared secret between the KDC and the client principal, called K<sub>KDC,client</sub>, and another one with a shared secret between the KDC and the server principal, K<sub>KDC,server</sub>.</p>
<p>In this step, we will create the Kerberos principal that represents the OpenSSH server and consequently its shared secret, K<sub>KDC,server</sub>. Later on, we will upload this shared secret to the OpenSSH server and install it into the Keytab file, so that the OpenSSH server can access it and use it to decrypt the user&#8217;s service ticket in order to retrieve the shared secret, K<sub>client,server</sub>.</p>
<div>
<pre>
$ kadmin
Authenticating as principal alice/admin@LAN with password.
Password for alice/admin@LAN:
kadmin:  addprinc -randkey host/ssh.lan
WARNING: no policy specified for host/ssh.lan@LAN; defaulting to no policy
Principal "host/ssh.lan@LAN" created.
</pre>
</div>
<p>NOTE: If you are logged in as <code>root</code> into the KDC, you can use <code>kadmin.local</code> instead of <code>kadmin</code> if you prefer, as the former doesn&#8217;t require any authentication (being able to run it as <code>root</code> is enough to prove yourself authorized).</p>
<p>The Kerberos principal associated with the OpenSSH has been created, the shared secrets generated, stored and protected by the stash key. We can check the status of the principal using the following command:</p>
<div>
<pre>
kadmin:  getprinc host/ssh.lan
Principal: host/ssh.lan@LAN
Expiration date: [never]
Last password change: Thu Dec 06 19:42:50 CET 2007
Password expiration date: [none]
Maximum ticket life: 0 days 10:00:00
Maximum renewable life: 7 days 00:00:00
Last modified: Thu Dec 06 19:42:50 CET 2007 (root/admin@LAN)
Last successful authentication: [never]
Last failed authentication: [never]
Failed password attempts: 0
Number of keys: 2
Key: vno 5, Triple DES cbc mode with HMAC/sha1, no salt
Key: vno 5, DES cbc mode with CRC-32, no salt
Attributes:
Policy: [none]
kadmin:  exit
</pre>
</div>
<p>Now that the principal has been created, we can move onto the next step.</p>
<h2>2. Creating <code>/etc/krb5.conf</code></h2>
<p>One of the requirements for Kerberizing OpenSSH server is configuring the Kerberos libraries via <code>/etc/krb5.conf</code>. These libraries are used by the OpenSSH server, <code>kpasswd</code>, the OpenSSH client and tools like <code>kadmin</code> or <code>kinit</code>.</p>
<p>This configuration file will also allow us to connect to the Kerberos administration server remotely by using <code>kadmin</code>, in order to download the OpenSSH shared secret. In my case, <code>/etc/krb5.conf</code> looks like this:</p>
<div>
<pre>
[libdefaults]
        default_realm = LAN
        dns_fallback = "no"
        default_tgs_enctypes = des-cbc-crc
        default_tkt_enctypes = des-cbc-crc

[realms]
        LAN = {
                kdc = kdc.lan:88
                admin_server = kdc.lan:749
        }

[domain_realm]
        .lan = LAN

[login]
        krb4_convert = true
        krb4_get_tickets = false
</pre>
</div>
<h2>3. Adding the Kerberos principal to the keytab file</h2>
<div>
<pre>
root@ssh.lan:# kadmin
Authenticating as principal root/admin@LAN with password.
Password for root/admin@LAN:
kadmin:  ktadd -k /etc/krb5.keytab host/ssh.lan@LAN
Entry for principal host/ssh.lan@LAN with kvno 7,
 encryption type Triple DES cbc mode with HMAC/sha1 added to
 keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/ssh.lan@LAN with kvno 7,
 encryption type DES cbc mode with CRC-32 added to
 keytab WRFILE:/etc/krb5.keytab.
</pre>
</div>
<p>This will add the OpenSSH shared secret to the Kerberos <code>/etc/krb5.keytab</code> file. We need to add the shared secrets to this file properly, as Leopard has a built-in KDC service and machine-specific shared secrets in this file that are used, among others, by the Screen Sharing service, the AFP service and the SAMBA service.</p>
<p>To check that OpenSSH shared secret was added to the keytab file, we use <code>ktutil</code> to read and display the contents of the Keytab file:</p>
<div>
<pre>
root@ssh.lan:# ktutil
ktutil:  rkt /etc/krb5.keytab
ktutil:  list
slot KVNO Principal
---- ---- ---------------------------------------------------------------------
   1    3 afpserver/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
   2    3 afpserver/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
   3    3 afpserver/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
   4    3 cifs/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
   5    3 cifs/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
   6    3 cifs/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
   7    3 vnc/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
   8    3 vnc/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
   9    3 vnc/LKDC:SHA1.E803840ADEAA3E91BF895E969F56FEDFF321BDD5@LKDC...
  10    7                      host/ssh.lan@LAN
  11    7                      host/ssh.lan@LAN
</pre>
</div>
<p>Once installed in the keytab file, OpenSSH will be able to access the shared secret, K<sub>KDC,server</sub> used to decrypt Kerberos service tickets shown by clients.</p>
<li>4. Reconfiguring OpenSSH to support Kerberos authentication</li>
<p>It is also necessary to change OpenSSH&#8217;s server configuration file, <code>/etc/sshd_config</code> to explicitly enable Kerberos/GSSAPI authentication. To achieve this, modify <code>/etc/sshd_config</code> file and add the following lines (by default they are either uncommented or disabled):</p>
<div>
<pre>
# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
</pre>
</div>
<h2>5. Restarting OpenSSH</h2>
<p>To last step on the server side requires that we restart the OpenSSH service so the previous changes are taken into effect:</p>
<div>
<pre>
root@ssh.lan:# launchctl
aunchd% stop com.openssh.sshd
launchd% start com.openssh.sshd
</pre>
</div>
<h2>6. Enabling Kerberos authentication on OpenSSH clients</h2>
<p>Some OpenSSH clients have Kerberos authentication disabled by default. The easiest way to enable Kerberos/GSSAPI authentication in clients is by adding the following directives to <code>$HOME/.ssh/config</code>:</p>
<div>
<pre>
Host *
        Protocol 2
        GSSAPIAuthentication yes
        GSSAPIKeyExchange yes
        GSSAPIDelegateCredentials no
        GSSAPITrustDns no
</pre>
</div>
<p>This will enable Kerberos/GSSAPI authentication on the client side. The fact that Kerberos/GSSAPI authentication succeeds depends on several factors, like the user having a valid Kerberos TGT, the remote server having Kerberos/GSSAPI authentication enabled, and that the clocks on both the client and server machines are synced (most implementations refuse Kerberos/GSSAPI authentication if the clocks differ more than 5 minutes).</p>
<h2>7. Testing</h2>
<p>First, we need to get a TGT from the Kerberos KDC:</p>
<div>
<pre>
$ kinit
Please enter the password for falfaro@LAN:
</pre>
</div>
<p>To check that it worked, we list the tickets available to us, and make sure we see a ticket valid for service <code>krbtgt/*</code>:</p>
<div>
<pre>
$ klist
Kerberos 5 ticket cache: 'API:Initial default ccache'
Default principal: falfaro@LAN

Valid Starting     Expires            Service Principal
12/06/07 18:06:26  12/07/07 04:06:26  krbtgt/LAN@LAN
	renew until 12/13/07 18:06:26
</pre>
</div>
<p>Now, let&#8217;s try to log in into the OpenSSH server. Kerberos/GSSAPI authentication should be negotiated, as shown by the debugging information:</p>
<div>
<pre>
core2:~ falfaro$ ssh -v solana
OpenSSH_4.5p1, OpenSSL 0.9.7l 28 Sep 2006
debug1: Reading configuration data /Users/falfaro/.ssh/config
debug1: Applying options for *
debug1: Reading configuration data /etc/ssh_config
debug1: Connecting to solana [10.42.242.12] port 22.
debug1: Connection established.
debug1: identity file /Users/falfaro/.ssh/id_rsa type -1
debug1: identity file /Users/falfaro/.ssh/id_dsa type 2
debug1: Remote protocol version 2.0, remote software version OpenSSH_4.5
debug1: match: OpenSSH_4.5 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_4.5
debug1: Offering GSSAPI proposal:
 gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==,
 gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==,
 gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==,
 gss-gex-sha1-A/vxljAEU54gt9a48EiANQ==,
 gss-group1-sha1-A/vxljAEU54gt9a48EiANQ==,
 gss-group14-sha1-A/vxljAEU54gt9a48EiANQ==,
 gss-gex-sha1-bontcUwnM6aGfWCP21alxQ==,
 gss-group1-sha1-bontcUwnM6aGfWCP21alxQ==,
 gss-group14-sha1-bontcUwnM6aGfWCP21alxQ==
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-cbc hmac-md5 none
debug1: kex: client->server aes128-cbc hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024&lt;1024&lt;8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'solana' is known and matches the RSA host key.
debug1: Found key in /Users/falfaro/.ssh/known_hosts:8
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue:
 publickey,gssapi-keyex,gssapi-with-mic,password,keyboard-interactive
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: Authentication succeeded (gssapi-with-mic).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
Last login: Thu Dec  6 20:29:59 2007 from foo.lan
$ hostname
ssh.lan
$ exit
logout
Connection to solana closed.
</pre>
</div>
<p>If we run <code>klist</code> again, we will see that, in addition to the TGT we saw before, we will see the Kerberos service ticket for the OpenSSH server:</p>
<div>
<pre>
Kerberos 5 ticket cache: 'API:Initial default ccache'
Default principal: alice@LAN

Valid Starting     Expires            Service Principal
12/06/07 18:06:26  12/07/07 04:06:26  krbtgt/LAN@LAN
	renew until 12/13/07 18:06:26
12/06/07 18:07:27  12/07/07 04:06:26  host/ssh.lan@LAN
	renew until 12/13/07 18:06:26
</pre>
</div>
<h2>8. Troubleshooting</h2>
<p>The GSSAPI authentication mechanism is very picky about many things, and error codes and messages are usually very cryptic but not very helpful about what the cause of the error is.</p>
<p>I found that acommon source of authentication problems are entries in <code>/etc/hosts</code> confusing GSSAPi about the host name. For example, entries like this in <code>/etc/hosts</code>:</p>
<div>
<pre>
192.168.0.1  ssh ssh.lan
</pre>
</div>
<p>can cause SSH to think the host name is <code>ssh</code> instead of the expected FQDN &#8212; <code>ssh.lan</code>.The previous entry causes reverse name resolutions for IP <code>192.168.0.1</code> to return <code>ssh</code> as the host name, but not <code>ssh.lan</code>. Since the Kerberos keytab is <code>host/ssh.lan</code> but IP <code>192.168.0.1</code> is resolved to <code>ssh</code> this may cause authentication attempts to fail because no Kerberos keytab for <code>host/ssh</code> exists in <code>/etc/krb5.keytab</code>. The most common symptom is trying to SSH to localhost, getting a failed authentication and but ticket for the target host. Example:</p>
<div>
<pre>
$ kinit
Password for alice@LAN: 

$ klist
Ticket cache: FILE:/tmp/krb5cc_501
Default principal: alice@LAN

Valid starting     Expires            Service principal
05/31/09 01:08:21  06/01/09 01:08:20  krbtgt/LAN@LAN
</pre>
</div>
<p>Then,</p>
<div>
<pre>
$ ssh ssh.lan
alice@ssh.lan's password:
</pre>
</div>
<p>But no Kerberos ticket for <code>ssh.lan</code> was even requested:</p>
<div>
<pre>
$ klist
Ticket cache: FILE:/tmp/krb5cc_501
Default principal: alice@LAN

Valid starting     Expires            Service principal
05/31/09 01:08:21  06/01/09 01:08:20  krbtgt/LAN@LAN
</pre>
</div>
<p>One possible solution consists of removing the matching entry from <code>/etc/hosts</code>, provided that the existing DNS name server can properly resolve the IP address of the server to the correct FQDN. If this is not possible, another solution is making sure the FQDN name is listed before the non-FQDN name in the corresponding line in <code>/etc/hosts</code>.</p>
<h2>8. References</h2>
<p>Some additional and very useful references:</p>
<ul>
<li><a href="http://wiki.linux-nfs.org/wiki/index.php/Enduser_doc_kerberos">Kerberos 5 setup for NFSv4</a>.
<p>Describes common pitfalls, like using a non-FQDN host name in <code>/etc/hosts</code> or not using clock synchronization.
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.felipe-alfaro.org/blog/2007/12/07/kerberizing-leopards-ssh/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

