Linux 네임스페이스에 대해 읽은 후 느낀 점은 다른 많은 기능 중에서 chroot를 대체한다는 것입니다. 예를 들어,이 기사:
[네임스페이스]의 다른 용도로는 [...] 단일 디렉토리 계층 구조의 일부로 프로세스를 chroot() 스타일로 격리하는 것이 있습니다.
그러나 예를 들어 다음 명령을 사용하여 마운트 네임스페이스를 복제하면 전체 원래 루트 트리가 계속 표시됩니다.
unshare --mount -- /bin/bash
이제 원래 네임스페이스와 공유되지 않는 새 네임스페이스에 추가 설치를 수행할 수 있다는 것을 알고 있으므로 이는 격리를 제공하지만 여전히 동일한 루트입니다. 예를 들어 /etc
두 네임스페이스는 여전히 동일합니다. 여전히 루트 디렉터리를 변경해야 합니까 chroot
, 아니면 다른 옵션이 있습니까?
기대하고 있어요이 문제답변이 제공되지만 답변에는 chroot
다시 ,만 사용됩니다.
편집 #1
삭제된 댓글이 있었습니다 pivot_root
. 왜냐하면 이것은 실제로linux/fs/namespace.c
, 이는 실제로 네임스페이스 구현의 일부입니다. unshare
이는 루트 디렉터리만 사용하고 변경하는 mount
것이 불가능하지만 네임스페이스는 더 스마트한 자체 버전을 제공한다는 것을 보여줍니다 chroot
. chroot
소스 코드를 읽은 후에도(예: 보안 또는 더 나은 격리 측면에서) 이 접근 방식의 주요 아이디어, 즉 .
편집 #2
이것은 중복이 아닙니다이 문제. 답변의 모든 명령을 실행한 후 별도의 /tmp/tmp.vyM9IwnKuY(또는 이와 유사한)가 있지만 루트 디렉터리는 여전히 동일합니다!
답변1
마운트 네임스페이스를 설정하기 전에 입력하면 chroot
호스트 네임스페이스가 다른 마운트에 의해 변경되는 것을 피할 수 있습니다(예 : 마운트 네임스페이스 내에서 훌륭하고 간단한 트릭으로 이를 사용할 /proc
수 있습니다 .chroot
이해하면 이점이 있다고 생각 pivot_root
하지만 약간의 학습 곡선이 있습니다. 문서는 모든 것을 완전히 설명하지는 않습니다. 비록 man 8 pivot_root
(셸 명령의 경우) 사용 예가 있지만. man 2 pivot_root
(시스템 호출의 경우) 동일한 작업을 수행하고 샘플 C 프로그램을 포함하면 더 명확할 수 있습니다.
피벗_루트를 사용하는 방법
또한 마운트 네임스페이스를 입력한 직후에 mount --make-rslave /
또는 이에 상응하는 작업을 수행해야 합니다. 그렇지 않으면 모든 마운트 변경 사항이 를 포함하여 원래 네임스페이스의 마운트로 전파됩니다 pivot_root
. :)
이 명령을 사용하는 경우 기본 응용 프로그램으로 unshare --mount
문서화되어 있음을 참고하세요 . mount --make-rprivate
AFAICS 이는 잘못된 기본값이므로 프로덕션 코드에서는 사용하고 싶지 않습니다. 예를 들어, 이 시점에서는 eject
호스트 네임스페이스에 마운트된 DVD 또는 USB에서 작동이 중지됩니다 . DVD 또는 USB는 전용 설치 트리에 설치된 상태로 유지되며 커널에서는 DVD를 꺼낼 수 없습니다.
이 작업이 완료되면 /proc
사용할 디렉토리를 마운트할 수 있습니다. 당신과 같은 방식으로 chroot
.
를 사용할 때와 달리 chroot
새로운 pivot_root
루트 파일 시스템이 마운트 지점이 되어야 합니다. 아직 그렇지 않은 경우 간단히 바인드 마운트를 적용하여 이를 충족할 수 있습니다 mount --rbind new_root new_root
.
-를 사용한 pivot_root
다음 umount
이전 루트 파일 시스템과 -l
/ MNT_DETACH
옵션을 사용하십시오. (그럴 필요는 없습니다 umount -R
. 시간이 더 오래 걸릴 수 있습니다.).
기술적으로 말하면, 사용에는 일반적 pivot_root
으로 chroot
"둘 중 하나"가 필요하지 않습니다.
에 따르면 man 2 pivot_root
스왑 마운트 네임스페이스의 루트로만 정의됩니다. 프로세스 루트가 가리키는 물리적 디렉터리를 변경하도록 정의되어 있지 않습니다. 또는 현재 작업 디렉터리( /proc/self/cwd
). 그런 일이 일어난다하다그렇습니다. 그러나 커널 스레드를 다루는 요령은 다음과 같습니다. 매뉴얼 페이지에는 이것이 미래에 변경될 수 있다고 나와 있습니다.
일반적으로 다음 순서를 원합니다.
chdir(new_root); // cd new_root
pivot_root(".", put_old); // pivot_root . put_old
chroot("."); // chroot .
이 시퀀스의 위치는 chroot
또 다른 미묘한 세부 사항입니다.. 마운트 네임스페이스를 재배치하는데 초점이 pivot_root
맞춰져 있지만, 커널 코드는 설정된 각 프로세스의 루트를 보고 이동할 루트 파일 시스템을 찾는 것으로 나타난다 chroot
.
피봇루트를 사용하는 이유
pivot_root
원칙적으로는 보안과 격리를 위해 사용하는 것이 합리적입니다. 나는 다음 이론에 대해 생각하는 것을 좋아합니다기능 기반 보안. 필요한 특정 리소스 목록을 전달하면 프로세스가 다른 리소스에 액세스할 수 없습니다. 이 경우, 마운트 네임스페이스에 전달된 파일 시스템에 대해 이야기하고 있습니다. 이 아이디어는 일반적으로 Linux "네임스페이스" 기능에 적용됩니다. 비록 제가 잘 표현하지는 않았지만요.
chroot
프로세스 루트만 설정되었지만 프로세스는 여전히 전체 마운트 네임스페이스를 참조합니다. 프로세스가 실행 권한을 유지하는 경우 chroot
백업 파일 시스템 네임스페이스를 통과할 수 있습니다. 에 자세히 설명된 대로 man 2 chroot
"수퍼유저는 다음 방법으로 'chroot 감옥'에서 탈출할 수 있습니다."
생각을 자극하는 또 다른 실행 취소 방법 chroot
은 입니다 nsenter --mount=/proc/self/ns/mnt
. 이것은 아마도 원칙에 대한 더 강력한 주장일 것입니다. nsenter
/ setns()
마운트된 네임스페이스의 루트에서 프로세스 루트를 다시 로드해야 합니다....두 개가 서로 다른 물리적 디렉터리를 참조하는 경우에는 작동하지만 커널 버그로 간주될 수 있습니다. (기술 참고 사항: 루트 디렉터리에는 여러 개의 파일 시스템이 서로 겹쳐 있을 수 있습니다. setns()
가장 최근에 설치된 최상위 파일 시스템을 사용하세요.)
이는 설치 네임스페이스와 "PID 네임스페이스"를 결합하면 얻을 수 있는 이점 중 하나를 보여줍니다. PID 네임스페이스 내부에 있으면 제한되지 않은 프로세스의 마운트 네임스페이스에 들어갈 수 없습니다. 또한 제한되지 않은 프로세스( /proc/$PID/root
)의 루트 디렉터리에 들어가는 것을 방지합니다. 물론, PID 네임스페이스는 외부 프로세스를 종료하는 것도 방지합니다. :-).