タグ: Ubuntu Page 1 of 12

Ubuntu 24.04に設定したMod_Securityでファイルアップロードエラーを退避。

事象

Redmineでクリップボードの画像を貼り付けようとした際、画像のアップロードができませんでした。

そこで、エラーログを確認したところ、以下のメッセージが表示されました。

ModSecurity: Request body no files data length is larger than the configured limit (131072). [hostname "redmine-url"] [uri "/uploads.js"] [unique_id "Zv0wom0FwSak1tXDUgFRLAAAAAw"], referer: https://redmine-url/issues/3

環境

  • Ubuntu 24.04
  • Apache 2.4
  • Mod_Security 2
  • Redmine 5.1

確認したこと

バーチャルサイトのMod_Securityの設定

SecRequestBodyInMemoryLimit 524288000
SecRequestBodyLimit 524288000

と、50MBはアップロードできるようになっています。

Redmineでアップロード可能なファイル容量

管理> 設定 > ファイルの「添付ファイルサイズの上限でも`51200KB`を確認。

Mod_Security Confファイル確認

`cat /etc/modsecurity/modsecurity.conf |grep Limit` の結果、以下を確認しました。

SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyInMemoryLimit 131072
SecRequestBodyLimitAction Reject
SecRequestBodyJsonDepthLimit 512
SecPcreMatchLimit 100000
SecPcreMatchLimitRecursion 100000
SecResponseBodyLimit 524288
SecResponseBodyLimitAction ProcessPartial

原因

`/etc/modsecurity/modsecurity.conf`の設定がバーチャルサイトの設定にオーバーライドしたため、こちらの設定が上書きされた模様です。

これを変更していきます。

対応手順

ファイルバックアップの作成

sudo cp -pi /etc/modsecurity/modsecurity.conf /path/to/backup/directory/modsecurity.conf.$(date +%Y%m%d)

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

バックアップ作成確認

diff -u /path/to/backup/directory/modsecurity.conf.$(date +%Y%m%d) /etc/modsecurity/modsecurity.conf

バックアップできていること(差分がないこと)を確認します。

sedによる書き換え

sudo sed -i 's/SecRequestBodyNoFilesLimit 131072/SecRequestBodyNoFilesLimit 52428800/; s/SecRequestBodyInMemoryLimit 131072/SecRequestBodyInMemoryLimit 52428800/; s/SecRequestBodyLimit 13107200/SecRequestBodyLimit 52428800/' /etc/modsecurity/modsecurity.conf

ファイル書き換え確認

diff -u /path/to/backup/directory/modsecurity.conf.$(date +%Y%m%d) /etc/modsecurity/modsecurity.conf

以下の差分を確認します。

-SecRequestBodyLimit 13107200
-SecRequestBodyNoFilesLimit 131072
+SecRequestBodyLimit 52428800
+SecRequestBodyNoFilesLimit 52428800
 
 # Store up to 128 KB of request body data in memory. When the multipart
 # parser reaches this limit, it will start using your hard disk for
 # storage. That is slow, but unavoidable.
 #
-SecRequestBodyInMemoryLimit 131072
+SecRequestBodyInMemoryLimit 52428800

設定反映

sudo systemctl restart apache2.service

書き換え後、無事にファイルのアップロードができることを確認しました。

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時に、その日に検知した怪しい動きをシャットダウンしてくれます。

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

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

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が検知されないことを確認します。

Ubuntuサーバ、コマンドラインでのパスワード入力時にアスタリスクを表示する。

運用の好みの問題です。

sudo su -

環境

  • Ubuntu 20.04 / 22.04 / 24.04

等でrootに昇格する際、入力されたかを確かめる*を表示するようにして視認性を高めます。

既存ファイルのバックアップ

  • 設定ファイルバックアップ
sudo cp -pi /etc/sudoers /path/to/backup/directory/sudoers.$(date +%Y%m%d)

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

  • バックアップ確認
sudo diff -u /path/to/backup/directory/sudoers.$(date +%Y%m%d) /etc/sudoers

差分が無ければバックアップは成功です。

ファイル書き換え

  • sedによるファイル書き換え
sudo sed -i 's/^Defaults\s\+env_reset$/Defaults env_reset,pwfeedback/' /etc/sudoers
  • 差分確認
