LinuxでMySQLやらプロセスやらを制限したりApacheのディレクトリを復活させるモジュールを作った

LinuxでMySQLやらプロセスやらを制限したりApacheのディレクトリを復活させるモジュールを作った

 標準リポジトリでありそうでなかったのが一定時間が経過したプロセスをkillするプログラムとMySQL、Postgresqlを保護するプログラム。といっても通常運用で長時間居座るプロセスを絶対にぶっ殺したいという場面はそれほど多くないとは思うが、共用サーバなどではしぶとく生き続けるプロセスなどを監視・killしたいという場面は多々出てくると思う。またMySQLやPostgresqlは、設定を複雑にしないとquotaすることができないので作った。

proc_killer

 このプログラムの主目的は簡単で、監視対象ユーザを作成して、そのユーザの制限時間を指定してやる。するとそのユーザが立ち上げたプログラムは、ホワイトリストに入っていない限り制限時間経過後にkillされる運命にある。デフォルトでは30秒周回するが、設定変えればもう少し短くできる。

役に立ちそうな場面

 上記のとおりで、共用サーバなどでcgroupをかければメモリとCPUなどの使用率は制限できるものの、sleep 999のようなうるさいコマンドを実行されるとうるさい。またApache環境下などで、一定時間が経過したphpプロセスなどを瞬時にkillしたいという需要があるが、標準だと.htaccessのTimeoutディレクティブを変えたりするとすり抜けられてしまう。それを潰す。

ソースコード

 Githubに直接公開した。 systemd、rc.dでも動く(はず)。

設定例

 基本的に次のようなファイル構成を想定している。

/usr/local/proc_check/bin/proc_killer

/etc/poc_check
├──monitor_users #監視対象ユーザ
├──cmdline_blacklist_regex #正規表現のコマンド規制
├──cmdline_blacklist #禁止コマンド
└──proc_allow_list #無条件で許可するコマンド

/etc/sysconfig/proc_killer.conf #メイン設定ファイル

proc_killer.confの例

[main]
# デフォルトの制限時間(秒)
DEFAULT_TIME_LIMIT=300

# ログ出力レベル / kill 動作レベル
# 0 = Dry-run(検知のみ)
# 1 = LOG_DEBUG(検知のみ、killなし)
# 2 = LOG_INFO(SIGTERMのみ)
# 3 = LOG_NOTICE(SIGTERM + SIGKILL)
DEBUG_LEVEL=3

# 外部設定ファイルを include して管理
include=/etc/poc_killer/proc_allow_list
include=/etc/poc_killer/monitor_users
include=/etc/poc_killer/cmdline_blacklist
include=/etc/poc_killer/cmdline_blacklist_regex

monitor_users

[user_limits]
localuser1=60      # 1分kill
noisyuser=300      # 5分超過で kill
tester=600         # 10分超過で kill

cmdline_blacklist_regex

# Regular expressions matched against process command line.
# Any match → highest priority kill (ignores allow list & user limits).

# Perl sleep bombs
^perl .*sleep

# Fork bombs
.*fork.*

# Netcat misuse
(^| )nc( |$)

# Long-running wget or curl
(^| )wget( |$)
(^| )curl( |$)

# Dangerous shell loops
:(){ :|:& };:

cmdline_blacklist

#ここに記載したコードは無条件kill対象になるので注意

proc_allow_list

bash
sh
zsh
csh
tcsh
httpd
apache2
php-cgi
php-fpm
perl
python
python3
ruby
proftpd
vsftpd
pure-ftpd
postfix
sendmail
exim
dovecot
courier
imapd
pop3d
sshd
cron
crond
atd
syslogd
rsyslogd
systemd
init
ls
cat
less
more
tail
head
grep
awk
sed
vim
vi
nano
scp
sftp
rsync
wget
curl
tar
gzip
bzip2
xz
zip
unzip
gcc
g++
make
man

