apache2のmellonとAzureADでSSOの実装

はじめに

適当に作ったWebサイト、SSOにしたい。apache2でmellonというモジュールがあり、特定のディレクトリにあるWebサービスがSSO対応になるっぽい。

1. 環境

ubuntu23.04ほか

2.参考

How To Set Up SSO in Apache using Mellon and Azure AD on Ubuntu - TechSupport

3. mellonの設定

必要なパッケージのインストール

apt -y install openssl apache2 libapache2-mod-auth-mellon ntpdate php php-fpm

mellonのディレクトリを作成

/etc/apache2/ディレクトリを作成しmellonメタデータファイルを作成

sudo mkdir -p /etc/apache2/mellon 
cd /etc/apache2/mellon

以下のスクリプトを実行して Mellon メタデータ ファイルを生成します。

:/etc/apache2/mellon# /usr/sbin/mellon_create_metadata https://10.24.2.33/ "https://10.24.2.33/mellon"
Output files:
Private key:               https_10.24.2.33_.key
Certificate:               https_10.24.2.33_.cert
Metadata:                  https_10.24.2.33_.xml

Host:                      10.24.2.33

Endpoints:
SingleLogoutService:       https://10.24.2.33/mellon/logout
AssertionConsumerService:  https://10.24.2.33/mellon/postResponse

ファイル名を変更します。

mv *.key mellon.key 
mv *.cert mellon.cert 
mv *.xml mellon_metadata.xml
mellonの設定ファイルを作成

/etc/apache2/conf-available/mellon.confファイルを作成し、以下を記述します。

<location />
MellonSPPrivateKeyFile /etc/apache2/mellon/mellon.key
MellonSPCertFile /etc/apache2/mellon/mellon.cert
MellonSPMetadataFile /etc/apache2/mellon/mellon_metadata.xml
MellonIdPMetadataFile /etc/apache2/mellon/AzureAD_metadata.xml
MellonEndpointPath /mellon
MellonEnable "info"
</Location>
自己署名 SSL 証明書の作成

以下コマンドで自己署名 SSL 証明書を作成します。サブジェクトは適宜変更してください。

openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -subj "/C=JP/ST=TOKYO/L=MinatoKu/CN=10.24.2.33" -out /etc/ssl/certs/server.pem -keyout /etc/ssl/private/server.key
Apache 構成ファイル作成

/etc/apache2/sites-available/server-ssl.confを作成し、以下を記述します。

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        DocumentRoot /var/www/html
        ServerSignature Off
        ErrorLog /var/log/apache2/error.log
        CustomLog /var/log/apache2/access.log combined
        LogLevel info ssl:warn
        SSLEngine on
        SSLCertificateFile /etc/ssl/certs/server.pem
        SSLCertificateKeyFile /etc/ssl/private/server.key
    </VirtualHost>
    <Location /protected>
        Require valid-user
        AuthType "Mellon"
        MellonEnable "auth"
        MellonDecoder "none"
        MellonVariable "cookie"
        MellonSecureCookie On
        MellonUser "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
    </Location>
</IfModule>

この構成では、/protected の下にあるすべてのものを保護し、すべての有効な IdP ユーザーにアクセスを提供します。

テストページ作成

/var/www/html/protected/index.htmlを作成し、以下を記述します。

<html>
<head>
  <title>index page</title>
  <meta charset="UTF-8" />
</head>
<body>
  <h2>このシンプルなインデックス ページは、
ユーザーが有効な資格情報を使用して 
Azure AD 経由で正常にサインインした場合にのみ
アクセ>ス可能になります。<h2>
</body>
</html>
apache2の構成変更

以下のコマンドを使用して Apache 構成をテストします。
apache2ctl configtest
すべてが正しく設定されている場合は、出力に「Syntax OK」と表示されます。構成エラーが返された場合は、まずそれらを修正してから、次のステップに進みます。

a2enmod ssl
a2enconf mellon.conf
a2ensite ssl-server.conf
systemctl restart apache2

