chroot에서 실행 중인지 어떻게 알 수 있나요?

chroot에서 실행 중인지 어떻게 알 수 있나요?

나는 chroot와 독립 실행형 시스템 모두로 작동해야 하는 유닉스 설치를 가지고 있습니다. chroot로 실행 중인 경우 호스트 시스템과 충돌하거나 중복될 수 있는 서비스(cron, inetd 등)가 실행되는 것을 원하지 않습니다.

chroot에서 실행되는지 여부에 따라 다르게 동작하는 쉘 스크립트를 어떻게 작성할 수 있습니까? 나에게 절실히 필요한 것은 /procchroot에 설치되고 스크립트가 루트로 실행되는 최신 Linux 시스템이지만 더 이식 가능한 답변을 환영합니다. (바라보다/proc가 마운트되지 않은 경우 chroot에서 실행 중인지 어떻게 알 수 있나요?. /proc​)

보다 일반적으로는 다른 격리 방법에 적용할 수 있는 제안이 흥미로울 것입니다. 실제 질문은 이 시스템이 어떤 서비스를 실행해야 하는가입니다. (chroot에서 대답은 '아니오'입니다. 본격적인 가상 머신에서 대답은 '예'입니다. 감옥이나 컨테이너와 같은 중간 사례에 대해서는 모르겠습니다.)

답변1

여기서 내가 하는 일은 init프로세스의 루트(PID 1)가 현재 프로세스의 루트와 동일한지 테스트하는 것입니다. /proc/1/root링크는 항상 존재 하지만 /( init링크 자체가 chroot되지 않는 한), 이를 따라가면 "마스터" 루트 디렉터리로 연결됩니다. 이 기술은 chroot에 설치한 후 udev 시작을 건너뛰는 것과 같은 Debian의 일부 유지 관리 스크립트에서 사용됩니다.

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

(그런데 이것은 루트 액세스 권한이 있는 chrooted 프로세스가 보안에 쓸모가 없는 이유에 대한 또 다른 예입니다 chroot. 루트가 아닌 프로세스는 읽을 수 없지만 /proc/1/rootRun /proc/1234/rootthe same way로 PID 1234를 사용하여 실행 중인 프로세스가 있는 경우 사용자를 따라갈 수 있습니다. ).

루트 액세스 권한이 없으면 /proc/1/mountinfo다음을 볼 수 있습니다 /proc/$$/mountinfo.filesystems/proc.txtLinux 커널 문서에서). 이 파일은 누구나 읽을 수 있으며 프로세스의 파일 시스템 보기에 있는 각 마운트 지점에 대한 광범위한 정보를 포함합니다. 이 파일의 경로는 판독기 프로세스(있는 경우)에 영향을 미치는 chroot에 의해 제한됩니다. 프로세스 읽기가 /proc/1/mountinfo전역 루트가 아닌 다른 파일 시스템으로 루트화되면(pid 1의 루트가 전역 루트라고 가정) /의 항목은 나타나지 않습니다 /proc/1/mountinfo. 프로세스가 전역 루트 파일 시스템으로 루트가 지정된 디렉토리를 읽는 경우 /proc/1/mountinfo항목이 에 표시되지만 마운트 ID는 다릅니다. 그런데 루트 필드( )는 기본 파일 시스템 내에서 chroot의 위치를 ​​나타냅니다.//proc/1/mountinfo$4

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

이것은 순수한 Linux 솔루션입니다. 충분한 유사성을 지닌 다른 Unix 변종으로 일반화할 수 있습니다 /proc(Solaris에도 비슷한 것이 있다고 /proc/1/root생각하지만 그렇지 않습니다 mountinfo).

답변2

에서 언급했듯이inode 번호를 찾는 휴대용 방법그리고내부에서 chroot 감옥 감지, inode 번호가 다음과 같은지 확인할 수 /있습니다 2.

$ ls -di /
2 /

2와 다른 inode 번호는 겉보기 루트가 파일 시스템의 실제 루트가 아님을 나타냅니다. 이는 마운트 지점이 무엇인지 감지하지 못하거나임의의 루트 inode 번호를 사용하는 운영 체제.

답변3

여기에 나열된 다른 많은 옵션만큼 이식성이 떨어지는 것은 분명하지만 데비안 기반 시스템을 사용하고 있다면 시도해 보십시오 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).

답변4

이것은 단지 우연한 관찰일 뿐입니다. 그러나 FUSE를 사용하여 무엇이든 액세스할 수 있는 경우 무언가를 마운트한 다음 mountchroot 경로가 접두어로 표시되는 show 마운트 경로를 사용할 수 있습니다.

예를 들어 Github Actions Mac 실행기에서는 다음을 수행할 수 있습니다.

pip install --user ratarmount
folder=$(mktemp -d)
mountedFolder=$(mktemp -d)
# simple bind mount a folder
ratarmount "$folder" "$mountedFolder"

이제 mount다음 내용이 인쇄됩니다.

TarMount on /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/tmp.P5g4TomF (macfuse, nodev, nosuid, synchronous, mounted by runner)

mountedFolder변수의 전체 경로 가 /var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/tmp.P5g4TomF. 그래서 우리는 그것에 깊이 뿌리박혀 있는 것 같습니다 /private.

mountpoint이 해킹 명령 때문에대안사용했지만 mountgrep에게 적합하지 않았습니다.

관련 정보