投稿者: manualmaton Page 1 of 288

ボードゲーム『大鎌戦役』星章獲得と終了トリガーメモ。

大鎌戦役の『星章獲得』は

  • 一度でもその条件に達したとき

です。そして、ゲーム終了は

  • 誰かが6つの星章を獲得した場合

直ちに、他の処理を終了して計算が行われます。これは、意図的にパラメーターが上がったりアクションを完遂したときは問題ないのですが

  • 徴用によるボーナス
  • 一部勢力のパラメーター変化

で異なるケースがあります。ある種の「意図しないルーリング」を紐解いていきましょう。

ケース1:徴用によるボーナスでトリガーを引いた場合

徴用は、どれか一つの上位アクションにより、自分自身並びに両隣がボーナスを享受します。ここで問題になるのは

  • 改善(改良)による戦力上昇
  • 建築による支持(民心)上昇です。

自分自身の隣のプレイヤーが

  • 戦力15 で 徴用-改良を解放
  • 支持(民心)17 徴用-建築を解放

場合を想定します。それぞれ星章5つを獲得していて、上記の星章を得ていないという状況。

ここで自分が改良を行った/建築を行った場合、徴用のチェックが入った後ゲームは終了します。

ケース2:自分のアクションと徴用によるボーナスが重なった場合

ケース1と同じく

  • 戦力15 で 徴用-改良を解放
  • 支持(民心)17 徴用-建築を解放

場合を想定します。それぞれ星章5つを獲得していて、上記の星章を得ていないという状況に加えて

  • 自分が改良/建築による星章獲得をすれば星章6つを獲得する

というタイミング。この場合、徴用のチェックは行われません。なぜなら、アクションによる星章の段階で全ての処理が断ち切られ、ゲームのスコア計算が走るからです。

これは、特に、相手の徴用ボーナスで支持(民心)の足切りが変わる数値(6と12)は特に注意しましょう。

ケース3:戦闘によるパラメータ上昇がある場合

これは、メック能力により状況が異なってきます。

  • 戸川幕府のメック能力:浪人(戦闘ユニット単騎で戦闘したときに戦力が+2)
  • アルビオン氏族のメック能力:盾(防御時に戦力が+2)

を解放した場合を想定します。

このとき、戸川/アルビオンが星章を5つ獲得していて戦力による星章が獲得されていない状況。それぞれ戦力は14/15だった場合。

サブケースは以下の通りになります。

戦力をある程度消費した

この場合、戦力は引いた数からそれぞれのメック能力が足されるため、戦闘はそのまま発生します。

戦力15 → 戦力7支払う → メック能力により+2されても、戦闘終了時の戦力は16に満たない。

戦力を一切消費しなかった

この場合、戦闘中に「戦力が16に達する」時が発生します。

この場合、戦闘はそのまま解決。解決後、戦闘の如何に関わらず星章を獲得してゲームは終了します。

なので「戦闘に負けてもゲームが終わる」のです。

戦闘による星章がさらに加わる

上記の条件に「攻撃を仕掛けた/仕掛けられた側が戦闘による星章で6つめを獲得する」という場合、どちらが先に適用されるのか?

これは、「戦闘中のパラメータ変化」が優先されます。つまり、勝敗より先に数値の変化が起こるからです。

まとめ

これらの状況は割と起こりやすいだけに注意が必要。

  1. 戦闘中のパラーメータ変化
  2. アクション
  3. 徴用によるボーナス

の3つの優先順位が必要です。

Growi v7.5.0のアップデートメモ(nodeのアップデート含む)

Grwoiをv7.5.0にアップデートしたときのメモです。

アップデート概要

  • 対象バージョン: v7.4.7 → v7.5.0
  • 実行環境:
    • Ubuntu 24.04
    • Apache 2.4によるリバースプロキシー

主要な変更点:

  • Node アップデートによる Next.js v16 / Vite v6 / Turbopack への移行
  • リバースプロキシにy-websocket への変更、
  • RegExp.escape() の採用

前提

  • nvmでnodeのバージョンを管理していること。
  • リバースプロキシの変更手順が整っていること。

事前準備・環境更新

最新のGROWI要件に合わせ、Node.jsランタイムをアップデートしました。

-Node.jsの更新:

nvm を使用して v24.14.1 をインストール。 筆者はroot環境で実施しているため

sudo su -

で管理者権限になってから実施しました。

  • nvm バージョンアップ
nvm install 24

bash
nvm use 24

nvm alias default 24
  • ビルドツールの更新:

はまったポイントです。一度バージョンアップするとv24環境で pnpmが消えてしまうので再有効化します。

corepack enable
corepack prepare pnpm@latest --activate

ビルドプロセスの修正

