6.21. pam_namespace - 비공개 네임스페이스 구성

pam_namespace.so [ debug ] [ unmnt_remnt ] [ unmnt_only ] [ require_selinux ] [ gen_hash ] [ ignore_config_error ] [ ignore_instance_parent_mode ] [ unmount_on_close ] [ use_current_context ] [ use_default_context ] [ mount_private ]

6.21.1. 설명

pam_namespace는 다형화 디렉터리로 세션을 위한 비공개 네임스페이스를 구성해 주는 PAM 모듈이다. 다형화 디렉터리란 사용자 이름에 따라서, 또는 SELinux를 쓰는 경우 사용자 이름이나 보안 문맥, 또는 둘 모두에 따라서 다른 인스턴스를 제공하는 디렉터리다. 인스턴스 디렉터리를 준비해서 다형화 디렉터리에 마운트한 다음에 실행 가능 스크립트 /etc/security/namespace.init이 존재하면 그 스크립트를 사용해 디렉터리를 초기화한다. 그 스크립트는 인자로 다형화 디렉터리 경로, 인스턴스 디렉터리 경로, 인스턴스 디렉터리가 새로 만들어진 것인지 여부를 나타내는 플래그(0은 아님, 1은 맞음), 사용자 이름을 받는다.

pam_namespace 모듈은 세션 네임스페이스를 부모 네임스페이스와 분리한다. 부모 네임스페이스에서 장치 마운트 같은 마운트/언마운트를 수행해도 세션 네임스페이스에 반영되지 않는다. 부모 네임스페이스의 마운트/언마운트 동작 일부를 분리된 세션 네임스페이스로도 전파시키고 싶다면 특수 공유 서브트리 기능을 이용할 수 있다. 공유 서브트리 기능에 대한 자세한 내용은 mount(8) 맨페이지, 그리고 http://lwn.net/Articles/159077 및 http://lwn.net/Articles/159092 에 있는 공유 서브트리 설명을 참고할 수 있다.

6.21.2. 설명

pam_namespace.so 모듈을 통해 다형화 디렉터리로 비공개 네임스페이스를 구성할 수 있다. 사용자 이름에 따라서, 또는 SELinux 사용 시 사용자 이름이나 민감도 단계, 또는 전체 보안 문맥에 따라서 여러 디렉터리 인스턴스가 생성될 수 있다. 실행 가능 스크립트 /etc/security/namespace.init이 존재하면 인스턴스 디렉터리를 준비해서 마운트할 때마다 그 스크립트를 사용해 네임스페이스를 초기화한다. 그 스크립트는 인자로 다형화 디렉터리 경로와 인스턴스 디렉터리 경로를 받는다.

어느 디렉터리를 어떻게 다형화할 것인지, 인스턴스 디렉터리 이름을 어떻게 붙일 것인지, 다형화를 수행하지 않을 사용자가 있는지 등을 /etc/security/namespace.conf 파일에 지정한다.

누군가 로그인을 하면 namespace.conf 파일을 탐색한다. # 문자는 주석을 나타낸다. 주석 아닌 행 각각이 다형화 디렉터리 한 개를 나타낸다. 공백으로 필드를 구분하며 " 문자로 필드를 감쌀 수 있고 이스케이프 열 \b, \n, \t도 인식한다. 필드는 다음과 같다.

polydir instance_prefix method list_of_uids

첫 번째 필드 polydir은 다형화할 디렉터리의 절대 경로명이다. 특수 문자열 $HOME이 사용자 홈 디렉터리로 바뀌고 $USER가 사용자 이름으로 바뀐다. 이 필드는 비어 있을 수 없다.

두 번째 필드 instance_prefix는 <polydir>의 인스턴스의 경로명을 만들 때 쓰는 선두 문자열이다. 다형화 method에 따라 그 뒤에 "인스턴스 구별 문자열"이 붙어서 인스턴스 디렉터리 최종 경로가 된다. 그 디렉터리가 이미 존재하지 않으면 생성한 다음 <method> 열에 따라서 <polydir>에 바인드 마운트해서 <polydir> 인스턴스를 제공한다. 특수 문자열 $HOME이 사용자 홈 디렉터리로 바뀌고 $USER가 사용자 이름으로 바뀐다. 이 필드는 비어 있을 수 없다.

세 번째 필드 method는 다형화를 하는 방식이다. "user"는 사용자 이름에 따른 다형화, "level"은 프로세스 MLS 단계 및 사용자 이름에 따른 다형화, "context"는 프로세스 보안 문맥과 사용자 이름에 따른 다형화, "tmpfs"는 tmpfs 파일 시스템을 인스턴스 디렉터리로 마운트하기, "tmpdir"은 임시 디렉터리를 만들어서 인스턴스 디렉터리로 쓰고 사용자 세션이 닫힐 때 제거하는 방식이다. "context" 및 "level" 방식은 SELinux를 쓸 때만 사용 가능하다. 이 필드는 비어 있을 수 없다.

