カテゴリー別アーカイブ: 学認

学認IdPをShibboleth3にする際のメモ

Shibboleth 2.Xが2016年夏にEnd-of-Lifeを迎えるため、そろそろ各学認Shibboleth IdP管理者様の方でもShibboleth 3.Xへの移行作業をされていると思います。学認サイトもShibboleth 3.X系の情報が増えていますが、まだ2.Xの頃の情報の整理された充実ぶりには及ばないようで、アップデート作業はかなり難儀しました。そのため、現状の最新バージョンであるShibboleth 3.2.1にアップデートを行った際にはまった罠について簡単に紹介しておこうと思います。

なお、まだマイナーバージョンの違いで、一部の重要そうな機能の設定が異なったり、この機能は絶対に必要だ、というような機能が3.2.0や3.2.1になってから追加されていたりするので、色々悩ましいのですが、とりあえず3.2.1ではなんとか2.Xから我々が使っている概ねすべての機能を移行することができました。作業を3.2.0以前で始められている方は、今からでも3.2.1にターゲットを変更することを強くおすすめします。

なお、以下の記述はまずCentOS 6+OpenJDK 7+Tomcat 7で構築した後、もう一度CentOS 7+Oracle JDK 8+Tomcat 8の組み合わせで構築しなおした経験にもとづいています。双方の差は、Tomcatの違いに起因する、consent-interceptのバックエンドのMySQL接続設定(conf/global.xml)の部分のみでした(もちろん、OSのセットアップやJava, Tomcatのインストール手順などは大きく異なりますが、Shibboleth3の設定という観点からのみ考えると、差は大きくありません)。

それでは、はまった点を紹介していきます。

LDAP由来の属性がSPに送信されない

LDAPの設定ファイルconf/ldap.properties中のidp.attribute.resolver.LDAP.returnAttributesを適切に設定しないと、LDAP経由の属性がSPに送信されない(LDAPに要求する属性をコンマ区切りで並べる必要がある)。ちなみにデフォルトではこの値はcn,homephone,mailのみとなっている。

(2016/03/24 追記)学認MLでご指摘いただいたのですが、こちらの問題は学認技術ガイドが現在提供しているattribute-resolver-template.xmlを利用した場合は生じないようです。

情報提供ありがとうございました。

属性送信許可がデフォルトで有効

Shibboleth3.Xでは、かつてのuApprove.jpプラグイン相当のconsent-intercept機能がShibboleth本体に搭載され、さらにデフォルトで有効化されているため、もしこの機能を利用しない場合は、conf/relying-party.xmlに次の設定が必要である(もちろん学認の場合はこの機能を利用するほうがおすすめ設定である)。

続きを読む

Shibboleth IdPのログをPostgreSQLに格納する

Shibbolethのログ保存の問題

Shibboleth IdPのログは通常、サーバ上のテキストファイルとして記録され続けますが、この形式では次のような問題があります。

  • 複数サーバでロードバランスしている場合にログが分散してしまう(Shibbolethのロードバランサ配下での利用に関してはこちら)。
  • ログを様々な条件で検索したい場合に不便。

特に、Shibbolethは標準ではログイン履歴的な情報を参照することが困難なため、監査ログ(idp-audit.log)の検索ができると特に便利です。

先行事例の検討

検索していたところ、いくつかの先行事例が見つかりました。例えば次のようなものがあります。

時間がたっぷりあれば、後者のほうが魅力的ではありますが、安易にやるならば前者のほうが実に簡単そうです。そこで、まずはsyslogベースで実現してみることにしましたが、やはりsyslogメッセージのパースは実現したいと思います。対象は監査ログということにしました。

(もちろん、信頼性やその他の問題から、Shibboleth IdPから直でDBに入れたほうが良いことはわかっているので、今後時間がある時に、そちらも試してみようかと思います) 続きを読む

Shibbolethのログインページをブックマーク可能にする

一般論として、Shibbolethのログインページはブックマークできません。もちろんブラウザからブックマーク操作をすることは可能ですが、再度そのブックマーク経由でログインしようとした場合、ログイン対象のアプリが識別できず、ユーザにとっては謎のエラーが出てしまいログインできません。

そこで、次のような方法を取れば、仮にブックマークしてしまった場合であっても、ポータルアプリなど、一番良く使われるであろうアプリケーションのログイン画面にリダイレクトが可能です。この手法は、ポータルのようなアプリがあることが前提となります。学認で専ら外部のアプリのみを利用している場合は、ローカルアプリとして学認ポータル的なものを作ると良いかもしれません。学認IdPにおけるローカルアプリの作り方に関してはこちらをご覧ください。

