KeycloakをIdpに使ってSAML認証(3)

この記事は、KeycloakをIdpに使ってSAML認証(1)およびKeycloakをIdpに使ってSAML認証(2)に続く記事である。(1)はKeyCloakのインストール、(2)はKeyCloakをSAMLのIdPとして、INTER-Mediatorで作ったアプリケーションに認証処理を提供する方法を記述したが、認証が通ったことはわかるものの、SAML属性にユーザ名が入っていないということで、INTER-Mediator側では想定した状態になっていなかった。そして、その点は解決したので、ここに記載しておく。

KeyCloak をIdPとし、SimpleSAMLphpをSPに設定している場合で、SP側の管理ページに入り、そこで認証をしてみる。そこでは、アプリケーション側で得られてるSAMLの属性がわかるので、その部分の確認と、ユーザ名を入れる拡張を進めてみた。まず、単にKeyCloakのClientとしてSAML SPを登録した状態では次のようになる。管理ぺ時のTestのところにSPが見えている(ここでは「default-sp」)。そのSPをクリックする。

すると、KeyCloakの黒い背景の認証ページに移動する。ここで、既存のkcuser1で認証をした場合、次のように、得られる属性が見えている。(2)で説明した通り、ここでも同様にRoleという属性しか見えていない。

しかしながら、以下のようにKeyCloak側を設定すると、次の図のように、kcuser1でログインした結果、そのユーザの姓名とメールアドレスに加えて、ユーザ名も取得することができた。

INTER-Mediator側で、取得した属性をチェックすると、このような感じになる。以前は、Roleだけだったのが、ユーザ名や氏名、メールアドレスも、ともかく取得できている。

ここで、INTER-Mediatorのparams.phpファイルでは、このように取得される属性から必要なデータを得られるように、$samlAttrRules変数の配列を定義しておく必要がある。この配列のキーは、ユーザテーブル(authuser)のフィールド名である。配列のキーに対する値は、SAMLの属性から取り出す時のキーと、|で挟んで配列の要素番号を指定している。メールや氏名については、前述の属性のダンプにあるように、複雑な記号がキーになっているので、それをコピペするなどして、きちんと配列を定義しなければならない。

いずれにしても、これで、INTER-Mediatorのアプリケーションで、KeyCloakをIdPとして認証ができることが確認できた。

どうすれば属性を増やすことができるのか

ということで、タイトル通りの疑問がここで沸く。言い換えれば、KeyCloakに設定したユーザでの認証については、「何かしなければRoleしか得られない」ということだ。

まず、左側で、Client Scopesを見てみよう。ここをみると、SAMLプロトコルに対しては、role_listという名前のものしか定義されておらず、他はみんなOpenIDのものである。以下の画像には1ページ目しか見えていないが、もう1項目だけ次のページにあり、それはOpenID向けのものである。ここを見て、「属性にRoleしかない」という状況と、Client scopesにSAMLのものはrole_listしかないという結果に大きな関連性があると着目して、ここに設定を加えれば良いということがわかる。

このリストで、Create client scopeボタンをクリックする。そうすると、以下のような画面になる。ここで、Nameを指定するが、この名前は、このリスト上の名前であり、すでに存在する名前はつけられない。ここでは、snとした。そして、もう1つProtocolからSAMを選択しておく。とりあえず、この2つで良いようだ。Protocolは後から変更できないので忘れないようにする。そしてSaveボタンをクリックする。

Saveボタンをクリックすると、Clinet scopeの1項目を編集する画面に入るのだが、上部のタブのMappersをクリックする。最初は次の図のように、No mappersとなっている。ある属性を得るには、マッパーを利用して、既存のどこかの値を持ってくるという設定を記述しないといけないようである。

ここでまず、Add predefined mapperボタンをクリックして、つまりは既定義のマッパーを探して設定する。ちなみに、既定義のマッパーが一覧されるので、該当する項目にチェックを入れて、Addボタンをクリックする。ただ、これをよくみると、既定義のマッパーでは、sureName、givenName、emailの3つしかない。ここでは、snに対するものとして、X500 surenameにチェックを入れて、Addをセットする。ちなみに、すでに設定したものはこのリストでは表示されなくなる。

この設定を、sn、gn、mailというClient scopeに対して行った。

では、usernameはどうすればいいか?まずは、usernameに対応するためのClient scopeの1項目を作る。もちろん、ProtocolをSAMLにするのを忘れないようにする。そしてマッパーを登録すが、usernameのマッパーは既定義には存在しないのでConfigure a new mapperをクリックする。すると、次のような選択画面が表示される。何を選択するか迷うが、とりあえず、User Attribute、User Propertyのいずれも成功している。ここではUser Attributeを選択したとする。

すると、次のようなマッパーを定義する画面に入るので、ここで、Name以下4つの項目で全部、usernameと入力する。なお、ここでは最後の項目にあるように、SAML属性上でのキー名も入力できるので、属性上の値の解釈も分かりやすくなる。入力後、Saveボタンをクリックして保存しておく。

こうして、4つのClient scopeを追加した。Client scopeの一覧で、SAML Protocolに絞って一覧を示すとこのような感じである。username以外は、既定義のマッパーを使っている。

