投稿者: manualmaton Page 1 of 296

セキュリティデッキを組もう:ModSecurity Request-900-Exclusionの編集意義

MtGやDMを遊んだことがあるのであれば聞いたことがあるだろう

「カードはルールに勝つ
 (カードの効果とルールが直接矛盾した場合、カードの効果を優先する)」

という大原則。

「カードを2枚引く」

というシンプルなテキストであっても、通常、プレイヤーは1ターンに1枚のみカードを引くと言うルールがありますが、カードにそう書かれていればそのルールを無視した挙動が可能になります。

一見すると乱暴な言葉ですが、実際にはゲームデザイン上もっとも重要な考え方の一つです。

基本ルールは全員共通。しかし、カードには「この場合だけは例外」が書かれています。だからこそ何万種類ものカードが共存できます。

実は、この考え方は ModSecurity にも、そのまま当てはまります。

今回、私がModSecurityに導入している「REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf」について解説します。

REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.confとは?

ModSecurityで本格的な防御を行う際、多くの人が「OWASP CRS(Core Rule Set)」という、世界中のセキュリテイ専門家が作った強力な既製ルール集を導入します。

CRSは非常に優秀ですが、何千もの緻密なルールが詰まっているため、上から順にすべてをチェックするとそれなりの処理コスト(CPUやメモリ)がかかります。

また、これは非常にデリケートでガチガチなので

  1. ファイルをアップロードした
  2. コードを書き込んだ
  3. クリックを繰り返した

だけで「こいつは怪しい動きをしている」として、アクセスそのものを遮断する「偽陽性」が発生します。

そこで、膨大なCRSの本体を書き換えることなく

  1. プログラムのコードやコマンドラインなどを投稿するのはOK
  2. だが、それを使った攻撃は許さない
  3. 複雑なスキャンは不要。「悪・即・斬」レベルで不審な攻撃をたたき落とす
  4. 逆に「こいつは面白い動きをするからハニーポットに誘導しよう」

などの「デッキを作るような感覚で」膨大なCRSを制御する方法として用意されているのが、REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf(以下、900番BEFOREルール)です。

設置例

筆者環境

  • ModSecurity 2.9.7
  • Core Rule Set 3.3.5
  • Apache 2.4
  • Ubuntu 24.04

どこに置くか?

筆者環境の場合は

/usr/share/modsecurity-crs/coreruleset/rules配下のREQUEST-900-EXCLUSION-RULES-BEFORE-CRS.confですが、

/home/hoge/script/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

など、自分がメンテナンスしやすい位置にこのファイルの実体を置いておき、ln -sfでシンボリックリンクを張る方が非常に簡単です。というのも、「このデッキ調整」はデリケートな作業なので何回も何十回も調整が必要になります。そのたびに深い階層を掘ってファイルを編集するのは効率的ではありません。

とはいえ、シンボリックファイル is Evil だったりrootアカウントしかないとかいう方はいるので流儀に合わせてください。

ケーススタディ

効果的なカスタム案

筆者が実際に使っている中で最も効果的なルールがこれです。

# IPアドレス直打ちアクセス対策 
SecRule REQUEST_HEADERS:Host "@rx ^[\d.]+(:\d+)?$" \
    "id:10004,\
    phase:1,\
    deny,\
    status:404,\
    log,\
    msg:'[CUSTOM RULE] Host header is a numeric IP address (incl port). Blocked immediately.',\
    tag:'application-attack',\
    tag:'PROTOCOL_VIOLATION/INVALID_HREQ'"

# Hostヘッダーが存在しない場合は即ブロック
SecRule &REQUEST_HEADERS:Host "@eq 0" \
    "id:10005,\
    phase:1,\
    deny,\
    status:404,\
    log,\
    msg:'[CUSTOM RULE] Missing Host Header. Blocked immediately.'"
  • id:10004:
    • 正規表現 @rx ^[\d.]+(:\d+)?$ を使い、Hostヘッダーの中身が「数字とドットだけ(または末尾にポート番号)」で構成されているかを判定します。IPアドレス直打ちであれば、その瞬間に合致(マッチ)します。
  • id:10005:
    • 変数の頭に & をつけることで、そのヘッダーの「個数」を数えます。@eq 0(=0個、つまりHostヘッダーが存在しない)場合にマッチします。
  • phase:1:
    • これが非常に重要です。リクエストの解析が始まった「最速の段階(フェーズ1)」で検査を行います。
  • deny, status:404:
    • 条件にマッチしたら、荷物の中身(Body)を見るまでもなく、即座に通信を拒否し、404エラーを返して追い払います。

カスタム案が拾ったログ

以下、実際に私のサーバにアクセスしたログです。

# 例①:Hostヘッダー自体が存在しない(欠落)
[ security2:error] ModSecurity: Access denied with code 404 (phase 1). ... [file "/usr/share/modsecurity-crs/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf"] [line "72"] [id "10005"] [msg "[CUSTOM RULE] Missing Host Header. Blocked immediately."]

# 例②:Hostヘッダーがドメインではなく「IPアドレス直打ち」
[ security2:error] ModSecurity: Access denied with code 404 (phase 1). ... [file "/usr/share/modsecurity-crs/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf"] [line "63"] [id "10004"] [msg "[CUSTOM RULE] Host header is a numeric IP address (incl port). Blocked immediately."]
sequenceDiagram Note over Crawler: 不正なリクエストを送信<br>(Host: 192.0.2.1) Crawler->>ModSecurity_WAF: HTTP GET / (Host不正) Note over ModSecurity_WAF: phase:1 で瞬時に検知!<br>背後のWebサーバーやアプリには<br>一切パスさせない ModSecurity_WAF-->>Crawler: 404 Not Found (即座に遮断)

という形で、ModSecurityの背後にあるコンテンツに一切触れさせることなく追い払うことができます。

余談:これで追い返して問題は無いのか?

ありません。断言します。なぜなら、ローカル運用ならいざ知らず、ドメインで動くモダンインターネットにおいて

