chroot環境を作る

perlも作れたし,前回のメモでforkを禁止するモジュールも作ったし,後やらないといけないのは/chroot環境を作ればllevalを移植できるはず.ということでchroot環境を作ってperlが動くところまで試してみました.

$ sudo mkdir /chroot
$ sudo mkdir /chroot/bin
$ sudo mkdir /chroot/lib64
$ sudo mkdir /chroot/usr
$ sudo mkdir /chroot/tmp
$ sudo mkdir /chroot/dev
$ sudo mkdir /chroot/etc
$ sudo mkdir /chroot/home
$ sudo mknod -m 666 /chroot/dev/null c 1 3
$ sudo mknod -m 666 /chroot/dev/zero c 1 5
$ sudo mknod -m 666 /chroot/dev/random c 1 8

と,これで必要最低限必要なディレクトリとファイルを作りました.まずはbashとlsが動くようにライブラリをコピーしましょう.ライブラリはlddで探すことができます.

$ ldd /bin/ls:
     linux-vdso.so.1 =>  (0x00007fff1698b000)
     libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003fc4a00000)
     librt.so.1 => /lib64/librt.so.1 (0x0000003fc7200000)
     libcap.so.2 => /lib64/libcap.so.2 (0x0000003fca200000)
     libacl.so.1 => /lib64/libacl.so.1 (0x0000003fc7600000)
     libc.so.6 => /lib64/libc.so.6 (0x0000003fc4200000)
     libdl.so.2 => /lib64/libdl.so.2 (0x0000003fc4600000)
     /lib64/ld-linux-x86-64.so.2 (0x0000003fc3e00000)
     libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003fc4e00000)
     libattr.so.1 => /lib64/libattr.so.1 (0x0000003fc6e00000)
$ ldd /bin/bash
     linux-vdso.so.1 =>  (0x00007fffeecaf000)
     libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003fc6600000)
     libdl.so.2 => /lib64/libdl.so.2 (0x0000003fc4600000)
     libc.so.6 => /lib64/libc.so.6 (0x0000003fc4200000)
     /lib64/ld-linux-x86-64.so.2 (0x0000003fc3e00000)

ここに出て来た/lib64配下のライブラリを/chroot/lib64にコピーします.んで,

sudo chroot --userspec=ec2-user /chroot

とすることでchroot環境に移ります.

$ sudo chroot --userspec=ec2-user /chroot
bash-4.1$ ls
bin  dev  etc  home  lib  lib64  tmp  usr
bash-4.1$ cd 
bash-4.1$ pwd
/home/ec2-user
bash-4.1$ exit
exit

ちなみに,色々入れた後に確認した結果を書いてるので,手順通りに作った場合とは表示が違うかもしれません.次にbashやlsと同じようにperlでもライブラリを調べて

$ ldd `which perl`
     linux-vdso.so.1 =>  (0x00007fff9b5ff000)
     libnsl.so.1 => /lib64/libnsl.so.1 (0x0000003fc8e00000)
     libdl.so.2 => /lib64/libdl.so.2 (0x0000003fc4600000)
     libm.so.6 => /lib64/libm.so.6 (0x0000003fc5600000)
     libcrypt.so.1 => /lib64/libcrypt.so.1 (0x0000003fc5a00000)
     libutil.so.1 => /lib64/libutil.so.1 (0x0000003fc9200000)
     libc.so.6 => /lib64/libc.so.6 (0x0000003fc4200000)
     /lib64/ld-linux-x86-64.so.2 (0x0000003fc3e00000)
     libfreebl3.so => /lib64/libfreebl3.so (0x0000003fc5e00000)

コマンドをいくつか実行してみて動かなかったらstraceを使って足りないライブラリを見つけては足して行くという作業を続けました.そして今の環境はこんな感じ.

$ tree --filelimit 18 /chroot
/chroot
├── bin
│     ├── bash
│     ├── curl
│     ├── ls
│     └── ping
├── dev
│     ├── null
│     ├── random
│     └── zero
├── etc
│     ├── group
│     ├── host.conf
│     ├── hosts
│     ├── localtime
│     ├── nsswitch.conf
│     ├── passwd
│     └── resolv.conf
├── home
│     └── ec2-user
│             └── perl5
...
├── lib64
│     ├── ld-linux-x86-64.so.2
│     ├── libacl.so.1
│     ├── libattr.so.1
│     ├── libcap.so.2
│     ├── libcrypt.so.1
│     ├── libc.so.6
│     ├── libdl.so.2
│     ├── libfreebl3.so
│     ├── libm.so.6
│     ├── libnsl.so.1
│     ├── libnss_dns.so.2
│     ├── libnss_files.so.2
│     ├── libpthread.so.0
│     ├── libresolv.so.2
│     ├── librt.so.1
│     ├── libselinux.so.1
│     ├── libtinfo.so.5
│     └── libutil.so.1
├── tmp
└── usr
    ├── bin
    │      ├── id
    │      └── strace
    ├── lib
    │      └── locale
    │               └── locale-archive
    └── lib64
        ├── libcurl.so.4
        └── libidn.so.11

29 directories, 44 files

この状況でchrootしてperlを動かすと,

$ sudo chroot --userspec=ec2-user /chroot
bash-4.1$ export PATH=/home/ec2-user/perl5/perlbrew/perls/perl-5.12.2/bin/:$PATH
bash-4.1$ perl -v

This is perl 5, version 12, subversion 2 (v5.12.2) built for x86_64-linux

Copyright 1987-2010, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

ってことで,llevalでの特徴となっているLWP::Simpleが動くかどうかを試してみると,

bash-4.1$ perl -MLWP::Simple -le 'getprint "http://www.perl.com"'
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" id="sixapart-standard">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="Movable Type Pro 5.02" />
<link rel="stylesheet" href="http://www.perl.com/pub/styles.css" type="text/css" />
<link rel="start" href="http://www.perl.com/pub/" title="Home" />
...

となるので,成功です.このとき,/etc/passwdは

ec2-user:x:222:500:EC2 Default User:/home/ec2-user:/bin/bash

同様に/etc/groupは

ec2-user:x:500:

としています.
ちなみに,今気になっているのはidコマンドの結果です.普通は

$ id
uid=222(ec2-user) gid=500(ec2-user) groups=500(ec2-user),10(wheel)

となるはずですが,chroot環境では

bash-4.1$ id
uid=222(ec2-user) gid=0 groups=500(ec2-user),0,1,2,3,4,6,10

となっています.なぜに0とかがでてくるのかよくわかっていません.大丈夫なのかな?