サーバーが突然重くなって応答しなくなった——そんな経験を持つエンジニアは少なくないでしょう。外部からのDDoSが原因の場合もありますが、意外と見落とされがちなのが「サーバー内部のプロセスが許可なくリソースを使い果たす」パターンです。
攻撃者がシステムへの侵入後にフォーク爆弾(Fork Bomb)を仕掛ける、あるいはバグのあるアプリが無限にファイルを開き続けてシステム全体を道連れにする——どちらも、Linuxのリソース制限を正しく設定しておけば被害を最小限に抑えられます。
この記事では、ulimitコマンドと/etc/security/limits.confの設定方法を、攻撃者の視点から見た脅威と合わせて解説します。現場で即使えるコマンドと設定例を中心に、systemdサービスへの適用まで踏み込んで紹介します。

ulimitとは?プロセスのリソースに「上限」を設ける仕組み
ulimit(User Limit)は、Linuxシェルの組み込みコマンドです。ユーザーやプロセスが使えるシステムリソース——プロセス数、ファイルディスクリプタ数、メモリ使用量、コアダンプサイズなど——の上限を設定します。
設定には2種類あります。
・ソフトリミット(soft limit): ユーザー自身が変更できる上限。ハードリミットの値を超えることはできない
・ハードリミット(hard limit): rootのみが変更できる絶対的な上限
ulimitコマンドをシェルで実行した場合、そのシェルセッションとその子プロセスにのみ反映されます。再起動や新しいログインセッションでは元に戻るため、恒久的に有効にするには/etc/security/limits.confへの記述が必要です。
まず現在の設定を確認してみましょう。
# 全リソース制限を一覧表示 ulimit -a # 開けるファイルディスクリプタ数のみ確認 ulimit -n # 最大プロセス数のみ確認 ulimit -u
サーバーによっては、nofile(ファイルディスクリプタ数)のデフォルトが1024という非常に低い値になっていることがあります。WebサーバーやDBを動かす環境では、この値が低いと接続数の限界にすぐ達してしまいます。
攻撃の仕組み——敵がリソース枯渇をどう使うかを知る
セキュリティの観点から見ると、リソース制限の欠如は攻撃者にとって好都合な状況をつくります。代表的な攻撃パターンを確認しておきましょう。
【攻撃1】フォーク爆弾(Fork Bomb)
フォーク爆弾とは、プロセスが際限なく自分自身のコピーを生成し続ける攻撃です。サーバーへの侵入に成功した攻撃者が実行すると、短時間でプロセステーブルが埋まり、システムがほぼ操作不能になります。
プロセス数(nproc)に上限を設けていれば、爆発的なプロセス生成を一定数で止めることができます。上限に達した後もシステム全体は動き続けるため、管理者がログインして対処する時間を稼げます。
【攻撃2】ファイルディスクリプタ枯渇
ファイルディスクリプタ(FD)はファイルやソケットを開くたびに消費されます。制限なしに大量のFDを開き続けるプロセス(バグ・悪意どちらも)が存在すると、他のプロセスが新しいファイルやネットワーク接続を開けなくなります。ログが書けなくなる、SSHでログインできなくなるといった深刻な影響が出ます。
【攻撃3】コアダンプによる情報漏洩
プロセスがクラッシュすると、デフォルト設定ではコアダンプ(crash dump)がディスクに書き出されます。このファイルにはプロセスがメモリに保持していた情報——パスワード、APIキー、セッショントークンなど——が含まれる場合があります。攻撃者が一時的にファイルへアクセスできる状況では、コアダンプが情報漏洩の経路になりえます。
【攻撃4】ディスク枯渇による証跡消去
不正侵入したプロセスが大量のファイルを書き出してディスクを満杯にすると、ログが書き込めなくなります。証跡の消去を狙う手口としても使われるため、1プロセスが作れるファイルサイズ・ファイル数の上限設定が有効です。
具体的なリソース制限の設定手順
1. /etc/security/limits.confの書式を理解する
/etc/security/limits.confの各行は以下の書式で記述します。
# <ドメイン> <種別> <項目> <値> # ドメイン: ユーザー名・グループ名(@group)・ワイルドカード(*) # 種別: soft(ソフトリミット)または hard(ハードリミット) # 項目: nofile, nproc, core, fsize, memlock, stack など # 値: 上限値(-1は無制限) # 全ユーザーへの基本設定例 * soft nofile 65535 * hard nofile 65535 * soft nproc 4096 * hard nproc 8192 * soft core 0 * hard core 0
この設定で、全ユーザーのファイルディスクリプタ上限を65535に引き上げ、プロセス数に上限を設け、コアダンプを無効化しています。
2. Webサーバー向けの推奨設定
nginxやApacheを動かすサーバーでは、接続数が多くなるため nofile を高めに設定しておく必要があります。
# /etc/security/limits.conf への追記例 # Webサーバー用(nginx が動くユーザー) www-data soft nofile 65535 www-data hard nofile 65535 nginx soft nofile 65535 nginx hard nofile 65535 # 全ユーザー共通 * soft nproc 4096 * hard nproc 8192 * soft core 0 * hard core 0 # fsize は KB 単位(1048576 KB = 1 GB) * soft fsize 1048576 * hard fsize 2097152
fsize(最大ファイルサイズ)を設定すると、1つのプロセスが巨大なファイルを作り続けてディスクを埋めるのを防げます。
3. /etc/security/limits.d/への個別設定ファイル
/etc/security/limits.d/配下に個別のファイルを置くと、サービスごとに設定を分離できます。/etc/security/limits.confに全部書くより管理しやすくなります。
# /etc/security/limits.d/90-nginx.conf として作成 nginx soft nofile 65535 nginx hard nofile 65535 nginx soft nproc 4096 nginx hard nproc 4096 # /etc/security/limits.d/90-mysql.conf として作成 mysql soft nofile 65535 mysql hard nofile 65535 mysql soft nproc 2048 mysql hard nproc 4096
設定ファイルは辞書順に読み込まれます。数字プレフィックス(90-)をつけると読み込み順を制御できます。
4. PAMの設定を確認する
/etc/security/limits.confの設定は、PAM(Pluggable Authentication Module)経由でログインセッションに適用されます。PAMの設定ファイルにpam_limits.soが含まれていないと、limits.confの設定が有効になりません。
# Debian/Ubuntu 系で確認 grep pam_limits /etc/pam.d/common-session # RHEL/CentOS 系で確認 grep pam_limits /etc/pam.d/system-auth # SSH経由のログインに反映されているか確認 grep pam_limits /etc/pam.d/sshd # 記述がない場合は以下の行を追加(session セクションに記述) # session required pam_limits.so
SSH経由のログインに反映させるには/etc/pam.d/sshdも確認が必要です。
5. systemdサービスへのリソース制限
systemdで管理されているサービスには、PAMを経由しないためlimits.confが直接適用されないことがあります。systemdのユニットファイルに[Service]セクションでリソース制限を個別に記述する方法が確実です。
# nginxサービスの上書き設定を作成 sudo mkdir -p /etc/systemd/system/nginx.service.d/ sudo vi /etc/systemd/system/nginx.service.d/limits.conf # 以下の内容を記述 [Service] # ファイルディスクリプタ数の上限 LimitNOFILE=65535 # プロセス数の上限 LimitNPROC=4096 # コアダンプを無効化(0 = 無効) LimitCORE=0 # メモリの上限(例: 2GB) MemoryMax=2G # 設定を反映 sudo systemctl daemon-reload sudo systemctl restart nginx # 反映を確認 sudo systemctl show nginx | grep -E 'LimitNOFILE|LimitNPROC|LimitCORE|MemoryMax'
systemdのサービス単位での隔離については、systemdサービスのサンドボックス化|PrivateTmp・NoNewPrivilegesでLinuxの攻撃面を最小化する実践ガイドでさらに詳しく解説しています。PrivateTmpやNoNewPrivilegesと組み合わせると、より堅牢な設定が実現できます。
6. 設定の確認と動作テスト
# 再ログイン後、設定が反映されているか確認 ulimit -a # 特定プロセスの現在のリミットを確認(PID を指定) cat /proc/$(pgrep nginx | head -1)/limits # systemd サービスのリミット確認 cat /proc/$(systemctl show nginx -p MainPID --value)/limits
limits.confを編集後は一度ログアウトして再ログインする必要があります。既存のセッションには新しい設定は反映されません。
中小企業でも今日からできること
「設定項目が多くて何から手をつければいいかわからない」という方のために、優先度の高い設定をまとめました。
| 優先度 | 設定項目 | 推奨値 | 防げるリスク |
|---|---|---|---|
| 高 | nofile(ファイルディスクリプタ数) | 65535 | FD枯渇によるサービス停止 |
| 高 | nproc(プロセス数) | soft:4096 / hard:8192 | フォーク爆弾によるプロセステーブル枯渇 |
| 高 | core(コアダンプサイズ) | 0(無効化) | メモリ内の認証情報・キーの漏洩 |
| 中 | fsize(最大ファイルサイズ) | 用途に応じて設定 | ディスク枯渇・ログ書き込み不能 |
| 中 | MemoryMax(systemdユニット) | サービス別に設定 | 1サービスのメモリ暴走の封じ込め |
最低限、nofile・nproc・coreの3項目を設定するだけでも、多くのリスクをカバーできます。まず/etc/security/limits.confを確認し、デフォルト値のままになっていないかチェックしてみてください。
Linuxカーネルレベルの堅牢化については、Linuxのsysctlセキュリティ設定|カーネルパラメータで攻撃を防ぐ実践ガイドも合わせて参照してください。ulimitとsysctlの組み合わせで、サーバーの防御層をさらに厚くできます。
よくある誤解と注意点
【注意1】rootユーザーにはlimits.confが適用されないことが多い
rootユーザーは通常のulimit制限の対象外です。/etc/security/limits.confにroot hard nproc 100と書いても、ディストリビューションによっては反映されません。rootで動くサービスのリソース制限はsystemdのユニットファイルで設定する方が確実です。
【注意2】制限を厳しくしすぎると業務に支障が出る
nprocを極端に低く設定すると、正規の処理でもプロセスが生成できずにエラーになることがあります。本番環境で変更する前にテスト環境で動作確認を行ってください。特にデータベースや多スレッド処理を行うアプリケーションは、プロセス・スレッド数の見積もりが必要です。
【注意3】既存セッションへの反映タイミング
limits.confを編集しても、現在のログインセッションには即時反映されません。新しいセッションでログインし直すか、サービスを再起動することで反映されます。サーバー立ち上げ時の一連の設定手順はLinuxサーバー初期セキュリティ設定チェックリスト|VPS・クラウドを立ち上げたら最初にやるべき25の手順にまとめています。
【注意4】コアダンプを完全に無効化するにはsysctlも必要
limits.confでcoreを0に設定しても、systemdのDefaultLimitCOREやkernel.core_patternの設定次第ではコアダンプが残ることがあります。完全に無効化するには、sysctl設定との組み合わせが必要です。
# コアダンプを完全に無効化する(sysctl設定) echo "kernel.core_pattern=/dev/null" | sudo tee /etc/sysctl.d/99-coredump.conf sudo sysctl -p /etc/sysctl.d/99-coredump.conf # systemd レベルでもコアダンプを無効化する場合 # /etc/systemd/coredump.conf を編集して以下を追記 # [Coredump] # Storage=none # ProcessSizeMax=0 # 設定反映 sudo systemctl daemon-reload # 確認 ulimit -c