MySQLのディスク監視

 長くなってしまったのでGithubに。README通りで、2デーモンと1プラグインでMySQLを保護する目的で作った。通常、MySQL単体でquotaすることは難しいが、これを入れると指定したユーザのデータベース利用を制限することができる。例えばuser1は500MBまで、user2は1GBまでといった具合。MySQLのパスが平文になってしまうので、必ずchmod 600しないと詰む。

/etc/mysql_monitor/user_limits

#user_name soft_limit_bytes hard_limit_bytes

alice 1000000000 2000000000
bob 5000000000 8000000000
yamagamitetsuya 0 300000000000000000000
/etc/storage_guard_users.conf

[users]
alice = 1073741824 , 2147483648
bob = 2147483648 , 3221225472
charlie = 536870912 , 1073741824
/etc/storage_guard.conf

[general]
log_level = INFO
check_interval = 30
metrics_file = /var/run/storage_guard.prom
kill_on_hard_limit = yes
user_limits_file = /etc/storage_guard_users.conf
threshold_trigger = 3
use_threads = yes
max_threads = 16
use_connection_pool = yes
connection_pool_size = 10
daemon_user = mysqlmon
daemon_group = mysqlmon

[database]
host = localhost
port = 3306
user = monitor
password_file = /root/etc/mysql_monitor/passwd
type = mysql
/etc/mysql_monitor/db_list
# hostname     username   database     monitor_interval  sharding_group  metrics_enabled
localhost      monitor    mysql        60                0               1
/etc/mysql_monitor/db_config
# hostname    username   password   database   port  check_interval  query_method
localhost     monitor    secretpw   mysql      3306  60              information_schema

※db_listとdb_configは必ずroot:root、chmod 600すること。
※事前にmonitorというユーザをMySQLに追加。権限付与すること。

CREATE USER 'monitor_user'@'%' IDENTIFIED BY '{PASSWORD}';
GRANT SELECT ON `information_schema`.* TO 'monitor_user'@'%';
GRANT SELECT ON `mysql`.* TO 'monitor_user'@'%';
GRANT SELECT ON *.* TO 'monitor_user'@'localhost';
GRANT ALTER USER ON *.* TO 'monitor_user'@'localhost';
GRANT PROCESS ON *.* TO 'monitor_user'@'localhost';
GRANT KILL ON *.* TO 'monitor_user'@'localhost';
GRANT PROCESS ON *.* TO 'monitor_user'@'%';
FLUSH PRIVILEGES;

 制限した容量を使うと勝手にアカウントをロックしてくれる。

Postgresql監視

 おまけみたいなコードなのでGithub記載の通り適当に入れてください。動作原理は上と同じ。

Apacheのログファイル問題とホームディレクトリ死ぬと復活できなくなる問題

 を解決するためにmod_logdir_improvedとmod_make_homedirを作った。logdirのほうは、ユーザにアクセスログ提供してやっても勝手に消して次の再起動まで復活しない問題を。homedirはユーザがホームディレクトリ消したらgracefulでもrestartでも復旧しなくなる問題を解決する(再起動前にhockして復活させる)もの。README通り、勝手にログディレクトリとホームディレクトリを作ってくれる。

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /home/user1/public_html

    # Ensure the DocumentRoot exists with secure ownership
    MakeHomedirEntries /home/user1/public_html user1 group 0700
    MakeHomedirEntries /home/user1/logs         user1 group 0750
    MakeHomedirEntries /home/user1/tmp          user1 group 0700

    ErrorLog logs/example.com_error.log
    CustomLog logs/example.com_access.log combined
</VirtualHost>

オマケ:ログ監査

 .bash_history消してログ消して逃げる者が世の中にはいるので作ったもの。標準入力をすべてログ取る。

コメントを投稿する

メールアドレスは公開されませんのでご安心ください。 * が付いている欄は必須項目となります。

内容に問題なければ、下記の「コメントを送信する」ボタンを押してください。

ページの先頭