え、staticイニシャライザーが呼ばれない?…ん、2回呼ばれる?

Qiitaにこんな記事を書いたのですが、実はこのとき調査を混乱させるもう一つの謎の事象がありました。

 Qiita – ログレベルが突然変わる謎の事象を追う ~ あるOSSサポートエンジニアの1日

記事が少し長くなることと話の軸がぶれることを考慮して、その事象についてばっさりカットしたのですが、今後同じような問題に遭遇する人がいるかもしれないので、私のブログで紹介します。


記事の簡単なおさらい

Qiitaの記事の問題となったのは以下のコードでした。

final static String RESTLET_LOGGER_NAME = "org.restlet.Component.LogService";

static {
    Logger logger = Logger.getLogger(RESTLET_LOGGER_NAME);
    logger.setLevel(Level.OFF);
}

このコードはロガーのログ出力を抑止する意図でWebアプリケーションに追加されたコードで、そのWebアプリケーションでは必ず実行されるはずなんですが、それにもかかわらず、ロガーがログを出力したという問題です。

原因は、弱参照しかないロガー(ログレベル=OFF)をGCが回収して、新たにロガーが生成されたことでした。

gc_wrlggr

で、この調査の際に、原因を探るために、以下のような修正を行って動作検証をしました。

final static String RESTLET_LOGGER_NAME = "org.restlet.Component.LogService";

static {
    System.out.println("ServiceEndpointApplication#clinit start");
    Logger logger = Logger.getLogger(RESTLET_LOGGER_NAME);
    logger.setLevel(Level.OFF);
    System.out.println("ServiceEndpointApplication#clinit end");
}

そして、tail -fコマンドでTomcatのログ(catalina.out)を監視しながら、JMeterで大量のリクエストを送信したわけです。

もう一つの謎

実はそのとき、tail -fコマンドの結果に以下のような出力があったのです(Qiitaの記事には書きませんでしたが)。

ServiceEndpointApplication#clinit start
ServiceEndpointApplication#clinit end
ServiceEndpointApplication#clinit end

endが2回出力されています。もちろん、System.out.println("ServiceEndpointApplication#clinit end");が他のソースコードにもあったということではありません。staticイニシャライザーにSystem.out.println();を追加した後でこの奇妙な出力が得られました。もし、次のようにstartが2回出力されたのであれば、そこまで驚きはしませんでした。

ServiceEndpointApplication#clinit start
ServiceEndpointApplication#clinit start
ServiceEndpointApplication#clinit end

startが2回出力されたのであれば、異なるクラスローダーがこのクラスをロードして、一方でエラー(ExceptionInInitializerError)が発生し、それをcatchして無視した可能性も考えられます(まあ、それも考えにくいですが…)。しかし、endが2回出力されたのであれば、そういうレベルの問題ではありません。

このとき、みなさんはどういった可能性を疑いますか?

私がそのとき考えたのはJVMのバグでした。それしか無いように思えました。


あっけなく分かった原因

その後、JVMのバグを探してみたり、同件の事例が無いかググってみましたが、それらしいものは見つからず。ふと、catalina.outviで見たときに気がつきました。実は、ServiceEndpointApplication#clinit endは1回しか出力されていないということに。つまり、JMeterで瞬間的に大量のリクエストを送信した結果、tail -fコマンドが1回余計にServiceEndpointApplication#clinit endを出力したということのようでした。

では、なぜtail -fコマンドが1回余計に出力したのかというと…

実はそれは分かっていません(今回はそれ以上原因追求する必要はなかったので…すいません)。このあたりに詳しい方はぜひ教えて下さい。

追記

シェルの達人さとうさんから以下のようなコメントをいただきました。ありがとうございました~

広告

スタンフォード大学の機械学習コースを修了しました!

たまには技術的ではないことも。

3ヶ月ほど前から始めた「Coursera(コーセラ)」というサイトのスタンフォード大学の機械学習コースを修了しました!