手法は超簡単です。Shibboleth IdPのlogin.jsp内で、ログイン対象アプリは <idpui:serviceName/> で表示されます。この部分を囲むタグ(なければ<span>を作れば良い)の中身をJavaScriptからDOMで読み取り、それが”Unspecified Service Provider”という文字列であれば、JavaScriptでポータルアプリのログインURLに飛ばしてやればよいのです。

こうすれば、IdPのログイン画面をブックマークしても、ユーザに表示されるのはUnspecified Service Providerへの謎のログイン画面ではなく、無事にポータルアプリ用のIdPログイン画面が瞬時に表示されます。

Tips的ですが、Shibbolethのユーザビリティで初心者が一番引っかかりやすいだろう部分を、これで解決できます。

Shibboleth関連サーバをロードバランサの下に置く場合の注意

ShibbolethのIdPやSP等のサーバを、SSLのオフローディングや冗長化のためにロードバランサの下に置く場合の注意点をまとめてみます。

Shibboleth IdPのロードバランサー利用

RNAT or client-IP

サーバをロードバランサー配下に置く場合、クライアントのIPアドレスをソースに持ったままサーバに届く設定と、特定のHTTPヘッダにクライアントのソースIPアドレスを入れて、ソースアドレスはロードバランサー自身となるタイプの2種類の構成が考えられます。前者はデフォルトルートをロードバランサーにする必要があるため、ロードバランサーで一種のNATを行います。

個人的には後者のほうがネットワーク構成に対する制約が少なくて好きなのですが、Shibbolethをロードバランサーの下に入れる場合は圧倒的に前者がお勧めです。後者だと、Apache, mod_proxy_ajp, Tomcat, Shibboleth IdPの各段階で色々設定してソースアドレスをShibboleth IdPに届けないと、ShibbolethのログにソースIPアドレスが記録されません。しかもいろいろな制約条件があります。

一回挑戦してみたのですが、あまりに複雑になるので諦めました。普通にNATするほうが良いと思います(諸事情で、NAT構成にするためにサーバにNICを足す羽目になりましたが…)。

SSLオフローディングに関する問題

ここでは、ロードバランサーでSSLオフローディングを行い、Apacheのmod_proxy_ajpとTomcat上のShibboleth IdPを単純に組み合わせて、80/tcpでロードバランサ経由のリクエストを受ける場合を考えます。

この場合、ShibbolethはSSLが必須のため、ブラウザが認証画面に移った際に、”Error Message: Message did not meet security requirements”というエラーが出て利用できません。

また、Tomcatはセキュアな通信の場合CookieにSecure属性を付けるようですが、この機能も働かなくなります。

これは、tomcatのserver.xmlで、AJPコネクタの設定を次のように変更すれば解決します(前者に対応するのがproxyPortとscheme、後者に対応するのがsecure)。

変更前:

変更後:

これで、エラーメッセージは発生しなくなり、またJSESSIONIDのCookieだけではなく、_idp_authn_ic_keyのCookieにもSecure属性が付くようになります。

続きを読む

Shibboleth SPとしてTomcatを用いた場合の属性受け渡し

ShibbolethはApacheからの環境変数として属性を受け渡すため、多くの環境では非常に簡単にアプリケーションから属性を取得することができますが、Tomcatはその例外の一つです(Tomcatのアプリにすんなりと環境変数を渡す方法が無いため)。今回実験環境でテストしたので、そのメモを残しておきます。

システム構成

Tomcat単体ではShibbolethのSPとなることはできないため、Shibboleth SPをApacheで構築し、そこからAJP経由で接続するのがもっとも簡単なように思えます。

たとえばCentOSであれば、/etc/httpd/conf.d/proxy_ajp.confみたいな感じでファイルを作成し、その中でTomcatのアプリケーション(ここでは/myapp/とする)を、

のようにAJPで繋ぎます。そして/etc/httpd/conf.d/shib.confの最後辺りに、

みたいな感じで/myapp/をShibboleth認証します(実際の環境では、ログインに必要なロケーションのみをShibboleth認証するほうがおすすめだと思います)。CentOSにおけるSPの構築は、学認の技術ガイドに詳しく解説されています。FreeBSD上での構築はこのサイトの昔の記事にあります。

以上の環境を仮定して、TomcatにShibboleth属性を渡す設定について紹介します。IdP側の設定は通常のSPと同じなので省略します。渡す属性はeduPersonPrincipalName(以下ePPN)を仮定します。 続きを読む