これでOKかと思ったのだが、まだRoleしか属性に入っていない。さらに続いて、次のように設定を行う。Clientsを選択すると、クライアントのリストが表示される。ここで、追加したSAML SPの項目のリンクをクリックする。

そして、Clientの設定画面が出てくるので、上部のタブで、Client scopesを選択する。規定値では、role_listが見えているはずだが、いずれにしても、Client scopesに登録し、さらにここで追加する必要があるということで、ここで、さらに選択を加えないといけない。

Add client scopeボタンをクリックすると、次のように、Client scopesで定義したProtocolがSAMLの項目が一覧される。とりあえず、ここでは全ての項目にチェックを入れて、Addボタンをクリックする。さらに選択するポップアップが出てくるので、Defaultを選択しておく。

SAML SPのClient scopesの設定が次のようになったらOKである。

ここまで設定を行うことで、最初に示したように、SAML属性にusernameや氏名、メールアドレスを含めることができ、INTER-Mediatorでの利用が可能になった。

KeycloakをIdpに使ってSAML認証(2)

この記事は、KeycloakをIdpに使ってSAML認証(1)に続く記事である。(1)では、ともかくKeyCloakを稼働するところまで進めた。そして、KeyCloakをIdPとし、SimpleSAMLphpを使ったINTER-Mediatorのアプリケーションまで稼働する。なお、SP側は、SimpleSAMLphp Ver.2を使ってみる(3)の設定が終わっているものとする。SPは、IdPもSPもSimpleSAMLphpを利用していて、default-spがとりあえず、SimpleSAMLphpのIdPに接続されている。

KeyCloak側にRealmを1つ定義する

ここでまず、KeyCloak側にRealmを1つ定義する。KeyCloakの管理画面にadminユーザでログインをして、左側のナビゲーションバーの一番上にあるドロップダウンリストにある「Create realm」ボタンをクリックする。

すると、次のようなフォームが表示される。ここではとりあえず、Realm Nameだけを入力して、Createボタンをクリックすれば良い。以下は、IM_Testと入力をした。

左側の上の方に、作ったRealmのIM_Testが見えているはずだが、ここでRealmを切り替えて利用できる。以後はここで作成したIM_Testが選択された状態で作業を進めることにする。

KeyCloak側にユーザを定義する

続いてユーザを定義する。左側でUsersを選択すると、ユーザの一覧が表示されるが、その中にあるAdd Userボタンをクリックする。すると、以下のようなフォームになるので、とりあえず、Usernameだけは入力しておく。ここではkcuser1とした。Emailも入力されている。そして、Createボタンをクリックすると、ユーザは作られた。

次に作ったユーザにパスワードを与える。管理画面の左側でUsersを選択すると、作ったユーザkcuser1が見えているはずだ。そのユーザ名のリンクをクリックすると。そのユーザの設定変更ができるフォームが見えている。ここで、右側上部のタブにあるCredentialsをクリックして、パスワードを設定する。

Credentialsをクリックすると、次のようなパネルが表示される。ここで、PasswordとPassword Confirmationに同じパスワードをキータイプする。TemporaryはOnだとログイン時にパスワードの変更が必要になる。ここではテストなので、Offにしておくのが良いだろう。そして、Savaボタンで、パスワードが設定される。

IdP(KeyCloak)のメタデータをSPに登録

ここからは、IdPとSPのメタデータの交換である。まずは、IdPのメタデータをSPに登録する。別記事の手順で作られたSPだが、SP側の設定はほぼそのままにして、IdPのメタデータだけを入れ替えることにする。

IdPのメタデータは、左側のReaml settingsをクリックして、Generalのタブの一番下にあるEndpointsというところにある「SAML 2.0 Identity Provider Metadata」というリンクをクリックする。

すると、次のように新たなウインドウにIdPのメタデータが表示される。このXMLを利用するのだが、ブラウザでXMLのコピペをするとしても、ブラウザが余計なことをしてしまうことになりそうなので、ここでは、URLをコピーしておく。そして、作業用のコンピュータ側でいいので、「curl -O メタデータのURL」とコマンドを入れて確実に中身の変更が行われない状態で、ファイルに納める。descriptorというファイルが作られるが、それをエディタで開いて、中身にコピーしておくと良い。

このメタデータをSP側に登録するのだが、SPはSimpelSAMLphpであるので、メタデータはXML形式ではなくPHPのプログラムにしなければならない。そこで、SP側の管理ページを開く。URLを示す意味があるかは若干疑問だが、別記事の通りにセットアップしてれば、「https://demo.inter-mediator.com/saml-trial/lib/src/INTER-Mediator/vendor/simplesamlphp/simplesamlphp/public/admin」で管理ページへのログインができる。ログイン後、上部で「連携」を選択する。ここにある「ツール」の「XMLをSimleSAMLphpメタデータに変換」の部分をクリックする。

すると、メタデータパーサと書かれたページが出てくるので、XMLメタデータ部分にペーストする。つまり、IdPのメタデータそのものを、ここに貼り付けて、「パース」ボタンをクリックする。

すると、次のように、PHPのコードに変換されたものが「変換されたメタデータ」の部分に見えるようになる。このPHPのコードを慎重にコピーして取り込んでおく。

