Apache mod_auth_mellon で SAML SP を設定してみる
Apache mod_auth_mellon で SAML SP の設定
環境
ここでは Docker コンテナ内に apache 環境を構築します。
$ sudo docker run --rm -it -p 443:443 -v /home/debian/docker/mellontest:/opt --name mellontest debian:bookworm-slim bash
(Rapberry pi OS の上にたてたKVM仮想マシンの上で Dockerコンテナを動かして検証しています。)
パッケージの導入
動作に必要なパッケージを導入します。
# apt update
# apt install --no-install-recommends apache2 libapache2-mod-auth-mellon openssl curl
IdP メタデータ作成
mellon_create_metadata の第一引数は Entityid 、第二引数は endpoint 。
作成したらリネームしておく。
# mkdir -p /etc/apache2/mellon
# cd /etc/apache2/mellon
# /usr/sbin/mellon_create_metadata https://192.168.11.40/ "https://192.168.11.40/mellon"
# mv *.key mellon.key
# mv *.cert mellon.cert
# mv *.xml mellon_metadata.xml
SP メタデータ
SP メタデータ mellon_metadata.xml を IdPに登録する。
(IdP は Azure EntraID / KeyCloak について記載しますが、いったん、Azure EntraIDを想定)
mod_auth_mellon の設定ファイルを作成
IdPから取得したメタデータを /etc/apache2/mellon/IdP_metadata.xml に配置する。
設定ファイルを記載する。
<location />
MellonSPPrivateKeyFile /etc/apache2/mellon/mellon.key
MellonSPCertFile /etc/apache2/mellon/mellon.cert
MellonSPMetadataFile /etc/apache2/mellon/mellon_metadata.xml
MellonIdPMetadataFile /etc/apache2/mellon/IdP_metadata.xml
MellonEndpointPath /mellon
MellonEnable "auth"
</Location>
TLS接続するための証明書を作成
ここでは自己署名のオレオレ証明書を作成している。
サブジェクト、コモンネームはよしなに。
# openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out /etc/ssl/certs/mywebserver.pem -keyout /etc/ssl/private/mywebserver.key -subj '/C=JP/ST=Tokyo/L=Shinjuku/CN=192.168.11.40'
Apache 設定ファイルを作成
Apache の設定ファイルを作成する。
ServerName はよしなに。
ServerName 192.168.11.40
<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/mywebserver.pem
SSLCertificateKeyFile /etc/ssl/private/mywebserver.key
</VirtualHost>
<Location />
Require valid-user
AuthType "Mellon"
MellonEnable "auth"
MellonDecoder "none"
MellonVariable "cookie"
MellonSecureCookie On
</Location>
</IfModule>
SAML認証によって守られるべきテストコンテンツを作成
# mkdir -p /var/www/html/protected
# date > /var/www/html/protected/index.html
設定を有効化
# apache2ctl configtest
# a2enmod ssl
# a2enconf mellon.conf
# a2ensite mywebserver.conf
# a2dissite 000-default.conf
# apache2ctl graceful
動作確認
WebサーバのURLにアクセスして、設定したIdPのログイン画面に遷移するること、ログインできること、コンテンツを表示できることを確認する。
設定によっては特定のブラウザで動作しない場合があるので、Firefox、Edge など複数のブラウザで、プライベートモード等を含めて動作確認すると確実。
Internal Server Error や Bad Requestのエラーがでたら、Apache の error.log にメッセージを確認する。
IdP として Azure EntraID を利用する
Azure EntraID はフリープランでOK。
参考
ユーザを追加する
Entra IDの画面へ移動して以下の手順でユーザを作成する。
(SAML設定自体とは関係ないが、前準備として必要に応じて実施)
- 左ペインで「ユーザー」へ移動 → 右ペイン上部で「新しいユーザ」 → 「新しいユーザの作成」
- ユーザープリンシパル名: 任意のユーザ名 (@xxx.onmicrosoft.com)
- 表示名: 任意の表示名
- パスワード: 任意
- 入力したら「レビューと作成」 → 「作成」
IdPを作成する
Entra IDの画面へ移動して以下の手順でIdPを作成する。
- 左ペインで「エンタープライズアプリケーション」へ移動 → 右ペイン上部で「新しいアプリケーション」 → 「独自のアプリケーションの作成」
- お使いのアプリケーション名: 任意の名前
- 「ギャラリーに見つからないその他のアプリケーションを統合します (ギャラリー以外)」にチェック
- 入力したら「作成」をクリック
ユーザーの追加
- 左ペイン「概要」で「1. ユーザーとグループの割り当て」の「ユーザまたはグループの追加」 → 画面上部で「ユーザまたはグループの追加」 → 「ユーザ」の「選択されていません」をクリック
- 追加したいユーザをチェックして、「選択」をクリック → 「割り当て」をクリック
シングルサインオンの設定
- 左ペイン「概要」で「2. シングル サインオンの設定」の「作業の開始」 → 「シングルサインオン方式」で SAML を選択
- 画面上部で「メタデータ ファイルをアップロードする」 → SP メタデータ mellon_metadata.xml をアップロードする
- 「基本的な SAML 構成」が開くので「保存」をクリック。(サインインのテストは実施しない)
IdP メタデータダウンロード
- 「SAML証明書」→ 「フェデレーション メタデータ XML」をダウンロード。
- ダウンロードしたxmlファイルを、/etc/apache2/mellon/IdP_metadata.xml として SP 側に保存する。
動作確認
WebサーバのURLにアクセスして、Azureのログイン画面に遷移すること、作成したユーザーのプリンシパル名(ユーザ名@xxx.onmicrosoft.com) でログインできること、コンテンツを表示できることを確認する。
サインインログ
サインインの履歴は「アクティビティ」 → 「サインインログ」で確認できる。
IdP として Azure KeyCloak を利用する
KeyCloak は例によって Docker で準備する。
証明書の準備
KeyCloak を TLS化するために適当な証明書を準備する
$ mkdir keycloak
$ openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out keycloak/example.crt -keyout keycloak/example.key -subj '/C=JP/ST=Tokyo/L=Shinjuku/CN=192.168.11.40'
docker compose で起動
sudo docker compose up -d で起動する。
services:
postgres:
image: postgres:16
volumes:
- ./postgresql:/var/lib/postgresql
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
keycloak:
image: quay.io/keycloak/keycloak:26.0
volumes:
- ./keycloak:/work/keycloak
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: password
KC_DB: postgres
KC_DB_PASSWORD: password
KC_DB_USERNAME: keycloak
KC_DB_URL_PORT: 5432
KC_DB_URL_HOST: postgres
KC_DB_URL_DATABASE: keycloak
KC_HTTPS_CERTIFICATE_FILE: /work/keycloak/example.crt
KC_HTTPS_CERTIFICATE_KEY_FILE: /work/keycloak/example.key
command:
- "start-dev"
ports:
- 8080:8080
- 8443:8443
depends_on:
- postgres
sudo docker compose ps で起動していることを確認する。停止する等の不具合があれば、
sudo docker compose logs (-f) で確認する。
Realm 作成
- KeyCloakのURL(https://アドレス:8443/)を開き、Username は KEYCLOAK_ADMIN の値、 Password は KEYCLOAK_ADMIN_PASSWORDでログイン。
- トップ画面から
Create realm
→Realm name
に 適当な名前を入力して、Create
を押下。
IdP 作成
- 左ペインの
Clients
を押下 → 右ペインでImport client
を押下 - Resource file:
Browse
を押下して mellon_metadata.xml を読み込む - Name に任意の名前を入力して、
Save
を押下
ユーザ作成
- 左ペインの
Users
を押下 → 右ペインでCreate new user
を押下 - Username に任意のユーザー名を入力して、
Create
を押下 -
Credentials
タブへ移動して、Set password
を押下 - Password、Password confirmation に適当なパスワードを入力
- Temporaryを
Off
にしてSave
を押下 →Save password
を押下
IdP メタデータダウンロード
Apache サーバ側で以下を実行して、IdP メタデータをダウンロードして、設定反映
# curl -k -s https://192.168.11.40:8443/realms/<Realm名>/protocol/saml/descriptor -o /etc/apache2/mellon/IdP_metadata.xml
# apachectl graceful
動作確認
WebサーバのURLにアクセスして、KeyCloak のログイン画面に遷移すること、作成したユーザー名でログインできること、コンテンツを表示できることを確認する。
おわりに
気が向くことがあれば、IdPとして SimpleSAMLphp を利用する場合の設定についても記載したい。
Discussion