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
}

dailyrotate 30compress が設定されており、問題なし。

まとめ

問題原因対処
syslogが380MBに肥大化Cowrieの -l - オプションでsyslogに垂れ流しStandardOutput=null でsyslogへの出力を遮断
journalが1.3GBに肥大化上記の影響--vacuum-size=200M で圧縮

Cowrieを運用している場合は、起動オプションに -l - が含まれていないか確認しておくことをおすすめします。専用のログディレクトリとlogrotateが正しく設定されていれば、syslogへの出力は不要らしい。良い密告者ライフを!!!