本記事のまとめ
ulimitと/etc/security/limits.confによるリソース制限は、地味ながらサーバー堅牢化の重要な一歩です。要点を整理します。
| 脅威 | 対策 | 設定場所 |
|---|---|---|
| フォーク爆弾 | nproc制限 | limits.conf / systemdユニット |
| ファイルディスクリプタ枯渇 | nofile引き上げ+上限設定 | limits.conf / systemdユニット |
| コアダンプによる情報漏洩 | core=0 + sysctl無効化 | limits.conf + sysctl設定 |
| ディスク枯渇・ログ消去 | fsize制限 | limits.conf |
| サービス単体のメモリ暴走 | MemoryMax設定 | systemdユニットファイル |
設定後は必ずulimit -aや/proc/[PID]/limitsで反映を確認する習慣をつけてください。1つの設定ミスがサービス停止につながることもあるため、テスト環境での検証を怠らないようにしましょう。
リソース制限はあくまで多層防御の一層にすぎません。ファイアウォール設定、SELinux/AppArmor、定期的な脆弱性スキャンと組み合わせることで、より実効性の高いセキュリティ体制が実現します。Linuxコマンドやシステム管理の基礎知識は、姉妹サイトLinuxMaster.JPで詳しく解説していますので、あわせてご参照ください。
PR
ulimitやPAM設定をはじめ、Linuxサーバー堅牢化に必要な知識を体系的に解説した一冊。インフラエンジニアや情シス担当者が手元に置いておきたい実践的な参考書です。