SPの設定を変更する。設定ファイルのsaml20-idp-remote.phpを修正する。テキストエディタで開いて、末尾に変換されたIdPのメタデータをペーストすれば良い。従来のIdPのメタデータはコメントにしておくのが良いだろう。

SPのメタデータをIdP(KeyCloak)に登録

次は、SPのメタデータをIdPに登録する。SPのメタデータは、SPの管理画面で「連携」のところのdefault-spの下にあるVの部分をクリックすると、表示される。XMLとPHPの両方で表示されるが、ここで必要なのはXMLの方である。ここではコピペは必要なく、SAML Metadataの直下「You can get the metadata XML on a dedicated URL:」のすぐ下にある1行のURLの部分の右端にクリック可能なボックスが出てくる。これをクリックすると、メタデータのXMLがファイルとしてダウンロードされる。ファイル名は、default-sp.xmlという名前になる。

KeyCloakの管理画面に戻る。IM_TestのRealmが選択されていることを確認した上で、左側でClientsをクリックする。以下のような画面になるので、リストの上にあるImport clientの部分をクリックする。

インポートの画面に遷移するが、ここでは、Browseボタンをクリックして、先ほどダウンロードしたSPのメタデータファイル(default-sp.xml)を選択する。すると、Resource fileの部分にメタデータファイルの中身が展開される。ここまででSaveボタンを押して保存をしておく。

アプリケーションを動かしてみるが…

では、実際にSAMLに対応したアプリケーションを動かしてみる。認証が必要な場面で、KeyCloakの認証画面に移動し、登録したユーザkcuser1での認証は通った。なお、名前を入力していなかったので、このように入力を促すパネルが出るが、認証自体は通っているようである。

しかしながら、その後には、次のようなメッセージが出てきた。というか、これはINTER-Mediatorが出すメッセージである。INTER-Mediatorは、認証時に得られる属性の配列から、ユーザ名や氏名、メールアドレス等を取り出すようにしており、ユーザ名の取得は必須にしてある。$samlAttrRules変数は設定ファイルに記述する属性の何を取り出すのかを指定する配列であるが、ここでは既定の状態でユーザ名の取得が正しく取れていないことを意味する。

SAMLのやり取りをみるとRoleしか来てない

デバッグメッセージを表示してもう少し詳しく見てみよう。右側、中央あたりに見えている6要素の配列が、IdPから得られたデータである。これをよくみると、Roleというキーがあるので、Roleが得られていることはわかるのだが、それ以外のデータが全くない。つまり、ログインは成功したもののIdPからRole以外のデータが全く来ていないということになり、その結果、どのユーザでログインしたのかは、アプリケーション側は全く検知できない状態になってしまっているということである。

つまり、KeyCloakを既定の状態で使うままではどうやらINTER-Mediatorでの認証はできない。ユーザ名を「気にしない」アプリケーションなら良いのかもしれないが、ユーザ名を取得できることを必須としているINTER-Mediatorでは対策が必要である。

ちなみに、SAML-tracerでチェックしてみた。ユーザ名とパスワードを入力した直後のSAMLのやり取り行をみてみると、SAML2.0 Responseはあるのだが、ここでやり取りされるデータは非常に少ない。

ちなみに、INTER-Mediatorを使って稼働している別のシステムではこのようなデータが見えている。なお、IdP, SPともにSimpleSAMLphpを使い、IdPはADに対してLDAPで接続して、ADユーザでのログインを可能にしている。ログイン直後に、SAML2.0 AttirubuteStatementの部分には、たくさんのデータが見えているが、事実上、これはADのユーザデータである。見てすぐにわかるように、cnでユーザ名、snとgivenNameで氏名が得られるので、そのようにINTER-Mediatorをセットアップして利用している。

ということで、KeyCloakとSimpleSAMLphpのSPは、接続等のセットアップはできるが、そのままではRoleしか得られないので、INTER-Mediatorでは認証はおそらくできているとしてもユーザ名が得られないので、認証していないとみなしているというところで、その解決策がわかれば、続きの記事を書くとする。

KeycloakをIdpに使ってSAML認証(1)

INTER-Mediatorで作るアプリケーションの認証基盤として、KeycloakをSAMLのIdPとして利用した場合の動作を検証する必要が出てきたので、実際に動かしてのチェックを進めてみる。SPはもちろんSimpleSAMLphpであり、これはINTER-Mediatorではcomposerでインストールできている状態になっている。ということで、まずは、Keycloakをきちんと動くようにしたい。(1)は、Keycloakを動かすまでである。

稼働するサーバは、INTER-Mediatorの公開サーバーで、Ubuntu 22で稼働している。そこに、kc.inter-mediator.comというドメイン名を割り当てて、Keycloakを利用することにする。ただ、Keycloak自体はJavaのアプリケーションであり、Apache2と連携しなくても連動するので、ともかく連携しない方法での稼働を目指すが、Let’s Encryptで、kc.inter-mediator.comの証明書を作るので、Apache2側も幾らかの設定を行うことにした。

なお、インストール方法は、ITC Enginnering Blog:Ubuntu 22にKeycloak 22をインストールして、Identity providers=Azure ADでSAMLを参考にさせていただいた。基本、概ね同じである。

利用するドメインの証明書を取得するまで