Screenshot_2018-08-28 W9LXN6DRD2UZ(1)

ちょっと覗いてみたら楽しそうだったので、そのまま最後までやりきりました。

AIについては、以前から興味はすごくあったのですが、今の仕事とは直結しないので、なかなか手を出せずにいました。それが、ふとしたきっかけで始めてみると、これがなかなか面白くて…学生時代は極端な理系人間だったので、数学が絡む分野は楽しいし、理解しやすいですね。

ここ数年は認証系の仕事がメインで、認証プロトコルのRFCを読みこむような、決して楽しいとは言えない(忍耐力が求められる)作業(苦行)が多かったので、久しぶりに楽しく学ぶことができました。これまでにやってきた仕事とは今のところあまり関係はないのですが、今はこの分野についてさらに勉強してみたいという気持ちです。認証の分野へのAIの活用事例(顔認証とか異常検知による再認証とか)もすでにたくさんあますし、新しい可能性もいろいろと考えられそうです。

ちなみにこのコースですが、修了した他の皆さんも言ってる通り、とてもよくできています。高校レベルの数学がちゃんと理解できている人であれば、問題なくついていける内容だと思います(おそらく)。一応3ヶ月で終わるようなスケジュールが推奨されています。ただ、コース内のところどころで、解説の際に証明が省略されているので、過程が気になってしまう人はそれを調べる時間も必要です。

それから、意外と英語力がいるかもしれません。大半は日本語字幕が出ますが、全然あってないこともありますし、徐々に字幕と内容がずれたりとか、いろいろな罠があります(一切話をしていないことについて言及したり)。なので、ネイティブのスピードで英語が聞ける人は短時間で終了できると思いますが、そうでない人はそれなりに苦労するかもしれません。

意外と知られていない、Tomcatのエラーページのバージョン番号の簡単な隠し方

Tomcatのデフォルトのエラーページのバージョン番号の隠したいという要望は結構あります。これについて調べてみると、「jarファイルを解凍して、その中のプロパティファイルを変更して、…」という情報が多いようですが、もっと簡単な方法があります。日本語の情報がほぼ無かったので、いくつかの補足情報とともにここに書いておきます。

設定の仕方

結論から言うと、conf/server.xmlに以下のValveの定義を追加して、Tomcatを再起動するだけです。

<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false"/> 

設定前後の画面の比較

この設定により、以下のようにデフォルトエラーページの表示が変わります。

設定前

1

設定後

2

NPEが発生したことをここに載せる必要があるのか判断は微妙なところですが…Tomcatの仕様上はこうなります。

注意事項(制限事項)

この設定を利用するに当たって、いくつのか注意事項があります。

  • この設定が機能するのは、バージョン7.0.54以降(8.0以降のメジャーバージョン含む)。
  • この設定は、Managerアプリケーションなどで表示されるバージョン情報は変更しない(以下のように)。

3

バージョン7.0.53以前や、Managerアプリケーションなど(具体的には、他にversion.shversion.bat、起動時のログのServer version)でもバージョン情報を隠したい場合は、後述する方法で対応します。

ErrorReportValveの属性について

ErrorReportValveに設定可能な属性は次の2つです。デフォルト(未設定時)はともにtrueです。

  • showReport:falseに変更すると、デフォルトのエラーページにスタックトレースを表示しないようになる
  • showServerInfo:falseに変更すると、デフォルトのエラーページにTomcatのバージョン番号を表示しないようになる

つまり、showReport="false"だけの場合は以下のようになります。

4

showServerInfo="false"だけの場合は以下のようになります。

5

この画面を見ると分かりますが、「注意 原因のすべてのスタックトレースは、のログに記録されています」というように「の」の前が空文字になってしまっています。これはTomcatのバグと言えますね(超軽微ですが)。

そもそもなぜバージョンを隠す必要があるの?