http://203.0.113.6

などと直打ちするケースはほぼありません。なので、IPアドレス直打ちはほぼ確実に「膨大なIPをしらみつぶしに探し回るボット」です。

そして、Webサイトを閲覧するとき、ブラウザとサーバーの間では「データの荷物」がやり取りされています。この荷物は、大きく分けると「ヘッダー(Header)」「ボディ(Body)」の2つで構成されています。

郵便に例えると、以下のようなイメージです。

  • ヘッダー(Header): 封筒の表面。「宛先」「差出人」「中身の形式」などが書かれた管理情報。
  • ボディ(Body): 封筒の中身。「実際のページデータ(HTML)」や「画像」そのもの。

普段目にするWebページは「ボディ」ですが、それを正しく届けて表示するためには、不備のない「ヘッダー(封筒の表面)」を付与するというのがブラウザの挙動です。

900番BEFOREルールである意味

そして、このファイルは「CRSが動く前に対処できる」という、MtGで言う「打ち消し呪文」のようなものとして機能します。

もし、これをRESPONSE-999-EXCLUSION-RULES-AFTER-CRS.confという「最終的に評価するルール」で書いた場合

sequenceDiagram Crawler->>ModSecurity_WAF: HTTP GET / (Host: 192.0.2.1) Note over ModSecurity_WAF: 1.900番BEFORE ルール(何もなし) -> 通過 Note over ModSecurity_WAF: 2. メインCRS審査(数千のルール) Note over ModSecurity_WAF: SQLインジェクションの検査...OK<br>XSSの検査...OK<br>(延々とノーマル審査が続く) Note over ModSecurity_WAF: 3. (AFTERルールに書いた場合) Note over ModSecurity_WAF: ここでようやくルール10004にヒット ModSecurity_WAF-->>Crawler: 404 Not Found (一応遮断はできたが...)

という流れになります。

もしクローラーが超高速で連射してきた場合、この「無駄なフルコンボ審査」のせいでModSecurity自体の処理が追いつかなくなり、サーバーのCPU使用率が100%に張り付いて、一般ユーザーのアクセスが重くなる(あるいは落ちる)という本末転倒な事態が起きます。

このカスタム案の意義

OWASP CRSは非常に優秀です。

SQLインジェクション、XSS、RCEなど、現代的な攻撃に対する膨大な知見が詰め込まれており、何も考えずに導入しても一定以上の防御力を得られます。

しかし、それはあくまで「世界中の誰にでも当てはまる最大公約数」です。

私のサーバーには私のサイト構成があり、私の利用者がおり、私の攻撃ログがあります。

だからこそ

  • このサイトではコードの投稿は許可する
  • このURLへの異常なクロールだけは絶対に許さない
  • この挙動は攻撃ではないので除外する
  • この通信はコンテンツを見る価値すらないので即座に落とす
  • 面白い相手ならハニーポットへ誘導する

という「自分だけのルール」が必要になります。そのための「私のデッキ」が900番BEFOREルールです。

CRS本体を直接編集する必要はありません。

世界中のセキュリティ専門家が更新し続けるルールセットはそのまま利用し、自分の環境だけに必要な判断を、カードを1枚追加するような感覚で差し込めます。

だから冒頭で紹介した

「カードはルールに勝つ」

という考え方が、そのままModSecurityにも当てはまるのです。

CRSという基本ルールがあり、その前に「このサイトではこうする」という例外を定義する。それだけで、自分だけのWAFが出来上がります。

私にとってREQUEST-900-EXCLUSION-RULES-BEFORE-CRS.confは、単なる設定ファイルではありません。

毎日流れてくるログを眺め、

  • 「これは900番で落とせるな」
  • 「このクローラーはハニーポット送りにしよう」
  • 「これはCRSに任せた方がいい」

そんな調整を繰り返しながらデッキをチューニングしていく場所です。Webサイトを運営する人にとって、攻撃ログは鬱陶しいものに見えるかもしれません。

しかし見方を変えれば、それは次の一枚を考えるための対戦ログでもあります。

オリジナルに手を加えない意義

また、この900番BEFOREルールを別ファイルとして管理する最大の理由は、「本家に手を入れない」ことです。

CRSは更新され続けます。

もしCRS本体を書き換えてしまうと、アップデートのたびに差分を確認し、競合を解消し、自分の修正を書き戻す必要があります。

一方、自分のデッキを900番BEFOREだけに閉じ込めておけば、CRSが更新されても自分のカードはそのまま使い続けられます。

新しいサーバーへ移行するときも、自分のデッキを1枚コピーするだけです。デッキは、一度組んで終わりではありません。

  • 新しい攻撃ログを見つけたら1枚差し替え、
  • 不要になったカードは抜き、
  • 新しい環境に合わせて調整していく。

世界中の専門家が作ったルールセットを土台に、自分のサイトで得た対戦ログから一枚ずつカードを選び、デッキを育てていく。それが私にとってのREQUEST-900-EXCLUSION-RULES-BEFORE-CRS.confです。

統率者デッキ:サイオンズ・スペルの入れ替え候補

先だって購入した統率者デッキ。この攻勢を維持したまま、更に楽しくなりそうなカードをストレージから…… というよりも、パーツ取りで他がある状態での他の構築済みから引っ張ってきました。

パーツ取りのために買っていたドクター・フー統率者デッキ「悪の支配者」から

Vislor Turlough / ヴィスラー・ターロー (3)(黒)
伝説のクリーチャー — ならず者(Rogue)
ブラック・ガーディアンとの取引 ― ヴィスラー・ターローが戦場に出たとき、あなたは「対戦相手1人はこれのコントロールを得る。」を選んでもよい。そうしたなら、そのプレイヤーがコントロールし続けているかぎり、これは使嗾される。
あなたの終了ステップの開始時に、カード1枚を引き、その後、あなたの手札にあるカードの枚数に等しい点数のライフを失う。
ドクターのコンパニオン(もう一方がドクター(Doctor)であるなら、あなたは統率者2体を使用できる。)
2/5