네 번째 필드 list_of_uids는 다형화를 수행하지 않을 사용자 이름의 쉼표 구분 목록이다. 비어 있으면 모든 사용자에 대해 다형화를 수행하게 된다. 목록 앞에 "~" 문자 하나가 붙어 있으면 그 목록의 사용자에게만 다형화를 수행한다.

method 필드에 선택적으로 다음 플래그들을 : 문자로 구분해서 붙일 수 있다.

create=mode,owner,group - 다형화 디렉터리를 만든다. 매개변수 mode, owner, group은 선택적이다. 모든 기본값은 umask로 정해지며, 기본 소유자는 세션을 여는 사용자이며, 기본 그룹은 사용자의 주 그룹이다.

iscript=path - 인스턴스 디렉터리 초기화 스크립트 경로. 상대 경로의 기준 디렉터리는 /etc/security/namespace.d다.

noinit - 인스턴스 디렉터리 초기화 스크립트를 실행하지 않는다.

shared - "context" 및 "level" 방식의 인스턴스 디렉터리에 사용자 이름을 포함시키지 않아서 모든 사용자가 공유하게 된다.

mntopts=value - tmpfs 마운트를 할 때 이 플래그 값을 mount 호출로 전달한다. 그래서 예를 들어 mount 호출로 만드는 tmpfs 인스턴스의 최대 크기를 지정할 수 있다. tmpfs(5) 매뉴얼에 있는 옵션들 외에도 nosuid, noexec, nodev 플래그를 사용해 마운트할 tmpfs 파일 시스템에서 setuid 비트 효과를 끄거나, 실행 파일을 실행하지 못하게 하거나, 장치 파일들이 해석되지 않게 할 수 있다.

다형화 인스턴스가 만들어질 디렉터리가 존재해야 하고 기본적으로는 모드가 0000이어야 한다. 인스턴스 부모의 모드가 0000이어야 한다는 요건을 명령행 옵션 ignore_instance_parent_mode로 무시할 수 있다.

context 내지 level 다형화인 경우 다형화에 쓰는 SELinux 문맥은 getexeccon으로 얻은 새 프로세스 실행을 위한 문맥이다. 호출 프로세스에서 또는 pam_selinux.so로 그 문맥을 설정해 둬야 한다. 그 문맥이 설정돼 있지 않으면 사용자 이름만 가지고 다형화가 이뤄지게 된다.

"인스턴스 구별 문자열"이 "user" 방식에서는 <사용자 이름>이고 "context" 및 "level" 방식에서는 <사용자 이름>_<디렉터리 문맥 값>이다. 전체 문자열이 너무 길면 끝부분을 그 문자열의 md5sum으로 바꾼다. 그리고 명령행 옵션 gen_hash를 쓰면 전체 문자열을 md5sum으로 바꾼다.

6.21.3. 옵션

debug

syslog를 이용해 많은 디버그 정보를 기록한다.

unmnt_remnt

su나 newrole 같은 프로그램에선 로그인 세션에 다형화된 네임스페이스가 이미 구성돼 있다. 그런 프로그램에선 새로운 사용자 ID나 보안 문맥에 따라 다형화를 수행하게 되는데, 먼저 login에서 수행한 다형화를 되돌려야 한다. 이 인자는 명령에서 새 ID/문맥에 따라 새로운 다형화를 진행하기 전에 먼저 이전 다형화를 되돌리도록 한다.

unmnt_only

기존 바인드 마운트가 있으면 되돌리고서 자체적으로 인스턴스 디렉터리 처리를 하려는 신뢰할 수 있는 프로그램이 있다면 이 인자를 써서 현재 마운트된 인스턴스 디렉터리가 언마운트되도록 할 수 있다.

require_selinux

selinux가 켜져 있지 않으면 실패를 반환한다.

gen_hash

인스턴스 이름에 보안 문맥 문자열을 쓰지 않고 그 문자열의 md5 해시를 생성해서 쓴다.

ignore_config_error

어느 다형화 디렉터리에 대한 설정 파일 행에 형식 오류가 있으면 그 행을 건너뛰고 다음 행을 처리한다. 이 옵션이 없으면 pam이 호출 프로세스에게 오류를 반환해서 세션 종료을 일으키게 된다.

ignore_instance_parent_mode

인스턴스 부모 디렉터리는 기본적으로 엄격한 000 모드여야 한다. 이 옵션을 사용해서 인스턴스 부모의 모드를 무시하기로 할 수 있다. 다형화 메커니즘의 보안성 및 격리 목표를 저하시키게 되므로 주의해서 사용해야 한다.