INTER-Mediatorの公開サーバーは、Sakura VPSである。すでにWeb等が稼働しているため、当然ながらのポートは開いているが、Keycloak用に、TCP 8443とTCP 9000のポートを開いた。9000はとりあえずは使わない。サーバ側にFirewallを設定する方式ではなく、コントロールパネルから設定するパケットフィルタを設定しているので、そこで8443/9000ポートを開いておいた。

そして、まずは、OSのアップデートを行い、kc.inter-mediator.comサイトを作る。サイトのルートは、/var/www/kcとした。そして、Apache2の設定ファイルをsites-availableディレクトリに作る。80番ポートと433番ポートは同じディレクトリを公開するように設定しているが、80側にはリダイレクトの設定があり、httpでアクセスがあると自動的にhttpsにしている。なお、certbotが成功するまでは、SSLCertificateFileとSSLCertificateKeyFileの設定は頭に#を入れてコメントにしておく必要がある。ここまで準備できれば、a2ensiteでサイトの設定ファイルをアクティブにして、systemctlでApache2を再起動し、certbotコマンドで証明書を作成する。証明書が正しく作成できれば、006-kc.confファイルのSSLCertificateFileとSSLCertificateKeyFileの前にある#を消しておき、改めてApache2をsystemctlで再起動する。もちろん、http://kc.inter-mediator.comにブラウザで接続して、証明書が正しく存在することは確認しよう。ここまでは、Keycloakとは関係のない、単にサーバ証明書を取得するための手順である。

sudo apt update
sudo apt upgrade
cd /var/www
mkdir kc
sudo chown www-data kc
sudo nano /etc/apache2/sites-available/006-kc.conf
# 006-kc.conf ファイルの内容をここで修正(証明書読み込み部分はコメント)
sudo a2ensite 006-kcsudo
systemctl restart apache2
sudo certbot certonly --webroot -w /var/www/kc -d kc.inter-mediator.com
sudo nano /etc/apache2/sites-available/006-kc.conf
# 006-kc.conf ファイルの内容をここで修正(証明書の読み込み部分を活かす)
systemctl restart apache2

以下は最終的な006-kc.confファイルの内容である。もちろん、これは一例であって、皆さんはご自分のスタイルがあるだろうから、それに従って作ろう。ともかく、Let’s Encryptで証明書を作ってもらうためだけのサイトなのである。

<VirtualHost *:80>
    ServerName kc.inter-mediator.com
    ServerAdmin info@inter-mediator.org
    DocumentRoot /var/www/kc

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

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =kc.inter-mediator.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:443>
    ServerName kc.inter-mediator.com
    ServerAdmin info@inter-mediator.org
    DocumentRoot /var/www/kc

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

    SSLCertificateFile /etc/letsencrypt/live/kc.inter-mediator.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/kc.inter-mediator.com/privkey.pem
</VirtualHost>

PostgreSQLのインストールと準備

KeyCloakは、データをPostgreSQLに溜め込むので、そのための準備が必要である。PostgreSQLをセットアップして、さらにデータベース側のユーザとデータベースを定義しておく必要がある。インストールは特に難しくはなく、aptで行う。その後に、システムに作られたpostgresユーザへのログインができるように、そのユーザにパスワードを設定する。ここでは書かないが、自分のパスワードはどこかにメモると良いだろう。その後、suでpostgresユーザに切り替わり、そしてpsqlコマンドでデータベースへのコマンド入力ができる状態にする。そして、CREATE USERとCREATE DATABASEのコマンドを入れる。PostgreSQLユーザのPASSWORDももちろん、独自に設定して自分で管理してもらいたい。

sudo apt install postgresql postgresql-contrib
sudo systemctl enable postgresql
sudo passwd postgres
# パスワードはきちんと把握しておく
su - postgres
psql
CREATE USER keycloak WITH PASSWORD 'PASSWORD' CREATEDB;
CREATE DATABASE keycloak OWNER keycloak;

Keycloakのインストール

やっと、Keycloakをインストールする段階にきた。インストールは簡単だが、aptでインストールはできない。そして、まずはJavaのインストールも必要である。コンポーネントとしては若干複雑な構成のようだが、JavaとKeycloakのインストールがともかく必要になる。

sudo apt install openjdk-21-jdk
java -version
cd /var/www
wget https://github.com/keycloak/keycloak/releases/download/25.0.2/keycloak-25.0.2.tar.gz
tar zfxv keycloak-25.0.2.tar.gz
sudo nano keycloak-25.0.2/conf/keycloak.conf

Javaのインストールは良いとして、Keycloak自体は/var/wwwにインストールした。もちろん、好みの場所で良いだろうが、使っているサーバはインストールしたものが概ね/var/wwwにあるのでこのようにした。wgetの後のURLは、KeyCloakのWebサイトのDownloadのページにあるtar.gzファイルのリンクをそのまま利用した。そして、そのまま展開している。よって、KeyCloak本体は、/var/www/keycloak-25.0.2というディレクトリに展開された。

続いて、KeyCloakの設定ファイル「conf/keycloak.conf」を編集する。実際のファイルにはコメントが丁寧に細かく書かれているので、それを読みながら作業するのが良いと思われる。以下コメントとともにファイルの内容を記載する。