Wound Reflection / 傷の反射 (5)(黒)
エンチャント
各終了ステップの開始時に、各対戦相手はこのターンに自分が失ったライフの点数に等しい点数のライフを失う。(ダメージによりライフは失われる。)

Blink / まばたき (2)(青)(黒)
エンチャント — 英雄譚(Saga)
(この英雄譚(Saga)が出た際とあなたのドロー・ステップの後に、伝承(lore)カウンター1個を加える。IVの後に、生け贄に捧げる。)
I,III ― クリーチャー1体を対象とする。オーナーはそれを自分のライブラリーに加えて切り直す。その後、調査を行う。(そのプレイヤーは手掛かり(Clue)トークン1つを生成する。)
II,IV ― 先制攻撃と警戒と「対戦相手1人がクリーチャー呪文1つを唱えるたび、ターン終了時まで、このパーマネントはクリーチャーでない。」を持つ黒の2/2のエイリアン(Alien)・天使(Angel)アーティファクト・クリーチャー・トークン1体を生成する。

Hunted by The Family / ファミリーの擬態 (5)(青)(青)
ソーサリー
あなたがコントロールしていないクリーチャー最大4体を対象とする。それらの各クリーチャーにつきそれぞれ、そのコントローラーは「そのクリーチャーは白の1/1の人間(Human)クリーチャーになりすべての能力を失う。」か「あなたはそれのコピーであるトークン1つを生成する。」かの最悪の二択を行う。


同じくドクター・フー統率者デッキ『過去からの来襲』より

The Second Doctor / 2代目ドクター (2)(白)(青)
伝説のクリーチャー — タイム(Time) ロード(Lord) ドクター(Doctor)
すべてのプレイヤーの手札の上限はなくなる。
見上げた文明人 ― あなたの終了ステップの開始時に、各プレイヤーはそれぞれカード1枚を引いてもよい。次の自分のターンまで、それを行った各対戦相手はそれぞれ、あなたやあなたがコントロールしているパーマネントを攻撃できない。
2/4

Trial of a Time Lord / タイムロードの審判 (1)(白)(白)
エンチャント — 英雄譚(Saga)
(この英雄譚(Saga)が出た際とあなたのドロー・ステップの後に、伝承(lore)カウンター1個を加える。IVの後に、生け贄に捧げる。)
I,II,III ― 対戦相手がコントロールしていてトークンでないクリーチャー1体を対象とする。これが戦場を離れるまで、それを追放する。
IV ― あなたから始めて各プレイヤーは「無罪」または「有罪」のいずれかに投票する。「有罪」がより多くの票を得たなら、これにより追放されている各カードのオーナーはそれぞれ、そのカードを自分のライブラリーの一番下に置く。


更にドクター・フー統率者デッキ『タイミーワイミー』から

Grasp of Fate / 命運の掌握 (1)(白)(白)
エンチャント
命運の掌握が戦場に出たとき、対戦相手1人につき、そのプレイヤーがコントロールする土地でないパーマネントを最大1つまで対象とし、命運の掌握が戦場を離れるまでそれを追放する。(それらのパーマネントはオーナーのコントロール下で戦場に戻る。)

Wedding Ring / 結婚指輪 (2)(白)(白)
アーティファクト
結婚指輪が戦場に出たとき、これが唱えられていた場合、対戦相手1人を対象とする。そのプレイヤーはこれのコピーであるトークン1個を生成する。
《結婚指輪/Wedding Ring》という名前のアーティファクトをコントロールしている対戦相手のターンにそのプレイヤーがカード1枚を引くたび、あなたはカード1枚を引く。
《結婚指輪/Wedding Ring》という名前のアーティファクトをコントロールしている対戦相手のターンにそのプレイヤーがライフを得るたび、あなたはその点数に等しい点数のライフを得る。

このあたり、

  • 統率者の誘発を助け
  • 自分を守り
  • 政治的駆け引きも多い

防御札。ここまで自由度が高い統率者はそうそう見られないとして、カードの発見が楽しいです。

AIのトークン消費はなぜバラつくのか?――創作・分析・編集で「脳の使い方」が違うように見える話

AIを日常的に使っていると、ふとこんなことに気付きます。

  • 「この依頼は意外と利用量が増えないな」
  • 「逆に、この程度の文章なのに思った以上に消費する」

私自身、普段はGeminiを使って画像生成プロンプトの修正や競馬予想の分析、ブログの推敲、物語の執筆など、さまざまな用途でAIを利用しています。

その中で感じたのは、「依頼する内容によって利用量の増え方がかなり違う」ということでした。

もちろん、AI各社は利用量の計算方法を公開しているわけではありません。表示される消費量が単純なトークン数なのか、推論時間なのか、それらを組み合わせた独自の指標なのかは分かりません。

この記事は、あくまで私が日常的に使う中で見えてきた経験則です。

「文字数」よりも「何をさせるか」の方が重要だった

最初に不思議だと思ったのが、画像生成プロンプトです。5000文字を超える長いプロンプトを修正しても、トークンの利用量は数%程度で済むことがあります。一方で、「1000文字くらいの短い物語を書いてください」と依頼すると、それだけで10%近く増えることもありました。

文字数だけを見れば、前者の方が圧倒的に長いはずです。ところが、AIにとって重要なのは文字数ではなく、「どんな仕事を頼まれているか」なのではないか、と感じるようになりました。

ゼロから創る仕事は、とにかく重そうだ

物語を書く仕事は、AIにとってかなり負荷が高いように見えます。

  1. 登場人物を考え、
  2. 会話を自然につなぎ、
  3. 伏線を張り、
  4. 最後まで一貫性を維持する。

しかも文章は一気に完成するわけではありません。

AIは「次に来る最も自然な単語は何か」を少しずつ判断しながら、文章を積み重ねていきます。つまり、1000文字の小説を書くということは、「1000文字分の判断」を積み重ねる作業でもあります。

