Linux OSユーザーの色々なリソースを制限する | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。


テーマ:

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起動時のスクリプトに書いてしまうという方法があるようです。

 

ulimitが効かない不安を無くす設定 @ 外道父の匠

 

 

まぁ、自動起動スクリプトの中で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ユーザーとか)、利用者にサーバーを開放するけど大きなファイルや大量のファイルを扱われたくないというような場合に制限をかけておくと便利でしょう。

 

 

 

 

 

 

 

itboyさんをフォロー

ブログの更新情報が受け取れて、アクセスが簡単になります

Ameba人気のブログ

Amebaトピックス