다음 이전 차례

4. 셸 스크립트

4.1 Virtfs

각각의 도메인은 자신만의 디렉토리 구조를 가진다. 따라서 만약 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

4.2 Virtexec

가상 환경에서 명령어를 실행시키기 위해서 당신은 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를 만들 수 있다. 만약 당신의 프로그램이 공유 라이브러리를 필요로 한다면 바이너리와 마찬가지로 가상 파일시스템에 위치시킬 수 있다.

4.3 공고(Note)

나는 모든 스크립트들을 /usr/local/bin에 설치했다. 그 이외에 가상 파일시스템에 넣고싶지 않은 것들은 /usr/local에 두었다. 스크립트는 /usr/local에 있는 파일을 가상 파일시스템으로 복사하지 않는다. 가상 파일시스템으로 넘어오면 안되는 중요한 파일들은 반드시 가상 시스템에서 제거되어야 한다. 한 예로, 내 시스템에는 ssh가 설치되어 있는데, 모든 가상의 파일 시스템의 서버에서는 개인키(private key)를 원하지 않기 때문에, virtfs를 실행시킨 이후에 각각의 가상 파일 시스템에서 이것을 제거했다. 또한 resolv.conf를 바꾸고, 그 안에 있던 다른 도메인들의 이름을 가진 모든 것들을 삭제했다. 이런 것들로는 /etc/hosts나 /etc/HOSTNAME 등이 있다.

내가 virtexec로 심볼릭 링크시킨 프로그램들이다:


다음 이전 차례