Samba-ad-dc シングルサインオンの設定

Q&Aシステムについて色々なシステムを試していく中で、LDAP認証に対応していないが、シングルサインオンに対応しているというシステムが現れた。これは…本気で取り組むべき時が来たようだ。





今回取り組んだのはSPNEGO。Samba ad dc導入当時に知っていたシングルサインオンの仕組みはSPNEGOだけで、2年越しの実現となった。

やること。

 

環境

Ubuntu 18.04でSamba ad dcを使ってドメインを構成し、1台のリアルWindows 10 Proと、1台のUbuntuサーバー、1台の仮想Windows 10 Pro(試用版を使わせていただきIEとChromeを動かす)を管理している。

Realm = HOGESERVER.HOGEDDNS.JP
Domain = MYHOME

Samba ad dcにはユーザーとして家族・親類を登録しており、KopanoAlfrescoをLDAP認証するように設定を済ませている。そして、色々なシステムをインストールしては、LDAP認証ができるかどうかを試したりもしている。

Sambaに内蔵しているDNSをDynamicDNSとして利用するためにスクリプトを動かしていて、そこでheimdal-clientsをインストールしていた。選択肢にはMIT版もあるが、SambaはHeimdal Kerberosのソースを取り込んでいると言うことで相性がいいかなぁくらいの理由だった。

SSOの学習

色々な技術があるけれど、今すぐ直結しそうなものを5つほど。

SPNEGO(今回の対象)

Kerberos認証をベースに実装されていて、大雑把にいうと

  1. ログインするときにADで認証を受けてチケット(TGT)を受け取る。
  2. SSOに対応したシステムにアクセスしたらADにチケット(TGT)を提示し、ADからサービスを受けるためのチケット(ST)を受け取る。
  3. サービスを受けるためのチケットをSSO対応システムに提示する。
  4. SSO対応システムは提示されたチケットで正式ユーザーとして扱う。

ってな具合なのかなと思っている。

SAML

ユーザーがSP(Service Provider)にアクセすると、SPからIdP(Identity Provider)に認証要求が飛び、IdPは承認してユーザーの情報をSPに戻す。ドメインを超えてやりとりできて便利。
IdPから始まる流れもあって、この場合はIdP側からサービスに進めるような仕組みが必要なんだろうなと思った。
CYBERNET / SAMLとは

検索してみると、チケットという言葉は出てこない。
大きなテーマになりそうなので別途。

DiscourseでSAML認証を試してみた。※2020/08/20追記

OpenID

あるサービスを利用しようとするとき、ユーザーは認証サーバーにサインインする。サービスを利用するために利用するアプリケーションは、その認証サーバーにIDトークン発行を依頼し、受け取ったIDトークンを使ってサービスにアクセスする、ということのようだ。
情シスNavi. / 【情シス基礎知識】OpenID Connectとは?

OAuth

とあるサイトAは、別のサービスプロバイダーBから「この機能を使ってもいいよ」という許可を受けている。Aに接続したユーザーは、Aを通じてBの機能を利用する、ということのようだ。
TDK / テクの雑学 / 第147回 便利と危険は裏返し 〜 知っておきたい、OAuthの仕組み 〜

ADFS

ADにチケットを提示すると、サービスチケットが帰ってくる。これをADFSサーバーに渡すとトークンが戻され、このトークンでサービスに接続する。
Serverworks / Active Directoryを通して知る認証・認可(承認)

OSSでこれを実現できるんだろうか?調べてないから分からない。

Kerberos関連の構成確認

ドメインを構築する際に、Kerberos認証のところには全く手を付けなかった。Samba ad dc構築の記事を書いたときに色々と教えていただいたサイトを改めて読み直し、問題がないか確認する。
iCRAFT / 【新人研修2016-5】 Samba4でActive Directory Domain Controller構築
Qiita / Samba4 を使用したKerberos バックエンドなSamba Active Directory を構築する

インストールされているKerberosクライアントの確認

Kerberosクライアントというのが正しいのかどうか分からないが、Apacheで使用するモジュールがkrb5-userを求めている。何が入っているのか調べてみる。

$ dpkg -l heimdal-clients krb5-user
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                     Version           Architecture      Description
+++-========================-=================-=================-=====================================================
ii  heimdal-clients          7.5.0+dfsg-1      amd64             Heimdal Kerberos - clients
un  krb5-user                <none>            <none>            (no description available)
Kerberos

※何度も入れ替えたのでどちらもリストに載っているが、インストールしていなければエラー表示されるかもしれない。

うちはheimdal-clientsの運用だったので入れ替えたが、そのままでも行けるかもしれない(やってみた感じ大体問題ないように思えたけど、問題があってもサポートされないかも)。

■krb5-userに入れ替え
$ sudo apt install krb5-user

■heimdal-clientsに入れ替え
$ sudo apt install heimdal-clients

 

krb5.conf

Samba ad dcを構成したときに、/var/lib/samba/private/krb5.conf に基本的なファイルが作成されており、これが/etc配下にあれば良いらしい。
これは/etc配下にあった(日付に2週間の差があったので、何かにトライしていじったのかもしれないが、中身は一緒だった)。

/etc/krb5.conf
[libdefaults]
    default_realm = HOGESERVER.HOGEDDNS.JP
    dns_lookup_realm = false
    dns_lookup_kdc = true

[realms]
HOGESERVER.HOGEDDNS.JP = {
    kdc = addc.hogeserver.hogeddns.jp
    admin_server = addc.hogeserver.hogeddns.jp
}

[domain_realm]
.hogeserver.hogeddns.jp = HOGESERVER.HOGEDDNS.JP
hogeserver.hogeddns.jp = HOGESERVER.HOGEDDNS.JP

※青文字部分を2020/08/22に追加。試していた日にはなくても動いていたんだけれども、無指定で見に行けるほうが不思議。

チケットを取り出してみる

Samba ad dcサーバーにSSHでログインしてコマンドを叩いてみる。

■チケット発行
$ kinit rohhie@HOGESERVER.HOGEDDNS.JP
Password for rohhie@HOGESERVER.HOGEDDNS.JP: [発行しようとするユーザーのパスワード]

■チケット確認
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: rohhie@HOGESERVER.HOGEDYDNS.JP

Valid starting       Expires              Service principal
06/27/2020 15:31:47  06/28/2020 01:31:47  krbtgt/HOGESERVER.HOGEDDNS.JP@HOGESERVER.HOGEDDNS.JP
        renew until 06/28/2020 15:31:43

■チケット破棄
$ kdestroy

どうやらチケットは取り出せる模様。PCがドメイン参加できるようになっているんだから、当たり前といえば当たり前だけど…。

ユーザーkrbtgt

krgtgtというKerberosサービスユーザーがいて、Key Distribution Center Service Accountとされている。Builtinユーザーにはなっていないが、とても大切なユーザーのようだ。

Denied RODC Password Replication Groupに所属しており、このドメインの読み取り専用ドメインコントローラーで、パスワードの複製を持てない人達らしい。

パスワードの複製を持てない?
Gihyo.jp / ここは知っておくべき!Windows Server 2008技術TIPS

複数の拠点にドメインコントローラーがあったとき、よそにコピーは持たせず、読み取り専用にして使わせることで、本体を守る機構っぽい。

他のシステムからのKerberos認証には、新しいユーザーを作ってDenied RODC Password Replication Groupに入れて使うのがよさそう。他のシステムにユーザー情報をいじらせないならば。

SPNEGO設定

シングルサインオンと一口に言っても色々なやり方があって…理解を深めるのはこれからなんだけれど、結果からするとSamba ad dcとApacheでSPNEGO Web認証っていうのを目指していたらしい。
なんとなく調べてこうかな?と思っていたものがこれだった。
SEの道標 / 【図解】初心者にも分かるKerberos認証とspnegoの仕組み ~SSOのシーケンス,統合windows認証について~

Samba ad dcの設定

Windows Serverではktpassというコマンドを使うと、サービスプリンシパル名を構成し、サービスの共有シークレットキーを含むkeytabを生成してくれる模様。
Microsoft Docs / ktpass

同じことをSamba ad dcで実行しよう。

認証に使うユーザーの作成

Samba ad dcサーバーにsshでログインして実行。
まずはユーザーの作成。