もちろん内部では人間のように「悩んでいる」わけではありませんが、利用量という観点では、このような創作タスクほど大きく増える傾向を私は何度も経験しました。(少なくともGeminiで可視化されている利用量を見る限り、その傾向ははっきり現れています。)

分析や編集は「答えを探す仕事」

逆に、競馬予想の分析やブログの校正、画像生成プロンプトの修正などは、それほど利用量が増えないことが多くあります。もちろん分析にも推論は必要です。

競馬であれば過去データや馬場状態、展開などを整理して結論を導かなければなりません。しかし、これは「何もないところから世界を創る」仕事ではありません。

与えられた情報を整理し、関連性を見つけ、答えを導く仕事です。画像生成プロンプトの修正も同様です。

  • 「かわいい雰囲気を少し減らして」
  • 「夕暮れを夜景に変更して」
  • 「背景をモンサンミッシェルからセントマイケルズマウントに変更して」

といった依頼では、新しい世界を創造しているのではなく、既にある設計図を編集しています。人間に例えるなら、小説を書くよりも、設計図を赤ペンで修正する仕事に近い印象があります。

文体変換は「下絵が完成している」

個人的に最も面白かったのが、文体変換です。

例えば、私がよくやっているのが

  • 「歴史的事実をニンジャスレイヤー風に書く」
  • 「ハリー・ポッターを池波正太郎風に書く」

といった依頼です。

これも一見すると創作のようですが、実際の利用量はゼロから物語を書く場合よりかなり少なく感じられました。

この理由を考えてみると、文体変換では「何が起こるか」は既に決まっています。

AIが考える必要があるのは、「どう表現するか」だけです。

これは白紙のキャンバスに絵を描く作業ではなく、完成した下絵に画風を合わせて色を塗るようなものです。物語の骨格が既に存在するため、ゼロから組み立てるよりも効率よく処理できるのではないか、と感じています。

AIにも「得意な仕事」と「重い仕事」がある

今回の観察から、私の中ではAIへの依頼は次のようなイメージになりました。

  • データ整理・分析(かなり軽い)
    • 与えられた情報を整理する仕事
  • 編集・文体変換 (軽い)
    • 内容はそのままに表現を整える仕事
  • ゼロからの創作(重い)
    • 内容そのものを組み立てる仕事

もちろん境界は曖昧ですし、実際の内部処理がこの通りだと断言することはできません。(AIの仕様そのものがブラックボックスであることは、皆様もご存じでしょう)それでも、利用量の増え方を見ていると、この順番で負荷が高くなっているように見えます。

AIを使い分けるヒント

この経験則を踏まえると、AIを効率よく使う方法も見えてきます。

  • 「物語のプロットだけは自分で考え、AIには文章を書き直してもらう」
  • 「まず箇条書きで構成を作り、そのあと文体だけ整えてもらう」

という使い方です。ゼロから創作を任せるよりも、利用量を抑えながら質の高いアウトプットを得られる場面が少なくありません。

なので「揮発性のアイデアは人間が捕まえ、形にするのはAIに任せる」やり方は相当効率的です。

おわりに

この記事は、AIの内部仕様を解説したものではありません。(そもそも筆者はAIを使うことはあっても作る技術はありません)

あくまで、一人のヘビーユーザーとして毎日のようにAIを使い続ける中で見えてきた経験則です。それでも、「文字数」ではなく「AIにどんな仕事を頼むか」で利用量が変わるように見えるという発見は、とても興味深いものでした。

AIは万能な魔法ではなく、それぞれの仕事に向き・不向きがあります。

人間が「何を考え」、AIに「何を考えてもらうか」を意識するだけでも、同じAIでも驚くほど付き合い方は変わってきます。AIの「脳の使い方」を少し意識するだけで、その能力をより引き出せるのではないでしょうか。

統率者メモ:FF「サイオンズ・スペル」

新たなデッキが到着しました。

FF統率者デッキでも人気が高い青白黒(エスパーカラー)のサイオンズ・スペル。

まずはオリジナルのリストからです。

統率者

Y'shtola, Night's Blessed / 魔女、ヤ・シュトラ・ルル (1)(白)(青)(黒)
伝説のクリーチャー — 猫(Cat) 邪術師(Warlock)
警戒
各終了ステップの開始時に、このターンにプレイヤー1人が4点以上のライフを失っていた場合、あなたはカード1枚を引く。
あなたがマナ総量が3以上でありクリーチャーでない呪文1つを唱えるたび、これは各対戦相手にそれぞれ2点のダメージを与え、あなたは2点のライフを得る。
2/4

クリーチャー (Creatures) - 22枚

  • 《時空を渡りし者、グ・ラハ・ティア/G'raha Tia, Scion Reborn(FIC)》
  • 《アリゼー・ルヴェユール/Alisaie Leveilleur(FIC)》
  • 《召喚:蛮神善王モグル・モグXII世/Summon: Good King Mog XII(FIC)》
  • 《タタル・タル/Tataru Taru(FIC)》
  • 《サンクレッド・ウォータース/Thancred Waters(FIC)》
  • 《アルフィノ・ルヴェユール/Alphinaud Leveilleur(FIC)》
  • 《エルピスの所長、ヘルメス/Hermes, Overseer of Elpis(FIC)》
  • 《聖竜フレースヴェルグ/Hraesvelgr of the First Brood(FIC)》
  • 《テロフォロイ、アシエン・ファダニエル/Fandaniel, Telophoroi Ascian(FIC)》
  • 《リセ・ヘクスト/Lyse Hext(FIC)》
  • 《ウリエンジェ・オギュレ/Urianger Augurelt(FIC)》
  • 《クルル・バルデシオン/Krile Baldesion(FIC)》
  • 《第三の座、エメトセルク/Emet-Selch of the Third Seat(FIC)》
  • 《エスティニアン・ヴァーリノ/Estinien Varlineau(FIC)》
  • 《パパリモ・トトリモ/Papalymo Totolymo(FIC)》
  • 《闇の戦士、アルバート/Ardbert, Warrior of Darkness(FIC)》
  • 《ヒルディブランド・マンダヴィル/Hildibrand Manderville(FIC)》
  • 《大魔導師の名誉教授/Archmage Emeritus(FIC)》
  • 《奔流の機械巨人/Torrential Gearhulk(FIC)》
  • 《残忍な騎士/Murderous Rider(FIC)》
  • 《悪意の大梟/Baleful Strix(FIC)》
  • 《惑乱スプライト/Hypnotic Sprite(FIC)》