という疑問を持つ人はきっとこのページを見ないと思いますが…バージョンを隠す理由は、セキュリティの対策のためです。一般的に稼動するサーバーの情報は表示しない方が安全です。バージョンを元に、そのバージョンで対策されていない脆弱性を攻撃することもできるので。TomcatのSecurity Considerationsなどでも推奨設定となっています。

7.0.53以前や、Managerアプリでもバージョンを隠したい場合

前述したとおり、ErrorReportValveの設定は、バージョン7.0.53以前や、Managerアプリケーションなどでは機能しません。このような場合では、conf/lib/catalina.jarの中にあるServerInfo.propertiesの次の定義を

server.info=Apache Tomcat/7.0.59

例えば、以下のように変更します。

server.info=Apache Tomcat

これをやるには、jar xf catalina.jarで解凍して…という方法もありますが、Windowsを使っているのであれば、Explzhを使って解凍せずにそのまま編集した方が簡単です。Explzhをインストールしていれば、jarファイルを右クリックして、「Explzh から開く」を選択します。後はファイルブラウザと同様にファイルを選択・修正して、Explzhのウインドウをクリックすれば画面のように反映されます。

6

このプロパティ値を削除するとどうなる?

ちなみに「server.info=」とした場合は空文字「””」がセットされたことになり、以下のように出力が変化します。

7

8

エラー画面は、showServerInfo=”false”だけの場合と同じですね。

このプロパティ自体を削除するとどうなる?

9

見てのとおり、「Apache Tomcat 7.0.x-dev」となります。

server.numberって変更する必要はある?

conf/lib/catalina.jarServerInfo.propertiesを編集しようとすると気がつきますが、「server.info」の下に「server.number」というプロパティもあります。

server.info=Apache Tomcat/7.0.59
server.number=7.0.59.0

これは何かと思って調べてみたのですが、Tomcatの公式ドキュメントには全く言及がありませんでした。ということ、ソースコードを調べてみましたが、これが関係するのは以下の2箇所のようでした。

  • version.batまたはversion.shが出力するServer numberの情報
>version.bat
Using CATALINA_BASE:   "D:\program\Tomcat\apache-tomcat-7.0.59"
Using CATALINA_HOME:   "D:\program\Tomcat\apache-tomcat-7.0.59"
Using CATALINA_TMPDIR: "D:\program\Tomcat\apache-tomcat-7.0.59\temp"
Using JRE_HOME:        "C:\Program Files\Java\jdk1.8.0_172"
Using CLASSPATH:       "D:\program\Tomcat\apache-tomcat-7.0.59\bin\bootstrap.jar;D:\program\Tomcat\apache-tomcat-7.0.59\bin\tomcat-juli.jar"
Server version: Apache Tomcat/7.0.59
Server built:   Jan 28 2015 15:51:10 UTC
Server number:  7.0.59.0
OS Name:        Windows 7
OS Version:     6.1
Architecture:   amd64
JVM Version:    1.8.0_172-ea-b03
JVM Vendor:     Oracle Corporation
  • 起動時のログに表示される以下の情報のServer numberの情報
8 14, 2018 2:51:23 午後 org.apache.catalina.startup.VersionLoggerListener log
情報: Server version:        Apache Tomcat/7.0.59
8 14, 2018 2:51:23 午後 org.apache.catalina.startup.VersionLoggerListener log
情報: Server built:          Jan 28 2015 15:51:10 UTC
8 14, 2018 2:51:23 午後 org.apache.catalina.startup.VersionLoggerListener log
情報: Server number:         7.0.59.0
8 14, 2018 2:51:23 午後 org.apache.catalina.startup.VersionLoggerListener log
情報: OS Name:               Windows 7
8 14, 2018 2:51:23 午後 org.apache.catalina.startup.VersionLoggerListener log
情報: OS Version:            6.1

jarファイルを解凍せずに変更できない?

「jarファイルを変更すると、アップグレード時にリグレッションしてしまうしなぁ」という場合は、lib/org/apache/catalina/utilディレクトリの下に以下の3行を記述したServerInfo.propertiesを配置しておいても同様に機能します。