■認証用のシステムユーザーの作成
$ sudo samba-tool user create ssoauth --unix-home /var/run --login-shell /usr/sbin/nologin
New Password: [ssoauthのパスワード、複雑な長いのを設定]
Retype Password: [同じものを再度入力]
User 'ssoauth' created successfully

■Denied RODC Password Replication Groupグループへの参加
$ sudo samba-tool group addmembers "Denied RODC Password Replication Group" ssoauth
Added members to group Denied RODC Password Replication Group

■usersグループからの離脱
$ sudo samba-tool group removemembers users ssoauth
Removed members from group users

■ユーザーIDの確認
$ id myhome\\ssoauth
uid=3000064(MYHOME\ssoauth) gid=100(users) groups=100(users),3000064(MYHOME\ssoauth),3000005(MYHOME\denied rodc password replication group),3000009(BUILTIN\users)

■パスワードを無期限にする
$ sudo samba-tool user setexpiry ssoauth --noexpiry
Expiry for user 'ssoauth' disabled.

※BUILTIN\usersから削除しても表示上残っている。Samba ad dcを稼働させているサーバーのgroup userとSambaのBUILTIN\userを紐付けていて、その上idコマンドで確認しているからそう見えていると思われる。LDAPで情報を見に行ったら、BUILTIN\usersからはちゃんと削除されていた。

ユーザーにサービスプリンシパル名を追加

サービスプリンシパル名は HOST/ホストのFQDNで登録。

$ sudo samba-tool spn add HOST/hogeserver.hogeddns.jp ssoauth
$ sudo samba-tool spn list ssoauth
ssoauth
User CN=ssoauth,CN=Users,DC=hogeserver,DC=hogeddns,DC=jp has the following servicePrincipalName:
         HOST/hogeserver.hogeddns.jp

SPNEGOが上手くいかず、ベーシック認証になってしまう現象に悩まされたとき、改めて流れを確認。
サーバーがネゴシエーションを求めたら、ChromeはTGTを提示するはずだが、できていないんだなと。
FreeIPA / Web App Authentication/Example setup

実際に間違っていたのはサービスプリンシパル名で、HTTP/addc.hogeserver.hogeddns.jp としていたのが問題の原因だった。サービスプリンシパル1つだけをエクスポートしている例を見つけられなかったよ、解決に途方もなく時間が掛かったよ。

keytabの生成

ウチは既にApacheをインストールしていたので、ここにディレクトリを掘ってkeytabを作る。
まだ、Apacheをインストールしていないのなら先にインストールしておくといいと思う。

keytabの出力について探していたら、再びこちらにお世話になった。
(全部のキーを出力する必要なんてないから、個別に出そうとしてここにたどり着いた)
Qiita / Samba4を用いたWindows/Linux認証統合とネットワークホームディレクトリ

暗号化方式についても確認してみていた。Windows 10のコマンドプロンプトでklistを叩いてみたところ、[AES-256-CTS-HMAC-SHA1-96]となっていた。
keytabにはそんなものは出力されていないので、調べて手順に追加してみた。
Samba wiki / Generating Keytabs

■Administratorのチケット発行
$ kinit administrator
Password for administrator@HOGESERVER.HOGEDDNS.JP: [Administratorのパスワード]

■対応する暗号化種類を強化
$ sudo net ads enctypes set ssoauth
'ssoauth' uses "msDS-SupportedEncryptionTypes": 31 (0x0000001f)
[X] 0x00000001 DES-CBC-CRC
[X] 0x00000002 DES-CBC-MD5
[X] 0x00000004 RC4-HMAC
[X] 0x00000008 AES128-CTS-HMAC-SHA1-96 ※この部分にチェックが入る
[X] 0x00000010 AES256-CTS-HMAC-SHA1-96 ※ 〃

■Administratorのチケットを破棄
$ kdestroy

■keytabを出力
$ sudo mkdir /etc/apache2/keytab
$ sudo samba-tool domain exportkeytab /etc/apache2/keytab/ssoauth.keytab --principal=HOST/hogeserver.hogeddns.jp
Export one principal to /etc/apache2/keytab/ssoauth.keytab

