ChrootDirectoryを使ってsshでchroot環境の作成
システムグループに所属する、鰯(いわし)です。
最近ハマっているのは、AWSとnode.js+express.jsです。 本日は、OpenSSH4.8以降で追加されたChrootDirectoryを使ってssh/chroot環境の作成を行いましたので、メモ的に作業ログをここに載せちゃいます。
ちなみにですが、昨今、弊社ではAWSの環境が増えて来て、テスト的になにかするのもAWSのAmazon Linuxで気軽にインスタンス起動って感じでやってますので、作業環境はAWSのAmazon Linuxを前提に進めさせて頂きます。
1 2 3 |
[sourcecode lang="bash"] $ uname -r 3.2.39-6.88.amzn1.x86_64 [/sourcecode] |
chroot環境作成
まずは、sshdの設定ですが、こんな感じの環境を作成します。
/etc/ssh/sshd_config
1 |
[sourcecode lang="plain"] Match Group *,!wheel ChrootDirectory /chroot [/sourcecode] |
あとは、chroot環境用に最低限必要なものを用意する感じですが、何もなさ過ぎだと不便なので、多少のものは用意しつつという感じで、そろえます、個人的に環境とかの用意は、Chefなどでも良いんですが、シンプルにshellで走らせる方が、どこでも動く感じで好きです。
なので、環境作成用に作成したshellを貼付けておきます、あと、こういう環境作成用途のshellは、再度、実行しても問題ないように、組んでおくと、間違って実行してしまった場合や、少しずつ環境に追加していく作業なども、実行し直せば良いだけなので、楽で良いです。
という事で、以下のスクリプトをrootユーザで実行して環境構築します。 変更した場合などは、修正後に再度実行すれば追加のものが処理される感じなので、よしなにやってください。
1 2 |
[sourcecode lang="bash"] #!/bin/bash ALLOW_CMD="sh bash clear env hostname printf ls id find touch mkdir cp mv rm pwd chmod cat less more vi id ssh scp sftp ping tty nc screen" ROOT=/chroot mkdir -p $ROOT && chmod 755 $ROOT test ! -e $ROOT && exit 1 cd $ROOT mkdir -p {bin,lib,lib64,home,etc,usr,tmp} mkdir -p usr/{bin,local} mkdir -p usr/local/bin LINKED_DIRS=( /etc/profile.d /usr/share/terminfo ) LINKED_FILES=( /etc/profile /etc/bashrc /etc/inputrc /etc/openldap/ldap.conf /etc/nsswitch.conf /etc/hosts /etc/fstab ) for d in ${LINKED_DIRS[@]} do test -d $ROOT$d && rm -rf $ROOT$d mkdir -p `dirname $ROOT$d` cp -Rpf $d $ROOT$d done for f in ${LINKED_FILES[@]} do test -f $ROOT$f && rm -f $ROOT$f mkdir -p `dirname $ROOT$f` cp -pf $f $ROOT$f done for prog in `which $ALLOW_CMD`; do test -e ./$prog && continue cp -p $prog ./$prog # obtain a list of related libraryes ldd $prog > /dev/null if [ "$?" = 0 ] ; then LIBS=`ldd $prog | awk '{ print $3 }'` for l in $LIBS; do mkdir -p ./`dirname $l` > /dev/null 2>&1 cp $l ./$l > /dev/null 2>&1 done fi done REQUIRED_SO="/lib/libnss_compat.so.2 /lib/libnsl.so.1 /lib/libnss_files.so.2 /lib/ld-linux.so.2 /lib/libc.so.6 /lib/libm.so.6 /lib/libpthread.so.0 /lib/librt.so.1 /lib/libthread_db.so.1" for so in $REQUIRED_SO; do test -e ./$so && continue mkdir -p ./`dirname $so` > /dev/null 2>&1 cp $so ./$so > /dev/null 2>&1 done if [ ! -e usr/bin/groups ]; then echo '#!/bin/bash id -Gn' > usr/bin/groups chmod 755 usr/bin/groups fi [/sourcecode] |
環境が構築されたら、/etc/fstab に、proc/dev とかの mount 設定追加する感じです
1 |
[sourcecode lang="bash"] mkdir /chroot/{proc,dev}; echo " /dev /chroot/dev none bind 0 0 " >> /etc/fstab echo " # for chroot environment mount --rbind /proc /chroot/proc mount --rbind /sys /chroot/sys " >> /etc/rc.local [/sourcecode] |
追記:2013/03/14 11:30 fstabへの記載ですが、間違ってたので訂正と /dev 以外の /proc, /sys は、なぜか fstab だとタイミングの問題かマウントされても中が空っぽ状態… やむなく、rc.local に入れ直して、正常にマウントできました…
ログインユーザの作成
sshでログインさせるユーザは、こんな感じで追加してます。
今回、ハマったのは、sshdの鍵認証させるときに、ホームディレクトリのPathを /home/username って感じで設定した場合、 鍵の認証をする時は、 /home/username/.ssh を参照するので、ログイン後の /chroot/home/username/.ssh は見てくれない事でしたね。
なので、以下のスクリプトでは、 本来のホームディレクトリは、/chroot 以下へ用意しつつ、 /home/username/.ssh だけシンボリックリンクを貼っとくようにしてます。
1 |
[sourcecode lang="bash"] #!/bin/bash ROOT=/chroot if [ -z $1 ]; then echo 'Undefined Username'; exit 1; fi useradd $1 || exit 1 mv /home/$1 $ROOT/home/ grep /etc/passwd -e "^$1" >> $ROOT/etc/passwd grep /etc/group -e "^$1" >> $ROOT/etc/group grep /etc/shadow -e "^$1" >> $ROOT/etc/shadow mkdir /home/$1 && chown -R $1. /home/$1 && chmod 700 /home/$1 sudo -u $1 ln -nfs $ROOT/home/$1/.ssh /home/$1/.ssh [/sourcecode] |
ユーザ作成が完了したら、あとは通常のsshのログイン設定 authorized_keys とかを設定すれば、たぶんOKです。 今回、いろいろハマりながらも、お世話になったサイトを紹介させて頂きます。 ご参考までにどうぞ
http://d.hatena.ne.jp/hogem/20100122/1264169759
http://www.sssg.org/blogs/hiro345/archives/9147.html
http://blog.layer8.sh/ja/2011/12/16/chroot%E3%82%92%E8%A8%AD%E5%AE%9Acentos/