server.info=Apache Tomcat
server.number=7.0.59.0
server.built=Jan 28 2015 15:51:10 UTC

参考

Pythonアプリでのメールヘッダーインジェクション対策について

Pythonでメール送信機能を実装する場合、標準ライブラリであるsmtplibを利用することが最も一般的な方法のようです。以下のような関数をつくって、それを呼び出せばメールが送信できます。

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def sendEmail(mail_to, mail_from, subject, content):
    msg = MIMEMultipart('alternative')
    msg['To'] = mail_to
    msg['From'] = mail_from
    msg['Subject'] = subject
    msg.attach(MIMEText(content))

    smtp_server = smtplib.SMTP('smtp.gmail.com', port=587)
    smtp_server.starttls()
    smtp_server.login('xxxxxxxx@gmail.com', 'xxxxxxxx')
    smtp_server.sendmail(mail_from, mail_to, msg.as_string())

簡単ですが、これで問題はないのでしょうか。メールヘッダーインジェクションの脆弱性に配慮する必要はないのでしょうか?


ということで、調べてみました。まずは、正常なメール送信の動作確認のために、以下の実装のスクリプトをつくって(sendmail.pyというファイル名にしました)、メールを送信してみましょう。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def sendEmail(mail_to, mail_from, subject, content):
    msg = MIMEMultipart('alternative')
    msg['To'] = mail_to
    msg['From'] = mail_from
    msg['Subject'] = subject
    msg.attach(MIMEText(content))
    smtp_server = smtplib.SMTP('localhost', port=2525)
    smtp_server.sendmail(mail_from, mail_to, msg.as_string())

print("Sending an Email.")
try:
    sendEmail('to@example.com', 'from@example.com', 'Test', 'Mail Header Injection Test')
    print("Complete.")
except Exception as e: 
    print("ERROR:" + str(e))

と、その前に、メール送信のために、SMTPサーバーが必要です。今回は単なる検証目的なので、FakeSMTPというテスト用途のSMTPサーバーを使用します。Javaで実装されているので、WindowsでもLinuxでも同様に簡単に起動します。ここからダウンロードして、以下のコマンドで実行します。

$ java -jar fakeSMTP-2.0.jar -s -p 2525

この場合、2525番のポートでSMTPサーバーを起動します。

起動したら、先程作成したsendmail.pyを実行してメールを送信します。

$ python sendmail.py

問題がなければ、「Sending an Email.」、「Complete.」と表示されて、以下のようにFakeSMTPサーバーにメールが送信されているはずです。

Screenshot from 2018-05-09 14-53-26

メールをクリックすると、内容が確認できます。見てのとおり、特に問題はありません。

            Wed, 09 May 2018 14:51:50 +0900 (JST)
Content-Type: multipart/alternative;
 boundary="===============7314347251575062497=="
MIME-Version: 1.0
To: to@example.com
From: from@example.com
Subject: Test

--===============7314347251575062497==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

Mail Header Injection Test
--===============7314347251575062497==--

では、メールヘッダーインジェクションの脆弱性を攻撃できるか検証してみましょう。

sendmail.pyの次の行を、

sendEmail('to@example.com', 'from@example.com', 'Test', 'Mail Header Injection Test')

次のように変更します。

sendEmail('to@example.com', 'from@example.com', 'Test\nbcc: all@example.com', 'Mail Header Injection Test')

件名「Test」の後に、「\nbcc: all@example.com」を追加することで、改行を入れてメールヘッダーとしてbccを追加できるか確認してみます。これができれば、メールヘッダーインジェクションの脆弱性を攻撃される可能性があることになります(メールヘッダーインジェクションがどういうものかについては、いろいろなサイトで解説されているので、このページでは言及しません)。ちなみに、all@example.comはメールが受信可能な適当なメールアドレスと考えて下さい。

では、再度sendmail.pyを実行してメールを送信します。