■keytabの中身を確認(サービスプリンシパルがないと成功したように見えてファイルが出力されない)
$ sudo klist -tke /etc/apache2/keytab/ssoauth.keytab
Keytab name: FILE:/etc/apache2/keytab/ssoauth.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   2 06/27/2020 18:40:00 HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP (aes256-cts-hmac-sha1-96)
   2 06/27/2020 18:40:00 HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP (aes128-cts-hmac-sha1-96)
   2 06/27/2020 18:40:00 HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP (arcfour-hmac)
   2 06/27/2020 18:40:00 HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP (des-cbc-md5)
   2 06/27/2020 18:40:00 HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP (des-cbc-crc)

■Apacheからkeytabにアクセスできるように所有者を変更
$ sudo chown www-data:www-data /etc/apache2/keytab/ssoauth.keytab

※samba-tool domain exportkeytab はファイルが既にあるならば追記してくれる。

このkeytabは他のホストでも使うことができる。
検証用に temp.hogeserver.hogeddns.jp というホストを立ててSSOしてみたが、ssoauthにサービスプリンシパルとしてHOST/temp.hogeserver.hogeddns.jp を追加し、それをkeytabに出力、そのkeytabファイルをtemp.hogeserver.hogeddns.jpに持って行けばSSOできる。

ところで、試行錯誤の過程で追加した余計なキーを消したくなった。

$ sudo ktutil
ktutil:  read_kt /etc/apache2/keytab/ssoauth.keytab
ktutil:  list
slot KVNO Principal
---- ---- ---------------------------------------------------------------------
   1    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   2    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   3    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   4    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   5    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   6    2         HTTP/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   7    2         HTTP/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   8    2         HTTP/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   9    2         HTTP/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
  10    2         HTTP/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
ktutil:  delete_entry 6 ←スロット番号指定
ktutil:  delete_entry 6
ktutil:  delete_entry 6
ktutil:  delete_entry 6
ktutil:  delete_entry 6
ktutil:  list
slot KVNO Principal
---- ---- ---------------------------------------------------------------------
   1    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   2    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   3    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   4    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
   5    2         HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
ktutil:  quit

無事に消えた。

Apacheの設定

今まで、Apacheの認証といえばクライアント証明書を必須にしたくらいで、ベーシック認証すら使ったことがなかった。
Apache HTTP SERVER PROJECT / モジュール一覧
Apache HTTP SERVER PROJECT チュートリアル / 認証、承認、アクセス制御

mod-auth-gssapi編

SPNEGO認証を実現する1つのモジュールが mod_auth_gssapi だった。
Github / gssapi / mod_auth_gssapi

インストールするだけで、モジュールは有効化される。

$ sudo apt install libapache2-mod-auth-gssapi

既存の環境にお試しポートで公開。

/etc/apache2/sites-available/hogeserver.conf
Listen 9443

<VirtualHost *:443>
    既存の設定
</VirtualHost>

<virtualhost *:9443="">
    ServerName  hogeserver.hogeddns.jp
    ServerAdmin webmaster@hogeserver.hogeddns.jp

    DocumentRoot /var/www/html

    ErrorLog  ${APACHE_LOG_DIR}/sso-error.log
    CustomLog ${APACHE_LOG_DIR}/sso-access.log combined

    SSLEngine On
    #LogLevel debug
    SSLCertificateFile    /etc/ssl/private/hogeserver.crt
    SSLCertificateKeyFile /etc/ssl/private/hogeserver.key

    <location />
        AuthType            GSSAPI
        AuthName            "GSSAPI Sign in"
        GssapiCredStore     keytab:/etc/apache2/keytab/ssoauth.keytab
        GssapiAllowedMech   krb5
    #   GssapiBasicAuth     On
        require             valid-user
    </location>

</virtualhost>

※ドメインの外からアクセスすることを許すなら、GssapiBasicAuthの行を有効化させればOK。ユーザーとパスワードはドメインのものが使えて、ユーザーからはLDAP認証みたいに見えそう。

mod-auth-kerb編

実は最初に見つけたのはこれ。こちらも外部で提供されており、設定マニュアルはこちらに。
Kerberos Module for Apache / Configure

$ sudo apt install libapache2-mod-auth-kerb