後は基本的に筆者が行っているものに習います。

growiディレクトリに移動します

cd /home/www-data/growi && pwd

自分の環境に合わせます。(筆者環境/home/www-data/growi)

リリースタグを確認します。

  • リリースタグ取得
sudo git fetch --tags
  • リリースタグ確認
sudo git tag -l

スペースで確認していき、上記リリースサイトと同じバージョンがあることを確認します。

チェックアウトとインストールを行います。

  • 変更を一時的に退避
sudo git stash
  • チェックアウト
sudo git checkout 【バージョン】

リリースタグは再確認しましょう。今回は 2026/04/07にリリースされたv7.5.0を選択しました。

メモリ不足の対処

  • pnpm install 時のセキュリティ警告(sharpのビルド停止)およびメモリ不足対策を実施しました。
  • ネイティブバイナリの許可:
    ```bash
    pnpm approve-builds
リストから sharp を選択して許可

bash
pnpm install

- Turbopackによるビルド:

メモリ消費を抑えるため、上限を指定して実行。

bash
NODE_OPTIONS="--max-old-space-size=4096" pnpm run app:build

### リバースプロキシ (Apache) の修正


同時編集プロトコルが `y-websocket` に変更されたことに伴い、`growi.conf` の書き換えルールを厳密化しました。

修正内容: すべてのWS通信ではなく、`/yjs` パスのみをWSプロキシへ流すよう変更。

apache
# リバースプロキシー設定
RewriteEngine on

# 1. /yjs へのアクセスのみ WebSocket プロキシへ飛ばす
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{REQUEST_URI} ^/yjs [NC]
RewriteRule /(.) ws://localhost:3000/$1 [P,L]

# 2. それ以外の通常の HTTP リクエスト
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
```

起動スクリプトの修正

2度目のはまりポイントです。RegExp.escape is not a function エラー(Node.jsのバージョン不足)を解消するため、サービスが参照する PATH を更新しました。
(これは筆者環境なので)

growi-start.sh の修正:

# 旧: v20.19.2 -> 新: v24.14.1
export PATH="/root/.nvm/versions/node/v24.14.1/bin:$PATH"

Growiの再起動

  • Growiサービス開始
sudo systemctl restart growi.service
  • サービス開始確認
systemctl status growi.service

active(running)を確認します。

完了確認

  • [x] 管理画面「システム情報」にて GROWI 7.5.0 / Node.js 24.14.1 を確認。
  • [x] ページリストの取得エラー(APIエラー)が解消されたことを確認。
  • [x] ページ複製時の RegExp.escape エラーが解消されたことを確認。
  • [x] Elasticsearch v9 への接続および検索ができることを確認。

AIツールを狙ったログのメモ

筆者の公開VPSにて、昨今のトレンドと言えるようなログを確認しましたので解説です。

攻撃者のIPやホスト名をダミー(例: ATTACKER_IP, TARGET_IP)に置き換えています。わざわざIP晒しをしないのは「テロリストに名前を与えない」の精神からです。

[DATE] [security2:error] [client ATTACKER_IP_1] ModSecurity: Access denied... [id "10004"] [msg "Host header is a numeric IP address"] [hostname "TARGET_IP"] [uri "/"]
[DATE] [security2:error] [client ATTACKER_IP_1] ModSecurity: Access denied... [id "10004"] [msg "Host header is a numeric IP address"] [hostname "TARGET_IP"] [uri "/favicon.ico"]
[DATE] [security2:error] [client ATTACKER_IP_2] ModSecurity: Access denied... [id "10004"] [msg "Host header is a numeric IP address"] [hostname "TARGET_IP"] [uri "/.git/config"]
[DATE] [security2:error] [client ATTACKER_IP_3] ModSecurity: Access denied... [id "10004"] [msg "Host header is a numeric IP address"] [hostname "TARGET_IP"] [uri "/api/tags"]
[DATE] [security2:error] [client ATTACKER_IP_3] ModSecurity: Access denied... [id "10004"] [msg "Host header is a numeric IP address"] [hostname "TARGET_IP"] [uri "/v1/models"]
[DATE] [security2:error] [client ATTACKER_IP_3] ModSecurity: Access denied... [id "10004"] [msg 
[DATE] [security2:error] [client ATTACKER_IP_3] ModSecurity: Access denied... [id "10004"] [msg "Host header is a numeric IP address"] [hostname "TARGET_IP"] [/update_weights_from_tensor]
"Host header is a numeric IP address"] [hostname "TARGET_IP"] [uri "/.well-known/mcp.json"]
[DATE] [security2:error] [client ATTACKER_IP_3] ModSecurity: Access denied... [id "10005"] [msg "Missing Host Header"] [hostname "example.com"] [uri "/"]

