Mod_Securityの連携。(検知した怪しい挙動とtor出口リストをブロックする)

個別に走らせていたスクリプトを1つにまとめました。

前提

  • Apache / Mod_Security導入済み
  • サイトのログローテーションが毎日であること

スクリプト

スクリプトの動き

  1. Tor出口リストを公式からダウンロードします。
  2. このリストからIPアドレスだけを抽出します。
  3. 変数に従ってエラーログからMod_Securityが検知したIPアドレスだけを抽出します。
  4. これらをMod_Securityのnegativelistに入れ、以下のサイトアクセスを丸ごと弾きます。
    • Tor出口リストに登録されているIPアドレス
    • Mod_Securityが検知したIPアドレス
  5. 自分の偽陽性を防ぐため、自分のゲートウェイなどのIPアドレスからのアクセスは除外します。
  6. リストを反映させるためApacheを再起動します。

スクリプト内容

#!/bin/bash
# このスクリプトは、Tor出口ノードリストをダウンロードし、特定のログファイルからIPアドレスを抽出して処理します。
# 使い方: このスクリプトを実行することで、最新のTor出口ノードリストを取得し、ログファイルから抽出したIPアドレスと照合します。
# 結果は指定されたディレクトリに保存され、Apacheが再起動されます。
# cronでの指定例: 毎日午前2時に実行する場合 -> 0 2 * * * /path/to/this_script.sh

# === 変数の定義 ===

# 出口ノードリストのURL
TOR_EXIT_LIST_URL="https://check.torproject.org/exit-addresses"

# ダウンロード先ファイル名
OUTPUT_FILE="/hoge/script/log/node_list/exit_nodes.$(date +%Y%m%d).txt"

# 各サイトのログディレクトリ
log_dirs=("/var/log/bookstack")  # 各サイトのログディレクトリを指定

# エラーログファイル名
log_file="bs_error.log"

# Tor出口ノードリストのディレクトリ
tor_list_dir="/hoge/script/log/sorted_list"  # tor_list.txtのディレクトリを指定

# Tor出口ノードリストのファイル名
tor_list_file="sorted_ip_addresses$(date +%Y%m%d).txt"

# 除外するIPアドレスをファイルで指定
exclude_ips_file="/hoge/script/log/exclude_ips.txt"

# 共通の出力ログディレクトリ
output_log_dir="/hoge/script/log"

# === Tor出口ノードリストのダウンロードと処理 ===

# curlを使用してリストをダウンロード
curl -o "$OUTPUT_FILE" "$TOR_EXIT_LIST_URL" >/dev/null 2>&1

# ダウンロードが成功したかどうかを確認
if [ $? -eq 0 ]; then
echo "Tor出口ノードリストをダウンロードしました。ファイル: $OUTPUT_FILE"
else
echo "ダウンロード中にエラーが発生しました。"
exit 1
fi

# IPアドレスのみを抽出し、ソートして出力
awk '/^ExitAddress/ {print $2}' "$OUTPUT_FILE" | sort -u | tee "$tor_list_dir/$tor_list_file" >/dev/null 2>&1

# === 各サイトのエラーログからIPアドレスを抽出して処理 ===

for log_dir in "${log_dirs[@]}"; do
cd "$log_dir"
awk '/ModSecurity/ && match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) { print substr($0, RSTART, RLENGTH) }' "$log_file" | sort -u > "$output_log_dir/suspicious_ip/suspicious_ip.$(date +%Y%m%d)"
done

# 過去のIPアドレスを読み込んで重複を排除し、ファイルに保存
cat "$output_log_dir/suspicious_ip/suspicious_ip."2* | sort -u > "$output_log_dir/suspicious_ip_all.txt"

# 新たにリストに書き起こすと同時に別のログファイルを読み込んで重複を排除し、negativelist.txtに追加
cat "$output_log_dir/suspicious_ip_all.txt" "$tor_list_dir/$tor_list_file" | sort -u > "$output_log_dir/negativelist.txt"

# 除外するIPアドレスをファイルから削除
while IFS= read -r exclude_ip; do
sed -i "/$exclude_ip/d" "$output_log_dir/negativelist.txt"
done < "$exclude_ips_file"

# Apacheを再起動
systemctl restart apache2.service

スクリプトの他に用意するもの

  • exclude_ips.txt
192.168.0.1
nnn.nnn.nnn.nnn

など、エラーログから除外したいIPアドレスのリストを作ります。

  • バーチャルサイトの編集

/etc/apache2/site-available 配下のバーチャルサイトの設定ファイルを以下のように追記します。

    # Mod_Security設定
    SecRuleEngine On

    SecRule REMOTE_ADDR "@pmFromFile negativelist.txt" "phase:1,id:2,deny,msg:'Negativelisted IP address'"
  • スクリプトが生成したファイルへのシンボリックリンク