こちらも、お試しポートの設定例。

/etc/apache2/sites-available/hogeserver.conf
Listen 9443

<VirtualHost *:443>
    既存の設定
</VirtualHost>

<virtualhost *:9443="">
    ServerName  hogeserver.hogeddns.jp
    ServerAdmin webmaster@hogeserver.hogeddns.jp

    DocumentRoot /var/www/html

    ErrorLog  ${APACHE_LOG_DIR}/sso-error.log
    CustomLog ${APACHE_LOG_DIR}/sso-access.log combined

    SSLEngine On
    #LogLevel debug
    SSLCertificateFile    /etc/ssl/private/hogeserver.crt
    SSLCertificateKeyFile /etc/ssl/private/hogeserver.key

    <location />
        AuthType            Kerberos
        AuthName            "Kerb Sign in"
        KrbServiceName      HOST/hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
        KrbAuthRealms       HOGESERVER.HOGEDDNS.JP
        Krb5KeyTab          /etc/apache2/keytab/temp.keytab
        require             valid-user
    </location>

</virtualhost>

もう終わってる的な記事もでており、実際に古いとは思うけれど、少なくともUbuntu 18.04では上手く動いていて問題はない。
選択した場合のデメリットは、ドメイン参加していない人からのアクセスを設定1行では止められないことくらいか。

どちらを選んでも大丈夫なんじゃないかと思う。

試してみる

Windows 10でTGTを確認

klistコマンドでチケットを確認できるとのこと。
Corrupted Work / Kerberosチケット情報を確認する

>klist

現在のログオン ID: 0:0x807d5

キャッシュされたチケット: (1)

#0>     クライアント: rohhie @ HOGESERVER.HOGEDDNS.JP
        サーバー: krbtgt/HOGESERVER.HOGEDDNS.JP @ HOGESERVER.HOGEDDNS.JP
        Kerberos チケットの暗号化の種類: AES-256-CTS-HMAC-SHA1-96
        チケットのフラグ 0x40e00000 -> forwardable renewable initial pre_authent
        開始時刻: 6/22/2020 18:44:56 (ローカル)
        終了時刻: 6/23/2020 4:44:56 (ローカル)
        更新期限: 6/29/2020 18:44:56 (ローカル)
        セッション キーの種類: AES-256-CTS-HMAC-SHA1-96
        キャッシュ フラグ: 0x1 -> PRIMARY
        呼び出された Kdc: addc.hogeserver.hogeddns.jp

※ログイン直後に実行した結果、有効期間9時間のチケットが配布されている。

 

Internet Explorerの設定とテスト

SSOのために行う設定がいくつか。
Shibboleth / Single sign-on Browser configuration

インターネットオプションで「ローカル イントラネット」を選択する。

サイトボタンから接続先サイトを追加する。
今回の例だと hogeserver.hogeddns.jp となる。

さらに「レベルのカスタマイズ」をクリックし、[ユーザー認証]→[ログオン]→[イントラネット ゾーンでのみ自動的にログオンする] を選択。

ここまでの設定をした状態でサーバーにアクセスしたところ、統合Windows認証がはたらいたらしく、裏で認証が走ってアクセスができた。

アクセスログにはこんなのが出ている。

24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - - [28/Jun/2020:08:17:46 +0900] "GET / HTTP/1.1" 401 2499 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)"
24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - rohhie@HOGESERVER.HOGEDDNS.JP [28/Jun/2020:08:17:46 +0900] "GET / HTTP/1.1" 200 3841 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)"
24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - rohhie@HOGESERVER.HOGEDDNS.JP [28/Jun/2020:08:17:46 +0900] "GET /favicon.ico HTTP/1.1" 404 800 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)"

※誰がアクセスしてきているのか分かる。

Chromeの設定とテスト

インターネットオプションの設定を読み取っている?らしく、統合Windows認証が働いたっぽい。
アクセスログにはこんなのが出ている。