$ python sendmail.py

新しいバージョンのPythonを使用している場合は、以下のように表示されるはずです(このブログではPython 3.6を使用しています)。

$ python sendmail.py
Sending an Email.
ERROR:header value appears to contain an embedded header: 'Test\nbcc: all@example.com'

メールヘッダー値に別のメールヘッダーを埋め込もうとしたことを検知した旨のエラーメッセージが出力されます。つまり、Python 3.6標準のsmtplibに対しては、メールヘッダインジェクションは攻撃できないということになります。

この検知機能は、いつから実装されているのでしょうか?

GitHubのPythonのリポジトリで、先程のエラーメッセージ「header value appears to contain an embedded header」を検索してみると、このコミットが見つかりました。どうやら、Python 3.1.4から実装されているようです。なので、3.1.3以前のバージョンを使っていなければ、問題は無さそうです(Python 2.x系も最新の2.7には実装(バックポート)されていました)。

ただし、調査していたときに気になるバグレポートを見つけました。

Issue#32606: Email Header Injection Protection Bypass

これによると、「bcc」と「:」の間に空白があるような値を使うことで、メールヘッダーインジェクションの脆弱性を攻撃できるとのことです。つまり、以下のうち前者は検知機能でエラーになるが、後者はスルーしてしまう、ということです。

・’Test\nbcc: all@example.com’ → エラー
・’Test\nbcc :all@example.com’ → スルー

では、さっそく検証してみましょう。sendmail.py'Test\nbcc: all@example.com'の箇所を'Test\nbcc :all@example.com'に修正して、実行します。

$ python2 sendmail.py
Sending an Email.
Complete.

送信できたようです。FakeSMTPが受信したメールをクリックすると、以下のように「bcc :all@example.com」はチェックされること無く、メールヘッダーに付加されてしまいました。

        Wed, 09 May 2018 16:35:27 +0900 (JST)
Content-Type: multipart/alternative;
 boundary="===============6879493970155011648=="
MIME-Version: 1.0
To: to@example.com
From: from@example.com
Subject: Test
bcc :all@example.com

--===============6879493970155011648==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

Mail Header Injection Test
--===============6879493970155011648==--

ただし、先程のバグレポートのコメントにもあるように、RFC 5322ではメールヘッダーのキーの直後には「:」を付けるのが正しい仕様のようです。したがって、「bcc :all@example.com」付きのメールが送信されるかどうかは、SMTPサーバーがRFC 5322を正しく実装しているか次第ということになります。

ということで、SMTPサーバーが「bcc :all@example.com」を「bcc: all@example.com」と変わらず解釈してメールが送信できるかどうかを確認してみましょう。

例えば、GoogleのSMTPサーバーの場合はどうでしょうか?次のようにsendmail.pyを修正し、実行します。

smtp_server = smtplib.SMTP('smtp.gmail.com', port=587)
smtp_server.starttls()
smtp_server.login('xxxxxxxx@gmail.com', 'xxxxxxxx')

bcc宛にはメールが送信されませんでした。Googleはメールヘッダーの「bcc :all@example.com」を無視したことになります。

次に、MSNのSMTPサーバーを検証してみましょう。次のようにsendmail.pyを修正し、実行します。

smtp_server = smtplib.SMTP('smtp-mail.outlook.com', port=587)
smtp_server.starttls()
smtp_server.login('xxxxxxxx@hotmail.com', 'xxxxxxxx')

bcc宛にメールが送信されました。MSNはメールヘッダーの「bcc :all@example.com」をもとにall@example.comにメールを送信したことになります。

このように、RFCを正確に実装していないSMTPサーバーを利用しているPythonプログラムには、メールヘッダーインジェクションの脆弱性が存在するということが言えます。


ところで、何でこんなことを調べたかというと、以前公開したバグだらけのWebアプリケーションのDjango2ベースのクローンをつくっているからです。まだ開発途中ですが、メールヘッダーインジェクションも実装したので、興味がある方はぜひ、チェックしてみて下さい。

