OpenAM起動時のJVMオプションについて

OpenAMを稼働するJavaコンテナ(Tomcatなど)にJVMオプションを指定して起動していると、トラブルがあった場合でも解析ができ、原因を突き止められる可能性が高くなります。ということで、参考までにGitHubにOpenAM用のTomcat環境変数設定ファイルを公開しておきました。

k-tamura/setenv-for-openam

  • setenv.sh (Linux用)
  • setenv.bat (Windows用)

$CATALINA_HOME/bin/にコピーして、実行権限を付与しておけば、自動的に読み込まれます。

各オプションについて、簡単に説明しておきます。

JITコンパイラのタイプ

JITコンパイラはサーバーコンパイラを選択します。通常、長時間起動するアプリケーションにおいて、-clientよりも性能が高くなります。

-server

Javaヒープサイズ

OpenAM管理ガイドのチューニングのセクションに書いてある通り、組み込みOpenDJを使用する場合(デフォルト)は最低でも2GBに設定します。また、Tomcat Expertによると、この2つの値は同じにした方がいいようです。

-Xms2048m
-Xmx2048m

Permanent領域/Metaspaceのサイズ

JDK 7以前の場合はPermanent領域のサイズを、

-XX:PermSize=256m
-XX:MaxPermSize=256m

JDK 8以降の場合はMetaspaceのサイズを設定します。

-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=256m

ForgeRock社の推奨値は、両方とも256MBです。

その他、OpenAM固有の推奨値

OpenAM管理ガイドのチューニングのセクションに書いてあったその他の推奨値を必要に応じて設定します。

-Dsun.net.client.defaultReadTimeout=60000
-Dsun.net.client.defaultConnectTimeout=30000
-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2

GC(ガベージコレクション)

GCのアルゴリズムやログ出力について設定します。GCのアルゴリズムはいくつかありますが、OpenAM管理ガイドのチューニングのセクションに書いてある通り、CMS(Concurrent Mark Sweep)を指定します。性能面の影響は小さいので、GCログの詳細も出力するようにします。

-Xloggc:$CATALINA_HOME/logs/gc.log
-XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSClassUnloadingEnabled
-XX:+PrintHeapAtGC
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=10M

-XX:+PrintGCTimeStamps」を付加すると、JVMを起動してからの時間が「17.890」のようにGCログに出力されますが、見づらいので「-XX:+PrintGCDateStamps」を付加して「2017-01-13T18:34:16.743」のような日時が出力されるようにしています(後者の方がごくわずかなオーバーヘッドが発生します)。

ヒープダンプの出力

OutOfMemoryErrorが発生したときにヒープダンプを出力するようにします。

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=$CATALINA_HOME/logs/

致命的なエラーの出力

JavaVMのクラッシュやJNIで呼び出したライブラリでのエラーなど、致命的なエラーがあった場合に、エラーファイルを出力します。この機能自体はデフォルトで有効ですが、出力先を変更したい場合は明示的に設定します。

-XX:ErrorFile=$CATALINA_HOME/logs/hs_err_pid%p.log

JFR(Java Flight Recorder)の有効化

商用利用のためにOracleのJava上でTomcatを動作させる場合は、Java Flight Recorder(JFR)も有効にします。JFRは、実行中のJavaアプリケーションに関する診断およびプロファイリングのためのデータを収集するツールです。記録中のオーバーヘッドはほとんどなく、性能面の影響は小さいので、常に有効化しておいていいと思います。

-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder

JFRを有効にするには、-XX:+UnlockCommercialFeaturesオプションの追加も必要です。

 


参考

http://www.tomcatexpert.com/blog/2011/11/16/setting-measurement-garbage-collection-apache-tomcat

http://www.tomcatexpert.com/blog/2011/11/22/performance-tuning-jvm-running-tomcat

https://backstage.forgerock.com/#!/docs/openam/13/admin-guide/chap-tuning

Javaパフォーマンス Scott Oaks 著、Acroquest Technology株式会社 監訳、寺田 佳央 監訳、牧野 聡 訳


 

OpenAMの新しい監査ログについて (2)

前回は、OpenAM 13.0.0で刷新された監査ログの概要について説明しました。最新のOpenAMでは、監査ログをCSVファイルに出力したり、SyslogやElasticSearchなどへの転送ができるようになっています。詳細については以下のページを参照下さい。

OpenAMの新しい監査ログについて (1)

今回はそれらの機能の一つであるJDBC監査ロギングについて書きます。JDBC監査ロギングは、OracleやMySQLなどのRDBMSに、OpenAMの監査ログを登録(INSERT)する機能です。

まず最初に言っておくと、このJDBC監査ロギングはOpenAM 13.0.0ではまともに動作しません…(新規に開発した機能は、最初のリリースでの動作が安定しないことがありますが、この機能はちょっと酷過ぎました…)。したがって、JDBC監査ロギングを利用する場合は、13.5.0以降(14.0.0のナイトリービルド)を使うか、いくつかのバグのパッチ(以下)を適用する必要があります。

設定手順