24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - - [28/Jun/2020:08:21:53 +0900] "GET / HTTP/1.1" 401 2917 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56"
24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - rohhie@HOGESERVER.HOGEDDNS.JP [28/Jun/2020:08:21:53 +0900] "GET / HTTP/1.1" 200 3820 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56"
24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - - [28/Jun/2020:08:21:54 +0900] "GET /icons/ubuntu-logo.png HTTP/1.1" 401 732 "https://hogeserver.hogeddns.jp:9443/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56"
24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - rohhie@HOGESERVER.HOGEDDNS.JP [28/Jun/2020:08:21:54 +0900] "GET /icons/ubuntu-logo.png HTTP/1.1" 200 3945 "https://hogeserver.hogeddns.jp:9443/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56"
24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - - [28/Jun/2020:08:21:54 +0900] "GET /favicon.ico HTTP/1.1" 401 732 "https://hogeserver.hogeddns.jp:9443/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56"
24nn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - rohhie@HOGESERVER.HOGEDDNS.JP [28/Jun/2020:08:21:54 +0900] "GET /favicon.ico HTTP/1.1" 404 793 "https://hogeserver.hogeddns.jp:9443/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56"

※こちらも、誰がアクセスしてきているのか分かる。

ドメインに参加していないPCからのアクセス

ドメインに参加していないUbuntuデスクトップからアクセスしてみたところ、ログイン画面が表示される。
そこにユーザー情報を入力したところ、承認され、ページにアクセスできた。

■ログイン画面が出たとき
fdnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - - [28/Jun/2020:08:35:44 +0900] "GET / HTTP/1.1" 401 2965 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.106 Chrome/83.0.4103.106 Safari/537.36"

■ユーザー情報を入力して承認されたとき
fdnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - rohhie@HOGESERVER.HOGEDDNS.JP [28/Jun/2020:08:36:03 +0900] "GET / HTTP/1.1" 200 4070 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.106 Chrome/83.0.4103.106 Safari/537.36"
fdnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - rohhie@HOGESERVER.HOGEDDNS.JP [28/Jun/2020:08:36:04 +0900] "GET /icons/ubuntu-logo.png HTTP/1.1" 200 3667 "https://hogeserver.hogeddns.jp:9443/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.106 Chrome/83.0.4103.106 Safari/537.36"
fdnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn:nnnn - rohhie@HOGESERVER.HOGEDDNS.JP [28/Jun/2020:08:36:04 +0900] "GET /favicon.ico HTTP/1.1" 404 515 "https://hogeserver.hogeddns.jp:9443/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.106 Chrome/83.0.4103.106 Safari/537.36"

 

設定の配布(グループポリシー)

Kerberos認証のテストが上手くいったので、設定を配布したい。

イントラネットゾーンのサイト

こちらに4つのやり方が丁寧に書かれている。人によって変わる設定ではないので、コンピューターの構成で適用する。
焦げlog / グループ ポリシーを用いて Internet Explorer 11 の各ゾーンのサイト設定を行う

グループポリシーの管理を起動し、Default Domain Policyを選択。
Default Domain Policyを右クリックしてコンテキストメニューから「編集」をクリックしてグループポリシー管理エディターを起動する。

コンピューターの構成→ポリシー→管理用テンプレート→Windows コンポーネント→Internet Explorer→インターネット コントロールパネル→セキュリティページの順でたどる。

そこに「サイトとゾーンの割り当て一覧」というアイテムがあるので、構成を有効にしてサイトを追加する。

この方法だと、ユーザーが独自に追加したサイトは消えてしまう。管理範囲が狭ければ都度足せばいいかもしれないが、広い場合はレジストリに追加するやり方がいいのかもしれない。
※未構成に戻してみたら、ユーザー個別の設定が復活した。

自動ログオン

同様に、コンピューターの構成→ポリシー→管理用テンプレート→Windows コンポーネント→Internet Explorer→インターネット コントロールパネル→セキュリティページ→イントラネット ゾーンの順でたどる。

そこに「ログオンのオプション」というアイテムがあるので、構成を有効にして「イントラネット ゾーンのみで自動的にログオンする」を設定する。

端末への適用

自動的に配布されると思うが、設定を試すときなどにはgpupdateコマンドが使える。
@IT / gpupdateでグループポリシーの適用を強制する

やったこと

Samba AD DCのFunctional Levels

