Open5

SAML認証

mnodmnod

Azure AD を IdPとして利用する設定

Azure AD の設定。
Azure AD はフリープランでOK.

参考

https://qiita.com/QGv/items/cd2b863a0bb6f7153ae0
https://www.techsupportpk.com/2021/05/integrate-azure-active-directory-authentication-apache-ubuntu-debian.html

ユーザを追加する

SAML設定自体とは関係ないが、前準備として、ユーザを追加する。

ユーザー → 新しいユーザ → 新しいユーザの作成

  • ユーザープリンシパル名: 任意のユーザ名@xxxoutlook.onmicrosoft.com
  • 表示名
  • パスワード(自動生成)

IdPを作成する

エンタープライズアプリケーション → 新しいアプリケーション → 独自のアプリケーションの作成

  • お使いのアプリケーション名: 任意の名前
  • ギャラリーに見つからないその他のアプリケーションを統合します (ギャラリー以外)

ユーザーの追加

ユーザーとグループ → ユーザまたはグループの追加 → ユーザ
→ 追加したいユーザをチェックして、選択

シングルサインオンの設定

シングルサインオン
→ シングルサインオン方式

  • SAML

→ 基本的なSAML構成

  • 識別子: エンティティ ID
  • 応答 URL: AssertionConsumerService
  • ログアウト URL: SingleLogoutService
    (SP側で作成したメタデータをアップロードすることでも設定可能なようだ)

→ SAML証明書

  • フェデレーション メタデータ XMLをダウンロード → SP 側に保存する。

サインインログ

アクティビティ → サインインログで確認できる。

mnodmnod

Apache mod_auth_mellon で SAML SP の設定

参考

https://www.techsupportpk.com/2021/05/integrate-azure-active-directory-authentication-apache-ubuntu-debian.html

環境

ここでは Docker コンテナ内に構築します。

$ sudo docker run --rm -it -p 443:443 -v /home/pi/work/test/mellon:/opt --name mellontest debian:bullseye-slim bash

パッケージの導入

動作に必要なパッケージを導入します。

# apt update
# apt install --no-install-recommends apache2 libapache2-mod-auth-mellon openssl

IdP メタデータ作成

mellon_create_metadata の第一引数は Entityid 、第二引数は endpoint 。
作成したらリネームしておく。

# mkdir -p /etc/apache2/mellon
# cd /etc/apache2/mellon
# /usr/sbin/mellon_create_metadata https://test.example.com/ "https://test.example.com/mellon"

# mv *.key mellon.key
# mv *.cert mellon.cert
# mv *.xml mellon_metadata.xml

SP メタデータ mellon_metadata.xml を IdPに登録する。

mod_auth_mellon の設定ファイルを作成

IdPから取得したメタデータを /etc/apache2/mellon/IdP_metadata.xml に配置する。

/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/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=コモンネーム'

Apache 設定ファイルを作成

Apache の設定ファイルを作成する。

/etc/apache2/sites-available/mywebserver.conf
ServerName サーバ名
<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 /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>

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

Docker 化に向けて

作成したApache 設定ファイルを Docker ホストへコピーしておく

sudo docker copy mellontest:/etc/apache2 .

今後作成するDockerイメージからは、Apache 設定ファイル、SSL 証明書、Web コンテンツをマウントして利用する想定。

mnodmnod

Docker で SimpleSAMLphp を動かす

SimpleSAMLphp のバージョンは 2.0.5 を利用します。

参考

https://simplesamlphp.org/docs/stable/simplesamlphp-install.html

Docker イメージを作成

下記のような内容で Dockerfile を作成する

まっさらの alpine のイメージから作ろうと試行錯誤したのだが、php-openssl を入れたところで、nginx/error.log への php のログ出力が無くなってしまい作業が進まなくなった。
なので、 php:8.1-fpm-alpine を利用することにした。
(ベストプラクティス的には nginx は別イメージにするべきかもしれない)

Dockerfile
FROM php:8.1-fpm-alpine

