コース一覧
サーバー運用実践:セキュリティ・監視・デプロイ
ログローテーション

サーバー運用実践:セキュリティ・監視・デプロイ

構築済みのnginxサーバーを、専用ユーザー・SSH鍵認証・ufwで保護し、HTTPS化、ログとヘルスチェックの監視、systemdタイマー、リリース切替、ロールバック、障害復旧までを実践します。本番を想定した安全な公開・監視・デプロイの基本を身につける30レッスンのコースです。

1
セキュリティのきほん
01. 専用ユーザーで動かす16分
02. SSH鍵認証16分
03. sshdを固める16分
04. ufwファイアウォール16分
05. ポートの棚卸し16分
06. ミッション サーバーを固める16分
07. 第4章クイズ12分
2
HTTPS
01. HTTPSとTLSのしくみ16分
02. 自己署名証明書を作る16分
03. nginxにHTTPSを設定16分
04. HTTPからのリダイレクト16分
05. ミッション HTTPS化完了16分
06. 第5章クイズ12分
3
運用と監視
01. tmuxで多重端末16分
02. ログローテーション16分
03. エラーログ監視16分
04. ヘルスチェック16分
05. systemdタイマー16分
06. ミッション 監視の自動化16分
07. 第6章クイズ12分
4
デプロイ
01. デプロイの型16分
02. シンボリックリンク16分
03. deploy.sh v216分
04. ロールバック16分
05. ミッション ワンコマンドデプロイ16分
06. 第7章クイズ12分
5
総合制作
01. ゼロから構築ミッション16分
02. 障害対応演習16分
03. 自由拡張16分
04. 完成と次のステップ16分

ログローテーション

ログは黙ってディスクを食い潰す

3章で専用のアクセスログを作りました。訪問のたびに1行ずつ増えます。1行はせいぜい 200 バイトですが、増え続けることに変わりはありません。

1日1万アクセスなら1日およそ 2MB、1年で 700MB です。放っておくとディスクが埋まります。ディスクが埋まったサーバーは、ログが書けないだけでは済みません。一時ファイルも作れず、データベースも書けず、全体が止まります。運用で最も多い停止原因のひとつです。

手で消すのは現実的ではありません。消すタイミングを忘れますし、消した瞬間に調査したい記録まで失います。そこで、古いものから順に畳んでいく仕組みを使います。

畳んで、圧縮して、捨てる

logrotate は次の順で処理します。

  1. いまのログに別の名前を付ける (mysite-access.log を mysite-access.log-20260808 に)
  2. 空の mysite-access.log を作り直す
  3. 名前を変えたほうを gzip で圧縮する
  4. 決めた世代数を超えた古いものを消す

ログは文字ばかりなので、圧縮はよく効きます。10 分の 1 以下になることも珍しくありません。

設定はパッケージが置いている

Debian の nginx は、導入した時点で自分の設定を置いています。

ターミナル

cat /etc/logrotate.d/nginx

プレーンテキスト