# Basic settings for running in production. Change accordingly before deploying the server.

# Database

# The database vendor.
db=postgres

# The username of the database user.
db-username=keycloak

# The password of the database user.
db-password=PASSWORD

# The full database JDBC URL. If not provided, a default URL is set based on the selected database vendor.
db-url=jdbc:postgresql://localhost/keycloak

# Observability

# If the server should expose healthcheck endpoints.
health-enabled=true

# If the server should expose metrics endpoints.
metrics-enabled=true

# HTTP

# The file path to a server certificate or certificate chain in PEM format.
https-certificate-file=${kc.home.dir}/conf/fullchain.pem

# The file path to a private key in PEM format.
https-certificate-key-file=${kc.home.dir}/conf/privkey.pem

# The proxy address forwarding mode if the server is behind a reverse proxy.
#proxy=reencrypt

# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy
#spi-sticky-session-encoder-infinispan-should-attach-route=false

# Hostname for the Keycloak server.
hostname=kc.inter-mediator.com

最初のdbはこのまま、次のdb-username、db-passwordは、psqlコマンドで打ち込んだCREATE USERの時の情報をここに記載する。db-urlはこのままでOKである。HTMLセクションの最初の2つは、サーバ証明書である。ここにLet’s Encriptのディレクトリをそのまま書きたいところだが、そこはrootしかアクセス権がなく、KeyCloak自体をそのためのユーザで稼働することを考えているためその方法は使えない。そこで、証明書をKeyCloakの配下に以下のようにコマンドを入れてコピーすることにした。3ヶ月後はどうするかはまた考えるとして、とにかくこのようにした。なお、privkey.pemはユーザしか読み出しできないので、グループや全員に読み出し許可を与えている。

cd /var/www/keycloak-25.0.2/conf
sudo cp /etc/letsencrypt/live/kc.inter-mediator.com/privkey.pem .
sudo chmod a+r privkey.pem
sudo cp /etc/letsencrypt/live/kc.inter-mediator.com/fullchain.pem .

KeyCloakを動かす

KeyCloakの起動スクリプトは、ディレクトリのbinにあるkc.shである。これをまずは起動してみる。とりあえず、サブコマンドにbuildを与えて、そしてサブコマンドstartで実際に起動する。出力結果を見ていてERRORがなければ大丈夫。そして、最後の方に、8443と9000ポートが開くメッセージがあるのでわかる。

cd  /var/www/keycloak-25.0.2/bin
./kc.sh build
./kc.sh start

そして、 https://kc.inter-mediator.com:8443 を開いてみる。すると以下のようなメッセージが見える。現状では管理者としてログインができないということを示している。

ここで、Ctrl+Cで一度止める。そして、記載の通り、環境変数に管理者のユーザ名、パスワードを指定して再度起動する。コマンドとしては次の通り。PASSWORDはもちろん、何か適当なパスワードを指定して、自分で記録管理しておく。

cd  /var/www/keycloak-25.0.2/bin #カレントはKeyCloakの中のbinとする
export KEYCLOAK_ADMIN=admin
export KEYCLOAK_ADMIN_PASSWORD=PASSWORD
printenv|grep KEY #一応確認
./kc.sh --verbose start

すると、次のように、ログインパネルが表示され、ここで、admin/PASSWORDでログインができるはずである。ここまでで、基本的な動作確認ができた。

なお、環境変数にパスワードがある状態になるが、おそらくこの後にサービス化するので、再起動して後付けの環境変数は消えるはずである。このKEYCLOAK_*という2つの環境変数がある状態で、まだ管理者がない状態であれば、この環境変数の値を使って管理者ユーザを作成する。つまり、その瞬間にだけ環境変数があれば良いようで、その後は環境変数になくても管理者は存在し、ログインができるのである。

KeyCloakのサービス化

コマンドラインで起動した状態で使うというのはちょっと現実的ではないので、SystemCTL配下のサービスとして、バックグランドで自動起動するようにしたい。そのために、以下のようにコマンドを入れた(ほとんど前述のブログ記事の通り)。

sudo groupadd -r keycloak
sudo useradd -m -d /var/lib/keycloak -s /sbin/nologin \
     -r -g keycloak keycloak
sudo nano /etc/systemd/system/keycloak.service
# ここで、新しいファイルが作られるので、以下のように記述する
sudo chown -R keycloak /var/www/keycloak-25.0.2
sudo systemctl enable keycloak.service
sudo systemctl start keycloak.service
systemctl status keycloak.service

ファイル「keycloak.service」については、以下のように作成した。おそらく調整ポイントは、WorkingDirectoryとExecStartのパスだけだろう。

[Unit]
Description=Keycloak Application Server
After=syslog.target network.target

[Service]
Type=simple
TimeoutStopSec=0
KillSignal=SIGTERM
KillMode=process
SuccessExitStatus=143
LimitMEMLOCK=infinity
SendSIGKILL=no
WorkingDirectory=/var/www/keycloak-25.0.2/
User=keycloak
Group=keycloak
LimitNOFILE=102642
ExecStart=/var/www/keycloak-25.0.2/bin/kc.sh start --log=console,file

[Install]
WantedBy=multi-user.target