EasyBuggy clone built on Django

Keycloakの内部DBにアクセスするには

Keycloakの内部DBにアクセスするにはどうすればいいでしょうか?簡単なので、その方法を紹介します(※今回はKeycloakの超小ネタです)。

その前に、Keycloakの内部DBについて簡単に説明します。Keycloakには、デフォルトでH2というRDBMSが組み込まれています。Keycloakを起動すると、このDBの中にKeycloakの管理コンソールで編集可能な設定データやユーザーデータが登録されます。ユーザーデータは外部のLDAPやActive Directoryで管理することもできますが、デフォルトはここで管理されます。

内部DBへのアクセス手順

任意のSQLクライアントでアクセスできると思いますが、H2には管理コンソールが付属しているので、これを使うのが簡単です。以下のコマンドを実行すると、ブラウザ上で操作可能なH2の管理コンソールが起動します。

$ cd keycloak/modules/system/layers/base/com/h2database/h2/main/
$ java -cp h2-1.4.193.jar org.h2.tools.Console

※h2-1.4.193.jarのバージョン部分は環境に応じて、変更して下さい。

このような画面が表示されるので、

2018-03-01 20.35.51 からのスクリーンショット

以下の値を入力して、「接続」ボタンをクリックして下さい。

入力項目
保存済設定 Generic H2 (Embedded)
設定名 Generic H2 (Embedded)
ドライバクラス org.h2.Driver
JDBC URL jdbc:h2:/opt/keycloak/standalone/data/keycloak;AUTO_SERVER=TRUE
ユーザ名 sa
パスワード sa

※「JDBC URL」は、環境やKeycloak(を起動するWildFly)の起動モードにより異なります。

接続してみると、テーブルがたくさんあることが分かります。テーブル名を見て分かるように、Keycloakの管理コンソールで設定した値はこれらのテーブルで管理されることになります。

2018-02-28 22.06.10 からのスクリーンショット

ちなみにスタンドアローン・モードの場合、KeycloakのDBアクセスの定義は、standalone/configuration/standalone.xmlにあります。

なお、デフォルトではlocalhost以外からこの画面にアクセスできないようになっています。これを許可するには、-webAllowOthersオプションを追加します。

$ cd keycloak/modules/system/layers/base/com/h2database/h2/main/
$ java -cp h2-1.4.193.jar org.h2.tools.Console -webAllowOthers

OpenAMはもはや「Open」ではないのか?

このブログでは、OpenAMについての記事を多く書いてきたのですが、ここ数ヶ月OpenAMの話題については触れていませんでした… というのも、OpenAMを開発しているForgeRock社が、昨年の春頃からOpenAMの公開を大幅に制限したことで、私のOpenAMに対するモチベーションが少し下がってしまったからです。

そのような状況のため、OpenAMはもはや「Open」ではないの?」と思われている方もいるかもしれませんが、そういうわけではありません。OpenAMはOSSです。このページからダウンロードして、利用することができます。CDDL 1.0ライセンスで、StashGItHubにソースコードも公開されています。

ただし、現在、ForgeRock社のサブスクリプションを購入せずに、ダウンロードサイトからダウンロードできるバージョンは、安定バージョンではないメジャーバジョンのみです(OpenAM 11.0.0/12.0.0/13.0.0、Web Agents 3.3.0/4.0.0/4.1.0、Java EE agents 3.1.0/3.3.0/3.5.0など)。また、これらのソースコードはStashに公開されていますが、一部の古いバージョンは公開されていません。安定バージョンはGitHubに公開されている11.0.3が最新です。

OpenAMの過去のメジャーバージョンのリリースは以下の通りでしたが、既に公開されていた13.5.0のソースコードも非公開となりました。

  • OpenAM 11.0.0 – 2013年11月
  • OpenAM 12.0.0 2014年12月
  • OpenAM 13.0.0 – 2016年1月
  • OpenAM 13.5.0 – 2016年7月

