본문 바로가기
K8s/컨테이너 격리

리눅스 프로세스 격리 - filesystem

by 식사법 2024. 8. 31.
  • 리눅스 프로세스 격리 - filesystem
격리 기술은 Container만이 있는 것이 아니다. 해당 계시글은 지금까지의 프로세스 격리 기술은 하나씩 실습하여 정리하고 있다.

격리 기술의 역사

1 chroot를 통한 격리 구현

  • 특정 프로세스에게 특정 디렉토리를 root 디렉터리로 속이는 기술입니다. ( chroot = change root )
  • 현재는 탈옥이 가능하여 사용하지 않습니다. 탈옥을 통해 격리가 되어있더라도 외부로 접근할 수 있기 때문에 보안상 문제가 생기기 때문입니다

1) Chroot 격리 구현

더보기

1) 루트 디렉토리로 속일 폴더 생성

cd /tmp
mkdir myroot

 

2) chroot 명령어 사용

# chroot [옵션] {경로} {사용할 명령어}
chroot /tmp/myroot /bin/sh
  •  지금까지 잘 sh를 사용하고 있었는데 chroot 명령어와 함께 sh를 사용하니 에러가 출력되었습니다. 왜냐하면, chroot를 통해 현재 내 최상위 경로는 /tmp/chroot로 변경 된 상황에서 /tmp/chroot 라는 경로에는 /bin/sh 가 존재하지 않기 때문입니다 그렇다면, /bin/sh 를 myroot로 넣어주게 된다면 정상 실행하게 될 것 입니다.

 

3) /tmp/myroot 내부 /bin/sh 생성

  • 우선 sh의 위치와 관련있는 파일을 확인합니다
  • ldd 명령어는 이번에 처음알게 되었는데 실행파일이 사용하는 공유 라이브러리를 출력하는 명령어입니다다. 즉, 해당 프로그램이 실행될 때 필요로하는 동적 라이브러리를 보여줍니다.
which sh
ldd /bin/sh
  •  /bin/sh 는 linux-vdso.so.1 , /lib/x86_64-linux-gnu/libc.so.6, /lib64/ld-linux-x86-64.so.2 가 필요한것으로 보입니다. 
  • usr/bin/sh , /lib/x86_64-linux-gnu/libc.so.6, /lib64/ld-linux-x86-64.so.2 를 myroot로 이동시켜 줍니다
mkdir /tmp/myroot/bin
cp /usr/bin/sh /tmp/myroot/bin
mkdir -p /tmp/myroot/{lib64,lib/x86_64-linux-gnu}

cp /lib/x86_64-linux-gnu/libc.so.6 myroot/tmp/lib/x86_64-linux-gnu/
cp /lib64/ld-linux-x86-64.so.2 /tmp/myroot/lib64

 

4) 다시 chroot 명령어 사용

# chroot [옵션] {경로} {사용할 명령어}
chroot /tmp/myroot /bin/sh
  • 이번에는 정상실행 되지만 ls 명령어가 없기때문에 폴더 내부를 확인하지 못하는 상황입니다. ls를 가져와 다시 실행해 보겠습니다

5) ls 이동

which ls
ldd /usr/bin/ls
  • 이번에는 libselinux. so.1,libc.so.6, libpcre2-8.so.0 가 필요한것을 확인할 수 있습니다
cp /usr/bin/ls /tmp/myroot/bin/
cp /lib/x86_64-linux-gnu/{libselinux.so.1,libc.so.6,libpcre2-8.so.0} myroot/lib/x86_64-linux-gnu/
cp /lib64/ld-linux-x86-64.so.2 myroot/lib64
chroot /tmp/myroot /bin/sh
# ls 실행
  • 정상적으로 ls 명령어를 사용하고 있는 모습입니다

6) 탈옥 시도

cd ..
cd ../../../../
ls
  • /tmp/myroot 가 가장 최상위 경로가 되었기 때문에 상위경로로 나가려 해도 나가지지 않는 모습입니다.

2) Chroot 에서 ps 실행

더보기

1) ps 명령어 이동