解説の前に

  • header is a numeric IP address
  • Missing Host Header

があることに気づく方はいるかと思います。

これは、筆者が導入しているMod_Securityに以下のカスタムルールを設けているからです。

# 1-3. 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.'"

攻撃の全体的な意図:なぜ「IPアドレス」でアクセスしてくるのか?

ログの多くが 「HostヘッダーがIPアドレスである」 という理由でModSecurity(WAF)に遮断されています。これには以下の意図があります。

  • 無差別スキャン:
    • ドメイン名を知らなくても、IPアドレスの範囲(例: 192.168.0.0/16)を片っ端から叩くことで、管理が甘い「生」のサーバーを見つけ出そうとしています。
  • デフォルト設定の探索:
    • 多くのWebサーバーは、不明なドメインやIP直接指定でアクセスされた際に「デフォルトのバーチャルホスト」を表示します。ここにはテストページや管理ツールが放置されていることが多いため、そこを突こうとしています。
  • WAF/CDNの回避:
    • CloudflareなどのCDNを経由せず、サーバーの「本当のIP」に直接攻撃を仕掛けることで、上位の保護層をバイパスしようとする手法です。

各パス(URI)が狙われた理由とケーススタディ

情報漏洩の古典:/.git/config

  • 意図:
    • Gitリポジトリの露出確認。
  • 背景:
    • 開発者が誤って .git ディレクトリを公開サーバーにアップロードしてしまうミスを狙っています。これが取得されると、ソースコード、DBのパスワード、APIキー、過去の全変更履歴が盗まれます。

AI・LLM時代の新潮流:/v1/models, /api/tags, /api/version

  • 意図:
    • OllamaやLocalAI、OpenAI互換API などのエンドポイント探索。
  • 背景:
    • 昨今、自宅サーバー等でローカルLLMを動かす人が増えています。これらのツールはデフォルトで /v1/models などのパスを使用するため、認証なしでAIリソースを悪用(AI寄生)したり、モデル情報を盗んだりするためにスキャンされています。

2026年での最新トレンドの追跡:/.well-known/mcp.json, agent.json

  • 意図:
    • Model Context Protocol (MCP) 設定ファイルの探索。
  • 背景:
    • MCPは2024年末〜2025年にかけて普及し始めた、AIエージェントとツールを接続するための規格です。これがあるサーバーは「AIエージェントが操作可能なリソース」を持っている可能性が高いため、攻撃者は踏み台やデータ奪取の対象としてリストアップしようとしています。

AI学習モデルの改竄:/update_weights_from_tensor

  • 意図:
    • 学習済みモデルの「重み(Weights)」を外部から直接書き換えようとしています。
  • 背景:
    • もし成功すれば、攻撃者はサーバにインストールされているAIの判断を密かに操作できます。例えば「特定の条件の時だけ誤判定させる(バックドア)」や「特定の顔をスルーさせる」といった、AIジャックが可能です。

監視・インフラの隙:/metrics, /queue/status

  • 意図:
    • Prometheusや監視ツールの露出確認。
  • 背景:
    • /metrics にはサーバーの負荷、プロセス一覧、時には内部ネットワークの構成情報がプレーンテキストで出力されます。攻撃者にとっては、攻撃の戦略を立てるための「設計図」を手に入れるようなものです。

ここから得られること

総括

「攻撃者はドメイン名で選んでいるのではない。露出している機能(Git, AI API, 監視ツール)をポートスキャンとパス探索で機械的に探り当てている」

今後の教訓:

  • ホワイトリスト運用:
    • /api//metrics などのパスは、特定のIP以外からは404にしましょう。
  • 「隠しファイル」の禁止:
    • .git.env など、ドットで始まるディレクトリへのアクセスはWebサーバーレベルで一括拒否しましょう。

いくら最新の(今回のようなAIサーバ)を狙ったところで

  • 「対策の甘いところから狙われる」
  • 公開されたらヤバいところは共有される

という普遍性は同じ。それこそ『緋色の研究』でホームズが言う

「日の下に新しきものなし」 (Nihil novi sub sole)

ぐらいの勢いで、基本的な対策をしていきましょうという話でした。

食事と収穫。

ボードゲーム『クランズ・オブ・カレドニア』の時の収穫です。

カレーセット

インドカレーセット。おなじみの鉄のプレートにカレーやらサラダやら。

問題はこちら。

中にキーマをたっぷりと詰めた、それだけで食事になるという非常に罪深い味わい。

これがまたスパイシーなカレーとの相性抜群で口の中が波状攻撃でした。

ナショナルエコノミー

そして、購入したのがこちらのボードゲーム『ナショナルエコノミー』。国産ワーカープレースメントの代名詞。