コマンド入力について説明しておく。最初のgroupaddとuseraddコマンドでは、ユーザkeycloak、グループkeycloakを作成している。もちろん、keycloakユーザはkeycloakグループに所属させる。このユーザで、デーモンを動かすということである。ここでのKeyCloakが存在するディレクトリ/var/www/keycloak-25.0.2以下についても、keycloakユーザが所有者となるように、chownコマンドで設定している。useraddについては、-dでホームディレクトリを設定しているが、ここに何かを仕掛ける予定は特にない-mによりホームは自動的に作られる。シェルをnologinにしてあるので、ログインをしないことを想定している。-rはシステムアカウントとしてkeycloakを作る。実際にはIDは997で作られた。

実際のログファイルは、/var/www/keycloak-25.0.2/data/log/keycloak.logとなる。つまり、KeyCloakのディレクトリ以下、data/logの場所に作られる。この内容は、kc.shで起動した時に画面で見えるのと同じである。なお、systemctlコマンドではログの一部はアクセス権がないということで出てこないが、ログの場所がわかっていれば問題ないだろう。

ということで、無事にKeyCloakが起動した。

(1)はここまでとする。

Ubuntu 22でINTER-Mediatorを稼働する

Ubuntu Server 22.04.1 LTS上で、INTER-Mediatorのサンプルを、MySQLで動かすところまでのセットアップ方法を紹介します。サーバは普通にDVD等でインストールします。ほぼ、デフォルトでセットアップした状態を想定しているので、Minimalの方ではありません。また、サーバアプリケーションは、SSH Serverだけをセットアップ時に含めているとします。

ということで、早速、インストール後のコマンド入力です。一気にまとめて紹介します。

sudo apt -y update
sudo apt -y upgrade
sudo apt install -y apache2 php mysql-server
sudo apt install -y php-curl php-xml php-gd libicu-dev \
                    mysql-client php-pdo-mysql
sudo apt install -y nodejs
sudo apt install -y composer
sudo chmod -R g+w /var/www
sudo chown -R www-data:<user> /var/www
sudo systemctl restart apache2

cd /var/www/html
git clone https://github.com/INTER-Mediator/INTER-Mediator.git
cd INTER-Mediator/
composer update
cd dist-docs
sudo mysql -uroot < sample_schema_mysql.sql 

「php」でインストールすると、Ver.8.1がセットアップされます。モジュール類も以前よりも多く初期設定で入っているので、記載した、php-curlなど3つと、データベースのドライバを追加するだけで大丈夫です。ただ、intlモジュールが利用するlibicu-devを入れておかないといけないのは以前から変わっていないところです。php-pdo-mysqlは実は存在しておらず、php8.1-mysqlが代わりにインストールされます。php-mysqlというモジュールもあってこちらでも良さそうな気がしますが、とりあえず、PDO本体は入るけどもMySQLのPDOサポート部分は追加しないといけないというところがポイントです。よって、PostgreSQL等でも同様にPDOドライバを入れないといけないということです。

Node.jsは「念の為に」入れておきます。composerもaptでインストールできるようになっています。

Apache2は以前の通り、www-dataユーザで稼働するので、このユーザのホームである/var/wwwのアクセス権を設定しておきますが、chownでのグループはログインユーザ名にしておくのがいいかと思います。そして、Apache2を再起動します。以前よりだいぶんとシンプルになった気がします。

後半は、INTER-Mediatorのインストールです。とりあえず、Web公開ディレクトリにレポジトリの中身を展開してそれを動かすことにします。クローン後、composer updateコマンドを動かし、サンプルのデータベースをMySQLに読み込ませて準備するだけです。これで、「http://ホストIP/INTER-Mediator/samples/」で、サンプルの目次ページが出てくるはずです。

現在は既定値でサービスサーバを落としていますが、INTER-Mediator/params.phpの以下の部分を修正すると、サービスサーバが稼働します。コード部分は修正前ですので、コメントに従って変更してみてください。Sample_formフォルダのサンプルがクライアント間同期の仕組みを組み込んであります。サンプルの目次ページだと、「Any Kinds of Samples」の最初にある「Master-Detail Style Page」のリンクを利用してください。

$notUseServiceServer = true; // 値をfalseにする
/*  // この行を消してコメントでなくする
$activateClientService = false; // 値をtrueにする
$serviceServerProtocol = "ws";
$serviceServerHost = "";
$serviceServerPort = "11478";
$serviceServerKey = "";
$serviceServerCert = "";
$serviceServerCA = "";
$serviceServerConnect = "http://localhost"; // localhostを実際のホストにする
$stopSSEveryQuit = false;
$bootWithInstalledNode = false;
$preventSSAutoBoot = false;
$foreverLog = '/tmp/forever.log';
*/ // この行を消してコメントでなくする

FileMaker Server 19.4(Ubuntu)の稼働するLinuxでPHPも稼働させる

FileMaker Server 19.4.2.204が稼働するUbuntu Server 18では、デフォルトではPHPは入っていません。自分で入れれば動くのはわかっているのですが、いわゆる「インストーラ」はないので、色々うまく設定しないといけなくなります。一応、動かす方法はわかったので、忘れないようにここに書いておきます。

まず、PHPのインストールですが、Ubuntuの普通のパッケージだと7.2です。せめて7.4にしたいので、こちらのサイトを参考に以下のようにコマンドを入れました。レポジトリを追加して、PHP 7.4をインストールします。