エラーが発生しました。内容を見ると/etc/apache2/mellon/AzureAD_metadata.xmlが無いよ、という内容でした。

mellon apachectl[11143]: AH00526: Syntax error on line 5 of /etc/apache2/conf-enabled/mellon.conf:
mellon apachectl[11143]: apr_stat: Error opening "/etc/apache2/mellon/AzureAD_metadata.xml" [2] "No such file or direct>
mellon apachectl[11140]: Action 'start' failed.
mellon apachectl[11140]: The Apache error log may have more information.

4. AzureADの構成

公式ページを参考に、AzureAD_metadata.xmlを作成します。

エンタープライズ アプリケーションの作成

Azure portal にログインし、[Microsoft Entra ID]->[エンタープライズ アプリケーション]に移動します。


[新しいアプリケーション]->[独自のアプリケーション]をクリックします。


今回apache_mellonという名前を付けました。チェックボックスは「ギャラリーに見つからないその他アプリケーションを統合します」を選択します。

無事作成されたら、[シングル サインオンの設定]を行います。

[SAML]の設定を行います。

[メタデータファイルをアップロードする]をクリックします。

少し前に作成した/etc/apache2/mellon/mellon_metadata.xmlファイルをアップロードします。
xml構文に間違いがなければアップロードが成功し、[基本的なSAML構文]が表示されるので保存します。(ユーザやグループの割り当てでアクセス制限も可能)

[フェデレーション メタデータ XML]をダウンロードします。

SSOのテスト実行の為、一度プロパティでユーザの割り当てをNoにします。

5. 仕上げ

Azureからダウンロードしたxmlファイルは、apache2のリスタートでエラーになった/etc/apache2/mellon/AzureAD_metadata.xmlです。ファイル名をAzureAD_metadata.xmlに変更して配置し、apache2をリスタートします。
systemctl restart apache2

6. アクセスしてみる

AzureADのログオン画面には飛んだが、レスポンスでバッドリクエストになった。

この辺りのドキュメントを読み込んで設定を見直す必要がありそう。
/var/log/apache2/error.logを見てみると、以下のエラーが出ていた。

NotOnOrAfter in SubjectConfirmationData was in the past., referer: https://login.microsoftonline.com/

Azureのシングルサインオンテスト機能でSAML要求を見てみるとSubjectConfirmationDataが存在し、時刻が大変にずれていたのが原因。
apacheサーバの時刻ずれを直し、無事にSSOができました。

さいごに

本当に作りたいのは、SSOしたユーザが初回アクセスした際、独自のLDAPにユーザを新規作成すること、Webページでは独自LDAPのパスワード設定ができること。
今回の実装はタダの下準備です。私いっつも下準備してるな…

追記

後日動作確認した時にInternalServerErrorが出てしまった。 /var/log/apache2/error.logに以下のエラーが出ていた。

User has disabled cookies, or has lost the cookie before returning from the SAML2 login server., referer: https://login.microsoftonline.com/

原因がわからず、Azureのアプリケーションの画面でSSOテストを実行した。SSOはうまくいっているようだが、接続先が想定していたhttps://10.24.2.33/protectedではなく、https://10.24.2.33だった。
/etc/apache2/sites-available/server-ssl.confのLocationを変更たらエラーを回避できた。

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        DocumentRoot /var/www/html
        ServerSignature Off
        ErrorLog /var/log/apache2/error.log
        CustomLog /var/log/apache2/access.log combined
        LogLevel info ssl:warn
        SSLEngine on
        SSLCertificateFile /etc/ssl/certs/server.pem
        SSLCertificateKeyFile /etc/ssl/private/server.key
    </VirtualHost>
-    <Location /protected>
+    <Location />
        Require valid-user
        AuthType "Mellon"
        MellonEnable "auth"
        MellonDecoder "none"
        MellonVariable "cookie"
        MellonSecureCookie On
        MellonUser "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
    </Location>
</IfModule>