筆者が初めてそのジャンルに触れて、また、そのソロゲームに夢中になったという曰く付きの品。

比較的手に入れやすい価格だったことも追い風でしたので、今後の楽しみが増えました。

ボードゲーム『クランズオブカレドニア』2人戦記録。

久しく回すことがなかった『クランズオブカレドニア』を回す機会がありました。それもソロではなく対人戦。

実はその友人とプレイした当初、ルールを盛大に間違えて

  • マップが2枚だけ
  • 商品は1商品につき何個でも買える

という勘違いもありました。

盤面、黒が私です。契約を順調に履行していたこと、序盤の経済的基盤が功を奏して151-120で勝利。

とはいえ、最終ラウンドで相手に大きくまくられてしまい、マジョリティで負けてしまいました。

正直、こちらのプレイ経験が高かったから勝てたぐらいのレベル。

比較的コンパクトでイメージもしやすいこのゲーム。なんとか一般市場に再流通してほしいです。(Kickstarterは気がついたら終わっていたので

TS-216GにSSL証明書を設定。

QNAP、Web管理画面へのアクセスがhttp通信のためブラウザで「保護されていない通信」と出てしまいます。

ローカル運用だからといっても多くのマルウェアは「ついでに」というより「こっちが本命」と言わんばかりにNASを狙うパターンが多いため、
(↑ 建前 ↑)
(↓ 本音 ↓)
こちらの美意識にそぐわないためSSL証明書を自前で設定します。

環境

別に以下の環境があることが要件です。

  • インターネットに接続されているLinuxサーバ。
    • Let's Encrypt(certbot)導入済み
  • 独自ドメインがあること。
    • そのDNSレコードを設定することができること。

さっくりとした手順

  1. certbotで証明書を発行します。
  2. 適切な手段でローカル環境に保存します。
  3. NAS(TS-216G)に適用します。

Let's Encryptで証明書を発行。

  • 証明書発行

以下、

  • -d ドメイン
  • -m 自分のメールアドレス

に置き換えます。

sudo certbot certonly --manual \
-d star.hoge.example.com \
-m hoge@example.com \
--agree-tos \
--key-type rsa \
--preferred-challenges dns-01

この、key-type rsaを付けなかったことがはまりポイントでした。というのも、ここ数年、Let's EncryptはECDSA方式をデフォルトで発行していますが、QNAPのOSは最新の暗号化に対応していません。そのため、RSAと「強度を下げて広く使われる形式」と明示する必要があります。

  • ドメイン所有者手続き

その後、DNSで、指定されたTXTレコードを登録せよという指示がありますので、それに従ってDNSを設定します。

このとき、TTLは60などと極めて短い時間にしておくと良いでしょう。(3600などとするとかなり待たされます)

証明書の整合性を確認

  • 90日の有効期限であることを確認します。

以下、自分が発行したドメインに基づく証明書や秘密鍵に読み替えます。

sudo openssl x509 -noout -dates -subject -in /etc/letsencrypt/live/star.hoge.example.com/fullchain.pem
notBefore=May 17 04:35:55 2025 GMT
notAfter=Aug 15 04:35:54 2025 GMT

のように90日間であることを確認します。

  • 確認1. 証明書から公開鍵データを確認
sudo openssl x509 -pubkey -in /etc/letsencrypt/live/star.hoge.example.com/fullchain.pem -noout | openssl md5
  • 確認2. 秘密鍵から公開鍵を取得
sudo openssl pkey -pubout -in /etc/letsencrypt/live/star.hoge.com/privkey.pem | openssl md5

→ 確認1/確認2で出てきた公開鍵のハッシュ値が一致していればOKです。

SSL証明書と秘密鍵をローカル環境に保存

発行されたら、以下のファイルを適切な方法でローカルに保存します。

  • /etc/letsencrypt/live/star.hoge.example.com/fullchain.pem
  • /etc/letsencrypt/live/star.hoge.com/privkey.pem

この時の保存はcatコマンドで表示して自分の環境にファイルを貼り付けるのが結果的に効率的ではありますが、privkey.pemは管理者権限でしか読めない(600)となっているため、

sudo cat /etc/letsencrypt/live/star.hoge.com/privkey.pem

としないと閲覧できません。

そうしてローカル環境に保存します。

QNAPへの運用

  1. ブラウザでQTSにログインし、[コントロールパネル] を開きます。
  2. [システム] > [セキュリティ] の順に進みます。
  3. 上部のタブから [証明書とプライベートキー] を選択します。
  4. [証明書の置換] ボタンをクリックします。
  5. 「証明書のインポート」を選択し、以下のファイルをそれぞれアップロードします。
  • 指定するファイルの対応表
項目ファイルの種類内容
プライベートキー**.key証明書発行時に生成した秘密鍵
証明書.crt または .pem認証局から発行されたドメイン証明書
中間証明書 (任意).crt または .pem認証局のチェーン証明書(推奨)
  1. [適用] をクリックします。これで、NASのWeb管理画面(HTTPS)に証明書が適用されます。

適用後の確認

設定が完了したら、以下の点を確認してください。

  • ブラウザの鍵マーク: NASにドメイン名(例:https://star.hoge.example.com:8081)でアクセスし、ブラウザのURL横にある鍵アイコンが正常(「この接続は保護されています」)になっているか確認します。
  • 有効期限: QTSの「証明書とプライベートキー」画面で、表示されている有効期限が正しいか確認します。

注意点とTips

証明書一式をインポートしたのに適用できない

ECDSA形式で発行しているパターンがほぼ大多数です。筆者はこれに一週間ほどハマり、「自分のブログメモ」に助けられました。

ポート開放とアクセス

自前証明書を適用しても、ローカルIPアドレス(192.168.x.x)でアクセスした場合は「保護されていない通信」と表示されます。必ず証明書に記載されたドメイン名でアクセスしてください。

しかし、これはある意味チャンスです。Let's Encryptは90日しか有効期限がないため、期限切れで

https://star.hoge.example.com:8081

とアクセスした場合、ブラウザでエラーが出ますが、ローカルIPアドレス直打ちはその範疇ではありません。

証明書の更新

自前の証明書(特に Let's Encrypt 以外を外部で取得したもの)は自動更新されません。有効期限が切れる前に、上記の手順で新しいファイルを再度インポートする必要があります。

myQNAPcloud を利用している場合

もし myQNAPcloud の DDNS 機能を利用している場合、QTS側で「myQNAPcloud証明書」が優先されていることがあります。その場合は、上記手順の「証明書の置換」で自前のものを優先するように設定を変更してください。

カード入れ替え。(統率者メモ2026/04/06)

このデッキを購入してから1ヶ月以上。ようやくカードの入れ替えです。

想定ブラケット

3。ゲームチェンジャーの《意志の力/Force of Will(ALL)》が入っているため。

また、2枚コンボは多数ありますがサーチなしという判断です。

デッキリスト

太字は入れたカード。

【統率者】 (1)

  • 1 《遠地点の頭脳、キロ/Kilo, Apogee Mind》

【クリーチャー】 (24)

  • 1 《遺跡の天使/Angel of the Ruins》
  • 1 《金属の徒党の種子鮫/Chrome Host Seedshark》
  • 1 《湖に潜む者、エムリー/Emry, Lurker of the Loch》
  • 1 《河童の砲手/Kappa Cannoneer》
  • 1 《ファイレクシアの変形者/Phyrexian Metamorph》
  • 1 《尋問のドミヌス、テクータル/Tekuthal, Inquiry Dominus》
  • 1 《思考の監視者/Thought Monitor》
  • 1 《ウェザーライトの艦長、ジョイラ/Jhoira, Weatherlight Captain》
  • 1 《搭載歩行機械/Hangarback Walker》
  • 1 《鋼の監視者/Steel Overseer》
  • 1 《かき鳴らし鳥/Thrummingbird》
  • 1 《刻まれた巫女/Etched Oracle》
  • 1 《愚鈍な自動人形/Mindless Automaton》
  • 1 《這い回る合唱者/Crawling Chorus》
  • 1 《鏡割りのキキジキ/Kiki-Jiki, Mirror Breaker》
  • 1 《修復の天使/Restoration Angel》
  • 1 《詐欺師の総督/Deceiver Exarch》
  • 1 《離反ダニ、スクレルヴ/Skrelv, Defector Mite》
  • 1 《微光蜂、ザーバス/Zabaz, the Glimmerwasp》
  • 1 《最高工匠卿、ウルザ/Urza, Lord High Artificer》
  • 1 《大建築家/Grand Architect》
  • 1 《電結のシカール/Arcbound Shikari》
  • 1 《電結の荒廃者/Arcbound Ravager》
  • 1 《エーテル宣誓会の法学者/Ethersworn Canonist》
  • 1 《歩行バリスタ/Walking Ballista》

【呪文】 (38)

  • 1 《洞察エンジン/Insight Engine》
  • 1 《太陽電池アレイ/Solar Array》
  • 1 《白鳥の歌/Swan Song》
  • 1 《燻蒸/Fumigate》
  • 1 《臨機応変な防御/Resourceful Defense》
  • 1 《潜在能力の波動/Ripples of Potential》
  • 1 《連鎖反応/Chain Reaction》
  • 1 《過去起こし/Wake the Past》
  • 1 《霊体のヤギ角/Astral Cornucopia》
  • 1 《ダークスティールの反応炉/Darksteel Reactor》
  • 1 《大出力自動生成器/Empowered Autogenerator》
  • 1 《タイタンの炉/Titan Forge》
  • 1 《剣を鍬に/Swords to Plowshares》
  • 1 《テゼレットの計略/Tezzeret's Gambit》
  • 1 《知識の渇望/Thirst for Knowledge》
  • 1 《秘儀の印鑑/Arcane Signet》
  • 1 《五元のプリズム/Pentad Prism》
  • 1 《太陽の指輪/Sol Ring》
  • 1 《実験的占い/Experimental Augury》
  • 1 《永遠溢れの杯/Everflowing Chalice》
  • 1 《発展のタリスマン/Talisman of Progress》
  • 1 《確信のタリスマン/Talisman of Conviction》
  • 1 《欠片の双子/Splinter Twin》
  • 1 《オゾリス/The Ozolith》
  • 1 《スクレルヴの巣/Skrelv's Hive》
  • 1 《現実からの遊離/Freed from the Real》
  • 1 《白の太陽の頂点/White Sun's Zenith》
  • 1 《意志の力/Force of Will》
  • 1 《サイクロンの裂け目/Cyclonic Rift》
  • 1 《摩耗+損耗/Wear+Tear》
  • 1 《秘密の複製機/Esoteric Duplicator》
  • 1 《降霜断崖の包囲/Frostcliff Siege》
  • 1 《流刑への道/Path to Exile》
  • 1 《屋敷の踊り/Dance of the Manse》
  • 1 《旗艦、インスピリット/Inspirit, Flagship Vessel》 (復帰!)
  • 1 《ウスロスの調査船/Uthros Research Craft》 (復帰!)
  • 1 《万象監視/Universal Surveillance》 (復帰!)

【土地】 (37)

  • 3 《平地/Plains》
  • 3 《島/Island》
  • 3 《山/Mountain》
  • 1 《きらめく地溝/Glittering Massif》
  • 1 《光輝の山頂/Radiant Summit》
  • 1 《アダーカー荒原/Adarkar Wastes》
  • 1 《滝の断崖/Cascade Bluffs》
  • 1 《断崖の避難所/Clifftop Retreat》
  • 1 《風変わりな果樹園/Exotic Orchard》
  • 1 《氷河の城砦/Glacial Fortress》
  • 1 《灌漑農地/Irrigated Farmland》
  • 1 《カーンの拠点/Karn's Bastion》
  • 1 《マイコシンスの庭/The Mycosynth Gardens》
  • 1 《岩だらけの大草原/Rugged Prairie》
  • 1 《シヴの浅瀬/Shivan Reef》
  • 1 《広漠なるスカイクラウド/Skycloud Expanse》
  • 1 《産業の塔/Spire of Industry》
  • 1 《硫黄の滝/Sulfur Falls》
  • 1 《統率の塔/Command Tower》
  • 1 《古えの居住地/Ancient Den》
  • 1 《埋没した廃墟/Buried Ruin》
  • 1 《大焼炉/Great Furnace》
  • 1 《孤立した砂州/Lonely Sandbar》
  • 1 《神秘の僧院/Mystic Monastery》
  • 1 《教議会の座席/Seat of the Synod》
  • 1 《溢れかえる岸辺/Flooded Strand》
  • 1 《金属海の沿岸/Seachrome Coast》
  • 1 《神聖なる泉/Hallowed Fountain》
  • 1 《墨蛾の生息地/Inkmoth Nexus》
  • 1 《ミレックス/Mirrex》

大きな違いは「毒殺を狙えるようになったこと」。また、ジェスカイ特有の

  • 青赤双子
  • 修復天使+キキジキ

も入っています。

進む誘惑、留まる勇気。(IDEA SPHERE)

雑多な事柄を無理矢理一つにまとめるエッセイに似た何か『IDEA SPHERE』の一節。

拙稿で取り上げているサーバ運用時の心構え

この大本のきっかけとなった「なぜ、切り戻しが大切か」という原体験を述べようと思います。

遭難、一歩手前。

話はかなり昔。筆者が訪れたベルナー・オーバーラント地方の4泊滞在

ものすごくさっくり言うと

  1. 観光ガイド地図では近そうだからと歩くのを試みた。
  2. 人気が無い道だけど下れば平気と思い込んでいた。
  3. 軽食を取っているときにユングフラウの雲に傘がかかっていた
  4. これはヤバいと引き返し
  5. 駅に着くと同時に雨
  6. そして本当に正しい道が分かった

この、「一歩でも間違えば客死寸前」というよりも「生きていたのが不思議」という体験。なぜ、人はこれに陥るのか?

それを紐解いていきます。

STOPの原則とサンクコスト

その背景には、人間の判断を狂わせる強力な心理的トラップと、それを打破するための基本的なプロトコルが欠けていたことにあります。

ここで重要になるのが、「サンクコスト(埋没費用)のバイアス」と、回避策としての「STOP」の概念です。

サンクコストの罠:「ここまで来たから」という呪縛

「せっかくここまで歩いたのだから」「もう少し進めば着くはずだ」という思考こそが、サンクコストのバイアスです。それまでに費やした時間や労力を惜しむあまり、客観的に見て「引き返すのが正解」という状況でも、損を認めたくない心理から無理な続行を選択してしまいます。

ガチャなどでも「10連でお目当てのSSRが引けないから次の10連こそ」で石を使い切り、追い課金をしてドツボにハマるアレです。

STOP:冷静さを取り戻すための技術

このバイアスを断ち切り、致命的な結果を回避するために有効なのが、登山の危機管理などでも用いられる「STOP」の法則です。

  • S (Stop) / 止まる:
    • 異変を感じたら、物理的に足を止める。焦燥感から逃れるための第一歩です。
  • T (Think) / 考える:
    • 現在の状況を冷静に分析する。感情を切り離し、事実のみを見つめます。
  • O (Observe) / 観察する:
    • 周囲の天候、道筋、自分の体力を客観的に見る。「雲に傘がかかっている」という兆候を見逃さないことです。
  • P (Plan) / 計画する:
    • 進むべきか、退くべきか。最善の安全策を再構築する。

「進む誘惑」を振り切り、「留まる(あるいは引き返す)勇気」を持つこと。この判断の遅れが、システム運用における障害の深刻化や、山岳における遭難の引き金となります。私の体験を、もう少し詳しく紐解いていきましょう。

いつものように長い全文(マクラ)と筆者の実例というスタイルです。

当初の「問題」:タグの数珠つなぎ検索

筆者が運営しているRedmineサイト。特定のプロジェクトページ(/projects/hoge)に対し、以下のようなリクエストが大量に発生していました。

GET /projects/hoge/search?tag=A,B,C,D,E,F...

カンマ(,)やURLエンコードされた区切り文字を使い、タグを5個も10個も連結して検索を繰り返す挙動です。これは明らかにサイト構造を網羅しようとするスクレイピング(採取)ボットの動きであり、アプリケーションのDB負荷を無駄に高めていました。

当初の「改善案」:ModSecurityでの防御

この「異常なタグの連結」を検知するため、ModSecurity(WAF)にカスタムルールを投入しました。

# 引数 "tag" の中にカンマが3つ以上あればブロック
SecRule REQUEST_URI "@contains /projects/hoge" \
    "id:10010,phase:1,chain,deny,status:404,nolog,msg:'Excessive tag stacking'"
    SecRule ARGS:tag "(?i)(?:%2c|,).?(?:%2c|,).?(?:%2c|,)"

「404を返し、かつ nolog で静かに処理する」という、完璧な罠を仕掛けたはずでした。

失敗:静寂を破る「Googlebot」のログ浮上

ルールを適用した直後、おかしな現象が起きました。これまでアクセスログへの出力を抑制(dontlog)していた Googlebot などの正規クローラーのログが、突如として出力され始めたのです。

ボットを黙らせるために設定を追加したのに、逆に「普段は隠れているはずのログ」が溢れ出す本末転倒な事態。ここで私は、

「軽微な修正ですぐに直るはずだ」

という思い込みに囚われました。ModSecurityのフラグをいじり、設定の微調整を繰り返します。しかし、ログの奔流は止まりません。

画面を埋め尽くす不毛なログ。高まる焦燥感。私は「なぜ」と自問しながら、STOP原則から最も遠い場所にいました。

踏み止まる勇気:サンクコストを捨てる「STOP」

「せっかくここまでルールを書いたのだから」
「あと一行修正すれば動くはずだ」

この心理こそが、ベルナー・オーバーラントの脇道で感じた「進む誘惑」、すなわちサンクコストのバイアスでした。

混濁する思考を救ったのは、かつての教訓から学んだ「STOP」の原則です。

  • S (Stop):
    • キーボードを叩く手を止め、一旦モニターから目を逸らす。
  • T (Think):
    • 「なぜ、本来無関係なログが出るのか?」という根本に立ち返る。
  • O (Observe):
    • 自分の呼吸が浅くなっていること、そして「何か食べて落ち着こう」と、判断する。
  • P (Plan):
    • 復旧策はそこからでも遅くない、と計画する。

炭酸水で出したお茶を飲み、空腹を満たして一息ついたとき、ようやく冷静な判断が戻ってきました。

「今の自分は、壊れた防衛線を直そうとして、さらに傷を広げている」と。

ここで私は、事前に取っておいたバックアップによる「切り戻し」を決断します。設定を完全に修正前の状態へロールバックしたのです。

失敗の原因:「ModSecurityの干渉」

真っ新な状態に戻って観察して、ようやく原因が見えてきました。ModSecurity の phase:1deny を行うと、Apache の処理サイクルがその時点で中断してしまいます。

本来、Apache側で「このUser-Agentならログを出さない」という env=!dontlog の判定を通る前に、WAF側の処理が割り込んだことで、ログ制御のフラグ管理がバイパスされていたのです。

次のアプローチ:Apacheレイヤーでの「入口断絶」

WAFに固執するのをやめ、より手前の Apache レイヤー(mod_rewrite)で、物理的に遮断とログ抑制を同時に行う作戦に切り替えました。

また、ボットが「カンマ」を「読点()」に変えてフィルターを回避しようとする動きも見せたため、それらも網羅する正規表現に強化しました。

修正後の設定(.conf)

<IfModule mod_rewrite.c>
    RewriteEngine On

    # 1. パスと異常なクエリ(タグ3つ以上のスタッキング)を特定
    SetEnvIf Request_URI "^/projects/hoge" is_target_path
    SetEnvIf Query_String "tag=.(%2c|,|%e3%80%81).(%2c|,|%e3%80%81).(%2c|,|%e3%80%81)" bad_bot

    # 2. 条件一致ならログを抑制(dontlog)しつつ、404で追い返す
    RewriteCond %{ENV:is_target_path} 1
    RewriteCond %{ENV:bad_bot} 1
    RewriteRule ^ - [E=dontlog:1,R=404,L]
</IfModule>

成功:ログの静寂

この設定を反映した結果、効果は絶大でした。

  • 採取ボット:
    • 404を返されつつ、dontlog によってアクセスログから完全に姿を消しました。
  • 正規ユーザー:
    • 普段通り 200 OK でアクセスでき、ログも正しく記録されます。
  • Googlebot:
    • 以前のように、音もなく巡回を続けています。

一度すべてを白紙に戻す「勇気」が、結果として最短ルートでの解決を導いたのです。

まとめ

きちんとした手順に則ったリリース作業などと違い、個人でやっているサイト運営は「このぐらいなら大丈夫だろう」が甚大な被害を生むことが多々あります。

これこそ、

  • プログラム1つの更新
  • 設定ファイルの修正
  • コマンドミス

などで、サーバは瓦解します。しかも、自分の指先一つで壊れるのですから、何があっても

誰かのせいにしたいが自分の顔しか思い浮かばない
I'm casting around in my head for someone to blame and it's just me, keeps coming back at me.

と筆者が冒頭で述べたことであり、『むこうぶち』で江崎が言った

「船が陸にたどり着く寸前に生憎の嵐……
どうすればいいと思います?
いったん沖に引き返すんですよ
船ってのは水に浮かぶようにできているんです
無闇に上陸を焦って座礁する事が一番怖い」

を自分が引き合いに出しておきながらそれを無視したという超特大のブーメランが自分に向かって飛んできたというお話しでした。

可搬性とサイズダウン(弁当メモ)

ランチバッグを新調したことで弁当箱もサイズアップしましたが……

「やはり鞄の中でずれてしまい傾く」リスクがあったので、

この、丸い縦型に戻りました。ややサイズダウンは否めませんが、ここのところ体重も増えてきたのでちょうどいいサイズと見ます。

今回の副菜は、いつものポテサラよりも大きく簡便化。

  • 中華クラゲ
  • 切り落としのサラダチキン
  • カニカマ
  • 刻みネギ

以上。ネギ以外の全てに味がついているので

単に混ぜるだけというのもお気に入りです。

桜と魚。

平日の休みで軽い花見と昼食。

今回、試したレンズは頂き物の

汎用ズームレンズとキャップレンズのフィッシュアイです。

愛宕神社の桜

いつものレンズと勝手が違ったという印象。これはもう少し精進が必要です。

葛西臨海水族園

おなじみのフィッシュカクテル。季節に合わせて桜のソーダと甘み、クラゲの水まんじゅうをチョイス。

  • 醤油風味のマグロのナゲットという他では見られないチョイス
  • 大容量のフライヤーと常に循環する油による抜群の油の切れ
  • 人が絶えない場所柄、常に揚げたてが提供される

それで650円という絶妙なチョイスにより、ここの隠れた人気メニューまで見えます。

なお、フィッシュアイでの水槽が取れたので満足でした。

Page 1 of 288

Powered by WordPress & Theme by Anders Norén