プロビジョニングの道具としてのOpenLDAP back-sql

OpenLDAPのバックエンドのおすすめはBDBなのですが、多くの場所から認証データを収集し、適切な形に編集してLDAP形式で公開する、いわばアカウント・プロビジョニング的な用途には、SQLのバックエンド機能(back-sql)も魅力的に見えます。

巨大なデータをトランザクションで全件更新しつつ、パスワードの更新は可能な限りリアルタイムで別テーブルに収集し、より新しいパスワードをクライアントに渡す…ような仕組みは、(単なるイメージなのかもしれませんが)やはりSQL系のデータベースに一日の長があるのではないかと考えます。

そんな魅力的に見えるOpenLDAPのback-sqlですが、実際に試してみると次のような欠点があります。

  • パフォーマンスが悪い
  • 設定が複雑すぎてわけがわからない

まずは性能面です。小規模なデータの場合はそれほどでもないのですが、大規模なデータを食わせると途端に悲惨な性能になってしまいます。実際に数万件のデータを食わせたところ、1秒に5件ほどしか検索ができないという悲惨な状況になりました。これではいくらなんでも実用的ではありません。

設定が複雑なのは、LDAPのスキーマを、SQLのスキーマとデータ(メタデータと呼ぶ)の双方を使って表現するからです。テーブル構造は難しくありませんが、メタデータの方はたしかに難解です。その分、さまざまなカスタマイズも可能と言えますが、そのメリットがあるかどうかはケースによりますが微妙でしょう。

これら2つの論点について、軽く解説します。なお、ここで用いたバックエンドのSQLデータベースはPostgreSQLです。

OpenLDAP back-sqlの性能問題

大規模なデータを入れると悲惨な性能になると評判のback-sqlですが、実はサンプルなどを見てスキーマをこさえて、何も考えずに大量のデータを入れると性能が悪化するのは当たり前で、PostgreSQL用のサンプルもMySQL用のサンプルも、インデックスの定義が含まれていません。

続きを読む

Shibbolethで複数のIDを同一人物としてログインさせる

(こちらの内容は、学認メーリングリストで国立情報学研究所の西村様、京都大学の針木様から頂いたアドバイスの内容を含んでいます)

Shibbolethにおいては、認証システムにおける「ユーザ名」に相当する概念が、uid(ログイン名)、ePPN(フェデレーション内で一意なユーザ名)、ePTID(IdP:SPのペアで一意なユーザ名)の3つがあります。

この仕組を利用して、他のID体系からShibbolethにユーザアカウントのプロビジョニングを行うにあたって、学内に複数のID体系が存在して、同一ユーザが複数のIDを持っている場合に、次のようなID管理を実現可能です。

  • ユーザはどのID体系でもIdPにログインできる
  • ログイン後は、どのID体系でログインしてもSPからは同一人物として見える

複数uidで同一ePPNのLDAPを用意する

まず、パスワードはuidに紐付いています。LDAP上にuidの異なる複数のエントリを設けることで、その双方でログインすることは可能となります。Shibbolethのuidはフリーフォーマットですので、「@ドメイン名」などのスコープを付けた形でuidを定義するなどの方法で、複数ID体系の衝突を防ぐことは可能でしょう。

そして、ePPNは一番広いアカウント体系のuidを採用するか、Trusted DBにあるユーザ識別可能な何らかの属性から生成して、LDAP上で同一人物は同一のePPNを持つようにすることで、ePPNを要求するSPからはどのuidでログインしても同一人物に見えるようにすることができます。

ePTIDは基本的にePPNとSPのentityIDから生成されるようにすれば、これもSPから見ればどのuidでログインしても同一人物に見えるようにすることができます。

これだけ読むと、LDAP上のデータを適切に用意することだけで実現できそうに思えるのですが、それほど簡単な話ではありません。

ePPNとePTIDをLDAPのePPN値ソースに変更する

まず、学認の標準テンプレートのattribute-resolver.xmlでは、ePPNをLDAPのePPNのエントリではなく、uidを流用するようになっています(2行目のsourceAttributeID=”uid”の部分)。

続きを読む

Shibboleth SPで学認独自属性にアクセスする

(2014年9月1日 追記) NIIの西村様から情報をいただき、これらの属性にアクセスするためのattribute-map.xmlは、https://meatwiki.nii.ac.jp/confluence/pages/viewpage.action?pageId=12158127#id-%E6%8A%80%E8%A1%93%E3%82%AC%E3%82%A4%E3%83%89-%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88 から取得できるということを教えていただきました。どうもありがとうございます。なお、以下の記事の内容は、そのまま掲載しておきます。