ここでは、MySQLに監査ログを登録する設定をします。おおまかな設定手順は、以下の通りです。

  1. JDBCドライバーをlibディレクトリにコピーする
  2. MySQLに、OpenAMの監査ログ用のテーブルを作成する
  3. OpenAMの管理コンソールで監査ログの設定を追加する

もう少し詳しく説明します。

※なお、MySQLのインストールや初期設定はしてあるものとします(省略します)。

手順1. JDBCドライバーをlibディレクトリにコピーする

JDBCドライバーを次のページからダウンロードしてきます。

https://dev.mysql.com/downloads/connector/j/

ダウンロードしたら、TomcatかOpenAMのlibディレクトリにコピーして下さい。

$ cp mysql-connector-java-5.1.38-bin.jar /usr/share/tomcat7/lib/

手順2. MySQLに、OpenAMの監査ログ用のテーブルを作成する

次に、MySQLにOpenAMの監査ログ用のデータベースを作成し、適当なユーザーでOpenAMからアクセスできるようにします。

$ mysql -u root -p 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.1.73 Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE DATABASE audit;
Query OK, 1 row affected (0.22 sec)

mysql> GRANT ALL PRIVILEGES ON audit.* TO root@'192.168.1.0/255.255.255.0' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.04 sec)

mysql> select user,host,password from mysql.user; 
+------+---------------------------+-------------------------------------------+
| user | host                      | password                                  |
+------+---------------------------+-------------------------------------------+
| root | localhost                 | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| root | openam02.example.co.jp    | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| root | 127.0.0.1                 | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| root | 192.168.1.0/255.255.255.0 | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
+------+---------------------------+-------------------------------------------+
4 rows in set (0.03 sec)

完了したら、OpenAMのwarファイルの中にあるaudit.sqlを実行して、監査ログ用のテーブルを作成します。

mysql> source /var/lib/tomcat7/webapps/openam/WEB-INF/template/sql/mysql/audit.sql
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected, 1 warning (0.00 sec)
Database changed
Query OK, 0 rows affected (0.09 sec)
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)

mysql> exit

手順3. OpenAMの管理コンソールで監査ログの設定を追加する

管理コンソールの 設定 > グローバル > 監査ロギング で、監査イベントハンドラのセクションの「新規」ボタンをクリックし「JDBC」を選択すると、JDBC用の監査ログを制御するハンドラが追加されます。

auditjdbcsettings1

「データベースの種類」はMySQLを選択し、「JDBCドライバー URL」から「データべースパスワード(確認)」までの項目に適切な値を入力して下さい。

auditjdbcsettings2

設定に問題がなければ、以下のように監査ログが4つのテーブルに登録されます。

audittables

大量の監査ログを捌くための仕組み

監査ログの設定後、OpenAMのログインや設定変更、ログアウトなどを行ってみると、あっという間にたくさんの監査ログレコードが登録されているのが分かります。実際の運用となり、ユーザー数が多くなると、さらに大量に登録されることになります。大量なログの高速な登録を実現するために、OpenAMは以下のような仕組みを実装しています。

afw4

ポイントとなるのは、以下の技術です。

  • 監査イベントバッファリング
  • ライタースレッド
  • ExecuteBatch()
  • HikariCP

ユーザーがOpenAMにログインしたり、自身の情報を更新すると、監査イベント(ログデータ)は、バッファ変数に一時的に保存されます(監査イベントバッファリング)。このログデータは監査ログINSERT用のSQLのプリペアドステートメントに結びつけられて、ライタースレッドによりexecuteBatch()メソッドで複数件まとめてデータベースに登録されます。

この時、データベースへのアクセスに使用しているコネクションプールのライブラリには、Commons DBCPやC3P0ではなく、HikariCPというものが使用されています。HikariCPは、軽量なJDBCコネクションプールのライブラリで、高速な処理性能を持っていることが特徴です。ただし、それだけではなく、シンプルな実装であるがゆえに信頼性や安定性も高いようです。

hikaricp-bench-2-4-0

HikariCPについて興味がある方は、以下を参照してみて下さい。

https://github.com/brettwooldridge/HikariCP

Java EEエージェントのビルド

Java EEエージェントのビルドもOpenAMサーバーと同様にmvnコマンドを実行するだけで完了します。

ビルド環境の整備

ビルドに必要なソフトウェアは、JDKとMavenです。前提ソフトウェアのバージョンについて、公式な情報は公開されていませんが、OpenAMのビルドができるバージョンを使えば問題はないはずです。

Java JDK Maven
1.7 以上 3.1.0 以上

ただし、1つ注意すべき点があります。WebSphere ASとWebLogic Server用のエージェントのビルドには、サーバーベンダーが提供する非公開のライブラリが必要です。これらの依存関係を解決するには、各サーバーソフ トウェアに含まれるライブラリを取得し、mvnコマンド実行時に参照できるようにしておく必要があります。詳細に関しては、Java EEエージェントのソースコードに添付されているreadme.mdファイルを参照してください。

手順. Java EEエージェントのビルド

まずは、ビルド用のディレクトリを作成し、そこに移動します。

$ mkdir jeeagent_build
$ cd jeeagent_build/