sudo diff -u /path/to/backup/directory/sudoers.$(date +%Y%m%d) /etc/sudoers
-Defaults       env_reset
+Defaults env_reset,pwfeedback

設定反映確認

設定を行ったサーバに対して、新しくSSHセッションを作成します。

sudo su -

でパスワードを入力時に*が表示されれば設定は反映されています。

UbuntuサーバにMod_Securityを導入。

ApacheのWAFモジュールであるmod_securityを導入します。

  • AWS Lightsailで早々とインストールしていた
  • 各種不審なIPアドレスを弾くための盾

として機能しているにもかかわらず文書化していなかったので、Web Arenaでの検証を機に文章に残します。

環境

  • Ubuntu 24.04 (20.04でも一応動くとは思います)
  • Apache 2.4

※ パッケージ管理にaptitudeを用いています。必要に応じてaptに読み替えてください。

さっくりとした手順

  1. mod_securityのインストールを行います。
  2. mod_securityの設定を行います。
  3. Apacheのバーチャルサイトにmod_securityを組み込みます。
  4. 設定を反映して動作を確認します。

mod_securityのインストールを行います。

  • パッケージ全体のアップデート
sudo aptitude update
  • mod_securityインストール
sudo aptitude install libapache2-mod-security2
  • インストール確認
sudo apache2ctl -M |grep security
security2_module (shared)

と表示されていることを確認します。

ModSecurityの設定

  • 設定ファイル書き換え
sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

推奨ファイルをそのまま設定ファイルとして書き換えます。

OWASP Core Rule Set (CRS)のインストールと設定

  • ディレクトリ移動
cd /usr/share/modsecurity-crs && pwd
  • ルールセットのダウンロード
sudo git clone https://github.com/coreruleset/coreruleset.git
  • ルールセットの設定書き換え
sudo mv /usr/share/modsecurity-crs/coreruleset/crs-setup.conf.example /usr/share/modsecurity-crs/coreruleset/crs-setup.conf

mod_securityモジュールにCRSを読み込む設定を追記

  • ディレクトリ移動
cd /etc/apache2/mods-available/ && pwd
  • ファイルのバックアップ
sudo cp -pi security2.conf /path/to/backup/directory/security2.conf.$(date +%Y%m%d)

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

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

エラーがなければバックアップは成功です。

  • ファイル追記

/etc/apache2/mods-available/security2.confを、以下の差分になるように教義・信仰に沿ったエディタで編集します。(要root権限)

