Fessのログイン成功後もIP単位の試行制限を維持する

Fessのログイン試行制限で、正常なログインが同じIPアドレスの失敗履歴まで消してしまう動作を修正しました。複数のアカウントに対する失敗を、1つの有効なアカウントへのログインで繰り返しリセットできていた問題への対応です。

対象となるログイン

対象はPOST /api/v2/auth/loginと、SPNEGOプラグインのBasicフォールバックです。成功時には「IPとユーザー名」の履歴をクリアしますが、IP全体ではその成功したリクエスト1件分だけを戻します。同じIPから別ユーザー名で行った失敗は残ります。すでに有効なロックアウトを解除・短縮する変更ではありません。

設定の初期値

修正を確認した本体開発版のfess_config.propertiesでは、次の設定です。

設定初期値
theme.api.login.rate.limit.per.ip.per.minute10
theme.api.login.rate.limit.per.user.per.minute5
theme.api.login.lockout.seconds900
theme.api.login.rate.limit.max.entries100000

IP単位の制限は0以下で無効、ロックアウト時間も0以下で無効です。「ユーザー単位」はIPとユーザー名の組み合わせであり、全IPにまたがるユーザー全体の集計ではありません。検索リクエスト全般のrate.limit.*とは別の設定です。

更新時に確認すること

SPNEGO側の変更は本体のLoginRateLimiter#releaseに依存します。本体に修正がない状態でプラグインだけを取り込む組み合わせは使えません。

NATやリバースプロキシ配下では複数ユーザーの試行が同じIPとして数えられることがあります。成功したログインでも他ユーザーの失敗履歴が残るため、利用人数とクライアントIPの認識を確認し、閾値を調整してください。制限はメモリ内の処理であり、複数Fessインスタンス間で共有する仕組みを追加する変更ではありません。

関連PR

Fessの辞書APIで同義語を改行区切りで登録する

Fessの管理APIで同義語を登録するとき、"inputs": "検索,サーチ"のようにカンマで語を並べると登録できません。1語ずつ改行で区切ったJSON文字列を送ります。15.9向けの文書訂正と、形式違反をHTTP 500ではなく400として返す修正を紹介します。

管理APIと辞書を使える環境を用意する

管理APIのapi.admin.access.permissionsの初期値はRadmin-apiです。標準設定では管理画面のアクセストークンに{role}admin-apiを設定し、Authorizationヘッダーで送ります。この権限は管理API全体へアクセスするもので、同義語だけに限定されません。

辞書APIは検索エンジンのCodeLibsプラグインを必要とします。プラグインなしのvanilla構成向けではありません。DICT_IDは自分の環境の同義語辞書IDへ、YOUR_TOKENは発行したトークンへ置き換えます。辞書IDや項目IDに共通の初期値はありません。

JSON内では改行を\nで表す

次の例はローカル環境へ同義語の項目を登録するリクエストです。

curl -X POST 'http://localhost:8080/api/admin/dict/synonym/setting/DICT_ID' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"inputs":"検索\nサーチ","outputs":"検索\nサーチ\nリサーチ"}'

JSON文字列の\nは、サーバーで文字列として読み取られた後に改行になります。JSONのバックスラッシュを二重にエスケープして文字通りの「\n」を送るのではなく、利用するHTTPクライアントで改行入りの文字列をJSONへ変換してください。

inputsとoutputsの各語にはカンマや=>を含められません。辞書ファイルで語やルールを区切る記号として使われるためです。mapping辞書のinputsも1語1行で指定し、カンマや=>を含む入力は拒否されます。辞書の種類ごとにフィールド構造が異なるので、同義語の例をほかの辞書へそのまま送らないでください。

入力違反を再試行で解決しない

修正を含む版では、同義語またはmappingの対象形式違反はHTTP 400、response.status=1と、問題の語を示すメッセージになります。修正前は同じ入力がHTTP 500、status=2になる場合がありました。POSTとPUTが対象です。

400になったら入力を直して送信します。同じカンマ区切りのデータを繰り返し送る方法では登録できません。正常時のstatus=0を確認したうえで、取得APIや管理画面で改行ごとの語が保存されたかを確認します。辞書の保存成功と、検索に解析設定が反映されたことは分けて確認してください。

関連PR

Fessのdeb更新で設定ファイルを保護する変更と移行時の注意点

Fessのdebパッケージで、/etc/fess内の設定ファイルをdpkgのconffilesとして扱う変更がマージされました。ローカルで編集した設定を、更新や再インストールで上書きされにくくする改善です。追加修正では、15.8からの初回移行で未編集の設定を新版へ置き換えます。編集済み設定の選択と無人更新の方針は、引き続き確認が必要です。

保護対象と更新時の動作

対象はfess_config.properties、logging.properties、tomcat_config.properties、tika.xmlと、chunk・crawler・suggest・thumbnail・web用の5つのfess_env_*.propertiesです。

従来はこれらが通常のパッケージファイルとして扱われ、編集した内容が確認なしで上書きされる場合がありました。修正後はconffilesとなり、ローカルとパッケージの双方で変更があればdpkgが選択を求めます。採用しなかった内容は状況に応じて.dpkg-oldや.dpkg-distに残ります。

初回移行と無人更新

追加修正#3627を含むパッケージでは、15.9より前からの更新時に、旧パッケージの記録したMD5と一致する未編集の/etc/fessファイルを新版へ置き換えます。この場合は確認を求めません。編集済みファイルは保持し、dpkgの通常の設定選択に従います。--force-confoldなら編集を残して新版を.dpkg-distへ、Yまたは--force-confnewなら新版を採用して旧編集を.dpkg-oldへ保存します。

#3608だけを含み#3627を含まないビルドでは、未編集のファイルにも確認が発生し、旧初期値を残す場合があります。対象ビルドの修正範囲を確認してください。/etc/default/fess、/etc/init.d/fess、systemdユニットは15.8時点ですでにconffilesで、今回の未編集ファイルの処理対象ではありません。

apt-get install -yだけでは、この設定選択への応答を保証できません。標準入力がない環境では更新処理が止まり、パッケージが未設定状態で残る場合があります。自動更新では既存設定を残すか新しい設定を採用するかを決め、dpkgの--force-confold・--force-confnewなどの方針を明示します。

既存設定を残す方針で、設定待ちの状態を解消する例は次のとおりです。

sudo dpkg --configure -a --force-confold

このコマンドは未設定のパッケージ全体を対象にします。実行前にパッケージ状態と設定のバックアップを確認してください。既存設定を残した場合、新しい初期値が自動で反映されるわけではありません。.dpkg-distなどを比較し、必要な差分を取り込みます。

削除との違い

修正後はdpkg -rで設定ファイルが残ります。dpkg -Pでは設定も削除されます。更新時の保護をバックアップの代わりにせず、設定の保管と差分確認を更新手順に含めてください。

関連PR