sudo ln -sf /hoge/script/log/negativelist.txt /etc/apache2/sites-enabled/negativelist.txt
  • cron設定
sudo crontab -e -u root

として、

0 2 * * * /path/to/this_script.sh

等と設定すれば、毎日2時に、その日に検知した怪しい動きをシャットダウンしてくれます。

『ライザのアトリエ3』2024/09/20のアップデートで変わったこと。(ネタバレあり)

『ライザのアトリエ』シリーズ5周年を記念して配布された「快適化アップデート」。

特に『ライザのアトリエ3』のゲーム進行で特に重要になったアップデートがいくつかありましたので、そのメモです。

難易度『Very Easy』の追加

シリーズに不慣れな方でも楽しめる難易度が追加されました。本作は難易度指定の実績が存在しないので、実績解除を手早くやりたい方向けとなっています。

ランドマーク『カラの天幕』の追加

異界オーリムでイベントの中心地となる『カラの天幕』がランドマーク化。

ウィンドルでのはしごの上り下り地味に面倒なので、これは嬉しいアップデートです。

https://atelier.reisalin.com/issues/661

とはいえ、新規ランドマーク扱いなので、既に訪れている場合でも、改めて訪れる必要があります。(恐らく実績にカウントされるでしょうが、必ず訪れるランドマークなので無視できるレベルです)

キャラクタークエスト『3つの薬』の条件が大幅緩和。

これが個人的に一番大きいものです。

ストーリー終盤で低品質のアイテムを作ることになった、ある意味で最難関クエスト。(特に秘密シリーズを通しでプレイしている人ほど陥る罠)

アップデート前は

  • 品質50未満
  • 品質51~100以下
  • 品質101以上

の「隠者の軟膏」をそれぞれ用意する必要がありましたが、

  • 品質200未満
  • 品質201~400以下
  • 品質401以上

と、それぞれの足切りラインが大幅に緩くなりました。

https://atelier.reisalin.com/issues/580

備考

  • このクエストを達成済みの場合は、任務がキャンセル扱いになることはありません。
  • このクエストを受諾できるまでストーリーが進行していない(周回プレイ含む)状態で適用されます。

他のアップデートによる修正は他にもあります(フェイタルドライブの早送りなど)が、上記3つが特に大きい内容です。

NextcloudのDB、照合順序を変更。

NextcloudのインストールでDBを作成す際に

CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

としていました。

運用中、より正確な比較やソートが必要という判断をしたのでDBの照合順序をci(Case Insentive)ではなく、bin(Binary)に変更します。

DBを操作するため、作業前後にメンテナンスモードに入るとともに、ユーザーへの周知は徹底して行ってください。

メンテナンスモードを実行

  • Nextcloudのルートディレクトリ移動
cd /var/www/html/nextcloud && pwd

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

  • メンテナンスモード有効化
sudo -u www-data php occ maintenance:mode --on
  • メンテナンスモード確認

運用中のNextcloudのURLにアクセスし、メンテナンスモードであることを確認します。

mysqldumpでバックアップを取得する

  • 作業ディレクトリに移動
cd /hoge && pwd

任意のディレクトリを指定します。

  • DBバックアップ作成
mysqldump -h localhost -u nextcloud -p --no-tablespaces --single-transaction nextcloud > nextcloud_backup.$(date +%Y%m%d).sql

DB名やユーザーは自分の環境に合わせます。

  • DBバックアップ作成確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql

ファイルがあることを確認します。

DB設定変更

  • 管理者権限でMySQLにログインする
mysql -u root -p
  • 対象のDBを確認する
SHOW DATABASES;

nextcloudが動いているDBであることを再確認してください。

  • データベース全体の照合順序を変更する
ALTER DATABASE nextcloud COLLATE utf8mb4_bin;
  • 既存のデーテーブルの照合順序を変更する
USE nextcloud;
SET @DATABASE_NAME = 'nextcloud';

DB名は自分の環境に合わせます。