以前、このことを調べたとき、インストール時のデフォルトが2008_R2で、上げようとして失敗した記事を書いていた。
でも、これによると少なくとも2012_R2まではサポートしているかに見える。
Samba Wiki / Raising the Functional Levels

前回実施したのはこれ。

$ sudo samba-tool domain level raise --domain-level 2012_R2 --forest-level 2012_R2
ERROR: Domain function level can't be higher than the lowest function level of a DC!

よく読むと、Domain function levelはDCの最低function levelレベルよりも高くできない、と書いてある。

確認。

$ sudo samba-tool domain level show
Domain and forest function level for domain 'DC=hogeserver,DC=hogeddns,DC=jp'

Forest function level: (Windows) 2008 R2
Domain function level: (Windows) 2008 R2
Lowest function level of a DC: (Windows) 2008 R2

Lowest function levelはどうやって上げるのかって調べようとしたけど、結局、実装されていないらしい。
表だけ見たら実装されているのかと思った…。

*Functional level is included for use against Windows, but not supported in Samba. Kerberos improvements from Windows Server 2012 and 2012 R2 are not implemented in Samba.
*機能レベルはWindowsで使用するために含まれていますが、Sambaではサポートされていません。 Windows Server 2012および2012 R2からのKerberosの改善はSambaに実装されていません。

Samba Wiki / Raising the Functional Levels

TGTを提示してSTを取得する

ChromeでSSOにならないところまでたどり着いて、Apacheで設定しているにもかかわらずベーシック認証しか動いていなくて、チケットのやりとりができていないのではないかと考えはじめた。
Qiita / Keycloakで統合Windows認証を試してみる
Qiita / WindowsデスクトップSSOを使ってみる ※OpenAM

本来、ドメインに参加したWindows 10でユーザーがログインしたら、TGT(Ticket Granting Ticket)が発行され、これを提示すれば各種サービスのチケットが取得できるのではなかったか。

Chromeのデバッガでやりとりを眺めてチケットのやりとりができていない、Apacheにはネゴシエートするように設定しているから…keytabに登録したサービスプリンシパルに問題あり、観点を絞り込んで調査を進めた。

SSOのサービスプリンシパルの先頭をどうするのか

ApacheでKerberos認証するには…とようやく見つけたのがこの記事。
サービスプリンシパルを作ってApacheに組み込むという話、と理解。
chaperone / samba/SSO/http

でもまだ整理しきれず、Kopanoのマニュアルを頼ってみたところ…
Kopano側の設定だけじゃなく、Apache側の設定が書かれている。
やっぱ凄いよKopano。
Kopano Knowledge Base / Kopano WebApp Kerberos Single Sign On configuration

ここから、Apacheでは認証モジュールを利用して「誰かがあるディレクトリにアクセスしてきたら、Kerberos認証を使ってその[誰か]を認証する」ってことをすれば良く、「認証にはkeytabを使うので、それを事前に用意しておくよ」と理解。

keytabに登録するサービスプリンシパル名の実例を探してみると、HTTPだけでなくHTTPSで上手くいったという投稿も。でも動かない…となって、HOSTで試したらKerberos認証が動き出した。

起きたこと

An unsupported mechanism…

認証機構が働き始めた?と思ったところでエラー。
動作的にも2回認証を求められ、2回目に上手くいく感じ。

[Sun Jun 21 07:44:54.654751 2020] [auth_kerb:error] [pid 2288:tid 139753552811776] [client fdnn:nnnn:nnnn:nnnn::nnnn:pontno] gss_accept_sec_context() failed: An unsupported mechanism was requested (, Unknown error)

ここに詳しいレポートがあった。
ExpertSys / Drupal SSO: An unsupported mechanism was requested…

実際に同じログが出ていた。