OpenAM 12.0.4のような安定バージョンや、新しいOpenAM 13.5.0を使用したい場合は、ForgeRock社のサブスクリプションを購入する必要があります(※私の理解が正しければ、サブスクリプションがなくても、以前ダウンロードした13.5.0のソースコードをビルドしていれば、それを利用することはできます、ただし、現在はMavenのリポジトリからOpenAM関連のライブラリが取得できないようになってしまっています…)。

OpenAM 14.0.0として開発されていたものは、「Access Management 5.0.0」という名称に変更され、2017年3月に非OSSとしてリリースされました。OpenではないAMということです。OpenAMの他にOpenDJなども同様で、以下のように「Open」が無くなり、バージョンは全て5.0.0に統一されています。

  • OpenAM 14.0.0 -> Access Manager 5.0.0
  • OpenDJ 4.0.0 -> Directory Services 5.0.0
  • OpenIDM 5.0.0 -> Identity Management 5.0.0
  • OpenIG 5.0.0 -> Identity Gateway 5.0.0

そして、このリリースは、ForgeRock社がビジネスモデルを変更したことも意味していました。もともとForgeRock社は、100%オープンソースを謳っていたんですが、100%オープンにすることのメリットよりもデメリットの方が大きいと判断したのではないかと想像しています。OpenAM(ForgeRock)が生き残るために必要な選択で、仕方なかったのかもしれません(実際のところは、私には分かりませんが)。

ForgeRock社のフォーラムに以下のようなコメントもありました。

Some ForgeRock sales reps gave me the heads up about this change, and they suggested it might have been due to integrators in Europe that create their own OpenAM releases based off the trunk which they sell themselves. I suppose this is similar to a RHEL/CentOS situation and that ForgeRock is trying to protect their investment as they are a 99% contributor of the source code, which is not the same for RHEL/CentOS.

莫大な費用をかけて、ForgeRock社がエンハンスするOpenAMを使って、何もコントリビュートしない外部の企業が利益を上げるという状況だったので、ForgeRock社とコミュニティはあまり良い関係性とは言えなかったと思います。2016年あたりから、ForgeRock社は徐々に非公開の範囲を増やしていきました。最初はマイナーバージョンのソースコードを非公開にし、ナイトリービルドのソースコードなども非公開にしていきました。そして、2017年の春には、外部のOpenAMユーザーがJIRAにバグを登録することすらできなくしました。

その当時の、OpenAMのユーザーの方とForgeRockのエンジニアであるPeterさんとの間で、以下のようなTwitterのやりとりがありました。

また、Stack Overflowでの「Is OpenAM free software?」という問いに対して、彼はこのような回答をしています。

これらの内容を要約すると、2017年4月3日以降は次のようなForgeRock版コミュニティ版に別れたことなります。

  • ForgeRock版
    • 前述の「Open」が付かない製品(Access Managerなど)
    • ソースコードは、オープンソースライセンスのもとでは提供されない
    • 使用するには、ForgeRock社のサブスクリプションを購入する必要がある
    • ForgeRockだけに属していないすべてのソースコード(例えば、Sunに属していたソースコード、またはオープンソースのコントリビューターが関わったソースコード)は、CDDLライセンスで継続して利用可能
    • 60日間のみ評価することができ
  • コミュニティ版
    • 「Open」が付く製品(OpenAMなど)
    • CDDL 1.0ライセンスのOSS
    • ソースコードはforgerock.github.ioに公開される
    • EOLとなったバージョンの最新メンテナンスリリースがForgeRock版の後にリリースされる予定
      • 今回は、AM5 -> OpenAM 11.0.3がリリースされた
      • 今後は、AM6 -> OpenAM 12.0.x、AM7 -> OpenAM 13.5.x、AM8 -> OpenAM 14.5とリリースされる予定(つまり、AMの最新バージョンがリリースされて約2年後にEOLとなってから、OpenAMとしてコミュニティ版がリリースされる)
    • 予定ではあるが、今後本当にそうなるかどうかは公言されているわけではない
    • メンテナンスリリースであるため、最初は安定しているが、その後のセキュリティパッチは提供されない

