각각의 도메인은 자신만의 디렉토리 구조를 가진다. 따라서 만약
chroot를 사용하려고 한다면, 당신은 공유 라이브러리나 바이너리
실행파일들, 설정 파일 등을 복제하는 과정이 필요하다. 나는 내가 만든
각각의 도메인에 대해서 /virtual/domain1.com을 사용한다.
물론 더 많은 디스크의 공간이 필요하게 되지만, 그것이 새로운 머신과 네트워크 카드를 설치하는 것보다는 값이 저렴하다. 만약 당신이 공간을 절약하고 싶다면 하드 링크를 이용할 수 있는데, 내 경우 이 방법을 사용하면 2M가 약간 넘는 공간만을 사용하게 된다. 하지만, 이 스크립트는 가급적 일반적인 시스템을 만들기 위해 메인 파일시스템에서 모든 파일을 복사하려 할 것이다.
여기 간단한 virtfs 스크립트가 있다:
#!/bin/sh
echo '$Revision: 1.1.1.1 $'
echo -n "Enter the domain name: "
read domain
if [ "$domain" = "" ]
then
echo Nothing entered: aborting
exit 0
fi
leadingdir=/virtual
echo -n "Enter leading dir: (Enter for default: $leadingdir): "
read ans
if [ "$ans" != "" ]
then
leadingdir=$ans
fi
newdir=$leadingdir/$domain
if [ -d "$newdir" ]
then
echo New directory: $newdir: ALREADY exists
exit 0
else
echo New directory: $newdir
fi
echo Create $newdir
mkdir -p $newdir
echo Create bin
cp -pdR /bin $newdir
echo Create dev
cp -pdR /dev $newdir
echo Create dev/log
ln -f /virtual/log $newdir/dev/log
echo Create etc
mkdir -p $newdir/etc
for i in /etc/*
do
if [ -d "$i" ]
then
continue
fi
cp -pd $i $newdir/etc
done
echo Create etc/skel
mkdir -p $newdir/etc/skel
echo Create home
for i in a b c d e f g h i j k l m n o p q r s t u v w x y z
do
mkdir -p $newdir/home/$i
done
echo Create home/c/crc
mkdir -p $newdir/home/c/crc
chown crc.users $newdir/home/c/crc
echo Create lib
mkdir -p $newdir/lib
for i in /lib/*
do
if [ -d "$i" ]
then
continue
fi
cp -pd $i $newdir/lib
done
echo Create proc
mkdir -p $newdir/proc
echo Create sbin
cp -pdR /sbin $newdir
echo Create tmp
mkdir -p -m 0777 $newdir/tmp
chmod +t $newdir/tmp
echo Create usr
mkdir -p $newdir/usr
echo Create usr/bin
cp -pdR /usr/bin $newdir/usr
echo Create usr/lib
mkdir -p $newdir/usr/lib
echo Create usr/lib/locale
cp -pdR /usr/lib/locale $newdir/usr/lib
echo Create usr/lib/terminfo
cp -pdR /usr/lib/terminfo $newdir/usr/lib
echo Create usr/lib/zoneinfo
cp -pdR /usr/lib/zoneinfo $newdir/usr/lib
echo Create usr/lib/\*.so\*
cp -pdR /usr/lib/*.so* $newdir/usr/lib
echo Create usr/sbin
cp -pdR /usr/sbin $newdir/usr
echo Linking usr/tmp
ln -s /tmp $newdir/usr/tmp
echo Create var
mkdir -p $newdir/var
echo Create var/lock
cp -pdR /var/lock $newdir/var
echo Create var/log
mkdir -p $newdir/var/log
echo Create var/log/wtmp
cp /dev/null $newdir/var/log/wtmp
echo Create var/run
cp -pdR /var/run $newdir/var
echo Create var/run/utmp
cp /dev/null $newdir/var/run/utmp
echo Create var/spool
cp -pdR /var/spool $newdir/var
echo Linking var/tmp
ln -s /tmp $newdir/var/tmp
echo Create var/www/html
mkdir -p $newdir/var/www/html
chown webmast.www $newdir/var/www/html
chmod g+s $newdir/var/www/html
echo Create var/www/master
mkdir -p $newdir/var/www/master
chown webmast.www $newdir/var/www/master
echo Create var/www/server
mkdir -p $newdir/var/www/server
chown webmast.www $newdir/var/www/server
exit 0
가상 환경에서 명령어를 실행시키기 위해서 당신은 chroot를
이용하여 디렉토리를 변경한 뒤 명령어를 실행해야만 한다. 여기 어떤
명령에 대해서 이런 기능을 수행할 수 있는 특별한 셸스크립트인
virtexec를 소개한다:
#!/bin/sh
echo '$Revision: 1.1.1.1 $'
BNAME=`basename $0`
FIRST4CHAR=`echo $BNAME | cut -c1-4`
REALBNAME=`echo $BNAME | cut -c5-`
if [ "$BNAME" = "virtexec" ]
then
echo Cannot run virtexec directly: NEED a symlink
exit 0
fi
if [ "$FIRST4CHAR" != "virt" ]
then
echo Symlink not a virt function
exit 0
fi
list=""
num=1
for i in /virtual/*
do
if [ ! -d "$i" ]
then
continue
fi
if [ "$i" = "/virtual/lost+found" ]
then
continue
fi
list="$list $i $num"
num=`expr $num + 1`
done
if [ "$list" = "" ]
then
echo No virtual environments exist
exit 0
fi
dialog --clear --title 'Virtexec' --menu Pick 20 70 12 $list 2> /tmp/menu.$$
if [ "$?" = "0" ]
then
newdir=`cat /tmp/menu.$$`
else
newdir=""
fi
tput clear
rm -f /tmp/menu.$$
echo '$Revision: 1.1.1.1 $'
if [ ! -d "$newdir" ]
then
echo New directory: $newdir: NOT EXIST
exit 0
else
echo New directory: $newdir
fi
echo bname: $BNAME
echo realbname: $REALBNAME
if [ "$*" = "" ]
then
echo args: none
else
echo args: $*
fi
echo Changing to $newdir
cd $newdir
echo Running program $REALBNAME
chroot $newdir $REALBNAME $*
exit 0
이 스크립트가 실행되기 위해서 당신 시스템에 dialog 프로그램이
설치되어 있어야 한다는 것을 주의하라. virtexec를 사용하기 위해서는 단지
심볼릭 링크를 해주면 된다. 예를 들면 다음과 같다.
ln -s /usr/local/bin/virtexec /usr/local/bin/virtpasswd ln -s /usr/local/bin/virtexec /usr/local/bin/virtvi ln -s /usr/local/bin/virtexec /usr/local/bin/virtpico ln -s /usr/local/bin/virtexec /usr/local/bin/virtemacs ln -s /usr/local/bin/virtexec /usr/local/bin/virtmailq
링크를 시킨 후 virtvi를 실행시키면 가상 시스템의 vi를 실행시킬 것이다. 마찬가지로 virtpasswd는 가상 시스템의 사용자 비밀번호를 바꿀 것이고, virtmailq는 가상 공간의 메일 큐(queue)를 확인할 것이다. 당신은 원하는 만큼 virtexec를 만들 수 있다. 만약 당신의 프로그램이 공유 라이브러리를 필요로 한다면 바이너리와 마찬가지로 가상 파일시스템에 위치시킬 수 있다.
나는 모든 스크립트들을 /usr/local/bin에 설치했다. 그 이외에 가상 파일시스템에 넣고싶지 않은 것들은 /usr/local에 두었다. 스크립트는 /usr/local에 있는 파일을 가상 파일시스템으로 복사하지 않는다. 가상 파일시스템으로 넘어오면 안되는 중요한 파일들은 반드시 가상 시스템에서 제거되어야 한다. 한 예로, 내 시스템에는 ssh가 설치되어 있는데, 모든 가상의 파일 시스템의 서버에서는 개인키(private key)를 원하지 않기 때문에, virtfs를 실행시킨 이후에 각각의 가상 파일 시스템에서 이것을 제거했다. 또한 resolv.conf를 바꾸고, 그 안에 있던 다른 도메인들의 이름을 가진 모든 것들을 삭제했다. 이런 것들로는 /etc/hosts나 /etc/HOSTNAME 등이 있다.
내가 virtexec로 심볼릭 링크시킨 프로그램들이다: