Hetznerのサーバーが毎日1%ずつ容量が増えていた原因と対処法
はじめに
Hetznerで運用しているVPS(38GB)のディスク使用量が毎日約1%ずつ増え続けていることに気づいた。このまま放置すると数ヶ月でディスクが満杯になってしまう。原因を調査して解決したので、手順をまとめます。
環境
- OS: Ubuntu 24.04
- サーバー: Hetzner VPS(38GB SSD)
- 運用中のサービス: Cowrie(SSHハニーポット)、Nginx、fail2ban
症状
df -h でディスク使用量を確認すると、38GBのうち5.7GBが使用済みで、毎日じわじわ増えている状態だった。
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 38G 5.7G 31G 16% /
調査手順
① 大きいディレクトリを特定する
まずどこが容量を食っているか du コマンドで調べる。
du -h / --max-depth=4 2>/dev/null | sort -rh | head -20
2.1G /var
1.7G /var/log
1.3G /var/log/journal
/var/log が1.7GBと異常に大きい。さらに掘り下げる。
du -sh /var/log/* 2>/dev/null | sort -rh | head -10
1.3G /var/log/journal
380M /var/log/syslog.1
7.1M /var/log/auth.log.1
syslog.1が380MB、journalが1.3GBと巨大になっていた。
② syslogに何が書き込まれているか確認する
syslogに何のプロセスが大量に書き込んでいるか調べる。
sudo grep -oP 'kernel|sshd|nginx|fail2ban|[a-z]+\[\d+\]' /var/log/syslog.1 \
| sort | uniq -c | sort -rn | head -20
609806 python[138942]
550283 python[74552]
400086 python[822]
375784 python[14267]
...
1260 nginx
50 sshd
Pythonプロセスが合計200万行以上のログを吐いていた。nginx・sshdは数百行程度なので、明らかに異常。
③ 正体を特定する
該当のPythonプロセスが何者か確認する。
ps aux | grep python
cowrie 176137 0.0 2.1 97468 84716 ? Ss 00:00 0:03
/home/cowrie/cowrie-env/bin/python
/home/cowrie/cowrie-env/bin/twistd --umask 0022 --nodaemon --pidfile= -l - cowrie
CowrieがPythonで動いていた。 そしてsyslogの中身を見ると:
python[822]: New connection: xxx.xxx.xxx.xxx:37756
python[822]: login attempt [b'admin'/b'admin2026'] failed
python[822]: connection lost
世界中のボットがSSH接続を試みているログが延々と記録されていた。
原因
Cowrieの起動オプションに -l -(ログを標準出力に出力する)が含まれていた。
sudo systemctl show cowrie.service --property=ExecStart
# ExecStart= ... twistd --umask 0022 --nodaemon --pidfile= -l - cowrie
# ^^^^
# これが原因
-l - は「ログを標準出力に流せ」という意味で、systemdがその出力をjournald経由でsyslogに転送していた。
CowrieはSSHハニーポットなので、インターネット上の攻撃者のアクセス試行を24時間記録し続ける。それがsyslogに垂れ流しになっていたため、急速に肥大化していた。
なぜ問題なのか
Cowrieには本来 /home/cowrie/cowrie/var/log/ という専用のログディレクトリがあり、logrotateで30日分管理される設計になっている。
しかし -l - のせいでsyslogにも二重に書き込まれ続けていた。syslogにはCowrie専用のlogrotate設定が適用されないため、圧縮もされず際限なく膨らんでいた。
対処法
① Cowrieのログ出力をsyslogから切り離す
systemctl edit でoverride設定を追加し、標準出力・標準エラーを /dev/null に向ける。
sudo EDITOR=vim systemctl edit cowrie.service
以下を入力して保存する:
[Service]
StandardOutput=null
StandardError=null
設定ファイルは /etc/systemd/system/cowrie.service.d/override.conf に保存される。既存の cowrie.service を直接編集しないため、Cowrieをアップデートしても設定が保持される。
② サービスを再起動して設定を反映する
sudo systemctl daemon-reload
sudo systemctl restart cowrie.service
sudo systemctl status cowrie.service
active (running) と表示されれば成功。
③ 肥大化した過去ログを削除する
# syslog.1(380MB)を削除
sudo rm /var/log/syslog.1
# journalを200MBまで圧縮
sudo journalctl --vacuum-size=200M
結果
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 38G 4.2G 32G 12% /
5.7GB → 4.2GB(約1.5GB削減)。今後はCowrieのログがsyslogに流れ込まなくなるため、毎日1%の増加も止まる。
Cowrieのlogrotate設定を確認する
ついでにCowrie専用ログのlogrotate設定も確認しておく。
cat /etc/logrotate.d/cowrie
/home/cowrie/cowrie/var/log/cowrie/*.log
/home/cowrie/cowrie/var/log/cowrie/*.json {
su cowrie cowrie
daily
rotate 30
compress
missingok
notifempty
dateext
dateformat .%Y-%m-%d
postrotate
systemctl restart cowrie
endscript
}
daily・rotate 30・compress が設定されており、問題なし。
まとめ
| 問題 | 原因 | 対処 |
|---|---|---|
| syslogが380MBに肥大化 | Cowrieの -l - オプションでsyslogに垂れ流し | StandardOutput=null でsyslogへの出力を遮断 |
| journalが1.3GBに肥大化 | 上記の影響 | --vacuum-size=200M で圧縮 |
Cowrieを運用している場合は、起動オプションに -l - が含まれていないか確認しておくことをおすすめします。専用のログディレクトリとlogrotateが正しく設定されていれば、syslogへの出力は不要らしい。良い密告者ライフを!!!