呪文 (Spells) - 40枚

  • 《稀なるつわもの/Champions from Beyond(FIC)》
  • 《停滞の光/Observed Stasis(FIC)》
  • 《邪竜の眼/Eye of Nidhogg(FIC)》
  • 《「踊り子」の投擲武器/Dancer's Chakrams(FIC)》
  • 《「青魔道士」の青魔器/Blue Mage's Cane(FIC)》
  • 《「リーパー」の両手鎌/Reaper's Scythe(FIC)》
  • 《トランス/Transpose(FIC)》
  • 《白聖石/White Auracite(FIC)》
  • 《「賢者」の賢具/Sage's Nouliths(FIC)》
  • 《「占星術師」の天球儀/Astrologian's Planisphere(FIC)》
  • 《黒魔紋の力/Circle of Power(FIC)》
  • 《古術師の地図/Archaeomancer's Map(FIC)》
  • 《領事の権限/Authority of the Consuls(FIC)》
  • 《浄化の輝き/Cleansing Nova(FIC)》
  • 《最後の裁き/Final Judgment(FIC)》
  • 《時を越えた探索/Dig Through Time(FIC)》
  • 《複製の儀式/Rite of Replication(FIC)》
  • 《崇高な天啓/Sublime Epiphany(FIC)》
  • 《命運の核心/Crux of Fate(FIC)》
  • 《致命的な策略/Lethal Scheme(FIC)》
  • 《名誉回復/Vindicate(FIC)》
  • 《虚空裂き/Void Rend(FIC)》
  • 《切望の宝石/Coveted Jewel(FIC)》
  • 《伝説たちの秘本/Tome of Legends(FIC)》
  • 《取り引き/Cut a Deal(FIC)》
  • 《未練ある魂/Lingering Souls(FIC)》
  • 《剣を鍬に/Swords to Plowshares(FIC)》
  • 《物語への没入/Into the Story(FIC)》
  • 《プロパガンダ/Propaganda(FIC)》
  • 《想起の拠点/Bastion of Remembrance(FIC)》
  • 《瀉血/Exsanguinate(FIC)》
  • 《殺し/Snuff Out(FIC)》
  • 《吸心/Syphon Mind(FIC)》
  • 《秘儀の印鑑/Arcane Signet(FIC)》
  • 《伝説の秘宝/Relic of Legends(FIC)》
  • 《太陽の指輪/Sol Ring(FIC)》
  • 《威圧のタリスマン/Talisman of Dominance(FIC)》
  • 《聖列のタリスマン/Talisman of Hierarchy(FIC)》
  • 《発展のタリスマン/Talisman of Progress(FIC)》
  • 《思考の器/Thought Vessel(FIC)》

土地 (Lands) - 37枚

  • 《島/Island》×3
  • 《沼/Swamp》×4
  • 《平地/Plains》×4
  • 《詰まった河口/Choked Estuary(FIC)》
  • 《ダークウォーターの地下墓地/Darkwater Catacombs(FIC)》
  • 《僻地のぬかるみ/Desolate Mire(FIC)》
  • 《水没した地下墓地/Drowned Catacomb(FIC)》
  • 《風変わりな果樹園/Exotic Orchard(FIC)》
  • 《悪臭の荒野/Fetid Heath(FIC)》
  • 《氷河の城砦/Glacial Fortress(FIC)》
  • 《孤立した礼拝堂/Isolated Chapel(FIC)》
  • 《港町/Port Town(FIC)》
  • 《大草原の川/Prairie Stream(FIC)》
  • 《屍肉あさりの地/Scavenger Grounds(FIC)》
  • 《光影の交錯/Shineshadow Snarl(FIC)》
  • 《広漠なるスカイクラウド/Skycloud Expanse(FIC)》
  • 《窪み渓谷/Sunken Hollow(FIC)》
  • 《沈んだ廃墟/Sunken Ruins(FIC)》
  • 《地底の大河/Underground River(FIC)》
  • 《秘儀の聖域/Arcane Sanctum(FIC)》
  • 《灰のやせ地/Ash Barrens(FIC)》
  • 《統率の塔/Command Tower(FIC)》
  • 《汚染された帯水層/Contaminated Aquifer(FIC)》
  • 《解体爆破場/Demolition Field(FIC)》
  • 《進化する未開地/Evolving Wilds(FIC)》
  • 《理想的な浜方/Idyllic Beachfront(FIC)》
  • 《祖先の道/Path of Ancestry(FIC)》
  • 《日向の湿地/Sunlit Marsh(FIC)》
  • 《邪神の寺院/Temple of the False God(FIC)》

強化に当たって

友人がこれの改良を回しても言うように「普通に強化したらブラケット2にはまず収まらない」ということ。ゲームチェンジャーを抜きにしても3は戦えてしまうという点。

これをセーブしつつシナジーを組んでいくのが今後の課題です。

Jailhouse Lockシステム技術スタック解説:mod_rewriteによるクローラー誘導作戦。

こちらの記事では、最速のナイフであるmod_aliasと、強力な拳銃であるmod_rewriteの特徴、そして「速度と役割のトレードオフ」についてお話ししました。