/var/log/nginx/*.log {
	daily
	missingok
	rotate 14
	compress
	delaycompress
	notifempty
	create 0640 www-data adm
	sharedscripts
	...
}

先頭が対象のファイルで、* が効くので3章で作った mysite-access.log も最初から含まれています。中括弧の中が指定です。

  • daily — 1日1回畳む。weekly や monthly も書ける
  • rotate 14 — 14 世代残す。15 個目が生まれると最も古いものが消える
  • compress — 畳んだものを gzip で圧縮する
  • delaycompress — 圧縮を1回ぶん先送りする
  • missingok — ファイルが無くてもエラーにしない
  • notifempty — 中身が空なら畳まない
  • create 0640 www-data adm — 作り直すファイルの権限と持ち主

create の行が効きます。4章で見たとおり、nginx の worker は www-data で動いています。作り直したファイルがその手に負えない権限だと、翌日からログが1行も書かれません。

delaycompress が何をしているか

分かりにくいのがこの1行です。付けると、畳んだ直後は圧縮せず、次に畳むときにまとめて圧縮します。

理由は、プロセスがまだ古いファイルを開いたまま書き続けている場合があるからです。書いている最中に圧縮すると、中身が壊れます。1回ぶん待てば安全というわけです。

引き換えに、直前の1世代だけは圧縮されないまま残ります。畳んだのに .gz が見当たらないと焦る原因はたいていこれです。

次の節で、畳んだ直後に nginx へ開き直させる設定を入れます。書き込み先が切り替わったあとなら圧縮しても壊れないので、この先送りは外して構いません。

名前を日付にする

既定では mysite-access.log.1、mysite-access.log.2 と番号が付きます。番号は畳むたびにずれるので、「3日前のログ」を探すのに数える必要があります。

プレーンテキスト

dateext

この1行で mysite-access.log-20260808 という日付つきの名前になります。ずれない名前になるので、後から探すのが楽です。

畳んだあと、開き直させる

もう1つ、見落とすと痛い部分があります。畳むというのは、ファイルの名前を変えているだけです。nginx は名前ではなく開いた実体に書き続けるので、何もしなければ畳んだあとの書き込みは、名前を変えたほうへ入り続けます。作り直された新しいログはいつまでも空のままです。

そこで、畳んだあとにプロセスへ「開き直せ」と伝えます。

プレーンテキスト

postrotate
	if [ -f /run/nginx.pid ]; then kill -USR1 $(cat /run/nginx.pid); fi
endscript

postrotate と endscript の間は、畳んだあとに走らせる処理です。kill は名前に反して、プロセスへ合図を送る命令です。-USR1 は nginx にとって「ログを開き直せ」の意味で、2章で systemctl reload が裏で送っていたものと同じ種類の合図です。

/run/nginx.pid には、動いている nginx の番号が書かれています。存在を確かめてから送るのは、nginx が止まっているときに空振りさせないためです。

Debian の nginx は既定で invoke-rc.d nginx rotate を呼びますが、systemd で動かしている環境では成功したように見えて何も起きません。畳んだ翌日からログが1行も増えていない、という形で気づくことになります。自分の手で確かめておく価値があります。

待たずに試す

設定を書いても、実際に畳まれるのは翌日です。それでは確かめられないので、強制的に走らせます。

ターミナル

logrotate -d /etc/logrotate.d/nginx   # 何をするかだけ見る
logrotate -f /etc/logrotate.d/nginx   # 実際に畳む

-d は試し打ちで、実行せずに手順だけ出します。-f は、まだその時期でなくても強制的に畳ませます。まず -d で確かめてから -f。この順を守ると、設定を間違えたまま本物のログを畳んでしまう事故が防げます。

手を動かす

nginx の設定を、日付つきの名前で7世代だけ残す形に直します。畳んだあとにログを開き直させるところまで入れて、実際に畳まれること、そのあとも書き続けられることを確かめます。

ヒント

-d は試し打ちで、実行せず手順だけ出します。-f は時期でなくても強制的に畳ませます

create の権限を間違えると、畳んだ翌日からログが1行も書かれなくなります

  • 1. curl でサイトに何度かアクセスし、ログに中身がある状態にする
  • 2. /etc/logrotate.d/nginx の rotate 14 を rotate 7 に直す
  • 3. dateext の行を足す
  • 4. delaycompress の行を消す
  • 5. postrotate の中身を if [ -f /run/nginx.pid ]; then kill -USR1 $(cat /run/nginx.pid); fi に書き換える
  • 6. logrotate -d /etc/logrotate.d/nginx で何をするか先に見る
  • 7. logrotate -f /etc/logrotate.d/nginx で実際に畳ませる
  • 8. ls -l /var/log/nginx/ > /root/rotated.txt で結果を保存し、もう一度 curl してログが書けることを確かめる

Linux は使うときに起動します(初回は約102MB通信します)

12 項目で採点します