スマートフォンからの画像を自分のPCに転用する形で用いているNextcloud。
アップロードが途中で失敗したり、特定の条件下で接続が切れたりすることがあります。Apacheビルトインのmod_reqtimeout設定を最適化し、サーバーの安定性と利便性を両立させるためのチューニングを行いました。
環境
- Nextcloud 32
- Apache 2.4
- PHP-FPM8.3
- Ubuntu 24.04
そもそもmod_reqtimeoutとは?
Slowloris(スローロリス)攻撃への対策
このモジュールがビルトインされたのは、Slowlorisという、非常に低コストで強力な攻撃手法への対抗があります。
通常のDoS攻撃は大量の通信を送りますが、Slowlorisは逆に「極めてゆっくり」通信します。
- サーバーに接続を開始する。
- リクエスト(ヘッダーやボディ)を、タイムアウトにならないギリギリの遅さで、1バイトずつ小出しに送る。
- サーバー側は「まだデータが来るはずだ」と判断し、その接続(スレッドやプロセス)を維持し続ける。
結果 サーバーの同時接続数の上限が攻撃者の「待ち」状態で埋まってしまい、正規のユーザーがアクセスできなくなります。
mod_reqtimeout は、この「嫌がらせ」を許さないための防衛線です。
サーバーリソースの適正管理
Apacheサーバーが1つの接続を維持するには、メモリやCPUリソースを消費します。
もしタイムアウト設定がない、あるいは極端に長い場合、以下のような問題が発生します。
- ゾンビ接続の蓄積: ネットワークが切れたのにクローズ処理が終わっていない接続が残り続ける。
- リソースの浪費: 応答の遅いクライアント(意図的か否かに関わらず)のために、サーバーの貴重な作業枠をいつまでも空けておくことになります。
なぜこれがNextcloudで徒になるのか
Nextcloudのデータの性質と通信の仕組みにあります。
巨大なファイルを細切れにする
Nextcloudは、数MBから数GBあるような大きなファイルを送る際、一気に送らずにファイルを分割して、「チャンク(塊)」に分割して送信します。
- 動作の流れ:
- チャンクAを送信 → サーバーが処理 → チャンクBを送信……
- 問題点:
- チャンクとチャンクの間に、クライアント側でのファイル読み込みやハッシュ計算などで一瞬「無通信」の時間が流れます。
- 結果:
- Apacheのmod_reqtimeoutは、この無通信を先のSlowlorisと誤認して、接続をバッサリ切ってしまいます。
モバイル回線の不安定さ
Nextcloudは外出先のスマートフォンから使うことを想定しています。
- 電波の瞬断:
- 移動中にWi-Fiから4G/5G回線に切り替わったりする。
- 上り速度の制限:
- モバイル回線は「下り」は速くても「上り」が極端に遅いことが多い。
これも、先のSlowloris攻撃と見做されてしまいます。
チューニングの必要性
だからといって、このmod_reqtimeoutを無効にすると、それらの攻撃への備えがなくなります。
Nextcloudの利便性を高めつつ不審な攻撃を守るというのは
「任務」は遂行する「部下」も守る
お前ごときに「両方」やるというのはそう難しいことじゃあないな
ぐらいの精神でやっていきましょう。
さっくりとした手順
- mod_reatimeoutの設定ファイルのバックアップを取る。
- mod_reatimeoutの設定ファイルを修正する。
- サービス再起動を行う。
mod_reatimeoutの設定ファイルのバックアップ
- 念のためのモジュール確認
sudo apache2ctl -M |grep req
reqtimeout_module (shared)を確認します。(apacheをapt等で入れていれば、まず入っています)
- ファイルバックアップ
sudo cp -pi /etc/apache2/mods-available/reqtimeout.conf /path/to/backup/directory/reqtimeout.conf.$(date +%Y%m%d)
/path/to/backup/directoryは自分の環境に合わせます。
- ファイルバックアップ確認
diff -u /path/to/backup/directory/reqtimeout.conf.$(date +%Y%m%d) /etc/apache2/mods-available/reqtimeout.conf
エラーがないことを確認します。
mod_reatimeoutの設定ファイルを修正
/etc/apache2/mods-available/reqtimeout.confを管理者権限で修正します。
筆者は以下のように行いました。
-RequestReadTimeout body=10,minrate=500
+RequestReadTimeout body=20,minrate=500
具体的には、リクエストボディ(データの送信本体)の読み取り開始を待機する時間を10秒から20秒へ延長しています。
- body=20:
- リクエストボディの最初の1バイトを待つ時間を20秒に設定。
- minrate=500:
- データが送り始められた後、最低でも秒間500バイトの転送速度を要求する。これより遅い状態が続くとタイムアウトします。
- ファイルの差分確認
diff -u /path/to/backup/directory/reqtimeout.conf.$(date +%Y%m%d) /etc/apache2/mods-available/reqtimeout.conf
以下のような差分を確認します。
-RequestReadTimeout body=10,minrate=500
+RequestReadTimeout body=20,minrate=500
設定反映
- 構文チェック
sudo apache2ctl configtest
→ Syntax OKとなることを必ず確認してください。でないと、apacheサービスが停止したままとなってしまい、サービス断が発生します。
- Apache サービス再起動
sudo systemctl reload apache2.service
- Apacheサービス再起動確認
systemctl status apache2.service
active(running)を確認します。
まとめ
Nextcloudサーバーにおいて、RequestReadTimeout のbody待ち時間を延長することは、「モバイル環境や大容量ファイル送信時の安定性」を向上させるために非常に有効な手段です。
もし、ログ(Apacheのerror_log)に The timeout specified has expired や request body read timeout といった記録が残っている場合は、この値を調整してみることをお勧めします。
- 参考コマンド
sudo grep "request body read timeout" /var/log/apache2/error.log



