sudo apt-get update
sudo apt -y install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt -y install php7.4

これだけだと、UbuntuでのサービスとしてのApache2を稼働させるとおそらくPHPは稼働しますが、FileMaker ServerのApacheは、独自の方法で起動しているので、そちらでPHPを認識させないといけません。

そこで、以下のようにコマンドを入れて、メインの設定ファイルを修正します。最初のcdコマンドで移動するパスが、FileMaker Serverをインストールした場合のApacheのルートディレクトリです。

cd /opt/FileMaker/FileMaker\ Server/HTTPServer/
sudo nano conf/httpd.conf

以下のような場所があるので、まずここを検索します。

#
# Disable PHP document
#
<FilesMatch "\.php$">
    Require all denied
</FilesMatch>

この部分を、以下のように変更します。php.confはこれから作ります。

#
# Disable PHP document
#
#<FilesMatch "\.php$">
#    Require all denied
#</FilesMatch>

Include conf/extra/php.conf

これだけでよさそうに思うのですが、これだけだと次のようなメッセージが出てしまいます。

[Wed Jan 19 11:11:29.516483 2022] [php7:crit] [pid 30487:tid 140490306792384] Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe.  You need to recompile PHP.
AH00013: Pre-configuration failed

Apacheはマルチスレッド対応だけど、PHPは違うから、PHPを再コンパイルしろとあります。再コンパイルできるなら、レポジトリから取って来ません。そこで、若干問題が生じる可能性もあるのですが、Apacheをマルチスレッドではない状態で動かします。こちらのサイトを参考にしましたが、手順は異なります。

この点を解決するためにconf/httpd.confの編集を続けます。以下のような部分を検索します。「mpm」で検索すると良いでしょう。

LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so
LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
LoadModule negotiation_module /usr/lib/apache2/modules/mod_negotiation.so

これを、次のように変更します。mpm_event_moduleをコメントにして読み込みません。新たに、mpm_prefork_moduleを読み込みます。記載されていないモジュールの読み込みが増えていますが、そのモジュールはもともとありました。

LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so
#LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
LoadModule mpm_prefork_module /usr/lib/apache2/modules/mod_mpm_prefork.so
LoadModule negotiation_module /usr/lib/apache2/modules/mod_negotiation.so

これで、httpd.confを保存しておきます。

続いて、php.confを作ります。php7.4をインストールしたときに作られるファイルから適当に記述を持ってきて作ったものです。エディタを起動するために、次のようにコマンドを入れます。

sudo nano extra/php.conf

もちろん、存在しないファイルなので、エディタの画面は真っ白です。ファイルの中身は次のようにします。

LoadModule php7_module /usr/lib/apache2/modules/libphp7.4.so

<FilesMatch ".+\.ph(ar|p|tml)$">
    SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch ".+\.phps$">
    SetHandler application/x-httpd-php-source
    # Deny access to raw php sources by default
    # To re-enable it's recommended to enable access to the files
    # only in specific virtual host or directory
    Require all denied
</FilesMatch>
# Deny access to files without filename (e.g. '.php')
<FilesMatch "^\.ph(ar|p|ps|tml)$">
    Require all denied
</FilesMatch>

冒頭のLoadModuleは必須として、最初のSetHandlerだけでも多分動くと思いますが、とりあえず、他のものも入れておきました。なお、元のファイルにあったユーザのホームで公開した場合にスクリプトを動かさないようにする設定は省きました。

ここで、Apacheサーバだけを再起動とかして動くようにするのがお作法なのですが、サーバ自体を再起動します。それが確実なようです。すると、PHPが動きました。ちなみに、php.iniファイルのパスは、/etc/php/7.4/apache2/php.ini です。

こうしてPHPが稼働する状態になっているなら、PHPのモジュールはインストールするだけでOKです。例えば、初期状態ではcurlが稼働しませんが、次のようにコマンドを入れます。

sudo apt-get install -y php7.4-curl

すると、/etc/php/7.4/apache2/conf.dに、curl.iniファイルへのショートカットが作られて、認識します。あとは、サーバー再起動でもいいのですが、httpdctl gracefulでも設定は反映されます。

ちなみに、この方法でPHPを動かすのはまたまたアップデートの時などに手順やファイル名が違ったりしたりと色々面倒な気がするので、実稼働するシステムでは、FileMaker Serverとは別にPHPを稼働させるサーバを立てるのが、トラブルは少ないのではないでしょうか。

Ubuntu Server 18でINTER-Mediatorを動かすまで

この原稿の内容は時間が経過して内容として不足しています。こちらの記事を参考にしてください。


Ubuntu Server 18.04.1 LTS上でINTER-Mediatorを動かす話です。とは言え、半分以上はLAMPサーバーセットアップの方法となるかと思います。なお、様々なコマンドがちょっとずつですが変わっているので、その辺りも含めてまとめておきます。