SET @COLLATE = 'utf8mb4_bin';
SELECT CONCAT('ALTER TABLE ', TABLE_NAME, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE ', @COLLATE, ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @DATABASE_NAME
AND TABLE_TYPE = 'BASE TABLE';
  • MySQLから抜ける
EXIT

メンテナンスモードの解除を実行

  • Nextcloudのルートディレクトリ移動
cd /var/www/html/nextcloud && pwd

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

  • メンテナンスモード無効化
sudo -u www-data php occ maintenance:mode --off
  • メンテナンスモード確認

運用中のNextcloudのURLにアクセスし、普通にアクセスできることを確認します。

切り戻し

何か不具合があった場合の切り戻し手順です。上記、メンテナンスモードを有効化してから行ってください。

  • バックアップしたDBがあることを再確認する
ls -l /hoge/nextcloud_backup.$(date +%Y%m%d).sql

バックアップを行ったディレクトリを指定します。

head -100 /hoge/nextcloud_backup.$(date +%Y%m%d).sql

ファイルがあること、平文で読めることを確認します。

  • 管理者権限でMySQLにログインする
mysql -u root -p
  • 対象のDBを確認する
SHOW DATABASES;

nextcloudが動いているDBであることを再確認してください。

  • 不具合が発生したDBを削除する

二回ほど深呼吸して、落ち着いて作業しましょう。

DROP DATABASE nextcloud;
  • DBを再作成する
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  • MySQLから抜ける
EXIT
  • DB復元

mysql -h localhost -u nextcloud -p nextcloud < /hoge/nextcloud_backup.$(date +%Y%m%d).sql

この後、メンテナンスモードを解除して、以前と同じ状態か確認します。

作業後:バックアップDBの削除

平文でSQLがサーバ上にあるのは危険な状態なので、以下の措置を執ります。

  • 作業ディレクトリに移動
cd /hoge && pwd

バックアップを行ったディレクトリを指定します。

  • DBバックアップ確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql

ファイルがあることを確認します。

  • バックアップしたDBの削除
rm nextcloud_backup.$(date +%Y%m%d).sql
  • DBバックアップ削除確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql

ファイルが無いことを確認します。

袋とペンケース。

新たな文具入れを作ってもらいました。

大きめの巾着袋です。こちらに入るのは

  • ジブン手帳
  • ほぼ日Weekly
  • 情報カードホルダー
  • サブのペンケース。

表、裏ともに贅沢に芯地を使って丈夫さは相当のもの。

それだけにとどまらず、

今年作ってもらったペンケースと同じ裏地が使われています。

  • ペンケース
  • ほぼ日(オリジナル)

と合わせ、日常の文具セットが統一です。

Linuxサーバの履歴を追いやすくする設定。

初期設定の機会が多くなったので、改めてメモをします。

「いつ、どのような操作をしたか」を追いやすくするために以下の設定を行います。

sudo tee -a /etc/profile.d/history.sh > /dev/null << 'EOF'
export HISTSIZE=50000
export HISTFILESIZE=50000
export HISTTIMEFORMAT='%Y/%m/%d %H:%M:%S '
EOF
  • 全ユーザーでhistoryコマンドの履歴を5万行に引き上げます。
  • コマンド実行した日付を記載します。

設定後、新しいシェルセッションを開始するか、

source /etc/profile.d/history.sh

を実行することで上記が反映されます。

設定後、

history

実行後、

 1964  2024/09/17 15:12:18 cd /mnt/wasabi/
 1965  2024/09/17 15:12:19 ll
 1966  2024/09/17 15:12:24 cd redmine/
 1967  2024/09/17 15:12:24 ll
 1968  2024/09/17 15:12:27 cd files/
 1969  2024/09/17 15:12:27 ll
 1970  2024/09/17 15:12:31 pwd
 1971  2024/09/17 16:27:20 cd 
 1972  2024/09/17 16:27:24 sudo aptitude update
 1973  2024/09/17 16:28:35 sudo aptitude upgrade
 1974  2024/09/17 16:30:23 sudo reboot
 1975  2024/09/17 16:33:05 df -h
 1976  2024/09/17 17:25:47 cd script/
 1977  2024/09/17 17:25:47 ll

のように、日付と時間入りでコマンド操作履歴が表示されます。

ボードゲーム『ポンペイ滅亡』ルール。

ボードゲーム『ポンペイ滅亡』、個人的に遊ぶことが多いために、以下、ルールの覚え書きです。

前準備

ボードの準備

  1. ゲームボード(グリッドが描かれたポンペイの地図)を広げます。
  2. ボードの穴が空いている部分に「ヴェスヴィオス火山」を組み立てて置いておきます。

コマの準備

  • 2~3人:各プレイヤーに30個のコマを配ります。
  • 4人:各プレイヤーに25個のコマを配ります。

火山タイルの準備

2013年の再販版なら、

  • 溶岩タイル45枚(片面プリント)
  • 溶岩タイル3枚(両面タイル)

があります。基本ルールでは45枚の片面プリントを全て袋に入れておきます。

デッキの準備

『パンデミック』のように、ある程度操作されたデッキを用います。

  • 市民が描かれたカード×53
  • 前兆(Omen)カード×7
  • A.D.79カード×2

を分けておきます。

  1. 市民カードを4枚ずつ、7個の束に分けます。(28枚)
  2. 残りの25枚の市民カードに前兆(Omen)カード7枚を入れて良くシャッフルします。
  3. シャッフルした前兆(Omen)カード入りのデッキを、以下のように処理します。
2~3人の場合

シャッフルした前兆(Omen)カード入りのデッキから下15枚を抜き出し、そこにA.D.79カード1枚を入れてシャッフル。残り17枚をその上に置きます。

4人の場合

シャッフルした前兆(Omen)カード入りのデッキから下15枚を抜き出し、そこにA.D.79カード1枚を入れてシャッフル。残り22枚をその上に置きます。

これが、後半戦トリガーのデッキになります。この上に、残りのA.D.79カードを1枚載せておきます。(表にしておいた方が良いでしょう)

更にその上に最初に切り分けた4枚の7つの束から2つを置きます。

全体の構造を上から

2~3人4人
4枚の束4枚の束
4枚の束4枚の束
A.D.79カードA.D.79カード
前兆(Omen)カードが入っていて、A.D.79カードが入っていない17枚の束前兆(Omen)カードが入っていて、A.D.79カードが入っていない22枚の束
前兆(Omen)カードが入っていて、A.D.79カードが入っている15枚の束前兆(Omen)カードが入っていて、A.D.79カードが入っている10枚の束

手札の配布

  • 最初に切り分けておいた4枚の束を1つ、各プレイヤーに渡して初期手札とします。
  • 選ばれなかった束(1~3)は箱にしまいます。

こうして、適当なプレイヤーからゲームを進めます。

前半-1-入植フェイズ

  1. 各プレイヤーは手番ごとにカードを1枚公開し、そこの番号に一致するエリアにコマを置いていきます。
  2. 置いたらデッキからカードを1枚、上から引いていきます。

この手番を続け、最初の「A.D.79カード」が公開されたら前半2に進みます。

前半-2-縁者と予兆

  1. 各プレイヤーは手番ごとにカードを1枚公開し、そこの番号に一致するエリアにコマを置いていきます。
  2. この時、自分のコマを置く前の、既に置かれている番号にいるコマを数えます。
  3. その、既に置かれているコマの一人同じぶんだけ、「他の共通するエリア」and/or「何も番号が書かれていない中立地帯」に自分のコマを置いていきます。(例えば、3番にコマを置きます。そこには2つのコマが置かれていました。なので、色を共通する2番のエリアや何も数字が書かれていないエリアに2つのコマを望むように割り振っておいておきます)
  4. 置いたらデッキからカードを1枚、上から引いていきます。
  5. ここで、「Omen」を引いたプレイヤーはそれを公開し、任意のコマをヴェスヴィオス火山の中に放り込みます。
  6. 続けて「Omen」を引いたら同じ事を繰り返し、「Omen」以外が出るまで繰り返します。

こうして縁者が増えてくると、プレイした番号のエリアに置けないことが多々起きます。そんなときは、ワイルドカードとして、任意のエリアであるかのように扱うことができます。

火山の噴火

以下の条件となったら、火山は噴火します。

  • 誰かがA.D.79カードを引いた
  • 手札全てがワイルドとなった(番号全てがコマで埋まってしまった)

高らかに宣言します。「火山が噴火した!」

火山が噴火したら、

  1. 残っているデッキ
  2. 自分が持っている手札のカード全て
  3. まだ置かれていないコマ

全てを箱に戻します。これらは残りのゲームでは使いません。

この、引いてしまった次のプレイヤーはこれまでのカードとコマではなく代わりに、タイルが入った袋に持ち替えます。

脱出の前の噴火

当時はまだ火山の脅威も知られていません。

なので、「何かヴェスヴィオスで大きな音がした」ぐらいの感覚で、ポンペイ市民は最初は何もしません。

順番に、溶岩タイルを布袋から引いて、グリッドに置いていきます。

コイン、巻物、青銅などがマップに描かれています。最初にそれらのマーク入りの溶岩タイルを引いたプレイヤーは、まずはそのマップの目印に目指してタイルを置いていきます。

これを、6回繰り返します。

その際に、同じマークのタイルを引いた場合は、既に置かれているタイルに隣接するようにタイルを置きます。この、置いた先にコマがあったら、それら全てをヴェスヴィオス火山に放り込みます。(つまり、溶岩の餌食となりました)

相手のいるコマに容赦なくぶつけるのも、ヘイト管理のため見逃すのも、全てはプレイヤーの意志にかかっています。

脱出

6枚のタイルが置かれたら、いよいよ市民達(コマ)は脱出を決意します。

マップ各所に描かれている門を目指していき、脱出したコマがそのまま得点になります。

  1. 袋からタイルを引いて、マークの隣接するグリッドに置く
  2. 市民コマを脱出させる

のサイクルを繰り返します。

溶岩配置のルール

  1. 上述したように、マークが描かれて、既に配置されている所に隣接しているところにタイルを置きます。
  2. この置いたところにコマがあったら、それら全ては火山の餌食に遭いました。マップにある火口にそれらコマを放り込みます。
  3. ゲームが進んで行くにつれ、溶岩タイルが完全にグリッド内にあるコマを閉じ込める場合があります。そうして囲まれた中で入り口がどこにもない場合は、閉じ込められたコマは全て蒸し焼きになります。やはり、ヴェスヴィオス火山が平らげます。

脱出のルール

  • プレイヤーがタイルを置いた後、逃がすチャンスのある(動かせる)コマは2つです。
  • コマは、上下左右にしか動けません。(斜めに動かすことはできません)
  • マップ外壁に描かれている門の外に出たプレイヤーが脱出です。門の手前ではないことに注意してください。
  • コマが動ける数は、そのグリッドにいたコマの数です。
    • グリッドに2つのコマがあった:1つのコマは2マス進めます。
    • グリッドに1つのコマしかない:コマは1つしか勧めません。
動かせる駒の例外
  1. ゲームも終盤も終盤、動かせるコマが1つしかない場合は、2回動けます。
  2. 移動した先に他のコマが既にいた場合、そのコマは「彼等を盾として」、その先にいたコマの数(自分含む)の分だけ移動できます。

噴火&脱出

このサイクルを繰り返し、自分のコマが全ていなくなった(脱出/火山に放り込まれた問わず)としても、ゲームは続きます。その場合は火山タイルを被害が大きくなるように置いていくでしょう。

  • 盤面から全てのコマがいなくなった
  • タイルが尽きた

のどちらかでゲームが終了です。なお、タイルが尽きた際にまだポンペイ市街にコマがいたとしても、これらは火山に放り込まれます。

終了と得点計算

各プレイヤーは、逃げ延びたコマの数を数えます。その数が一番多いプレイヤーの勝利です。

多く脱出させたプレイヤーが同数いる場合、火山に放り込まれたコマの数を数えます。死者が少ない(コマが少ない)方が勝利します。

それも同じだった場合は「歴史を繰り返しましょう」。

バリアント

公式:両面タイル

別に分けていたタイルを一緒に袋に入れておきます。ゲーム中、それらの両面タイルを引いたプレイヤーは、どちらのサイドでも使えます。

非公式ハウスルール: ミープル差し替え

ゲーム本体はコマは筒状です。そこで、ミープルに差し替えることで、「今入植させているのは/脱出させているのは」とよりリアリティを出します。

非公式ハウスルール:火山の神、降臨

5人目には「ヴェスヴィオス火山の神」になってもらいます。

  • 予兆(Omen)でどのコマが投げ込まれるか
  • 火山タイルをどこに配置するか

を、その5人目全てが取り仕切ります。

つまり、溶岩タイルがどこに向かうかは神の機嫌次第です。怒りを買わないようなプレイングを心がけましょう。

ボードゲーム『ポンペイ滅亡』改めての感想。

Cave! Hoc ludus ex rebus veris motus est. (注意! このゲームは実際の出来事をモチーフにしています)

コンポーネントもルールも全てが不謹慎。デザイナーが『カルカソンヌ』の作者であることを説明すると更に驚かれること間違い無しの作品です。

概要

「A.D.79 イタリア」この年号にピンとくる歴史好きは多いことでしょう。

紀元79年8月24日、たった一夜で(文字通り)埋もれてしまったポンペイの歴史を追体験するゲームです。

ルール

  • 都市に市民を入植させていく前半
  • 火山の噴火から市民を脱出させる後半

に分かれていて、最終的に脱出させた自コマが多いプレイヤーが勝利します。

前半:入植フェイズ

カードをプレイし、示された地図のグリッドにコマを置いておきます。

最初の「A.D.79」がデッキから公開されたら、入植者は次々に縁者を呼び寄せていきます。(別の共通するグリッドや他の色に更に駒を置くことができます。

この時、前兆となる「Omen」カードを引いたら任意のコマを火山に投げ入れることができます。

後半: 逃亡フェイズ

2枚目の「A.D.79」がデッキから公開された→ヴェスヴィオスの大噴火。

ゲームは後半戦にスタート。今まで持っていたカードや置かれていないコマを全て箱に戻し、全く別のゲームが始まります。

迫り来る溶岩タイルがポンペイ市街に降り注ぎ、被害は拡散していきます。

溶岩タイルをルールに従って配置し、出口である門の外へとコマを移動させるフェイズです。

  • 溶岩タイルがグリッドに直撃した → 当然、市民はヴェスヴィオスの餌食になります。
  • グリッドが溶岩タイルに囲まれた → ヴェスヴィオス火山はその範囲内のコマ全てを平らげます。

そして、全てのコマが地図からいなくなったり溶岩タイルで埋められたらゲーム終了です。

このゲームの好きなところ

インパクト

  • 名前
  • 箱絵
  • ポンペイの地図が描かれたゲームボード
  • ひときわ異彩を放つ立体のヴェスヴィオス火山
  • ゲーム進行

等すべてに出落ち感が満載。歴史にある程度触れているならお察し案件になることもインパクトを増大させます。

言語依存がないルール

『カルカソンヌ』と同じデザイナーということもあって、言語依存は極めて少なく、没入感に溢れたゲーム進行が出できます。

脱出ルールに少し説明が必要ですが、「他の市民を盾にして逃げる」とイメージさせやすいです。

このゲームの問題点

テーマ

「ゲームと現実の区別がつかない方」には徹底的にオススメできないテーマです。不謹慎さが許容できない方へのチョイスは厳に避けるべきです。

入手難易度

テーマの不謹慎さも相まって日本語版が用意されておらず、再販も2013年に一回しかかありません。自分が和訳ルールつきの新品を2018年に手に入れられたのは本当に幸運でした。

まとめ

  • 歴史上のイベントをそのまま再現するかのようなテーマ
  • 比較的インストしやすいルール
  • 不謹慎だけに盛り上がる盤面

など、「こういう方向性のボードゲームもあるんだ」という、自分のその後の作品チョイスの方向性を決定づけたという記念の作品。

2018年に購入して以来、本当に定期的に遊ぶ作品のため改めてレビューいたしました。

おまけ

自宅など、環境が許すなら

  • ジミ・ヘンドリックス
  • マイケル・ジャクソン
  • ムーディー・ブルース
  • プリンス

等の特定の曲/アルバムを流すとニヤリとされます。(この遺跡は漫画『第5部』の戦いの舞台です)

Snipe-ITのデータを別サーバに移行したときにハマったこと。(Ubuntu20.04/v6→Ubuntu24.04/v7)

Snipe-IT のv7からPHP 8.1以降(PHP8.3含む)で動くようになりました。

こちらの方法を用いることでUbuntu24.04でもインストール可能だったことを確認していますが、データ移行はかなりハマりました。

うまくいかなかった手段1:データのバックアップ/リストア機能

Snipe-ITはデータ全体のバックアップとリストア機能を備えていますが、

  • 移行元:Ubuntu 20.04
    • v6
    • PHP8.1
    • Apache2.4
    • MySQL8
  • 移行先:Ubuntu 24.04
    • v7
    • PHP8.3
    • Apache2.4
    • MySQL8

のため、PHPのバージョンが合わないせいかインポート時にエラー発生。再アクセスしようとすると500エラーが発生。

うまくいかなかった手段2:データの移行とSQLリストア

  • firefly-iii
  • BookStack

と同じように、アップロードしたファイルを移行先に持っていき、mysqldumpで取得したファイルをインポートすることでうまくいくのではと思いましたが、これでも500エラーが発生。

お手上げ状態だった時に公式ドキュメントを見ると、答えが書いてありました。

うまくいった手段:keyファイルの上書きとマイグレーション

「手段2:データの移行とSQLリストア」に加えて、これが必要でした。

Moving Snipe-ITによると

Moving/migrating Snipe-IT to a new server should be a pretty painless process. You really only have a few things to worry about:

  • Your .env
  • Your database
  • Your uploaded files
  • Your OAuth keys

とあります。上記サイトにある情報を元に、手順化を行います。

【移行先】Snipe-ITを新たにインストールします。

セットアップを行い、管理者アカウントを作成するところまで進めます。

【移行元】→【移行先】各種データを転送します。

  • SQLのダンプファイル
mysqldump -h localhost -u snipeit -p --no-tablespaces --single-transaction snipeit > snipeit_db.$(date +%Y%m%d).sql

パスワードは移行元のDBパスワードです。取得したダンプファイルは、任意の安全な方法で移行先に転送します。

  • .envのAPP_KEY

移行元先ルートディレクトリ/storage配下にある.envAPP_KEY=base64:移行の文字列を、

移行元のAPP_KEY=base64:のものにそのまま上書きして保存します。

  • ファイルディレクトリ一式の転送

移行元のルートディレクトリ配下

public/uploads
storage/private_uploads

のディレクトリ一式を、同じように移行先に転送した上で、移行先のディレクトリに上書きます。(アクセス権は一致させます)

  • OAuth key

移行元のルートディレクトリ/storage配下にある

oauth-private.key
oauth-public.key

を、移行先の同じディレクトリにコピーして上書きます。

【移行先】DBのリストアとマイグレーションを行います。

これ以降は移行先のみで作業を行います。

  • ダンプファイルのリストア
mysql -h localhost -u snipeit -p snipeit < /path/to/backup/directory/snipeit_db.$(date +%Y%m%d).sql

転送したディレクトリにあるダンプファイルのパスを指定します。

  • Snipe-ITのルートディレクトリに移動
cd /var/www/html/snipe-it && pwd

など、移行先のsnipe-itのルートディレクトリに移動します。

  • DBマイグレーション
sudo -u www-data php artisan migrate

途中のプロンプトはyesを指定します。

  • コンフィグクリア
sudo -u www-data php artisan config:clear

Webサービスを再起動し、データ移行を確認します。

  • Webサービス再起動
sudo systemctl restart apache2.service
  • Webサービス再起動確認
systemctl status apache2.service

active(running)を確認します。

  • データ移行確認
  1. 移行先のSnipe-ITをインストールしたURLにアクセスします。
  2. 移行元のアカウントでログインできることを確認します。
  3. 移行元と同じデータがあることを確認します。

BookStackのサーバ移行でハマったこと。

LAMP環境で動くアプリケーションを移行する際、だいたいは

  1. 移行先でWebアプリを作成する
  2. 移行元から移行先へとデータ(画像や添付ファイル)をコピーする
  3. DBをエクスポート→インポートする

の流れで別サーバへと移行が可能です。BookStackも同じような理屈で移行が行えるかを確かめたところ、罠がいくつかありました。

環境

共通環境

  • Apache 2.4
  • MySQL8系

移行元

  • Ubuntu 20.04
  • PHP 8.1

移行先

  • Ubuntu 24.04
  • PHP 8.3

さっくりといかない手順

  1. 【移行先】BookStackを構築します。
  2. オプション【移行元】アカウントのセキュリティ設定を一度解除します。
  3. 【移行元】→【移行先】画像や添付データ一式を転送します。
  4. 【移行元】→【移行先】MySQLのダンプを行い、DBを転送します。
  5. 【移行先】DBをインポートします。
  6. 【移行先】DBマイグレーションを行います。
  7. オプション【移行先】URLの変更処理を行います。
  8. 【移行先】設定の反映を行います。
  9. 【移行先】移行先で確認を行います。

【移行先】BookStackを構築します。

自サイトで恐縮ですが、手順はこちらをそのまま用いています

オプション【移行元】管理アカウントの二要素認証を解除。

これが一番ハマったポイントでした。

マイアカウント > アクセス&セキュリティ > 多要素認証

で、二要素認証をオンにしていると、移行先でログインができませんでした。

なので、移行時の一時的な措置として解除を行います。

【移行元】→【移行先】データの転送

BookStackのルートディレクトリ配下の

/public/uploads/を一式、移行先へと転送して、同じディレクトリ構造に上書きします。SCPやtarで固める塔、任意の方法で転送します。

このとき、アクセス権をWebサービス実行ユーザにしてください。(Ubuntuのデフォルトはwww-data)

【移行元】→【移行先】DBのデータ移行

mysqldump -h localhost -u bookstackuser -p --no-tablespaces --single-transaction bookstack > bookstack_backup.$(date +%Y%m%d).sql

-h DBサーバ名、-u bookstackのDBにアクセスできるユーザー DB名という形です。DBユーザに設定されているパスワードを入力してダンプを取ります。

こうしてできたDBは、任意の(安全で確実な)方法で移行先に転送します。

【移行先】DBのリストア

  • ディレクトリ移動
cd /hoge && pwd

ダンプしたDBファイルが転送されているディレクトリに移動します。

  • DBインポート
mysql -h localhost -u bookstackuser -p bookstack < bookstack_backup.$(date +%Y%m%d).sql

【移行先】DBのマイグレーション

これもハマったポイントでした。

  • BookStackルートディレクトリに移動
/path/to/BookStack/root/directory && pwd

/var/www/html/BookStackなど、移行先の、BookStackがインストールされているディレクトリに移動します。

  • DBマイグレーション
sudo -u www-data php artisan migrate --force

このマイグレーションを行わないと、リストアしたDBを参照してくれませんでした。

オプション【移行先】URL変更処理

サーバのURLを変える場合はここにも罠があります。BookStackの設定ファイル、.env

# Application URL
# This must be the root URL that you want to host BookStack on.
# All URLs in BookStack will be generated using this value
# to ensure URLs generated are consistent and secure.
# If you change this in the future you may need to run a command
# to update stored URLs in the database. Command example:
# php artisan bookstack:update-url https://old.example.com https://new.example.com

という但し書きがありますので、この処理を行います。

  • BookStackルートディレクトリに移動
/path/to/BookStack/root/directory && pwd
  • URLアップデート
sudo -u www-data php artisan bookstack:update-url https://old.example.com https://new.example.com

二回ほど確認されますので、両方とも「yes」で答えます。

DB上書き反映

  • BookStackルートディレクトリに移動
/path/to/BookStack/root/directory && pwd
  • キャッシュクリア
sudo -u www-data php artisan cache:clear
  • Webサービス(apache)再起動
sudo systemctl restart apache2.service
  • Webサービス(apache)再起動確認
systemctl status apache2.service

active(running)を確認します。

サーバ移行確認

  1. ブラウザで移行先のURLにアクセスします。
  2. ログインできることを確認します。
  3. 前のデータ(画像や添付含む)が閲覧できることを確認します。
  4. 記事の作成等が行えることを確認します。
  5. 多要素認証をしている場合は、再設定します。

Mod_Securityで特定のルールを無視する設定(Nextcloudでの偽陽性を排除)

Nextcloudにmod_securityを導入するに当たり、気をつけなければならないのがファイルの閲覧や登録、入力処理中にMod_securityが不審な処理として判断してしまうこと(偽陽性)です。

そこで、

  1. 偽陽性と思われるログの調査
  2. 調査時の補助線引き
  3. 偽陽性になるルールを無視する設定

を行います。

ログ確認

/var/log/nextcloud_error.logから、以下のようなログを見ました。

[Wed Sep 11 16:35:02.048442 2024] [security2:error] [pid 32762:tid 32762] [client aaa.bbb.ccc.ddd:56994] [client aaa.bbb.ccc.ddd] ModSecurity: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "/usr/share/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "92"] [id "980130"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): individual paranoia level scores: 5, 0, 0, 0"] [ver "OWASP_CRS/3.3.5"] [tag "event-correlation"] [hostname "nextcloud.hoge.com"] [uri "/ocs/v2.php/apps/user_status/api/v1/heartbeat"] [unique_id "ZuFIJU_udFaqxqrJvRLaPQAAAAA"]

ここで見たいのは

  • クライアントのIPアドレス
  • どのようなルールIDを
  • どのぐらい検知したか

です。

ログ確認のワンライナー

これらを確認するため、copilotの助けを借りてawkスクリプトを生成します。

awk '/ModSecurity/ {
ip = gensub(/.*\[client ([0-9.]+):.*/, "\\1", "g", $0);
rule_id = gensub(/.*\[id "([0-9]+)"\].*/, "\\1", "g", $0);
print rule_id, ip;
}' /var/log/nextcloud/nextcloud_error.log | sort | uniq -c

これを実行したところ、Mod_Securityがエラーとして検知したログの中から

     36 911100 127.0.0.1
    267 911100 aaa.bbb.ccc.ddd
     65 920420 aaa.bbb.ccc.ddd
     36 949110 127.0.0.1
    267 949110 aaa.bbb.ccc.ddd
     36 980130 127.0.0.1
    267 980130 aaa.bbb.ccc.ddd

という結果を確認しました。127.0.0.1はローカルアドレス、aaa.bbb.ccc.dddも自分がアクセスしてきたIPアドレス。この間、自分がしていたのはNextcloudの設定変更やファイルの閲覧のみです。

Mod_securityが検知したルールIDを「偽陽性」と判断し、処置していきます。

Mod_Securityで特定のルールを検知させない処理

Apacheのバーチャルサイトで設定しているという形です。

設定ファイルの修正

  • ファイルのバックアップ
sudo cp -ci /etc/apache2/sites-available/nextcloud.conf /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d)

