LoginSignup
3
3

More than 3 years have passed since last update.

一般ユーザー権限で chroot を使う

Posted at

chroot を使いたい

chroot 環境を作成し、一般ユーザー権限で使用するまでの手順をまとめます。
一般ユーザー権限での chroot を制限されている環境では、ファイルケーパビリティを設定した chroot (→mychroot) を作成して、制限を回避します。


$ cp -a /usr/sbin/chroot mychroot
$ sudo setcap cap_sys_chroot+ep mychroot

→chroot の代わりに mychroot を使う。
$ mychroot NEWROOT COMMAND

どういうこと?

そもそもは、リモートからアップロードされたアーカイヴファイルを展開するのに、chroot を使いたいな…と思ったことが発端です。

例えば、こういう処理のとき:


$ cd /var/spool/upload/
$ tar xf ./archive.tar
$ unzip ./archive.zip

ここで、/var/spool/upload/ に chroot して、tar や unzip を実行すれば、
悪意で作りこまれたアーカイヴで親ディレクトリを攻められも大丈夫だろう…という目算です。つまり

  • パストラヴァーサル攻撃への対策

を想定しています。

環境

CentOS 7 で確認しました。

まずは chroot 環境を作成する

chroot するディレクトリを作り、その配下に chroot 環境下で使用するコマンドと、コマンドが使用する shared library を集めれば良いです。
例えば bash、touch、ls、rm だけ使える chroot 環境をざっくり作るには、以下のようにします。


chr="/path/to/testroot/"
mkdir -p $chr
mkdir -p $chr/{bin,lib,lib64}
cd $chr
cp -v /bin/{bash,touch,ls,rm} $chr/bin

for F in bin/*
do
    list="$(ldd ${F} | egrep -o '/lib.*\.[0-9]')"
    for i in $list; do cp -v --parents "$i" "${chr}"; done
done

※この手順は、How to Use the chroot Command on Linux を参考にし、一部改変したものです。

この後、chroot "${chr}" で、chroot 環境に入ります。

…言うまでもありませんが、実運用に供するには、shell を削除する、パーミッションを厳しく設定する、など調整が必要ですよ。この chroot 環境では出来ることが多すぎて chroot の有難みが薄いです。

一般ユーザー権限で chroot 環境を使用するには

ところが一般ユーザー権限での chroot は、多くの環境で制限されています。
CentOS 7 で試したところ、以下のエラーが出ました。


$ chroot ./testroot
chroot: cannot change root directory to ./testroot: Operation not permitted
$

もちろん sudo が適切に設定されていれば sudo chroot ./testroot で入れますが…root 権限で chroot 環境に入っても嬉しさ半減ですね。もっと小さい権限で入りたいところです。

さて、CentOS 7 において chroot のこの制限は、ケーパビリティの機能によって実現されています。なので一般ユーザーが chroot するには、ケーパビリティ cap_sys_chroot+ep を追加した chroot を使う手があります。


$ cp -a /usr/sbin/chroot mychroot
$ sudo setcap cap_sys_chroot+ep mychroot    # setcap には root 権限が必要です

# 確認:
$ getcap -v /usr/sbin/chroot
/usr/sbin/chroot
$ getcap -v ./mychroot
./mychroot = cap_sys_chroot+ep
$

この mychroot (=ケーパビリティ cap_sys_chroot+ep を追加した chroot)を使えば、一般ユーザー権限で chroot 環境を使用できます。


$ mychroot ./testroot
bash-4.2$

# 確認:
bash-4.2$ pwd
/
bash-4.2$ ls -lia .
total 0
 9623382 drwxrwxr-x. 4 1000 1000  30 Jan 12 01:27 .
 9623382 drwxrwxr-x. 4 1000 1000  30 Jan 12 01:27 ..  # inode が . と同じですね
19648905 drwxrwxr-x. 2 1000 1000  67 Jan 12 01:49 bin
26370704 drwxrwxr-x. 2 1000 1000 214 Jan 12 01:27 lib64
bash-4.2$

/usr/sbin/chroot に直接ファイルケーパビリティを設定するのは避けるべきでしょう。影響の範囲が OS 全体に及び、どこにどんな影響が出るのか把握が困難になるためです。代わりに、chroot をコピーした mychroot にファイルケーパビリティを追加し使用する方が、より良い方法です。

その他

ファイルケーパビリティを設定したファイルは、ls --color=auto で色が付きます。

dircolors.png

dircolors に CAPABILITY 30;41 # file with capability の設定があります。dircolors --print-database で確認できます。

資料

getcap / setcap

linux - How to run a command in a chroot jail not as root and without sudo? - Stack Overflow の、Corey Henderson 氏のコメントが参考になりました。

You can make use of linux capabilities to give your binary the ability to call chroot() w/o being root. As an example, you can do this to the chroot binary. As non-root, normally you'd get this:

$ chroot /tmp/
chroot: cannot change root directory to /tmp/: Operation not permitted

But after you run the setcap command:

sudo setcap cap_sys_chroot+ep /usr/sbin/chroot

It will let you do the chroot call.

I don't recommend you do this to the system's chroot, that you instead do it to your own program and call chroot. That way you have more control over what is happening, and you can even drop the cap_sys_chroot privilege after you call it, so successive calls to chroot in your program will fail.

ref. linux - How to run a command in a chroot jail not as root and without sudo? - Stack Overflow

capabilities / ケーパビリティ

man 7 capabilities から抜粋します。ケーパビリティがどんな要請から出来上がったものか良くわかります。

権限のチェックを行う観点から見ると、伝統的な UNIX の実装では プロセスは二つのカテゴリーに分類できる: 特権 プロセス (実効ユーザーID が 0 のプロセス。ユーザーID 0 は スーパーユーザーや root と呼ばれる) と 非特権 プロセス (実効ユーザーID が 0 以外のプロセス) である。 非特権プロセスでは、プロセスの資格情報 (通常は、実効UID 、実効GID と追加のグループリスト) に基づく権限チェックが行われるのに対し、 特権プロセスでは全てのカーネルの権限チェックがバイパスされる。

バージョン 2.2 以降の Linux では、 これまでスーパーユーザーに結び付けられてきた権限を、 いくつかのグループに分割している。これらのグループは ケーパビリティ(capability) と呼ばれ、グループ毎に独立に有効、無効を設定できる。 ケーパビリティはスレッド単位の属性である。

CAP_SYS_CHROOT

chroot(2). を呼び出す。

ref. Man page of CAPABILITIES

関連コマンド:

fakeroot / fakechroot

fakeroot / fakechroot というコマンドがあるらしいです(未調査)。

fakechroot - gives a fake chroot environment

fakechroot runs a command in an environment were is additional possibility to use chroot(8) command without root privileges. This is useful for allowing users to create own chrooted environment with possibility to install another packages without need for root privileges.

ref. fakechroot(1): gives fake chroot environment - Linux man page

参考文献

capabilities:

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3