Linux上のユーザーのリソースの使用状況であったり、運用のポリシーを下に様々な制限を加えたいという場合があります。
例えば、利用するディスクスペースや生成するプロセス数の制限であったり、ログイン数を限定するという具合です。
ということで、その制限方法をまとめていきたいと思いますが、環境としてはRedHat5.9をベースに書いています。
/etc/security/limits.confに制限内容を書く
ユーザーのリソース制限の設定はこのファイルに内容を書いていきます。
例えば、あるユーザーが生成するプロセス数を限定したいという場合
foo soft nproc 20 foo hard nproc 100
のように書いておきます。
書式としては
ユーザー名(または@グループ名または*で全ユーザー) soft | hard 識別子 設定値
となります。
nprocが最大プロセス数を定義するための識別子となるので、今回の場合はfooユーザーに対して20のプロセス数までしか起動できない設定となります。
softとhardの設定の違いは、softが一般ユーザが変更できる限界値で、hardはrootが変更できる限界値となります。
この状態で、プロセスを大量に生成してみたいと思います。
簡易的にプロセスを大量に作るShellプログラムとして下記のようなものを用意します。
(とはいってもsleepプロセスをバックグラウンドで20個作るだけですけど)
#!/bin/bash
for i in `seq 1 20`
do sleep 10 & done
実行直後にpsコマンドで見てみると
$ ps aux | grep sleep --- snip --- foo 3162 0.0 0.0 58924 524 pts/3 S 11:52 0:00 sleep 10 foo 3163 0.0 0.0 58924 524 pts/3 S 11:52 0:00 sleep 10 foo 3164 0.0 0.0 58924 524 pts/3 S 11:52 0:00 sleep 10 foo 3165 0.0 0.0 58924 524 pts/3 S 11:52 0:00 sleep 10 foo 3166 0.0 0.0 58920 524 pts/3 S 11:52 0:00 sleep 10 foo 3168 0.0 0.0 65416 828 pts/3 S+ 11:52 0:00 grep sleep
と、プロセスが作られています。
この場合は、限界値が20なのでこのShellスクリプト実行直後にエラーがでます。
確認する場合は、別のユーザーまたはrootで確認する必要があります。
$ ./proc.sh ./proc.sh: fork: リソースが一時的に利用できません
この状態で何かコマンドを打ってみたり、fooユーザーでログインすると同様に
-bash: fork: リソースが一時的に利用できません
というようなエラーが出てリソース利用の制限に引っかかっていることがわかります。
syslogのほうもsecureログに近い内容のものが出力されます。
Jul 31 11:58:48 localhost sshd[9341]: Accepted password for fuga from 192.168.100.1 port 57033 ssh2 Jul 31 11:58:48 localhost sshd[9341]: pam_unix(sshd:session): session opened for user foo by (uid=0) Jul 31 11:58:48 localhost sshd[9343]: Disconnecting: fork failed: Resource temporarily unavailable Jul 31 11:58:48 localhost sshd[9341]: pam_unix(sshd:session): session closed for user foo
最後から2つ目のメッセージに書いてあるように、リソースが一時的に利用できないというメッセージが残されています。
ちなみに、この設定は設定後にログインしたユーザーに対して有効になります。
現在の状況を確認したければ、
$ ulimit -u 20
で、確認できます。
動的に変更したい場合は、
$ ulimit -u 30 -bash: ulimit: max user processes: cannot modify limit: 許可されていない操作です
にて変更できます。
上記の場合は、一般ユーザーがnprocを20までしか変更できないのに対して、30に設定しようとしたのでエラーがでています。
もう1つ、特定ユーザーのログイン数を制限してみたいと思います。
foo - maxlogins 5
この状態でターミナルを5つ以上開いてログインしようとすると、拒否されます。
secureログの方にも
Jul 31 09:38:34 localhost sshd[32519]: Accepted password for foo from 192.168.1.100 port 63460 ssh2 Jul 31 09:38:34 localhost sshd[32519]: pam_limits(sshd:session): Too many logins (max 3) for foo Jul 31 09:38:34 localhost sshd[32519]: pam_unix(sshd:session): session opened for user foo by (uid=0) Jul 31 09:38:34 localhost sshd[32519]: error: PAM: pam_open_session(): Permission denied Jul 31 09:38:34 localhost sshd[32521]: Received disconnect from 192.168.1.100: 2: disconnected by server request
接続をサーバー側で拒否したことがわかります。
その他にlimit.confやulimitコマンドで制限できるものには下記のようなものがあります。
| 項目 | リソース名 |
|---|---|
| core | 吐き出すcoreファイルのサイズのリミット |
| data | 最大データサイズ |
| fsize | 最大ファイルサイズ |
| nofile | オープンできる最大ファイル数 |
| rss | 実行プロセスのメモリサイズ |
| stack | 最大スタック数 |
| cpu | CPU割り当て時間 |
| maxlogins | 最大ログイン数 |
| maxlogins | 最大ログイン数 |
その他の項目や設定方法はlimits.conf内にコメントがありますので、そちらも参照してください。
limits.confの制約と制限
limits.confに書くことでユーザーのリソースが制限されるわけですが、全てにおいて適用されるわけではありません。
元々、このlimits.confはpam_limits.soという共有ライブラリで提供されており、pam.dディレクトリにあるsystem-authファイルなんかで読み込まれています。
session required pam_limits.so
下記のサイトなんかを参考にすると、sessionというタイプの指定はユーザー認証前後に実行するということなので、この時にリソースの使用状況が制限内かチェックしているようです。
PAMによる認証の仕組みを調べてみたAdd Star @ GeekFactory
その他にも、
# grep -l "pam_limits.so" ./* ./atd ./runuser ./sudo ./sudo-i ./system-auth ./system-auth-ac
なんかのファイルにてpam_limits.soが読み込まれているので、それぞれのコマンド実行時にリソースの制限がかかるわけですが、これ以外の場合やそもそもpamを利用していないアクションをした場合は制限されません。
自動起動スクリプトなんかから実行しているユーザーにも制限を加えたいという場合は、その自動起動スクリプトにulimitコマンドを書いて制限を加えるか、下記のようにOS起動時のスクリプトに書いてしまうという方法があるようです。
まぁ、自動起動スクリプトの中でsuしてたりrunuserしてたりする場合は、pamを通るので制限がかかるかと思いますが。
現在の設定内容の確認および設定時のオプションは、下記のコマンドを実行すればわかります。
$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 38911 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 38911 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
先に書いたnproc(-uオプション)の変更のように、上記のそれぞれのオプションを指定して制限を動的に変更しておけば起動時に制限を反映することができます。
プロセスを大量発行するユーザー(例えばApacheユーザーとか)、利用者にサーバーを開放するけど大きなファイルや大量のファイルを扱われたくないというような場合に制限をかけておくと便利でしょう。
[PR]
[PR]
関連記事
[Linux] ディスク性能テストにfioを使ってみる
udevを使ってデバイス名の固定する
chkconfigに登録されていないデーモンのランレベルをいきなり変えてはいけない