RUN apk update \
&& apk add nginx \
&& rm -rf /var/cache/apk/*

VOLUME ["/var/www/html", "/etc/nginx/http.d"]
EXPOSE 443

CMD php-fpm -D && nginx -g 'daemon off;'

イメージを作成

$ sudo docker build --build-arg http_proxy=http://<プロキシアドレス>:<プロキシポート>/ -f Dockerfile -t nginx-php-fpm:test .

nginx の設定ファイルを作成

作業ディレクトリに nginx の設定ファイルを作成

http.d/default.conf
server {
    listen 443 ssl default_server;
    server_name idp.example.com;

    ssl_certificate        /etc/pki/tls/certs/example.org.crt;
    ssl_certificate_key    /etc/pki/tls/private/example.org.pem;
    ssl_protocols          TLSv1.3 TLSv1.2;
    ssl_ciphers            EECDH+AESGCM:EDH+AESGCM;

    location ^~ /simplesaml {
            alias /var/simplesamlphp/public;
            location ~^(?<prefix>/simplesaml)(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ {
                include          fastcgi_params;
                fastcgi_pass     localhost:9000;
                fastcgi_param SCRIPT_FILENAME $document_root$phpfile;

                # Must be prepended with the baseurlpath
                fastcgi_param SCRIPT_NAME /simplesaml$phpfile;
                fastcgi_param PATH_INFO $pathinfo if_not_empty;
            }
    }
}

TLS接続用のサーバ証明書を作成する。
コモンネームはよしなに。

$ openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out example.org.crt -keyout example.org.pem -subj '/C=JP/ST=Tokyo/L=Shinjuku/CN=コモンネーム'

SimpleSAMLphp の準備

公式からダウンロードしてきたアーカイブを展開する

$ curl -L https://github.com/simplesamlphp/simplesamlphp/releases/download/v2.0.5/simplesamlphp-2.0.5.tar.gz -o simplesamlphp-2.0.5.tar.gz
$ tar xzvf simplesamlphp-2.0.5.tar.gz
$ simplesamlphp-2.0.5.tar.gz

Docker 起動

$ sudo docker run --name simplesaml --rm -d -p 8443:443 \
 -v <作業ディレクトリパス>/simplesamlphp-2.0.5:/var/simplesamlphp \
 -v <作業ディレクトリパス>/http.d:/etc/nginx/http.d \
 -v <作業ディレクトリパス>/example.org.crt:/etc/pki/tls/certs/example.org.crt \
 -v <作業ディレクトリパス>/example.org.pem:/etc/pki/tls/certs/example.org.pem \
 nginx-php-fpm:test
mnodmnod

SimpleSAMLphp を IdP として設定

ネット上の日本語情報はVer1系のものが多かったが、Ver2系の設定を進めるうえでは、あまり参考にならなかった。

参考

https://simplesamlphp.org/docs/stable/simplesamlphp-idp.html
https://blog.msyk.net/?p=1566

設定

simplesamlphp-2.0.5 ディレクトリ内で下記を変更

証明書作成

openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out cert/example.org.crt -keyout cert/example.org.pem -subj '/C=JP/ST=Tokyo/L=Shinjuku/CN=コモンネーム'

ソルト値作成

LC_ALL=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo

パスワードハッシュ作成

$ sudo docker exec -it simplesaml php -f /var/simplesamlphp/bin/pwgen.php
Enter password: password1234

  $2y$10$PWH6KnnQPmLkchR7xcuPmercvnxQ/NowObU65KHdkJNHfRmyY7vWS
$ cp -pi config/config.php{,.dist}
$ vi config/config.php

以下を変更
'baseurlpath' => 'https://yourfqdn:port/simplesaml/',

'secretsalt' => '作成したソルト値',

'auth.adminpassword' => '作成したパスワードハッシュ',

'enable.saml20-idp' => true,

'exampleauth' => true,
$ cp -pi config/authsources.php{,.dist}
$ vi config/authsources.php

以下を変更

'entityID' => 'エンティティID',

コメントアウトされている 'example-userpass' => [], の箇所の有効化
$ cp -pi metadata/saml20-idp-hosted.php{,.dist}
$ vi metadata/saml20-idp-hosted.php


$metadata['エンティティID']

'privatekey' => '作成した秘密鍵',
'certificate' => '作成した証明書',

https://yourfqdn:port/simplesaml/ で表紙画面が表示できる。
管理画面は https://yourfqdn:port/simplesaml/admin/ で表示できる。
設定したパスワードで中に入れる。

連携ページのツール「XMLをSimpleSAMLphpメタデータに変換」を開く
SPメタデータの内容を貼り付けてパースをクリック。

$ cp -pi metadata/saml20-sp-remote.php{,.dist}
$ vi metadata/saml20-sp-remote.php

上でパースされた内容に置き換える。
mnodmnod

SimpleSAMLphp を SP として設定

参考

https://simplesamlphp.org/docs/stable/simplesamlphp-sp.html

設定

simplesamlphp-2.0.5 ディレクトリ内で下記を変更

ソルト値作成
パスワードハッシュ作成
confit.php 編集

$ cp -pi config/config.php{.dist,}

'baseurlpath' => 'https://yourfqdn:port/simplesaml/',

'secretsalt' => '作成したソルト値',

'auth.adminpassword' => '作成したパスワードハッシュ',

authsources.php 編集

$ cp -pi config/authsources.php{.dist,}
$ vi config/authsources.php

以下を変更

'entityID' => 'エンティティID',

saml20-idp-remote.php の編集

$ cp -pi metadata/saml20-idp-remote.php{.dist,}

$metadata['https://example.org/saml-idp'] = [
    'SingleSignOnService'  => 'https://example.org/simplesaml/saml2/idp/SSOService.php',
    'SingleLogoutService'  => 'https://example.org/simplesaml/saml2/idp/SingleLogoutService.php',
    'certificate'          => 'example.pem',
];

https://yourfqdn:port/simplesaml/ で表紙画面が表示できる。
管理画面は https://yourfqdn:port/simplesaml/admin/ で表示できる。
設定したパスワードで中に入れる。

連携ページの Hosted entities の SAML 2.0 SP metadata の メタデータの内容(XML形式)を、IdP側でインポートする。
IdP側のメタデータをエクスポート
連携ページのツール「XMLをSimpleSAMLphpメタデータに変換」を開く
IdPメタデータの内容を貼り付けてパースをクリック。

$ vi metadata/saml20-idp-remote.php

上でパースされた内容を追記する。

テスト

Testページで、SP名をクリックすると、IdPの認証画面へ推移する。
認証が成功すると、ステータスページが表示され、属性情報、認証データなどを確認できる。