ここからは、筆者が実際に運用している atelier.reisalin.com の設定ファイルを元に、この2つの武器をどのように組み合わせ、悪意あるボットや過剰なクローラーを迎撃しているのか。その具体的な防衛システム、名付けて「Jailhouse Lock(ジェイルハウスロック)」の核となるmod_rewriteモジュールについてお話しします。

mod_rewriteとは?

mod_rewriteは、リクエストされたURLをファイルシステム上の特定の場所にマッピング(転送・代替)したり、別のURLへリダイレクトしたりするための、Apacheの拡張モジュールです。(そのため、多くのディストリビューションではインストールと同時に機能が有効化されていないことが多数あります。)

Ubuntu系であれば

sudo a2enmod rewrite
sudo systemctl restart apache2.service

で有効化されます。

再掲:mod_alias との違い

どちらも「URLを操作する」という意味では同じですが、そのアプローチと内部処理の複雑さに大きな違いがあります。

項目mod_aliasmod_rewrite
コンセプト単純なマッピングとリダイレクト強力なURLカスタマイズと書き換え
判定基準単純な前方一致(接頭辞マッチ)正規表現、Cookie、環境変数、時間など
処理速度非常に高速(軽量)やや低速(ルール毎に正規表現エンジンが動く)
設定の難易度簡単(初心者向け)複雑(記述ミスで無限ループが起きやすい)
主な用途フォルダの共通化、単純なサイト引っ越し綺麗に整形されたURL(Smart URL)の実現、複雑な条件分岐

最大の違い:正規表現と条件分岐の有無

mod_aliasは、URLの「先頭が一致しているか」という単純な比較しか行いません。

一方、mod_rewriteは「リクエストがGoogle Chromeから来たら」「平日の昼間なら」「Cookieに特定の文字が含まれていたら」といった、高度な条件分岐(RewriteCond)や、正規表現を使った自由自在なURLの作り替え(RewriteRule)が可能です。

筆者の設定内容抜粋

まずは、実際に稼働している設定の抜粋をご覧ください。

<VirtualHost *:80>
    ServerName atelier.reisalin.com
    RewriteEngine On
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName atelier.reisalin.com

    # ----- ログの選別と抑制 -----
    SetEnvIf Remote_Addr "192.0.2.1" dontlog
    SetEnvIfNoCase User-Agent "Googlebot" dontlog
    SetEnvIfNoCase User-Agent "GoogleOther" dontlog

    # ModSecurity等、WAFで捕獲したエラーはログを肥大化させない
    SetEnvIf MSC_RULE_ID "4009" dontlog
    CustomLog /var/log/apache2/atelier_access.log combined env=!dontlog

    DocumentRoot /home/www-data/atelier/public

    # --------------------------------------------------
    # 第一層:【mod_alias】によるハニーポットへの一撃転送
    # --------------------------------------------------
    <IfModule mod_alias.c>
        # 監獄(Jailhouse)となる隔離ディレクトリを定義
        Alias /__jailhouse_lock /home/www-data/nepenthes

        # 存在しないはずの脆弱性パスへのアクセスを最速でトラップへ
        Alias /wp-login.php   /home/www-data/nepenthes/login.html
        Alias /wp-admin       /home/www-data/nepenthes/login.html
        Alias /.git           /home/www-data/nepenthes/git.html
        Alias /assets-archive /home/www-data/nepenthes/login.html

        <Directory /home/www-data/nepenthes>
            Options -Indexes
            AllowOverride None
            Require all granted
        </Directory>
    </IfModule>

    # --------------------------------------------------
    # 第二層:【mod_rewrite】による動的・精密迎撃
    # --------------------------------------------------
    <Directory /home/www-data/atelier/public>
        Options -MultiViews
        AllowOverride All
        Require all granted

        <IfModule mod_rewrite.c>
            RewriteEngine On

            # 【迎撃フェーズ1】悪質botフラグが立っている通信の隔離
            RewriteCond %{ENV:bad_bot} =1
            RewriteCond %{REQUEST_URI} !^/__jailhouse_lock/
            RewriteRule ^.*$ /__jailhouse_lock/topgear.html [L,E=dontlog:1]

            # 【迎撃フェーズ2】特定の重いコンテンツを狙った過剰クローラー対策
            SetEnvIf Request_URI "^/projects/zettel" is_zettel

            # 大量のカンマ区切り(%2C)や、極端に長い(150文字以上)悪意あるクエリを検知
            SetEnvIf Query_String "tag=.*(%2[cC]|,|%e3%80%81).*(%2[cC]|,|%e3%80%81).*(%2[cC]|,|%e3%80%81)" bad_tag_stacking
            SetEnvIf Query_String "tag=.{150,}" bad_tag_stacking

            # 特定ページ、かつ異常クエリというパズルが揃った瞬間に500エラーで即撃破
            RewriteCond %{ENV:is_zettel} 1
            RewriteCond %{ENV:bad_tag_stacking} 1
            RewriteRule ^ - [E=dontlog:1,R=500,L]
        </IfModule>
    </Directory>
</VirtualHost>

防衛ストーリー:ナイフで受け流し、拳銃で仕留める

この「Jailhouse Lock」システムは、先の記事で述べたmod_alias(ナイフ)とmod_rewrite(拳銃)の特性をコンビネーションとして昇華させたものです。

この言葉は大好きなので何度でも再掲しますが:『MASTERキートン』のプロフェッサーの言葉。

「やめておけ」
「…………」
「拳銃の方が、ナイフよりも速いと思っているんだろう。
 だが、拳銃はデリケートな道具だ。
 弾が出ないかもしれないし、
思い通り的に当たるとは限らん。
おまけに拳銃は、
抜き、構え、引き金を引くまでに三動作(スリーアクション)……
 その点ナイフは、一動作(ワンアクション)で終わる。
この距離なら、絶対に俺が勝つ!!
どうする? それでもやってみるかね?」

これはナイフの方が有利という単純な比較論ではなく、

「この距離ではナイフが有用」だが、「ある程度のアクションや破壊力が必要な場合は拳銃が必要なるケース」というお話と筆者は捉えています。