ldd /usr/bin/ps;
cp /usr/bin/ps /tmp/myroot/bin/;
cp /lib/x86_64-linux-gnu/{libprocps.so.8,libc.so.6,libsystemd.so.0,liblzma.so.5,libgcrypt.so.20,libgpg-error.so.0,libzstd.so.1,libcap.so.2} /tmp/myroot/lib/x86_64-linux-gnu/;
mkdir -p /tmp/myroot/usr/lib/x86_64-linux-gnu;
cp /usr/lib/x86_64-linux-gnu/liblz4.so.1 /tmp/myroot/usr/lib/x86_64-linux-gnu/;
cp /lib64/ld-linux-x86-64.so.2 /tmp/myroot/lib64/;
  • ps명령어를 정상적으로 이동했음에도 사용이 되지 않고 있습니다. ps 명령어는 /proc에서 커널과 프로세스에 대한 정보를 가져옵니다. mount 명령어를 이동하고 /proc를 마운트 해보겠습니다

2) Mount 이동 및 실행

mkdir /tmp/myroot/proc
ldd /usr/bin/mount;
cp /usr/bin/mount /tmp/myroot/bin/;
cp /lib/x86_64-linux-gnu/{libmount.so.1,libc.so.6,libblkid.so.1,libselinux.so.1,libpcre2-8.so.0} /tmp/myroot/lib/x86_64-linux-gnu/;
cp /lib64/ld-linux-x86-64.so.2 /tmp/myroot/lib64/;
  • ps명령어를 정상적으로 이동했음에도 사용이 되지 않고 있습니다. ps 명령어는 /proc에서 커널과 프로세스에 대한 정보를 가져옵니다. mount 명령어를 이동하고 /proc를 마운트 해보겠습니다

3) chroot 실행 후 ps 사용

  • 정상적으로 ps 가 실행되는 것을 확인할 수 있습니다

chroot 탈옥 (이 문제로 chroot를 통한 격리는 사용되지 못한다 )

더보기
  • 탈옥 코드 - escape.c 
  • 최상위 경로로 가서 그경로를 root로 다시 설정하는 c 코드이다
#include <sys/stat.h>
#include <unistd.h>

int main(void)
{
  mkdir(".out", 0755);
  chroot(".out");
  chdir("../../../../../");
  chroot(".");

  return execl("/bin/sh", "-i", NULL);
}

 

1) 컴파일 후 chroot를 통해 실행

gcc -o /tmp/chroot/escape /tmp/chroot/escape.c
  • 위의 코드 파일을 실행한 뒤 최상위 경로로 이동된것을 확인할 수 있다.

2 마운트 네임스페이스 + Pivot_root를 통해 격리 구현

  • mount namespace

마운트 네임스페이스를 형성하게 된다면 서로 독립적인 Mount point를 가지게 됩니다. 즉 A 네임스페이스는 B라는 네임스페이스 파일들을 건들일 수 없게 됩니다.

  • pivot root

pivot root는 chroot와 비슷하지만 chroot 와는 달리 현재 루트 파일 시스템을 완전히 교체하는 것이며, 새로운 루트 파일 시스템을 설정합니다.

pivot의 경우 루트파일시스템에 영향이 갈 수 있음으로 mount namespace를 생성해 기존 루트파일 시스템에 영향이 가지 않도록 해야합니다.

 

pivot_root와 mount namespace를 활용해 격리 구현

더보기

 

 

1) mount namespace 생성

# mount namespace를 생성하고 해당 namespace에서 /bin/sh를 실행합니다
unshare --mount /bin/sh

이렇게 네임 스페이스를 생성하더라도 기본적으로 기존 마운트 정보를 복사하기 때문에 df -h 를 수행하더라도 결과는 같습니다.

새로운 namespace

 

root namespace

 

2) 새로운 namespace에서 mount 진행 및 파일 복사 후 확인

mkdir new_root
mount -t tmpfs none new_root
cp -r myroot/* new_root
새로운 namespace
root namespace

 

3) Pivot 실행

mkdir new_root/put_old
cd new_root
pivot_root . put_old #이렇게 한다면 new_root라는 경로가 새로운 namespace의 root경로가 됩니다

 

새로운 namespace
root namespace
  • root경로가 바뀌었기 때문에 ping이 깔리지 않은 새로운 namespace는 정상적으로 수행하지 못합니다

4) 탈옥 수행

  • chroot 에서 사용했던 탈옥을 수행했음에도 여전히 기존 경로를 바라보고 있는모습 

'K8s > 컨테이너 격리' 카테고리의 다른 글

컨테이너 격리 - process  (0) 2024.08.31
도커 기본 설명  (0) 2024.08.31