OSにShibboleth-SPをインストールした状態で、主なShibbolethの属性はアプリケーションから環境変数経由で読み出せるのですが、学認独自の属性に関しては、標準状態では読みだすことができません。

独自属性には、日本語の組織名(jaOrganizationName, jaOrganizationalUnitName)、氏名(jaSurName, jaGivenName, jaDisplayName)等の日本語データや、身分や学籍番号などを表すgakuninScopedPersonalUniqueCode等があります。

これらの属性にアクセスするには、Shibboleth SPの設定ファイルattribute-map.xmlの <Attribute>…</Attribute>内に、次のように追記することで実現可能です(環境変数経由でアクセスするときのパラメータ名は適当に短縮しています)。

なお、このファイル中にはたとえば

のように、OIDではなくパラメータの名前で定義されている行もありますが、これはShibboleth 1.3対応のものなので、Shibboleth2系でアプリケーションを構築するのであれば必要ありません。

OIDに関しては、学認サイトの属性リストページで調べられますので、上記に挙げられていないパラメータにアクセスしたい場合は、ここからOIDを調べてください。

学認用Shibbolethリバースプロキシの構築

学認で利用されている認証ソフトウェアであるShibbolethは、SP部分はC++で記述されているため、SPの動作にJava VMの必要などもなく、既存のシステムへの組み込みも比較的容易です(IdPはJava VMやtomcatが必須です)。一方で様々な理由で、認証リバースプロキシがあると、内製ではないWebアプリの対応が楽になる場合があります。

そのため、Shibbolethの認証リバースプロキシを構築してみました。作業環境にはFreeBSDを用いましたが、CentOS等の場合でもそれほど違いはないと思います。

まずは、shibboleth-spをインストールします。FreeBSDの場合、標準だとapache22がprefork MPMでインストールされてしまい、メモリを無駄遣いするので、このあたりの手順でworker MPM版をインストールするのがお勧めです。

そして、ApacheのSSLを適切に設定し、SPとしての設定も行います。リバースプロキシを使って実現するようなサービスはたいてい学内サービスでしょうから、学認のSPとしてグローバルに登録しない、ローカル的なSPとしての構築をしたい場合はこの辺りの手順を参考にしてください。

そして、ApacheのSSL設定部分(FreeBSDならば/usr/local/etc/apache22/extra/httpd-ssl.conf、CentOSならば/etc/httpd/conf.d/ssl.confあたり)の<VirtualHost _default_:443>…</VirtualHost>の中で、次のような設定を行います。ここで、プロキシ先は平文で、http://192.168.1.2/を仮定します。

この例では、ePPNとeduPersonAffiliationを属性として受け取り、Affiliationが教員か学生の場合のみにプロキシにアクセスを許可ています。そして背後のサーバに、HTTPのパラメータとしてX-Shib-EppnにePPNを、X-Shib-AffiliationにeduPersonAffiliationを渡しています。

続きを読む

学認のIdPを用いた学内サービス用SPを構築する

学認のIdPを構築することで、学認で利用可能な外部のSPを利用可能となりますし、学認の多くのユーザに使ってもらうSPを構築することも可能です。一方で、作成したいSPの中には、外部のユーザに公開することが適切ではないサービスもあります。

そのようなサービスでは単に外部のユーザには使用できないだけではなく、学認の公式メタデータにもリストアップされず、認証に用いるIdPの選択画面なども表示されないようにする必要があります。

学認公式サイトの技術ガイドではこの辺りの手順がよくわからないので、以下にまとめてみます。

IdP側の設定

まずは、SPのメタデータを生成します。学認申請システム(運用フェデレーション用テストフェデレーション用は別です)にログインし、「新規SP申請」から「SPメタデータ情報」のところに必要なデータを入力し、そこにある「以下の内容でエンティティメタデータをテスト生成」をクリックすることでメタデータを生成できます。

この際、XMLファイル冒頭の<EntityDescriptor>のID属性は、適当に修正しましょう(他と同じでも特に問題はなさそうですが)。

これを適当なファイル名で、IdPの/opt/shibboleth-idp/metadata/に置きます(ここでは仮にtestsp.xmlというファイル名を仮定します)。そして、IdPのrelying-party.xmlの、/rp:RelyingPartyGroup/metadata:MetadataProviderの中にある

の前か後に、次のようにしてローカルメタデータへの参照を追加します。ここでも、id属性は適当に設定してください。複数のSPを登録したければこれを並べていけば問題ありません。

続きを読む