第一層(mod_alias):無差別スキャンを「無駄なく」いなす

サイトがWordPressで作られていようがいまいが、botは機械的に /wp-login.php/.git を探して叩いてきます。これらはURLの文字列そのものが標的であるため、複雑な条件分岐は不要です。

ここで登場するのがナイフの速度を持つ mod_alias です。

        # 監獄(Jailhouse)となる隔離ディレクトリを定義
        Alias /__jailhouse_lock /home/www-data/nepenthes

        # 存在しないはずの脆弱性パスへのアクセスを最速でトラップへ
        Alias /wp-login.php   /home/www-data/nepenthes/login.html
        Alias /wp-admin       /home/www-data/nepenthes/login.html

この部分。ボット、クローラー、悪意ある攻撃者が挨拶代わりに上記のサイトへのURLに一致した瞬間に、メインアプリケーション(PHPなど)を一切起動させることなく、最速でハニーポット(ダミーのHTML空間 nepenthes)へと受け流します。サーバーのリソースを1ミリも無駄にしない、ナイフならではの「一動作(ワンアクション)」の防御です。

第二層(mod_rewrite):パズルを解き明かし「精密に」射抜く

しかし、中には特定のコンテンツ(例:負荷の重い検索機能など)に対して、URLの引数(クエリ)を巧妙に変えながら何度もクロールしてくる、たちの悪いボットがいます。

URLの文字しか見られない mod_alias では、URLの後ろに付く ?tag=xxx の中身まで検知することはできません。ここで拳銃である mod_rewrite を引き抜きます。

RewriteCond %{ENV:is_zettel} 1
RewriteCond %{ENV:bad_tag_stacking} 1
RewriteRule ^ - [E=dontlog:1,R=500,L]

「特定のコンテンツへのアクセスである(is_zettel)」
「かつ、タグの指定が異常に長い、または大量に詰め込まれている(bad_tag_stacking)」

この複数の条件が上から順にカチリと噛み合った瞬間、mod_rewrite は狙い違わず [R=500,L] という弾丸を放ち、リクエストを強制終了させます。同時に [E=dontlog:1] フラグを立てることで、ボットの嫌がらせによる「ログファイルの肥大化(ディスク容量の圧迫)」という二次災害まで綺麗に防いでみせるのです。

なぜ nginx ではなく、Apache なのか?

近代的なWebサーバーとしてnginxが台頭する中、なぜ筆者がApacheを用いる理由は以下の通り。

Apacheの持つ「上から下に流れる手続き型の思考」が、このような防衛ロジックを組む際に圧倒的に人間にとって直感的だからです。

もし、これと同じ「AかつBの条件を満たした時だけ、500エラーで弾いてログを消す」という処理をnginxで実装しようとすると、事情が変わってきます。nginxには条件を連鎖させる RewriteCond のような仕組みがなく、また if 文の挙動が非常にデリケート(通称:If is Evil)であるため、以下のような不格好な「変数ハック」を強いられます。

例えば、これと同等の機能をnginxでやろうとすると

# nginxで複数の動的条件を重ねる場合の苦肉の策
set $block_trigger "";
if ($is_zettel) { set $block_trigger "Y"; }
if ($bad_tag_stacking) { set $block_trigger "${block_trigger}Y"; }
if ($block_trigger = "YY") {
    return 500;
}

かなりifの入れ子構造が面倒になります。それに対し、Apacheは「この条件を満たし、さらにこの条件も満たしたら、このルールを適用して終了!」と、設計思想をそのまま設定にぶち込む強みがあります。

結び:適材適所の美学

強力な道具は、それ単体で振り回しても真価を発揮しません。

  • 固定の攻撃パスは、システムに最も負荷をかけない mod_alias で門前払いする。
  • 動的なパラメータや環境変数が絡む高度な迎撃は、mod_rewrite の柔軟性を活かしてピンポイントで処理する。

速度のナイフと、射程の拳銃。

この2つのモジュールを「適切なコンテキスト」で併用することで、設定ファイルそのものである程度の防御は出来るというお話です。

余談ではありますが:mod_rewriteは強力ですが、設定を一行誤れば自分自身が500エラーの被害者になります。

「『いい鉄砲は打ち手を選ぶ』ってことわざ知ってるか?
威力のある鉄砲は その分扱いも難しく危険
だから未熟者が使うと打ち手の方がケガをするってことさ」

という『ONE OUTS』で渡久地が言った言葉を持って、本記事を締めくくります。

初夏のご馳走、第二段。

更に美味しい食事を戴く機会がありました。

第一皿:お通し三種盛り

  • 手作り豆腐
    • 大豆の甘みとコクがぎゅっと詰まった、なめらかで濃厚な味わい。
  • 茹で枝豆
    • ぷっくりと実が詰まった、ビタミンB1豊富な疲労回復の定番。
  • アサリと山菜の和え物
    • タウリンや鉄分が豊富な貝類と、食感の良い山菜を合わせた胃腸に優しい小鉢。

第二皿:豪華お刺身盛り合わせ(五種盛り)

  • 本マグロ(赤身)
    • 筋と平行に美しく包丁が入れられた、口当たりなめらかでDHA・EPA豊富な極上品。
  • 生ウニ
    • 一粒一粒がふっくらと自立した、濃厚でビタミンEたっぷりの黄金色の海の恵み。
  • 〆サバ
    • 皮目が銀色に輝く、しっとりとした絶妙な締め具合の青魚。
  • カツオのタタキ
    • 香ばしく炙られた身に、刻みネギとおろし生姜の薬味がベストマッチ。
  • 白身魚(タイまたはヒラメなど)
    • 透明感があり、コリコリとした歯ごたえと上品な甘みが広がる高タンパクな一品。

🦪 第三皿:旬の岩牡蠣(ミディアムレア焼き)

  • 焼き岩牡蠣
    • 「Rのつかない月」に最高潮を迎える夏の贅沢。焼いても殻いっぱいのサイズを保つ圧倒的なボリュームと、亜鉛・タウリンの塊のようなクリーミーな旨味。まさに言葉を失う一品。