- </IfModule>
+        # Include OWASP ModSecurity CRS rules if installed
+        IncludeOptional /usr/share/modsecurity-crs/*.load
+</IfModule>
  • 設定追記の整合性を確認
sudo apache2ctl configtest

Syntax OKを確認します。

  • Apache再起動
sudo systemctl restart apache2.service
  • Apache再起動確認
systemctl status apache2.service

active (running) を確認します。

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

稼働済みのApacheバーチャルサイトの設定ファイルをいじります。バックアップ確認は入念に行ってください。

  • ディレクトリ移動
cd /etc/apache2/sites-available && pwd
  • バーチャルサイトの設定ファイルバックアップ
sudo cp -pi your_site.conf /path/to/backup/directory/your_site.conf.$(date +%Y%m%d)

.confファイルやバックアップディレクトリは自分の環境を指定します。

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

エラーがなければバックアップは成功です。

  • ファイル追記

/etc/apache2/sites-available/your_site.confを、以下の差分になるように教義・信仰に沿ったエディタで編集します。(要root権限)

# Mod Security

## ModSecurity有効化
SecRuleEngine On
## ModSecurity検知モード
### 検知モードで動かす場合はSecRuleEngine Onをコメントアウトしてこちらを有効化します
#SecRuleEngine DetectionOnly

## ファイルのアップロードをできるようにします。
SecRequestBodyInMemoryLimit 524288000
SecRequestBodyLimit 524288000

## テスト用の検知パラメータを付け加えます。
    SecRule ARGS:modsecparam "@contains test" "id:4321,deny,status:403,msg:'ModSecurity test rule has triggered'"
  • ファイル差分
diff -u /path/to/backup/directory/your_site.conf.$(date +%Y%m%d) your_site.conf
+# Mod Security
+
+## ModSecurity有効化
+SecRuleEngine On
+## ModSecurity検知モード
+### 検知モードで動かす場合はSecRuleEngine Onをコメントアウトしてこちらを有効化します
+#SecRuleEngine DetectionOnly
+ 
+## ファイルのアップロードをできるようにします。
+SecRequestBodyInMemoryLimit 524288000
+SecRequestBodyLimit 524288000
+
+## テスト用の検知パラメータを付け加えます。
+    SecRule ARGS:modsecparam "@contains test" "id:4321,deny,status:403,msg:'ModSecurity test rule has triggered'"
+
  • 設定追記の整合性を確認
sudo apache2ctl configtest

Syntax OKを確認します。

  • Apache再起動
sudo systemctl restart apache2.service
  • Apache再起動確認
systemctl status apache2.service

active (running) を確認します。

mod_security動作確認

  1. ブラウザで、上記の設定を行ったWebサイトにアクセスし、閲覧できることを確認します。
  2. アドレスバーの末尾に?modsecparam=testを追加してアクセスします。

のように、アクセスできないことを確認します。

また、サーバでも

sudo cat /path/to/sites_log/directory/sites_error.log

※ログの格納場所やログの名前は自分の環境に合わせます。

を開き、

ModSecurity: Access denied with code 403 (phase 2). String match "test" at ARGS:modsecparam. [file "/etc/apache2/sites-enabled/your_site.conf"] [line "53"] [id "4321"] [msg "ModSecurity test rule has triggered"] [hostname "host_address"] [uri "/"] [unique_id "xxxxxxx"]

のように、エラーが発生していることを確認します。

備考

WordPress、Redmine等のWebアプリは自身の操作によって「不審なアクセス」として遮断することが極めてよくあります。(偽陽性)

そのため、テストを行った後は

## ModSecurity有効化
#SecRuleEngine On
## ModSecurity検知モード
### 検知モードで動かす場合はSecRuleEngine Onをコメントアウトしてこちらを有効化します
SecRuleEngine DetectionOnly

として検知モードとして動かした方が良いでしょう。

Ubuntu24.04サーバの初期設定。(ufwとfail2ban)

  • インターネット上に公開されたWebサーバを運営している
  • IPアドレスが固定されていない

場合に必要な措置となる、NW保護を行います。

環境

  • Ubunt 24.04

さっくりとした手順

  • ufwを有効化します。
  • fail2banをインストールします。
  • fail2banの設定をします。

SSHとWeb通信のみを有効化させます。

  • SSH接続を許可するが過度な接続を制限する
sudo ufw limit proto tcp from any to any port 22
  • http通信を許可
sudo ufw allow 80/tcp
  • https通信を許可
sudo ufw allow 443/tcp
  • ufwの設定を反映
sudo ufw enable

Command may disrupt existing ssh connections. Proceed with operation (y|n)?はyで続けます。

  • 反映確認
sudo ufw status

以下を確認します。

状態: アクティブ

To                         Action      From
--                         ------      ----
22/tcp                     LIMIT       Anywhere                  
80/tcp                     ALLOW       Anywhere                  
443/tcp                    ALLOW       Anywhere                  
22/tcp (v6)                LIMIT       Anywhere (v6)             
80/tcp (v6)                ALLOW       Anywhere (v6)             
443/tcp (v6)               ALLOW       Anywhere (v6) 

別ウィンドウで新たなSSH接続を行い、通信できるかを確認します。

  • 再起動後でもufwが有効であることを確認
sudo reboot

再起動後、SSH接続ができることを確認します。

sudo ufw status

上記、許可された設定が有効になっていることを確認します。

fail2banをインストールします。

  • インストール
sudo aptitude update && sudo aptitude install fail2ban
  • インストール確認
systemctl status fail2ban.service 

active(running)を確認します。

fail2banを設定します。

  • jail.localの作成

教義と進行に沿ったエディタを用いて/etc/fail2ban/jail.localを管理者権限で編集します。

[ufw]
enabled=true
filter=ufw.aggressive
action=iptables-allports
logpath=/var/log/ufw.log
maxretry=1
bantime=-1
ignoreip = 127.0.0.0/8 ::1
# ignoreipは任意の(ある程度アクセス元が判明しているIPアドレス)を指定ください。スペース区切りで複数指定できます。

[sshd]
enabled=true
filter=sshd
mode=normal
port=22
protocol=tcp
logpath=/var/log/auth.log
maxretry=3
bantime=-1
ignoreip = 127.0.0.0/8 ::1
# ignoreipは任意の(ある程度アクセス元が判明しているIPアドレス)を指定ください。スペース区切りで複数指定できます。
  • ufw.aggressiveを作成
sudo tee /etc/fail2ban/filter.d/ufw.aggressive.conf > /dev/null << 'EOF'
[Definition]
failregex = [UFW BLOCK].+SRC=<HOST> DST
ignoreregex =
EOF
  • 設定反映
sudo systemctl restart fail2ban.service
systemctl status fail2ban.service 

active(running)を確認します。

  • 設定確認
sudo cat /var/log/fail2ban.log

この時点で、

2024-09-01 17:14:26,476 fail2ban.filter         [1720]: INFO    [ufw] Found xxx.xxx.xxx.xxx - 2024-09-01 17:14:26
2024-09-01 17:14:26,623 fail2ban.actions        [1720]: NOTICE  [ufw] Ban xxx.xxx.xxx.xxx
2024-09-01 17:14:44,198 fail2ban.filter         [1720]: INFO    [ufw] Found yyy.yyy.yyy.yyy - 2024-09-01 17:14:44
2024-09-01 17:14:44,647 fail2ban.actions        [1720]: NOTICE  [ufw] Ban yyy.yyy.yyy.yyy

と、fail2banが不審なアクセスを弾いています。

sudo fail2ban-client status ufw

設定して10分も経たないうちに100ほどのIPアドレスがブロックされていました。

WebARENA Indigo®を利用したUbuntu 24.04サーバへの立ち上げ。

概要

Ubuntu 20.o4サーバのEOLが近づいてきたため、現時点でのUbuntu最新版LTSサーバのvpsを立ち上げたときの記録です。

選定したサービス:WebARENA Indigo®

https://web.arena.ne.jp/indigo

今回は国産vpsを選定です。

  • 円安の影響下でAWS Lightsailが高額になった
  • 回線キャリアが運営しているだけあってNWが安定(アップロードも500Mbps/ベストエフォート)
  • Lightsailと同じく月額課金のため安心

が選定理由です。

申し込みそのものは

  • サインイン
  • クレジットカード情報の入力
  • 携帯電話を利用した本人確認

で、アカウント作成後は

こんな形のダッシュボードができました。

ここからUbuntuサーバを立ち上げていくのですが、罠が待っていました。

Ubuntu24.04サーバの罠-rsa秘密鍵、再び-

上記ダッシュボードから

  1. サービス管理
  2. インスタンス管理
  3. SSH鍵

で鍵を作成後、

  1. インスタンス
  2. インスタンス作成

で、Ubuntu 24.04インスタンスを作成するとログインできません

過去にもこういう事例があったので、それに沿って対応します。

これと同じく、

(SSH-1アルゴリズムによるRSA認証が無効化されます)

に引っかかるので、

  1. Ubuntu 20.04でインスタンスを立ち上げる
  2. アクセスできるアカウントを作成する
  3. Ubuntu 22.04/24.04に対応した秘密鍵を作成する
  4. その上でUbuntuのアップグレードをする

回りくどい方法を採りました。

最初のインスタンスへのアクセス

  1. WebARENAのコンソールからSSH鍵を作ります。
    • SSH鍵の作成
    • SSH鍵名を入力して作成をクリック
    • ダウンロードされた秘密鍵を利用
  2. Ubuntu20.04でインスタンスを立ち上げます。
    • インスタンス管理>インスタンスに移動
    • イメージの選択「Ubuntu」>「Ubuntu20.04」を選択
    • 自分の運用に沿ったサイズを選択
    • SSH鍵は上記で作成したものを選択
    • インスタンス名は任意のものを入力
    • 「インスタンスの作成」をクリック
  3. インスタンスを起動します。OSがインストールされたら、「操作」から「インスタンスの起動」をクリックします。
    • AWSと違って、最初からグローバルのIPアドレスがアタッチされているのが利点です。
    • ドメインとDNS登録できる環境があれば、この時点で名前解決できるようにします。
  4. ターミナルクライアントソフトから、インポートされた秘密鍵を使ってアクセスします。
    • アクセス先:アタッチされたIPアドレス
    • ユーザー名:ubuntu
    • 秘密鍵を利用
    • パスワード:空白

Ubuntu 22.04以降に対応したアカウントの作成

  • root昇格
sudo su -

パスワードは設定されていないので空エンターです。

  • ユーザー作成
adduser hoge

hogeは任意のユーザー名です。その後、パスワードなどを設定していきます。

  • 作成したユーザーを管理者グループに入れる
usermod -G sudo hoge

hogeは自分が作成したユーザー名です。

  • 作成したユーザーに切り替え
su - hoge
  • ユーザー名確認
whoami

作成したユーザー名であることを確認します。

  • root昇格確認
sudo su -

パスワード入力後、作成したユーザーがrootに昇格できることを確認します。

  • 作成したユーザーに戻る
exit && whoami

作成したユーザーであることを確認します。

秘密鍵作成

  • edEd25519での秘密鍵作成
ssh-keygen -t ed25519

鍵の格納場所は初期値(/home/hoge/.ssh)なので空エンターです。特別な運用がない限りはパスワードを設定します。

  • 秘密鍵確認
cd .ssh && pwd

/home/hoge/.sshにいることを確認します。

  • ファイルの内容確認
ls -l
  1. id_ed25519
  2. id_ed25519.pub

の2つを確認します。

cat id_ed25519
cat id_ed25519.pub

とした上で内容をコピーし、ローカル環境に貼り付けて保管します。この、秘密鍵と公開鍵はサーバセキュリティの生命線です。管理と保管は厳密に行ってください。

  • サーバ上から秘密鍵を削除
rm id_ed25519

サーバにアクセスするための秘密鍵がサーバ上にあっては意味がありません。「ローカルに秘密鍵があることを再確認した上で」秘密鍵を削除します。

  • 公開鍵の名前と権限変更
mv id_ed25519.pub authorized_keys
chmod 600 authorized_keys

公開鍵の名前をauthorized_keysに変更して、所有者のみがアクセスできるようにします。

ローカルPCからアクセスできることを確認します。

ターミナルクライアントソフトで

  • IPアドレス(設定していればドメイン名)
  • 作成したユーザー名とパスワード
  • ローカルに保管した秘密鍵

を用いてアクセスできることを確認します。

Ubuntuのアップグレード

Ubuntu 20.04から24.04まで上げるので、二段階に上げます。

また、OSの再インストールなので、休憩時間を一切挟まず、一気通貫で行ってください。

Ubuntu 20.04→22.04

  • root昇格
sudo su -

ここから全てroot権限で設定します。

  • パッケージの最新化とアップグレード前の再起動
apt update && apt upgrade && apt autoremove

パッケージを最新版にして不要パッケージを削除します。途中で不要パッケージを消すかを求められるので[y]で消去します。

reboot

再起動を行います。

  • 再ログインしてroot昇格
sudo su -
  • OSのアップグレード
do-release-upgrade

アップグレード中にプロンプトから質問されたこと

以下、主要な質問事項です。コメント(#の後)に概要を書いています。

Reading cache

Checking package manager

Continue running under SSH?

This session appears to be running under ssh. It is not recommended
to perform a upgrade over ssh currently because in case of failure it
is harder to recover.

If you continue, an additional ssh daemon will be started at port
'1022'.
Do you want to continue?

# SSHのポートを追加するか
# → y

Starting additional sshd 

To make recovery in case of failure easier, an additional sshd will 
be started on port '1022'. If anything goes wrong with the running 
ssh you can still connect to the additional one. 
If you run a firewall, you may need to temporarily open this port. As 
this is potentially dangerous it's not done automatically. You can 
open the port with e.g.: 
'iptables -I INPUT -p tcp --dport 1022 -j ACCEPT' 

To continue please press [ENTER]

# 設定を変更するか
# → Enter

Do you want to start the upgrade?


4 packages are going to be removed. 85 new packages are going to be
installed. 555 packages are going to be upgraded.

You have to download a total of 247 M. This download will take about
49 seconds with a 40Mbit connection and about 6 minutes with a 5Mbit
connection.

Fetching and installing the upgrade can take several hours. Once the
download has finished, the process cannot be canceled.

 Continue [yN]  Details [d]

# アップグレード前の最終確認
# → y

There are services installed on your system which need to be restarted when certain libraries, such as libpam, libc, and libssl, are upgraded. Since these restarts may cause interruptions of service for the system, you will     x
   x normally be prompted on each upgrade for the list of services you wish to restart.  You can choose this option to avoid being prompted; instead, all necessary restarts will be done for you automatically so you can avoid being   x
   x asked questions on each library upgrade.                                                                                                                                                                                            x
   x                                                                                                                                                                                                                                     x
   x Restart services during package upgrades without asking?

# アップグレード時、各種サービスを再起動前にプロンプトでy/nを確認するか
# → 質問されるのがめんどいので yes

# この間、SSH等の設定変更を行うか訊いてきます。プロンプトの選択を変えずに先に進みました
# keep the local version currently installed

Remove obsolete packages? 

# 不要パッケージの削除
# → Yes

System upgrade is complete.

Restart required

To finish the upgrade, a restart is required.
If you select 'y' the system will be restarted.

Continue [yN]

# アップグレード完了後にリブートするか
# → y
  • 22.04へのアップグレードを確認

再起動後、再びアクセスします。

cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.1 LTS"

となっていればまずはアップグレード完了です。

Ubuntu 22.04 → 24.04

  • root昇格
sudo su -
  • OSのアップグレード
do-release-upgrade

途中のプロンプトはほぼ同じなので割愛。再起動後、

cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=24.04
DISTRIB_CODENAME=noble
DISTRIB_DESCRIPTION="Ubuntu 24.04.1 LTS"

にて成功です。

初期ユーザーの無効化

WebARENAのコンソールで作成された初期ユーザーはパスワードがない状態なので、無効化します。

  • root昇格
sudo su -
  • 初期ユーザーのsshディレクトリに移動
cd /home/ubuntu/.ssh
  • 公開鍵退避
mv authorized_keys ../

以上、仕様によって「すぐに立ち上げ」というわけには行きませんでしたが、クラウドでUbuntu24.04サーバを立ち上げることができました。

ViewCustomizeによるガントチャートの修正

RedmineのViewCustomizeはいじりがいがあるプラグインです。

今回もまたちょっとした要望に応えるユースケースとなりました。

やりたいこと

攻略情報をRedmineのチケットとして載せています。

https://atelier.reisalin.com/projects/ryza3/issues/gantt

この、「アトリエ-全般」やチケットNo.が視認性を悪くしているので、これの表示を変えます。

具体的には

トラッカー名-チケット番号-チケットの件名

を、

チケットの件名-トラッカー名-チケット番号

に変える形です。

環境

  • Redmine 4.2
  • View_Customizeプラグインが入っていること

手順

※ 参考:Redmine View Customizeサンプルスクリプト:ガントチャートでトラッカー名・チケット番号を非表示にする

  1. Redmineの管理画面にログインします。
  2. 「管理」 > 「表示のカスタマイズ」に移動します。
  3. 「新しい表示のカスタマイズ」をクリックします。

以下の通り設定します。

  • 「パスのパターン」: /issues/gantt
  • 「プロジェクトのパターン」:空白
  • 「挿入位置
  • 「種別」:JavaScript
  • コード
$(function() {
$('div.issue-subject span').each(function() {
var $this = $(this);
var issue_link = $this.find('a.issue');
var issue_number = issue_link.text().trim();
var issue_title = $this.clone().children().remove().end().text().trim();
var new_html = issue_title + ' ' + issue_number;
// 新しいHTMLを設定
$this.html(new_html);
// リンクを再設定
$this.wrapInner('<a href="' + issue_link.attr('href') + '"></a>');
});
});
  • コメント:ガントチャートの並び順を変える
  • 有効:チェック
  • プライベート:チェックを外す

設定後、保存します。

修正確認

上記の設定を行ったプロジェクトのガントチャートを確認します。

このように、並び順が変われば設定OKです。

Page 1 of 12

Powered by WordPress & Theme by Anders Norén