サーバーはVirtual Boxで稼働させました。このサーバーは単に実験するだけでなく、INTER-Mediatorのデモ用にも使いますので、外部からのアクセスが必要です。そこで、ネットワークは、NATとブリッジネットワークをこの順序に設定しておきました。そして、インストール途中で、ブリッジネットワーク側は、ローカルネットワーク側に存在できるような固定IPに設定します。この設定は後からでもできるのですが、最初からやっておくのが失敗がありません。NATが必要かどうかの問題もありますが、ブリッジネットワークを切っても外部に接続できるようにするために、こうしました。

さて、セットアップ後、apt-getなのですが、その前に、以下のように、レポジトリの設定ファイル/etc/apt/sources.listの3行いずれも末尾に「universe」という単語を入れておきます。こうしないと、PHPのいくつかのモジュールをインストールできませんでした。

$ cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu bionic main universe
deb http://archive.ubuntu.com/ubuntu bionic-security main universe
deb http://archive.ubuntu.com/ubuntu bionic-updates main universe

(2019-01-03追記)ubuntu-18.04.1.0-live-server-amd64.isoというファイルでインストールしたところ、上記のuniverseを追加する作業は不要でした。最初から、レポジトリが読み込まれる状態になっています。

こうして、apt-getします。私はaptitudeでやる習慣ができてしまったので、aptitudeでやったのですが、試行錯誤しないのなら、apt-getでやることになるので、コマンドはapt-getで書きます。Apache、PHP7.2、MySQL、PostgreSQL、SQLiteまでを入れました。INTER-Mediatorを稼働するのに必要なPHP追加モジュールは、概ねこのようなあたりですが、追加が必要そうならこの文書を更新します。

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y apache2 php7.2 libapache2-mod-php7.2
sudo apt-get install -y php7.2-mbstring php7.2-bcmath php7.2-curl php7.2-xml
sudo apt-get install -y mysql-server-5.7 mysql-client-core-5.7 php7.2-pdo-mysql
sudo apt-get install -y postgresql php7.2-pdo-pgsql
sudo apt-get install -y sqlite3 php7.2-pdo-sqlite

ちなみに、PDOのライブラリは、「-PDO」の付いていないもののエイリアスらしく、そういうメッセージが出て、例えばMySQLなら「php7.2-mysql」がインストールされます。

なお、Apacheの再起動が必要になることがあるかと思われますが、こちらのコマンドを使います。serviceコマンドも従来通り使えますが、systemdベースになっていますので、今現在の状況に合わせたコマンドを使いましょう。

sudo systemctl restart apache2

INTER-Mediator Ver.6を試すなら、composerは必須です。ホームフォルダをカレントにして以下のようなコマンドを入れることでインストールされます。レポジトリのものもあるようなのですが、この方法だと最新版が入手できるので、こちらを紹介します。他のサイトもほとんどこちらの方法を紹介しています。これで、コマンドプロンプトに「composer」と入れればヘルプが表示できます。なお、実際のcomposerの動作では、PHPのzipモジュールとunzipコマンドのインストールも必要なので、そのコマンドも記載しておきます。それから、gitも必要ですね。

cd
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer

sudo apt-get install -y php7.2-zip unzip
sudo apt-get install -y git

ここまでで、LAMPサーバーセットアップができているということになります。WebサーバーのルートにINTER-Mediatorをインストールするとしたら、例えば、以下のコマンドで行えます。

cd /var/www/html
git clone https://github.com/INTER-Mediator/INTER-Mediator.git

ファイルのダウンロード後に、INTER-Mediatorフォルダをカレントにして、composerコマンドを稼働します。composerを稼働させないと、PHPのプログラムへのパスが通りません。composerを使ったいろんな作業はあるのですが、ここではダウンロードしたものをそのまま動かす方法をまずは説明しました。

cd INTER-Mediator
composer update

MySQLへのrootユーザーでのログインは次のように行います。なんとなくPostgreSQLのようになってきました。rootパスワードを設定してどうこうするという状況ではなくなったようで、この状況に適応しましょう。管理者ユーザーで、mysqlコマンドを打つのでjはなく、sudo mysqlということです。パスワードは、sudoの時のパスワードで、つまりはログインしている管理者のパスワードを入力します。MySQLのrootのパスワードはつまりは指定しません。

sudo mysql -uroot

INTER-Mediatorのサンプルファイルを読み込むとしたら、こんな感じになります。もちろん、必要に応じて、管理者のパスワードを入力します。サンプルは、INTER-Mediator/dist-docsにあります。

sudo mysql -uroot < sample_schema_mysql.txt

一方、PostgreSQLは、以前からpostgresユーザーでの接続を行うことで、データベース接続していましたが、その点は変わりません。sudoでpostgresユーザーになるので、現在のログインしている管理者ユーザーのパスワードを知っておく必要があり、postgresユーザーのパスワードは利用しません。コマンド接続と、INTER-Mediatorのサンプルの読み込み例を記載します。サンプルは、INTER-Mediator/dist-docsにあります。

sudo -u postgres -i

sudo -u postgres psql -c 'create database test_db;'
sudo -u postgres psql -f sample_schema_pgsql.txt test_db

SQLiteは特に違いはありません。サンプルは、INTER-Mediator/dist-docsにあります。

sudo mkdir -p /var/db/im
sudo sqlite3 /var/db/im/sample.sq3 < sample_schema_sqlite.txt
sudo chown www-data /var/db/im
sudo chown www-data /var/db/im/sample.sq3