🪵 第四皿:メインディッシュ・アイナメの兜煮

  • アイナメの兜煮
    • 初夏に旬を迎える高級白身魚。一切の煮崩れなしに美しく照り映える職人技。目玉、唇、ほお肉、ヒレ肉に詰まった極上のゼラチン質とコラーゲン、そして奥深いタレの融合に目を疑うほどの傑作。

第五皿:もろこし天と脱皮エビ唐揚げ

  • もろこし天(とうもろこしの天ぷら)
    • サクサクの衣の中に、シャキシャキとした歯触りとプッツリ弾ける濃厚な甘みを閉じ込めた初夏の一品。
  • 脱皮エビ(ソフトシェルシュリンプ)の唐揚げ
    • 殻ごと丸ごと香ばしく揚げ、身のプリプリ感を完璧に残した、カルシウムとタウリンがたっぷりの悪魔的揚げ物。

結び:黒蜜きな粉アイスクリーム

  • 和風バニラアイス
    • ひんやり冷たいバニラに、濃厚な黒蜜と香ばしいきな粉(大豆タンパク)が三位一体となった、脳と心を満たす至福のデザート。

と、恐るべきボリュームと量でした。

カレーの戦略。

美味しいお店のメニューの狙いを見るのが好きです。

ある日にいただいたカレーの戦略性をこっちで勝手に推理してみます。

見た目は本当に日本の家のカレー。

  • ジャガイモ
  • にんじん
  • タマネギ

違いがあるとすれば福神漬けの代わりに細切り唐辛子。まずは食べてみます。

「肉」

でした。それも普通にお目にかかれないような圧倒的な牛肉の旨味と歯ごたえ、筋の柔らかさがこれでもかと出てきます。

そして飛び込んでくるほくほくのジャガイモとにんじん、ジャガイモの甘みがご飯と一体化。

そして、やや辛のスパイスが刺激し、全てを平らげてくれます。

この店の狙い、推測

ここで、一つ謎が出てきました。なぜこの店は、この牛肉で勝負ができるカレーを

  • おしゃれなカレーポットに入れず
  • 奇をてらわない平皿盛りで
  • 日本のカレーの見た目にしたのか

です。それは、この「圧倒的な牛肉」を強烈に意識させるためではないかという仮説。

どうしたって人はバイアスに捕らわれます。そこで高級店のカレーのスタイルで出てくれば「さすがは高級店」と、比較対象が別のものになります。

しかし、店のカレーが、こちらのように家庭的な見た目ならば、どうしたって「家のカレーとどう違うのか」の確固たる評価軸が出てきます。

その上で「肉が違う。この肉の出し方は自分には難しい」と思わせる戦略。

正直、普段の手作りカレーが一歩下がるような感覚でした。つまりこれは、味の美味しさで勝負するのはもちろん

「あなたの普段食べているカレーとは素材が違います」

をすり込むための擬態、とも取れそうです。実際問題、もう一度このカレーを食べたいという気持ちにあふれていますので。

『メリー・ポピンズ リターンズ』

Cover is not the book / 心が目に見えないように本も
So open it up and take a look / 表紙の美しさに騙されちゃダメ
'Cause under the covers one discovers / 中身読んだらやさしい王様
That the king may be a crook / 詐欺師だとわかるかも

を地で行くカレーでした。

タマネギ利用の副菜

タマネギを消費する必要が出てきたため、これを活かした副菜を作ってみます。

輪切りにした結果、紫タマネギ。この甘みを活かすため、レンジグリルで5分温め、かき混ぜて更に5分の加熱。

ここに加えるのは

  • ツナ缶
  • 鰹節
  • ポン酢

ツナ缶は油ごと。ポン酢は心持ちたっぷり。鰹節はケチをせずどっさり。

最後に七味で味を調えました。

  • タマネギの甘みとわずかに残るシャキシャキ感
  • ポン酢の鮮烈な酸味
  • 鰹節とツナ缶の旨味

がしっかり加わり、単体でも美味しいものが。

お弁当の付け合わせとしても最高ですし、

サンドイッチと合わせても申し分ないものができあがりました。

2026年6月の差しボードゲームの記録。

友人と1 vs 1でのボドゲの記録です。

リビングフォレスト・デュエル

二戦続けて実施。

  • 1戦目:鬼火を連続で送りつけて勝利。
  • 2戦目:召喚獣全てをこちら側で埋めての勝利。

ナショナルエコノミー完全版(グローリー)

これは完全に実力差が出たという形。100点差を付けての圧勝。

カエサル!

準アブストラクト。私はカエサル担当。史実通りに周辺植民地の支配を得るように奮闘したものの、ポンペイウスがイタリアの実権を握ったという史実通りの敗退。

差しゲーは2人千専用ゲームもできるので好みです。

食事と海鮮。

素晴らしい食事を戴きました。

お作り

季節の盛り合わせ。特にしめさばに感動。

豚の角煮

クリアなあく取りと、しっかりと染みこんだ豚肉、とろけるような脂身。

鮎の塩焼き

この焼き色はもちろん、頭も骨もしっかり食べられて詰まらない絶技です。

厚揚げ

一番感動したのは実はこちら。「その場で揚げた」真に出来たての厚揚げ。なので、普通に口にした瞬間に熱々の豆腐が飛び出てきて火傷寸前でした。

なので、その香ばしさが更に薬味とひき立て合います。

ジャガイモの素揚げ

好物だからと挙げてくれました。バターと塩のみという潔さがジャガイモのほくほく感を引き立てます。

稲庭うどんと野菜点

食事の締め。正義の取り合わせという感じ。

手まり寿司

感動したというしめさばのフィードバックをそのまま手まりにするという技術と心配り。

と、実に素晴らしい食事をいただけました。

Page 1 of 296

Powered by WordPress & Theme by Anders Norén