サーバーが侵害されたとき、攻撃者が自由に動き回れる範囲をどれだけ狭められるか——これがセキュリティの勝負どころです。「chroot(チェンジルート)」は、その封じ込めを実現するためにLinuxが古くから備えてきた仕組みです。
最新のコンテナ技術に押されて地味な印象を持たれがちですが、特定ユーザーをSFTPのみに制限する・古いサービスを隔離する・管理コストをかけずに攻撃面を絞るといった場面では、今も現役で役に立ちます。
この記事では、chrootジェイルの仕組みから、SSHサーバーへの実践的な適用手順、さらに「chrootだけでは足りない理由」まで、現場で使えるレベルで解説します。

chrootジェイルとは?
chroot(change root)は、プロセスから見える「ルートディレクトリ(/)」を、指定した別のディレクトリに付け替えるLinuxのシステムコールです。
たとえば /var/jail/ftpuser をルートに設定したプロセスは、そのディレクトリより上位の /etc/passwd や /home/admin を参照できません。外から見れば完全に別の世界に閉じ込められた状態になります。これを「ジェイル(jail)= 牢屋」と呼びます。
| 項目 | 通常のプロセス | chrootジェイル内のプロセス |
|---|---|---|
| 見えるルート(/) | 本物のシステムルート | 指定したディレクトリ |
| /etc/passwd の参照 | できる | できない(ジェイル外) |
| ネットワーク・PID | 共有 | 共有(chrootのみでは分離されない) |
| 設定の複雑さ | — | 低~中(コンテナより手軽) |
よく使われる場面は次のとおりです。
・SFTPユーザーの隔離: FTP/SFTPで接続するユーザーを、自分のホームディレクトリより外に出られないよう制限する
・レガシーサービスの封じ込め: 古い DNS サーバー(BIND)や FTP デーモンをジェイル内で動かす
・ビルド環境の分離: 外部コードのコンパイルや実行を隔離された環境で行う
攻撃者の視点からみるchrootの価値
侵入経路となりやすいのは、インターネットに公開されたサービスです。Webサーバー・FTPデーモン・メールサーバーなど、外部入力を受け付けるプロセスは必ず攻撃対象になります。
こうしたサービスが脆弱性を突かれてシェルを奪われた場合、chroot環境がなければ攻撃者はサーバー全体のファイルシステムを探索できます。/etc/shadow(パスワードハッシュ)や/root配下の設定ファイル、他サービスの認証情報にたどり着くのは時間の問題です。
chrootジェイルがあれば、侵害されたサービスが「見られる」ファイルはジェイル内に限定されます。攻撃者がシェルを得ても、ジェイル内に置かれた最低限のファイルしか見えません。被害を「小さな箱の中」に封じ込められる可能性が高まります。
chrootジェイルの具体的な構築手順
1. SSHサーバーでSFTPユーザーをchrootに閉じ込める
最も実践的かつ設定が簡単なのが、OpenSSHのChrootDirectoryディレクティブを使う方法です。特定グループのユーザーをSFTP専用に制限し、ジェイル外へのアクセスを遮断します。
まず専用グループとユーザーを作成します。
# SFTPのみ許可するグループを作成 groupadd sftponly # ユーザーを作成してグループに追加(ログインシェルは /sbin/nologin) useradd -m -s /sbin/nologin -G sftponly fileuser1 # パスワードを設定(鍵認証の場合は不要) passwd fileuser1
次にchrootディレクトリを用意します。重要な制約があるので注意してください。OpenSSHはChrootDirectoryとして指定したディレクトリの所有者がrootであり、かつrootのみが書き込み可能でなければ起動を拒否します(セキュリティ上の必須条件)。
# ジェイルのルートディレクトリを作成 mkdir -p /var/jails/sftponly # オーナーをroot、パーミッションを755に設定(rootのみ書き込み可) chown root:root /var/jails/sftponly chmod 755 /var/jails/sftponly # ユーザーが実際にファイルを置くサブディレクトリを作成 mkdir -p /var/jails/sftponly/fileuser1/upload chown fileuser1:sftponly /var/jails/sftponly/fileuser1 chmod 755 /var/jails/sftponly/fileuser1 chown fileuser1:sftponly /var/jails/sftponly/fileuser1/upload chmod 775 /var/jails/sftponly/fileuser1/upload
次に/etc/ssh/sshd_configを編集します。
# ファイル末尾に追加(既存の設定より後に記述すること) Match Group sftponly # SFTPサブシステムのみ許可(シェルログイン不可) ForceCommand internal-sftp # chrootディレクトリを指定(%u = ユーザー名) ChrootDirectory /var/jails/sftponly/%u # X11・TCP転送を無効化 X11Forwarding no AllowTcpForwarding no # ポートフォワーディング無効化 PermitTunnel no
設定を反映させてSSHサービスを再起動します。
# 設定ファイルの構文チェック(エラーがないことを確認) sshd -t # 問題なければリロード systemctl reload sshd
動作確認はSFTPクライアントから行います。接続後、ジェイルの外(/etcなど)に移動できないことを確認してください。
# 別端末からSFTP接続して動作確認 sftp fileuser1@your-server # 接続後:ルートに移動して /etc が見えないことを確認 sftp> cd / sftp> ls # upload/ のみ表示されるはずです
2. 手動でchrootジェイルを構築する(汎用手順)
SFTPではなく、任意のコマンドをジェイル内で動かしたい場合は、必要なライブラリ・バイナリをジェイル内にコピーする作業が必要です。
# ジェイルのベースディレクトリ JAIL=/opt/myjail # 最低限必要なディレクトリ構造を作成 mkdir -p $JAIL/{bin,lib,lib64,etc,dev,proc,tmp} # /dev/null と /dev/random を作成 mknod -m 666 $JAIL/dev/null c 1 3 mknod -m 644 $JAIL/dev/random c 1 8 # bashをコピー cp /bin/bash $JAIL/bin/ # bashが依存するライブラリをコピー(lddで確認) ldd /bin/bash # 出力例: # linux-vdso.so.1 # /lib/x86_64-linux-gnu/libtinfo.so.6 # /lib/x86_64-linux-gnu/libc.so.6 cp /lib/x86_64-linux-gnu/libtinfo.so.6 $JAIL/lib/ cp /lib/x86_64-linux-gnu/libc.so.6 $JAIL/lib/ cp /lib64/ld-linux-x86-64.so.2 $JAIL/lib64/ # chrootして動作確認 chroot $JAIL /bin/bash
同様の手順でlsやidなどの必要なコマンドとその依存ライブラリをコピーすることで、任意のジェイル環境を構築できます。
3. バインドマウントで必要なディレクトリをジェイルに取り込む
ジェイル内でDNS名前解決が必要な場合など、/etc/resolv.confなどのシステムファイルをジェイル内に反映させたいケースがあります。ファイルのコピーではなくバインドマウントを使うと、本番の設定と自動的に同期されます。
# /etc/resolv.confをジェイル内にバインドマウント touch $JAIL/etc/resolv.conf mount --bind /etc/resolv.conf $JAIL/etc/resolv.conf # /proc をマウント(プロセス情報が必要な場合) mount -t proc proc $JAIL/proc # 恒久的に適用する場合は /etc/fstab に追記 # /etc/resolv.conf /opt/myjail/etc/resolv.conf none bind 0 0
中小企業でも今日からできること
「chrootジェイルを全サービスに適用する」のは現実的ではありませんが、まずSFTPユーザーの隔離から始めることを強くおすすめします。
多くの中小企業では「取引先や外部スタッフにファイルを渡すためのSFTP接続を許可している」という運用があります。このケースで最も怖いのは、SFTPアカウントが侵害された際にサーバー全体を探索されることです。上述のOpenSSH設定を入れるだけで、この被害を大幅に限定できます。
今日からできる優先順位は次のとおりです。
・Step 1: 外部公開しているSFTPユーザーがいれば、ChrootDirectory設定を即日適用する
・Step 2: FTPデーモン(vsftpd・ProFTPD)を使っている場合は、各ソフトウェアのchroot設定オプションを有効化する
・Step 3: ジェイル内のファイル構成を定期的に確認し、不要なコマンドやライブラリが増えていないかチェックする
姉妹サイトLinuxMaster.JPでは、SSHサーバーの詳細な設定管理についてもLPIC試験の範囲を含めて解説しています。Linuxの基礎から体系的に学びたい方はあわせてご参照ください。
また、chrootと組み合わせると効果的なのが、systemdのサービスサンドボックス機能です。systemdのPrivateTmp・NoNewPrivileges設定と組み合わせることで、プロセスの隔離をより多層的に実現できます。
よくある誤解と注意点
【注意1】chrootはrootによる脱出を防げない
最も重要な制限を理解してください。chrootは「root権限を持つプロセスには突破される」という設計上の限界があります。攻撃者がジェイル内でroot権限を取得できれば、chroot()システムコールを再実行して元のファイルシステムに抜け出すことが可能です。
chrootジェイル内ではroot権限で動くサービスをできる限り避けることが原則です。サービス起動後にsetuid()で一般ユーザー権限に降格する設計が望ましいです。
【注意2】ネットワーク・PID名前空間は分離されない
chrootはファイルシステムの見え方を変えるだけです。ネットワークソケットやPID(プロセスID)空間は共有されたままです。Dockerコンテナのような完全な分離ではありません。より高度な隔離が必要な場合は、Linuxの名前空間(namespaces)やcgroupsを組み合わせたコンテナ技術を検討してください。
【注意3】/proc や /dev のマウントに注意
ジェイル内に/procをマウントすると、プロセス情報がジェイル外に漏れる可能性があります。必要最小限のマウントに留め、noexec・nosuid・nodevオプションを必ず付けてマウントしてください。
【注意4】現代的な代替手段も検討する
新規構築のシステムであれば、chrootよりLinux capabilitiesやsystemdのサンドボックス機能のほうが設定が体系的で管理しやすいことが多いです。既存環境でchroot運用が定着している場合は引き続き有効ですが、新設サービスはsystemdのセキュリティディレクティブを優先的に検討することをおすすめします。

本記事のまとめ
| 項目 | ポイント |
|---|---|
| chrootの効果 | プロセスが見えるファイルシステムをジェイル内に限定し、侵害時の被害範囲を封じ込める |
| 最も簡単な適用 | OpenSSHのChrootDirectory + ForceCommand internal-sftpでSFTPユーザーを隔離 |
| ジェイルルートの要件 | 所有者がroot、rootのみ書き込み可(これを守らないとSSHDが起動拒否) |
| 限界 | root権限があれば脱出可能。ネットワーク・PID名前空間は共有のまま |
| モダンな代替 | systemdサンドボックス・Linux capabilities・コンテナ(要件に応じて選択) |
chrootジェイルは「古い技術」ではなく、設定の手軽さと確実な効果を兼ね備えた実用的な防御手段です。特にSFTPユーザーの隔離は、今日から誰でも設定できる対策として導入を検討してみてください。
PR
chrootジェイルをはじめ、PAM・SELinux・ファイアウォール設定まで、Linuxサーバーの堅牢化手法を体系的に学べる実践書。手を動かしながら理解を深めたい方に最適です。
