chroot에서 실행 중임을 어떻게 알 수 있습니까?


46

chroot 및 독립형 시스템으로 사용할 수있는 유닉스 설치가 있습니다. chroot로 실행 중이면 호스트 시스템과 충돌하거나 중복 될 수 있으므로 모든 서비스 (cron, inetd 등)를 실행하고 싶지 않습니다.

chroot에서 실행 중인지에 따라 다르게 동작하는 쉘 스크립트를 작성하려면 어떻게해야합니까? 나의 즉각적인 요구는 /procchroot에 마운트 된 최신 Linux 시스템이며 스크립트는 루트로 실행되지만 더 이식 가능한 답변도 환영합니다. ( 없는 Linux의 경우 / proc가 마운트되지 않은 경우 chroot에서 실행 중임을 어떻게 알 수 있습니까?) 을 참조하십시오 /proc.

더 일반적으로, 다른 격리 방법에 적합한 제안은 흥미로울 것입니다. 실질적인 질문은,이 시스템은 어떤 서비스를 실행해야합니까? (응답은 chroot에서는 아니오이고 본격적인 가상 머신에서는 그렇습니다. 감옥이나 컨테이너와 같은 중간 사례에 대해서는 모르겠습니다.)

답변:


45

여기서 내가 한 것은 init프로세스 의 루트 (PID 1)가 현재 프로세스의 루트와 같은지 테스트하는 것입니다. 하지만 /proc/1/root항상에 대한 링크입니다 /(하지 않는 init자체가 chroot에,하지만 그게 내가 약을 신경 경우이 아니다)는 "마스터"루트 디렉토리에 이르게 다음,. 이 기술은 데비안의 일부 유지 보수 스크립트에서 사용됩니다 (예 : chroot에서 설치 후 udev 시작을 건너 뛰는 등).

if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
  echo "We are chrooted!"
else
  echo "Business as usual"
fi

(이것은 chrootchroot 된 프로세스가 루트 액세스 권한을 가진 경우 보안에 쓸모없는 이유의 또 다른 예입니다 . 루트가 아닌 프로세스는 읽을 수 없지만 PID 1234가 동일한 프로세스로 실행중인 프로세스가있는 경우 /proc/1/root따를 수 있습니다 /proc/1234/root사용자.)

루트 권한이없는 경우에, 당신은 볼 수 /proc/1/mountinfo/proc/$$/mountinfo(에 설명 간단히 filesystems/proc.txt리눅스 커널 문서에 ). 이 파일은 세계적으로 읽을 수 있으며 프로세스의 파일 시스템보기에서 각 마운트 지점에 대한 많은 정보를 포함합니다. 해당 파일의 경로는 독자 프로세스 (있는 경우)에 영향을 미치는 chroot에 의해 제한됩니다. 프로세스 읽기 /proc/1/mountinfo가 전역 루트와 다른 파일 시스템으로 chroot 된 경우 (pid 1의 루트가 글로벌 루트라고 가정)에 대한 항목이 /나타나지 않습니다 /proc/1/mountinfo. 프로세스 읽기 /proc/1/mountinfo가 글로벌 루트 파일 시스템의 디렉토리에 chroot 된 경우에 대한 항목이 /표시 /proc/1/mountinfo되지만 마운트 ID가 다릅니다. 또한 루트 필드 ($4)는 chroot가 마스터 파일 시스템에서 어디에 있는지 나타냅니다.

[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]

이것은 순수한 리눅스 솔루션입니다. 충분히 비슷한 다른 유닉스 변종에 일반화 할 수 있습니다 /proc(Solaris는 비슷 /proc/1/root하지만 그렇지는 않습니다 mountinfo).


1
이것은 임의의 PID를 가지고 있기 때문에 OpenBSD에서는 작동하지 않습니다 . 루트 프로세스는 기본적으로 PID 1이 아닙니다. 이제 이유를 알고 있습니다!
Adam Katz

@AdamKatz "... init (8)과 같은 몇 가지 명백한 예외가 있습니다." 그래서 어느 것입니까?
muru

@ 무루 : 아, uck. 넌 날 쓰러 뜨 렸어 init(8)하드 코딩 된 자연이 필요하지 않은 한 왜 슬롯이 필요 하지 않은지 잘 모르겠습니다 (여전히 왜 그런지 확실하지 않습니다 ). 물론, BSD는 chroot보다 훨씬 더 고급 감옥을 가지고 있기 때문에 이것이 얼마나 문제가 있는지조차 확실하지 않습니다.
Adam Katz

4
@AdamKatz 그 반대입니다 : pid 1은 특별한 역할을합니다 (좀비를 가져 와야하며 SIGKILL에 면역입니다). init 프로그램은 해당 역할의 구현입니다. 내 대답이 OpenBSD에서 작동하지 않는 이유는 이것과 아무런 관련이 없습니다. OpenBSD에는 Solaris / Linux와 같은 것이 없기 때문 /proc입니다. 내 대답은 어쨌든 리눅스 이외의 것을 다루기위한 것이 아닙니다.
Gilles 'SO- 악마 그만'

@Gilles OpenBSD가 어떤 식 으로든 패배했을 것이라고 생각했습니다. 그럼에도 불구하고, 이러한 모든 특수 역할 항목이 임의의 PID (결과없이)에 적용 할 수 없다는 사실에 놀랐습니다. 이는 필자가 이탤릭체로 된 "왜"에 대한 의미였습니다.
Adam Katz

22

에서 언급 한 바와 같이 휴대용 inode 번호를 찾는 방법내에서 chroot로 검출 , 당신의 아이 노드 번호가 있는지 확인할 수 /있습니다 2:

$ ls -di /
2 /

2와 다른 inode 번호는 겉보기 루트가 파일 시스템의 실제 루트가 아님을 나타냅니다. 이것은 마운트 포인트 또는 임의의 루트 inode 번호를 가진 운영 체제 에서 루팅되는 chroot를 감지하지 않습니다 .


이 휴리스틱은 어떤 파일 시스템에서 작동합니까?
Gilles 'SO- 악한 중지

ext3 및 hfs에서 테스트되었습니다.
l0b0

그래서 나는 장난을 쳤으며 루트 권한이 필요없는보다 안정적인 방법을 찾았습니다 (Linux 만 해당). 나는 여전히 반례 또는 더 휴대용 방법에 열려 있습니다.
Gilles 'SO- 악마 그만

6
이것은 ext [234]에 해당하지만 모든 파일 시스템에 해당되는 것은 아닙니다. 또한 루트가 파일 시스템의 루트인지 테스트하여 실제 루트로 마운트되지 않을 수도 있습니다. 다시 말해, / jail 및에 다른 파티션을 마운트 chroot /jail하면이 테스트의 실제 루트처럼 보입니다.
psusi

1
@AdamKatz 분명히 아닙니다. openbsd 6.0- 안정적으로 테스트 된 inode 번호는 실제 루트 경로의 경우 2이고 chroot의 난수입니다.
Dmitri DB

5

여기에 나열된 다른 많은 옵션만큼 이식성이 좋지는 않지만 데비안 기반 시스템 인 경우을 사용해보십시오 ischroot.

참조 : https://manpages.debian.org/jessie/debianutils/ischroot.1.en.html

ischroot를 사용하여 콘솔에서 직접 상태를 얻으려면 다음을 수행하십시오.

ischroot;echo $?

종료 코드 :

0 if currently running in a chroot
1 if currently not running in a chroot
2 if the detection is not possible (On GNU/Linux this happens if the script is not run as root).
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.