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
]
pam_namespace는 다형화 디렉터리로 세션을 위한 비공개 네임스페이스를
구성해 주는 PAM 모듈이다. 다형화 디렉터리란 사용자 이름에 따라서,
또는 SELinux를 쓰는 경우 사용자 이름이나 보안 문맥, 또는 둘 모두에
따라서 다른 인스턴스를 제공하는 디렉터리다. 인스턴스 디렉터리를
준비해서 다형화 디렉터리에 마운트한 다음에 실행 가능 스크립트
/etc/security/namespace.init
이 존재하면
그 스크립트를 사용해 디렉터리를 초기화한다. 그 스크립트는 인자로
다형화 디렉터리 경로, 인스턴스 디렉터리 경로, 인스턴스 디렉터리가
새로 만들어진 것인지 여부를 나타내는 플래그(0은 아님, 1은 맞음),
사용자 이름을 받는다.
pam_namespace 모듈은 세션 네임스페이스를 부모 네임스페이스와 분리한다. 부모 네임스페이스에서 장치 마운트 같은 마운트/언마운트를 수행해도 세션 네임스페이스에 반영되지 않는다. 부모 네임스페이스의 마운트/언마운트 동작 일부를 분리된 세션 네임스페이스로도 전파시키고 싶다면 특수 공유 서브트리 기능을 이용할 수 있다. 공유 서브트리 기능에 대한 자세한 내용은 mount(8) 맨페이지, 그리고 http://lwn.net/Articles/159077 및 http://lwn.net/Articles/159092 에 있는 공유 서브트리 설명을 참고할 수 있다.
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으로 바꾼다.
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에서 지동으로 탐지해서 다형화된 디렉터리를 비공개로 만들게 된다. 서브트리만 공유이고 /는 아닐 때만 이 옵션을 쓰면 된다.
참고로 이 옵션을 쓰거나 공유된 / 마운트 포인트를 자동 탐지했을 때는 비공개 네임스페이스에서 이뤄진 마운트 및 언마운트가 부모 네임스페이스에 영향을 끼치지 않는다.
네임스페이스 구성에 성공했다.
네임스페이스를 준비하는 중 예상치 못한 시스템 오류가 발생했다.
예상치 못한 네임스페이스 구성 오류가 발생했다.
/etc/security/namespace.conf
주 설정 파일
/etc/security/namespace.d
추가 설정 파일 디렉터리
/etc/security/namespace.init
인스턴스 디렉터리 초기화 스크립트
다음은 /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로 문맥을 설정해 줘야 한다.