ソースコードはForgeRock社のBitbucketサーバー上で公開されています。ここでは、バージョン3.5.0のソースコードを圧縮したファイルをダウンロードします。

https://stash.forgerock.org/projects/OPENAM/repos/jee-agents/browse?at=refs%2Ftags%2F3.5.0

ダウンロードが完了したら、圧縮ファイルを解凍してください。

$ unzip jee-agents-master\@36016b991ff.zip 
Archive:  jee-agents-master@36016b991ff.zip
36016b991ff2aeb694a5d09e062591704f9eec45
 extracting: .gitignore              
   creating: jee-agents-agentapp/
  inflating: jee-agents-agentapp/pom.xml  

  .......

  inflating: pom.xml                 
  inflating: readme.md

解凍したら圧縮ファイルは削除します。

$ rm jee-agents-master\@36016b991ff.zip 
rm: remove 通常ファイル `jee-agents-master@36016b991ff.zip'? yes

ディレクトリ構成は、以下のようになっています。各サーバー毎のエージェントモジュールやサンプルアプリケーション(sampleapp)用のモジュールが、ディレクトリ毎に分かれて配置されています。

$ ll
合計 1828
drwxr-xr-x  3 root root    4096  9月 16 23:26 2016 jee-agents-agentapp
drwxr-xr-x  4 root root    4096  9月 16 23:26 2016 jee-agents-appserver
drwxr-xr-x 12 root root    4096  9月 16 23:26 2016 jee-agents-distribution
drwxr-xr-x  5 root root    4096  9月 16 23:26 2016 jee-agents-jboss
drwxr-xr-x  4 root root    4096  9月 16 23:26 2016 jee-agents-jetty
drwxr-xr-x  3 root root    4096  9月 16 23:26 2016 jee-agents-jsr196
drwxr-xr-x  3 root root    4096  9月 16 23:26 2016 jee-agents-library
drwxr-xr-x 15 root root    4096  9月 16 23:26 2016 jee-agents-sampleapp
drwxr-xr-x  3 root root    4096  9月 16 23:26 2016 jee-agents-sdk
drwxr-xr-x  3 root root    4096  9月 16 23:26 2016 jee-agents-tomcat
drwxr-xr-x  3 root root    4096  9月 16 23:26 2016 jee-agents-weblogic
drwxr-xr-x  4 root root    4096  9月 16 23:26 2016 jee-agents-websphere
drwxr-xr-x  2 root root    4096  9月 16 23:26 2016 legal
-rwxr-xr-x  1 root root   33221  9月 16 23:26 2016 pom.xml
-rw-r--r--  1 root root    2097  9月 16 23:26 2016 readme.md
$

全体のpom.xmlがあるので、ここでmvnコマンドを実行すれば、ビルドが開始されますが、前述した商用のサーバーのライブラリが存在しないの で、ビルドエラーとなってしまいます。Tomcatエージェントだけをビルドしたいということでれば、以下のようにpom.xmlを編集し、Tomcat以外のサーバー用のmoduleタグをコメントアウトすればビルドできるようになります。

    <modules>
        <module>jee-agents-sdk</module>
        <module>jee-agents-library</module>
        <module>jee-agents-agentapp</module>
        <module>jee-agents-tomcat</module>
<!-- ここから
        <module>jee-agents-jboss</module>
        <module>jee-agents-jetty</module>
        <module>jee-agents-appserver</module>
        <module>jee-agents-weblogic</module>
        <module>jee-agents-websphere</module>
        <module>jee-agents-jsr196</module>
ここまでコメントアウト -->
        <module>jee-agents-sampleapp</module>
        <module>jee-agents-distribution</module>
    </modules>

mvn clean installコマンドでビルドを実行します。テストを省略する場合は、-DskipTests=trueオプションを付加してください。

$ mvn -DskipTests=true clean install
[INFO] Scanning for projects...
[WARNING] 

  .......

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:00.510s
[INFO] Finished at: Sun Sep 25 09:42:15 JST 2016
[INFO] Final Memory: 64M/349M
[INFO] ------------------------------------------------------------------------

数分で、ビルドは完了します。jee-agents-distribution/jee-agents-distribution-tomcat- v6/target/以下に、Tomcatエージェントの圧縮ファイル(tomcat_v6_agent_4.0.0-SNAPSHOT.zip)が作成 されているはずです。

$ ll jee-agents-distribution/jee-agents-distribution-tomcat-v6/target/
合計 33888
drwxr-xr-x 2 root root     4096  9月 25 09:41 2016 archive-tmp
-rw-r--r-- 1 root root       27  9月 25 09:41 2016 build_date.js
-rw-r--r-- 1 root root 34692736  9月 25 09:41 2016 tomcat_v6_agent_4.0.0-SNAPSHOT.zip

OpenAMをRESTでセットアップする

OpenAMのJIRAを眺めていたら、RESTでOpenAMの初期設定(セットアップ)をすることができることに気付きました。OpenAMのwarファイルをサーブレットコンテナにデプロイして、以下のようにURL エンコードした各種パラメータを/openam/config/configuratorエンドポイントにPOSTすると、数秒後に初期設定が完了します。

# curl --request POST "http://openam.example.com:8080/openam/config/configurator" \
 --header "Content-Type:application/x-www-form-urlencoded" \
 --data-urlencode "SERVER_URL=http://openam.example.com:8080" \
 --data-urlencode "DEPLOYMENT_URI=openam" \
 --data-urlencode "BASE_DIR=/opt/tomcat7/openam" \
 --data-urlencode "locale=en_US" \
 --data-urlencode "PLATFORM_LOCALE=en_US" \
 --data-urlencode "ADMIN_PWD=p@s2word" \
 --data-urlencode "ADMIN_CONFIRM_PWD=p@s2word" \
 --data-urlencode "AMLDAPUSERPASSWD=Passw0rd" \
 --data-urlencode "AMLDAPUSERPASSWD_CONFIRM=Passw0rd" \
 --data-urlencode "COOKIE_DOMAIN=.example.co.jp" \
 --data-urlencode "DATA_STORE=embedded" \
 --data-urlencode "DIRECTORY_SSL=SIMPLE" \
 --data-urlencode "DIRECTORY_SERVER=localhost" \
 --data-urlencode "DIRECTORY_PORT=50389" \
 --data-urlencode "DIRECTORY_ADMIN_PORT=4444" \
 --data-urlencode "DIRECTORY_JMX_PORT=1689" \
 --data-urlencode "ROOT_SUFFIX=dc=openam,dc=forgerock,dc=org" \
 --data-urlencode "DS_DIRMGRDN=cn=Directory Manager" \
 --data-urlencode "DS_DIRMGRPASSWD=p@s2word" \
 --data-urlencode "acceptLicense=true"

Configuration complete!

GUIを使うと入力の手間やミスがあるので、動作検証などで何回もセットアップするような場合にこの方法は便利です。設定ツール(openam-configurator-tool.jar)を使って、同様にサイレントインストールをすることもできますが、設定ツールはダウンロードとインストールをしないといけないので、RESTの方が少しだけ簡単にできます。

ただし、この方法は今のことろOpenAMのインストールガイドにも載っていない、非公式なもののようです。初期化処理の途中経過が分からない点や例外処理が弱い点も考慮して、非公式のままにしているのだと思います。エラーレスポンスもスタックトレース付きのHTML形式で返ってきていました…

# curl --verbose --request POST "http://openam.example.com:8080/openam/config/configurator" \
 --header "Content-Type:application/x-www-form-urlencoded" \
 --data-urlencode "SERVER_URL=http://openam.example.com:8080" \
 --data-urlencode "DEPLOYMENT_URI=openam" \
 --data-urlencode "BASE_DIR=/opt/tomcat7/openam" \
 --data-urlencode "locale=en_US" \
 --data-urlencode "PLATFORM_LOCALE=en_US" \
 --data-urlencode "ADMIN_PWD=p@s2word" \
 --data-urlencode "ADMIN_CONFIRM_PWD=p@s2word" \
 --data-urlencode "AMLDAPUSERPASSWD=p@s2word" \
 --data-urlencode "AMLDAPUSERPASSWD_CONFIRM=p@s2word" \
 --data-urlencode "COOKIE_DOMAIN=.example.co.jp" \
 --data-urlencode "DATA_STORE=embedded" \
 --data-urlencode "DIRECTORY_SSL=SIMPLE" \
 --data-urlencode "DIRECTORY_SERVER=localhost" \
 --data-urlencode "DIRECTORY_PORT=50389" \
 --data-urlencode "DIRECTORY_ADMIN_PORT=4444" \
 --data-urlencode "DIRECTORY_JMX_PORT=1689" \
 --data-urlencode "ROOT_SUFFIX=dc=openam,dc=forgerock,dc=org" \
 --data-urlencode "DS_DIRMGRDN=cn=Directory Manager" \
 --data-urlencode "DS_DIRMGRPASSWD=p@s2word" \
 --data-urlencode "acceptLicense=true"

* About to connect() to openam.example.com port 8080 (#0)
* Trying 172.105.126.221... connected
* Connected to openam.example.com (172.105.126.221) port 8080 (#0)
> POST /openam/config/configurator HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.1.0 zlib/1.2.3 libidn/1.18 libssh2/1.2.2
> Host: openam.example.com:8080
> Accept: */*
> Content-Type:application/x-www-form-urlencoded
> Content-Length: 572
>
< HTTP/1.1 500 Internal Server Error
< Server: Apache-Coyote/1.1
< Content-Type: text/html;charset=utf-8
< Content-Language: en
< Content-Length: 2474
< Date: Thu, 25 Aug 2016 05:58:34 GMT
< Connection: close
<
<html><head><title>Apache Tomcat/7.0.57 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - AMSetupFilter.doFilter</h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u>AMSetupFilter.doFilter</u></p><p><b>description</b> <u>The server encountered an internal error that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>javax.servlet.ServletException: AMSetupFilter.doFilter
com.sun.identity.setup.AMSetupFilter.doFilter(AMSetupFilter.java:141)
org.forgerock.openam.audit.context.AuditContextFilter.doFilter(AuditContextFilter.java:51)
</pre></p><p><b>root cause</b> <pre>com.sun.identity.setup.ConfiguratorException: Default Agent Password cannot be the same as Administrator password.
com.sun.identity.setup.ServicesDefaultValues.validateURLAccessAgentPassword(ServicesDefaultValues.java:443)
com.sun.identity.setup.ServicesDefaultValues.validatePassword(ServicesDefaultValues.java:353)
com.sun.identity.setup.ServicesDefaultValues.setServiceConfigValues(ServicesDefaultValues.java:125)
com.sun.identity.setup.AMSetupServlet.processRequest(AMSetupServlet.java:466)
com.sun.identity.setup.AMSetupServlet.doPost(AMSetupServlet.java:439)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.forgerock.openam.validation.ResponseValidationFilter.doFilter(ResponseValidationFilter.java:44)
com.sun.identity.setup.AMSetupFilter.doFilter(AMSetupFilter.java:125)
org.forgerock.openam.audit.context.AuditContextFilter.doFilter(AuditContextFilter.java:51)
* Closing connection #0
</pre></p><p><b>note</b> <u>The full stack trace of the root cause is available in the Apache Tomcat/7.0.57 logs.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.57</h3></body></html>

OpenAMの新しい監査ログについて (1)

OpenAM 13.0.0では、監査ログの仕組みが刷新され、ForgeRock製品共通の出力形式に統一されています。また、次の監査ログ機能が提供されました。

  • CSV監査ロギング
  • Syslog監査ロギング
  • JDBC監査ロギング

さらに、OpenAM 13.5.0からは、次の機能も追加されています。

  • JMS監査ロギング
  • ElasticSearch監査ロギング

従来からある(12.0.x以前の)監査ログに代わって、デフォルトではCSV監査ロギング機能が有効になっており、[OpenAMの設定ディレクトリ]/[コンテキスト名]/log (例えば、/opt/tomcat7/openam/openam/log) ディレクトリに以下のようなファイルを出力します。

イベント ファイル名 説明
Access access.csv すべてのアクセスに対して、誰が、いつ、何をしたのかを出力します。
Activity activity.csv 13.xでは、エンドユーザーのセッションの状態の変更のみがログに記録されます。今後のリリースでは、ユーザーの信頼できるデバイス、UMAポリシー、OAuth 2.0のトークンなどへの変更が記録される予定です。
Authentication authentication.csv いつ、どのようにユーザーが認証されたか、また認証に関連するイベントを出力します。
Configuration config.csv 誰が、いつ、OpenAMの設定変更をしたかを出力します。設定の変更を行った対象を示すuserIdは、config.csvにはキャプチャされませんが、access.csvのtransactionIdから追跡できます。

この中の一つのaccess.csvを表示してみると、以下のような情報が出力されています。

"_id","timestamp","eventName","transactionId","userId","trackingIds","server.ip","server.port","client.ip","client.port","request.protocol","request.operation","request.detail","http.request.secure","http.request.method","http.request.path","http.request.queryParameters","http.request.headers","http.request.cookies","http.response.headers","response.status","response.statusCode","response.detail","response.elapsedTime","response.elapsedTimeUnits","component","realm"
"9c651f8b-d475-4be6-ab49-a4267125c751-491","2016-08-08T13:30:04.634Z","AM-ACCESS-OUTCOME","9c651f8b-d475-4be6-ab49-a4267125c751-489",,"[""""]","192.168.1.101","8080","192.168.1.12","47108","CREST","ACTION","{""action"":""validate""}","false","POST","http://openam01.example.co.jp:8080/openam/json/sessions","{""_action"":[""validate""]}","{""accept"":[""application/json, text/javascript, */*; q=0.01""],""accept-api-version"":[""protocol=1.0,resource=1.1""],""host"":[""openam01.example.co.jp:8080""],""origin"":[""http://openam01.example.co.jp:8080""],""referer"":[""http://openam01.example.co.jp:8080/openam/XUI/""],""user-agent"":[""Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36""],""x-nosession"":[""true""],""x-password"":[""anonymous""],""x-requested-with"":[""XMLHttpRequest""],""x-username"":[""anonymous""]}","{""JSESSIONID"":""F1B35FF947BFD9EF7C9DDC026A1C15F4"",""amlbcookie"":""01"",""i18next"":""ja""}",,"SUCCESSFUL",,,"298","MILLISECONDS","Session","/"
"9c651f8b-d475-4be6-ab49-a4267125c751-496","2016-08-08T13:30:04.870Z","AM-ACCESS-OUTCOME","9c651f8b-d475-4be6-ab49-a4267125c751-494",,"[""428f5cd47cea8c1d01""]",,,"192.168.1.12","47108",,,,"false","POST","http://openam01.example.co.jp:8080/openam/json/authenticate","{}","{""accept"":[""application/json, text/javascript, */*; q=0.01""],""accept-api-version"":[""protocol=1.0,resource=2.0""],""host"":[""openam01.example.co.jp:8080""],""origin"":[""http://openam01.example.co.jp:8080""],""referer"":[""http://openam01.example.co.jp:8080/openam/XUI/""],""user-agent"":[""Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36""],""x-nosession"":[""true""],""x-password"":[""anonymous""],""x-requested-with"":[""XMLHttpRequest""],""x-username"":[""anonymous""]}","{""JSESSIONID"":""F1B35FF947BFD9EF7C9DDC026A1C15F4"",""amlbcookie"":""01"",""i18next"":""ja""}",,"SUCCESSFUL",,,"4","MILLISECONDS","Authentication","/"
"9c651f8b-d475-4be6-ab49-a4267125c751-507","2016-08-08T13:30:08.698Z","AM-ACCESS-OUTCOME","9c651f8b-d475-4be6-ab49-a4267125c751-499","id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org","[""428f5cd47cea8c1d01""]",,,"192.168.1.12","47108",,,,"false","POST","http://openam01.example.co.jp:8080/openam/json/authenticate","{}","{""accept"":[""application/json, text/javascript, */*; q=0.01""],""accept-api-version"":[""protocol=1.0,resource=2.0""],""host"":[""openam01.example.co.jp:8080""],""origin"":[""http://openam01.example.co.jp:8080""],""referer"":[""http://openam01.example.co.jp:8080/openam/XUI/""],""user-agent"":[""Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36""],""x-nosession"":[""true""],""x-password"":[""anonymous""],""x-requested-with"":[""XMLHttpRequest""],""x-username"":[""anonymous""]}","{""JSESSIONID"":""F1B35FF947BFD9EF7C9DDC026A1C15F4"",""i18next"":""ja"",""amlbcookie"":""01""}",,"SUCCESSFUL",,,"8","MILLISECONDS","Authentication","/"

従来の監査ログの1つであったamSSO.access(以下)と比較してみると、出力される情報量が増えているのが分かります。

#Version: 1.0
#Fields: time Data ContextID LoginID IPAddr LogLevel Domain MessageID LoggedBy NameID ModuleName HostName 
"2016-08-08 22:29:54" /usr/share/tomcat7/openam/openam/log/|/usr/share/tomcat7/openam/openam/log/|File|File|OFF|OFF|INACTIVE|ACTIVE|INFO|INFO 4690fe938b6fdd2b01 "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" "Not Available" INFO dc=openam,dc=forgerock,dc=org LOG-3 "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" "Not Available" amSSO.access 192.168.1.101 
"2016-08-08 22:30:04" id=amadmin 2436c2b623da170301 id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org 192.168.1.12 INFO dc=openam,dc=forgerock,dc=org SESSION-4 "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" "Not Available" amSSO.access 192.168.1.12 
"2016-08-08 22:30:08" id=amadmin 428f5cd47cea8c1d01 id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org 192.168.1.12 INFO dc=openam,dc=forgerock,dc=org SESSION-1 "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" "Not Available" amSSO.access 192.168.1.12 

新しい監査ログの設定は、管理コンソールの 設定 > グローバル > Audit Loggingで確認できます。

GlobalAuditConfig

information なお、13.0.0より前のバージョンで提供されていたロギング機能(管理コンソールの設定 > システム > ログ)は13.xでも利用できますが、デフォルトで非アクティブな状態になっており、今後のリリースでは廃止される予定になっています。

Screenshot from 2016-08-08 22-11-59

次回は、13.0.0で追加されたJDBC監査ログ機能について、調べた結果をまとめます。

OpenAMをビルドする

 OpenAMのビルドはとても簡単です。基本的には、OpenAMのソースコードをダウンロードして、Mavenのコマンドを実行するだけです。ただし、注意すべき点がいくつかあります。

注意点

  • OpenAMと、Java、Maven、Gitのバージョンを確認すること
  • Windows上でのビルドは失敗する可能性があるので、LinuxかMac上で実施すること
  • ビルドするだけであれば、-DskipTests=trueオプションを付けること(テストはスキップする)

ビルド環境の整備

 OpenAM 11.0.0以降のビルドに必要なソフトウェアは、JDK、Maven、Gitですが、OpenAMのバージョンによって若干異なります。

OpenAM Java JDK Maven Git
OpenAM 13.0.0 1.7 以上 3.1.0 以上 1.7.6 以上
OpenAM 12.0.0 1.6 以上 3.3.1 以下 1.7.6 以上
OpenAM 11.0.0 1.6 または 1.7 3.0.5 1.7.6 以上

Mavenのビルドコマンドを実行する前に、これらのバージョンを確認しておきましょう。

$ mvn -version
Apache Maven 3.1.0 (893ca28a1da9d5f51ac03827af98bb730128f9f2; 2013-06-28 11:15:32+0900)
Maven home: /opt/apache-maven-3.1.0
Java version: 1.7.0_101, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.101.x86_64/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "2.6.32-642.el6.x86_64", arch: "amd64", family: "unix"

$ git --version
git version 2.2.0

参考までに、今回使った環境は以下の通りです。

  • CentOS 6.8
  • OpenJDK 1.7.0.101
  • Apache Maven 3.1.0
  • Git 2.2.0

ソースコードの取得

 ソースコードはForgeRock社のBitbucketサーバーからgit cloneで取得してくることもできますが、アカウントをつくってログインしないといけないので、GitHubからダウンロードします。ダウンロードしたら、解凍して出来たディレクトリに移動して下さい。

$ wget --no-check-certificate https://github.com/ForgeRock/openam/archive/13.0.0.zip
$ unzip 13.0.0.zip
$ cd openam-13.0.0

Mavenによるビルド

 以下のコマンドを実行すると、ビルドが始まります。

$ export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=512m"
$ mvn -DskipTests=true clean install

マシンの性能によりますが、30分くらいはかかると思います。完了すると、openam-server/target/にOpenAM-13.0.0.warが作成されます。

非公式日本語版OpenAMのビルド

 次のページにも書きましたが、私がつくった非公式日本語版OpenAMも簡単にビルドできます。

https://github.com/k-tamura/openam1300-japanese-properties/blob/master/README.jp.md

Java、Maven、Gitがインストールされていれば、以下のコマンドを実行するだけです。

$ wget --no-check-certificate https://raw.githubusercontent.com/k-tamura/openam1300-japanese-properties/master/build-openam-jp.sh
$ chmod +x build-openam-jp.sh
$ ./build-openam-jp.sh

※レビュー未実施なので、日本語訳が間違っていたり、分かりにくい部分はあるかもしれません。

ということで、ビルドはとても簡単なので試してみて下さい。

OpenAMのデバッグログについて

 一般的なアプリケーションと同様に、OpenAMも問題が発生した際の解析などを目的として、デバッグログを出力します。OpenAMが意図した通りに動作しない場合、デバッグログを確認することが問題解決の第一歩になります。

OpenAMサーバーのデバッグログ

 OpenAMサーバーのデバッグログの出力先は、デフォルトで[OpenAMの設定ディレクトリ]/[コンテキスト名]/debug (例えば、/opt/tomcat7/openam/openam/debug) になります。この中に以下のようなカテゴリー単位のログが出力されます。

表. デバッグログのファイル名と内容

ファイル名 内容
amUpgrade OpenAMのアップグレード中に出力されるログ
Authentication 認証に関するログ
Configuration 設定に関するログ
CoreSystem OpenAMのコアとなるクラスが出力するログ
Federation SAMLなどのフェデレーションに関するログ
IdRepo データストアにアクセスするモジュールが出力するログ
Policy ポリシーに関するログ
Session セッションに関するログ

この他にも、カテゴリーに応じたデバッグログファイルは出力されます。ちなみに、[OpenAMの設定ディレクトリ]/[コンテキスト名]/log (例えば、/opt/tomcat7/openam/openam/log) 以下には、監査ログが出力されます。問題が発生した場合に最初に確認するのは、logディレクトリではなく、debugディレクトリのファイルであることに注意して下さい。

デバッグレベルと出力先の変更

 デバッグログのレベルと出力先は、管理コンソールで変更できます。 設定 > サーバーおよびサイト > サーバー名 をクリックして、表示された一般設定のページの「デバッグ」セクションで設定ができます。

Screenshot from 2016-06-18 17-51-20

「デバッグ」セクションの設定項目の詳細は、以下の通りです。

表. OpenAMのデバッグログの設定

設定項目 デフォルト値 説明
デバッグレベル エラー OpenAM全体のデバッグレベル。
デバッグファイルのマージ オン すべてのデバッグログを 1 つのファイル (debug.out) に転送します。オフ: カテゴリー毎に個別のデバッグファイルを作成します。
デバッグディレクトリ %BASE_DIR%/%SERVER_URI%/debug デバッグファイルが存在するディレクトリ。

解析のためにログの出力量を多くしたいば場合は、デバッグレベルを「メッセージ」に変更します。

カテゴリー単位のデバッグレベルの変更

 OpenAMは、システム全体のログレベルだけでなく、カテゴリーやデバッグインスタンス単位でログレベルを変更することができます。 この機能を利用するには、amadminでOpenAMにログインし、Debug.jsp (例えば、http://openam.example.com:8080/openam/Debug.jsp) にアクセスします。

Screenshot from 2016-06-18 18-17-46

例えば、カテゴリー「OAuth2Provider」のログレベルだけを「メッセージ」レベルにして、詳細なデバッグ情報を出力する、といったことができます。

デバッグログのローテーション

 デフォルトでは、OpenAMはデバッグログをローテーションしません。デバッグログをローテーションさせるには、OpenAMがデプロイされているディレクトリのWEB-INF/classes/debugconfig.propertiesを編集します。

表. デバッグログのローテーション設定

プロパティ名 デフォルト値 説明
org.forgerock.openam.debug.prefix 無し デバッグログファイルのプレフィックスを文字列で指定します。
org.forgerock.openam.debug.suffix -MM.dd.yyyy-kk.mm デバッグログファイルのサフィックスをSimpleDateFormat形式で指定します。
org.forgerock.openam.debug.rotation 無し ローテーションの間隔を分単位で指定します。ゼロよりも大きい値に設定します。

debugconfig.propertiesへの変更は、OpenAMを再起動後に反映されます。

ポリシーエージェントのデバッグログ

 ポリシーエージェントのデバッグログの設定は、WebエージェントとJ2EEエージェントで若干異なります。なお、以降で説明するWebエージェントはバージョン3.xについてです。バージョン4.0以上の場合は、若干異なります。

Webエージェントのデバッグログ

 Webエージェントのデバッグログの出力先はデフォルトで、[Webエージェントのインストールディレクトリ]/agent_[N]/logs/debug/amAgentになります。出力先を含むデバッグログの設定は、[Webエージェントのインストールディレクトリ]/agent_[N]/config/OpenSSOAgentBootstrap.propertiesに以下のように定義されています。

#
# AGENT DEBUG FILE
#   Name of the file to use for debug information.
#
# Hot-Swap Enabled: No
#
com.sun.identity.agents.config.debug.file = /root/web_agents/apache22_agent/Agent_001/logs/debug/amAgent

#
# AGENT DEBUG LOG LEVEL
# Set the logging level for the specified logging categories.
# The format of the values is
#
# <ModuleName>[:<Level>][,<ModuleName>[:<Level>]]*
#
# The currently used module names are: AuthService, NamingService,
# PolicyService, SessionService, PolicyEngine, ServiceEngine,
# Notification, PolicyAgent, RemoteLog and all.
#
# The all module can be used to set the logging level for all currently
# none logging modules. This will also establish the default level for
# all subsequently created modules.
#
# The meaning of the 'Level' value is described below:
#
# 0 Disable logging from specified module*
# 1 Log error messages
# 2 Log warning and error messages
# 3 Log info, warning, and error messages
# 4 Log debug, info, warning, and error messages
# 5 Like level 4, but with even more debugging messages
# 128 log url access to log file on AM server.
# 256 log url access to log file on local machine.
#
# If level is omitted, then the logging module will be created with
# the default logging level, which is the logging level associated with
# the 'all' module.
#
# For level of 128 and 256, you must also specify audit.access.type property.
#
# Even if the level is set to zero, some messages may be produced for
# a module if they are logged with the special level value of 'always'.
#
# Hot-Swap Enabled: No
#
com.sun.identity.agents.config.debug.level =256

また、デバッグログに関する設定の一部は管理コンソールで変更が可能です。Webエージェントの場合は、 レルム > (レルム名) > エージェント > Web > グローバル をクリックして、表示されたエージェントのグローバル設定ページの「デバッグ」セクションで以下の設定ができます。全ての項目でホットスワップが有効になっています。

表. Webエージェントのデバッグログの設定

設定項目 デフォルト値 説明
エージェントデバッグレベル エラー Webエージェントのデバッグレベル。
エージェントのデバッグファイルローテーション 有効 デバッグファイルは指定されたサイズに基づいてローテーションされます。
エージェントのデバッグファイルサイズ 10000000 エージェントのデバッグファイルサイズ (バイト単位)。

ただし、「エージェント設定リポジトリの場所」が「集中化」に選択されている場合に限ります。「ローカル」に設定されている場合は、ポリシーエージェントのインストールディレクトリ配下にある[Webエージェントのインストールディレクトリ]/agent_[N]/config/OpenSSOAgentConfiguration.propertiesというファイルでこれらの設定を変更可能です。

J2EEエージェントのデバッグログ

 J2EEエージェントのデバッグログの出力先はデフォルトで、[J2EEエージェントのインストールディレクトリ]/agent_[N]/logs/debug/debug.outになります。出力先を含むデバッグログの設定は、[J2EEエージェントのインストールディレクトリ]/agent_[N]/config/OpenSSOAgentBootstrap.propertiesに以下のように定義されています。

#
# DEBUG SERVICE PROPERTIES
# - com.iplanet.services.debug.directory: Specifies the complete path to the
# directory where debug files will be stored by the Agent.
# - com.sun.services.debug.mergeall: consolidates all the debug information
# into one file if it is set to on. Each component has its own debug file
# if it is set to off.
# Hot-Swap Enabled: No
#
com.iplanet.services.debug.level=error
com.iplanet.services.debug.directory=/home/jetty/j2ee_agents/jetty_v7_agent/Agent_003/logs/debug
com.sun.services.debug.mergeall=on

また、デバッグログに関する設定の一部は管理コンソールで変更が可能です。J2EEエージェントの場合は、 レルム > (レルム名) > エージェント > Web > グローバル をクリックして、表示されたエージェントのグローバル設定ページの「デバッグ」セクションで以下の設定ができます。この項目もホットスワップは有効になっています。

表. J2EEエージェントのデバッグログの設定

設定項目 デフォルト値 説明
エージェントデバッグレベル エラー J2EEエージェントのデバッグレベル。

ただし、こちらも「エージェント設定リポジトリの場所」が「集中化」に選択されている場合に限ります。「ローカル」に設定されている場合は、ポリシーエージェントのインストールディレクトリ配下にある[J2EEエージェントのインストールディレクトリ]/agent_[N]/config/OpenSSOAgentConfiguration.propertiesというファイルでこれらの設定を変更可能です。