今後のOpenAMとのつきあい方

このブログを書いている際に次期バージョンがどうなるのか気になったので、Peterさんに聞いてみました。それによると、今年(2018年)の春に予定されている6.0.0リリースと同時に12.0.4もGitHubに公開される見込みだそうです(確約はできないようですが)。コミュニティ版のOpenAMが今後どのように公開されるのか不透明(というかForgeRock社次第)なので、未来のことについては明言は難しいですが、現状のOpenAMで事足りる場合は、継続してコミュニティ版を使ってもいいと考えます(脆弱性をどう対処するかによりますが)。何か困ったことがあれば、国内のOpenAMサポートをしている企業にサポートを依頼することもできます。私もサポートします。

Access Manager 5.0以降の新しい機能を使用したい場合や、脆弱性を早期に対策していきたいということであれば、ForgeRock社のサブスクリプションを購入する方がいいでしょう。ただし、結構高いです…

OpenAMのフォーク・プロジェクト

OpenAMがクローズな方向に進む中で、OpenAMをフォークしてOSSとして継続しようとする人たちも現れました。そして、このようなプロジェクトが立ち上がりました。そして、OpenAMは改名されて、GitHubに「WrenAM」という名前のOSSとして公開されました。

ただし、今のところ、このプロジェクトが軌道に乗っているようには見えません。状況をあまり把握できていないので、多くを語ることはできませんが、現時点では「うーん…」という印象です。

※注意:ライセンスなどに関して誤った理解があるかもしれません。正しい情報はForgeRock社にお問い合わせ下さい。

Cocha Iconsのトリセツ

先日、記事や設計書、プレゼン資料の作成に役立つネットワークアイコン集を公開しました。このアイコンは自由に使っていただいて構いませんが、悪用やセンスのひどすぎる使用は避けていただくようお願いします。以下に正しい使い方と誤った使い方の例を挙げておきます。

正しい使い方


グリッドを利用する

use

背景のグリッドを活用して適当な場所にアイコンを配置し、矢印はグリッドの方向に平行にしてください。

光の当たる方向を意識する

PowerPointの「左右反転」でアイコンの向きを変えることができます。

WS000024.JPG

ただし、光の当たる方向を意識して色を変更しないと統一感が崩れます。

gg.png

適当な大きさに拡大・縮小する

アイコンのサイズは適宜変更して下さい。

ss.png

動きをつける

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f34333836392f66666462306263322d376337642d366561322d356366392d3165383464616637303639372e676966

動きをつけてみるのもいいと思います。動くバージョンのアイコンもいつか公開したいです。

誤った使い方


以下のような使い方はしないで下さい。

質感の異なるアイコンとの併用

ff.png

これはやめて欲しいです。

作者の意図に反する使い方

dontsitfw

できるだけ作者(私)の意図を汲んで下さい。

理解しがたい動きをつける

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f34333836392f35616235383236652d353033382d646131642d393762362d3961336539383230303133622e676966

PowerPointってついつい遊んでしまいますよね…

遠近法の無視、悪用

big

部分的に巨大化しないで下さい。

最後に


使用する場合はGitHubにスターを付けて、以下の画像を作成物のどこかに付け加えていただくようお願いします。

mark.png

Qiitaの記事で使うのであれば、以下を本文の最後に埋め込んで下さい。

[![mark.png](https://github.com/k-tamura/cocha-icons/raw/master/mark.png)](https://github.com/k-tamura/cocha-icons)

HTMLの場合はこちら:

<a href="https://github.com/k-tamura/cocha-icons">
    <img src="https://github.com/k-tamura/cocha-icons/raw/master/mark.png" alt="mark.png" style="max-width:100%;">
</a>