しょんぼり技術メモ

まいにちがしょんぼり

Kerberosのメモ

研究を進める上で引っかかった点についてのメモ。

Kerberized NFSサーバでの要件

KDCは用意済みという仮定で。

Kerberized NFSサーバを knfs.example.com として、クライアントを kclient.example.com レルムを EXAMPLE.COM とした場合。

必要となるプリンシパルは、ホスト自身を相互に識別する際に用いるhost/プリンシパルと、Kerberized NFSサービスを利用する際に用いられるnfs/プリンシパルの2つ。

host/knfs.example.com@EXAMPLE.COM
ホストの識別に必要。
nfs/knfs.example.com@EXAMPLE.COM
Kerberized NFSの利用に必要。

つまり、ホストプリンシパル(host/)と、使いたいサービスにおいて自身を証明するためのプリンシパルが必要となる。
なお、Kerberized NFSでは rpc.gssd (rpcgssd) がプリンシパルをキャッシュするので、上記の2つのプリンシパルをフラッシュする場合には、サービスを再起動させる必要がある。

HTTPでKerberos認証を使う(mod_spnego)

mod_spnegoのインストールは、Apache2-SPNEGOこのあたりを参照。

その上で、AuthTypeにSPNEGOを指定してやる。

AuthType SPNEGO
Require valid-user

そうすると、REMOTE_USERにプリンシパル名が入る。Rubyだとこのように書ける。

cgi = CGI.new
princ = cgi.remote_user

受け取ったプリンシパルを分解して表示するスクリプトはこんな感じに書ける。

#!/usr/bin/ruby

require "cgi"
print "Content-type: text/plain\n\n"

def error_exit
  puts "ERROR! Exiting..."
  exit
end

# プリンシパル名
cgi = CGI.new

princ = cgi.remote_user
if (princ == "") then
  error_exit
end

# 分解してみる
if ( princ =~ /^(([^\/]+)\/)?([^@]+)+@(.+)$/ ) then
        primary_name = $2
        instance     = $3
        realm        = $4
else
        error_exit
end

puts "Your principal's info:"
puts " Primary name: #{primary_name}" if (primary_name != nil)
puts " Instance:     #{instance}"     if (instance != nil)
puts " Realm:        #{realm}"        if (realm != nil)

wgetはspnegoに対応していないので、テストにはcurlを使う。

$ curl -u : --negotiate  http://test.example.com/whoareyou.cgi

spnegoの使用を指示する"--negotiate"オプションだけではなく、"-u :"も必要。本来は"-u user:pass"のようにしてユーザ名をパスワードを明示するために使う。