[Sun Jun 21 08:36:52.750849 2020] [auth_kerb:debug] [pid 5472:tid 139753412331264] src/mod_auth_kerb.c(1965): [client fdnn:nnnn:nnnn:nnnn::nnnn:59679] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos
[Sun Jun 21 08:36:52.751103 2020] [auth_kerb:debug] [pid 5472:tid 139753412331264] src/mod_auth_kerb.c(1298): [client fdnn:nnnn:nnnn:nnnn::nnnn:59679] Acquiring creds for HTTP/addc.hogeserver.hogeddns.jp@HOGESERVER.HOGEDDNS.JP
[Sun Jun 21 08:36:52.751833 2020] [auth_kerb:debug] [pid 5472:tid 139753412331264] src/mod_auth_kerb.c(1721): [client fdnn:nnnn:nnnn:nnnn::nnnn:59679] Verifying client data using KRB5 GSS-API
[Sun Jun 21 08:36:52.751976 2020] [auth_kerb:debug] [pid 5472:tid 139753412331264] src/mod_auth_kerb.c(1737): [client fdnn:nnnn:nnnn:nnnn::nnnn:59679] Client didn't delegate us their credential
[Sun Jun 21 08:36:52.752097 2020] [auth_kerb:debug] [pid 5472:tid 139753412331264] src/mod_auth_kerb.c(1765): [client fdnn:nnnn:nnnn:nnnn::nnnn:59679] Warning: received token seems to be NTLM, which isn't supported by the Kerberos module. Check your IE configuration.
[Sun Jun 21 08:36:52.752223 2020] [auth_kerb:debug] [pid 5472:tid 139753412331264] src/mod_auth_kerb.c(1158): [client fdnn:nnnn:nnnn:nnnn::nnnn:59679] GSS-API major_status:00010000, minor_status:00000000
[Sun Jun 21 08:36:52.752365 2020] [auth_kerb:error] [pid 5472:tid 139753412331264] [client fdnn:nnnn:nnnn:nnnn::nnnn:59679] gss_accept_sec_context() failed: An unsupported mechanism was requested (, Unknown error)

※ログの示し方は参照先の方が洗練されているが、ここでは全てを載せてみた。

インターネットのプロパティで「ローカル イントラネット」のWebサイトに今回構築中の hogeserver.hogeddns.jp を追加したところ、認証回数が減った。
Qiita / ApacheでActive Directory SSO

  • Chrome(通常) 1回
    NTLMの認証は行われず(エラーログは残るが先に進む)、Apacheの認証が必要。
  • Chrome(シークレットモード) 2回
    NTLMの認証(正しいユーザーとパスワードを入力してもエラーログが残る)とApacheの認証が必要。
  • IE 0回
    NTLMの認証が必要だが、Apacheの認証はスルー。
    ただ、ここで認証をキャンセルしてエラーページを表示させた後、もう一度ページにアクセスするとNTLMの認証なしでアクセスできる。

※IEとの相性が抜群で、ここまでの設定で完成したように見える。その時代のものだから?

ブラウザが情報をキャッシュするので、上手くいっているように見えてしまうこともあり、だいぶ手間が掛かった。

後から考えると、NTLMの認証は自動入力になったけれど、Kerberosのチケットのやりとりはできておらず、Apacheがベーシック認証でユーザー情報を要求し、Kerberos認証を通してくれていたのだと思われる。

調べていくと…
Github / gssapi / mod_auth_gssapi

このモジュールは、古くなったmod_auth_kerbの代替として構築されています。その目的は、GSSAPI呼び出しのみを使用し、使用される実際のメカニズムにできるだけ依存しないことです。

最初はこれも上手く動かなかったが、だいぶ時間を掛けて最終的に本編の設定にたどり着いた。

さいごに

最初の頃に見つけて最後まで為になったサイトがこちら。
chaperone / samba/SSO/http

トラブル事例を探し回ったけれども、Windows Serverでkeytabを出力しているケースでは中身をさらしてくれていることもなく、そうなると「上手くいっているKeytabの中身」を見たいと思ったとき、ここしかよりどころがない言っても過言ではない状態だった。

この記事ではHTTPのサービスプリンシパルを追加していることが強調されているが、keytabは全部出力する手法が使われ、HTTPもHOSTも出力されていた。この手法に沿っていたら…もっと楽にSPNEGO認証が始まったのかもしれない。

今回は、会社で使う技術になりそうだったので1つ1つ細々見ていったが、こちらに知識と理解力があれば記事を見ただけで十分に理解ができた可能性が高い。

素晴らしい記事にとても感謝している。

お気軽にどうぞ ~ 投稿に関するご意見・感想・他

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です