unmount_on_close

네임스페이스 마지막 프로세스가 끝난 후 네임스페이스가 자동 파기되는 것에 기대는 게 아니라 다형화 디렉터리를 명시적으로 언마운트한다. 세션이 닫힌 후 그 비공개 네임스페이스 안에 도는 프로세스가 없다는 것이 어떻게든 보장되는 경우에만 이 옵션을 써야 한다. 같은 프로세스에서 연이어 여러 번 pam 세션 호출을 하는 경우에도 유용하다.

use_current_context

setexeccon 호출로 SELinux 문맥을 바꾸지 않는 서비스에 유용하다. level 및 context 다형화에 호출 프로세스의 현재 SELinux 문맥을 사용하게 된다.

use_default_context

setexeccon 호출로 SELinux 문맥을 바꾸기 위해 pam_selinux를 이용하지 않는 서비스에 유용하다. level 및 context 다형화에 사용자의 기본 SELinux 문맥을 사용하게 된다.

mount_private

(예를 들어 mount --make-rshared / 명령으로) / 마운트 포인트나 그 하위 마운트가 공유돼 있는 시스템에서 이 옵션을 쓸 수 있다. 다형화 네임스페이스 안의 모든 마운트 및 언마운트 동작이 비공개가 되도록 전체 디렉터리 트리에 표시를 하게 된다. 보통은 공유된 / 마운트 포인트를 pam_namespace에서 지동으로 탐지해서 다형화된 디렉터리를 비공개로 만들게 된다. 서브트리만 공유이고 /는 아닐 때만 이 옵션을 쓰면 된다.

참고로 이 옵션을 쓰거나 공유된 / 마운트 포인트를 자동 탐지했을 때는 비공개 네임스페이스에서 이뤄진 마운트 및 언마운트가 부모 네임스페이스에 영향을 끼치지 않는다.

6.21.4. 제공하는 모듈 종류

session 모듈 타입만 제공한다. 멀티스레드 프로세스에서 이 모듈을 호출해선 안 된다.

6.21.5. 반환 값

PAM_SUCCESS

네임스페이스 구성에 성공했다.

PAM_SERVICE_ERR

네임스페이스를 준비하는 중 예상치 못한 시스템 오류가 발생했다.

PAM_SESSION_ERR

예상치 못한 네임스페이스 구성 오류가 발생했다.

6.21.6. 파일

/etc/security/namespace.conf

주 설정 파일

/etc/security/namespace.d

추가 설정 파일 디렉터리

/etc/security/namespace.init

인스턴스 디렉터리 초기화 스크립트

6.21.7. 예시

다음은 /etc/security/namespace.conf에 지정할 수 있는 예시 설정이다.


      # 다음 세 행이 /tmp, /var/tmp, 사용자 홈 디렉터리를
      # 다형화하게 된다. /tmp와 /var/tmp는 보안 단계와 사용자
      # 이름을 가지고 다형화되는 반면, 홈 디렉터리는 전체 보안
      # 문맥과 사용자 이름을 가지고 다형화된다. 사용자 root와
      # adm에 대해선 /tmp 및 /var/tmp 디렉터리의 다형화를
      # 수행하지 않는다. 반면 홈 디렉터리는 모든 사용자에게
      # 다형화한다.
      #
      # 참고로 인스턴스 디렉터리가 다형화 디렉터리 안에 위치할
      # 필요가 없다. 아래 예에서 /tmp의 인스턴스는 /tmp-inst
      # 디렉터리 안에 생성된다. 반면 /var/tmp 및 사용자 홈
      # 디렉터리의 인스턴스는 다형화 디렉터리 안에 위치하게 된다.
      #
      /tmp     /tmp-inst/               level      root,adm
      /var/tmp /var/tmp/tmp-inst/    level      root,adm
      $HOME    $HOME/$USER.inst/inst- context
    

다형화가 필요한 <service>가 있으면 (예를 들어 login) 다음 행을 /etc/pam.d/<service>의 세션 관련 내용 마지막 행으로 넣어 주면 된다.

session required pam_namespace.so [arguments]

이 모듈을 위해 pam_selinux.so로 문맥을 설정해 줘야 한다.

6.21.8. 작성자

Stephen Smalley, Janak Desai, Chad Sellers가 네임스페이스 구성 체계를 설계했다. Janak Desai <janak@us.ibm.com>, Chad Sellers <csellers@tresys.com>, Steve Grubb <sgrubb@redhat.com>이 PAM 모듈 pam_namespace를 개발했다. Xavier Toth <txtoth@gmail.com>, Tomas Mraz <tmraz@redhat.com>가 추가 개선을 했다.