設定ファイルやバックアップディレクトリは自分の環境に合わせます。

  • バックアップ確認
diff -u /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d) /etc/apache2/sites-available/nextcloud.conf

エラー無く、差分も表示されていなければバックアップは成功です。

  • ファイル修正

/etc/apache2/sites-available/nextcloud.confを以下のように修正していきます。(要root権限)

# Mod_security
## 最初は検知モード

SecRuleEngine DetectionOnly

## 偽陽性と判断したID
SecRuleRemoveById 911100
SecRuleRemoveById 920420
SecRuleRemoveById 949110
SecRuleRemoveById 980130
  • ファイル修正確認
diff -u /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d) /etc/apache2/sites-available/nextcloud.conf

SecRuleRemoveById IDで、これにマッチするパターンは無視します。

  • 差分例
 ## 最初は検知モード

 SecRuleEngine DetectionOnly
+
+## 偽陽性と判断したID
+SecRuleRemoveById 911100
+SecRuleRemoveById 920420
+SecRuleRemoveById 949110
+SecRuleRemoveById 980130
+
 </VirtualHost>

設定ファイルの設定反映

  • 構文確認
sudo apache2ctl configtest

Syntax OKを確認します。

  • 設定反映
sudo systemctl restart apache2.service
  • Apache稼働確認
systemctl status apache2.service

active(running)を確認します。

動作確認

ターミナルで

tail -f /var/log/nextcloud/nextcloud_error.log

としてエラーログを流します。(エラーログは自分の環境に合わせます)

  • 上記処理を行ったNextcloudにアクセスして操作をしていきます。
  • 処理を行ったIDが検知されないことを確認します。

Page 7 of 237

Powered by WordPress & Theme by Anders Norén