4. Linux-PAM 설정 파일

Linux-PAM은 시스템 관리자에게 시스템에 있는 권한을 부여하는 응용프로그램들을 설정하는데 있어서 많은 유연성을 제공해주기 위해 디자인되었다. Linux-PAM에의해 조정되는 시스템 보안에 관련된 설정들은 /etc/pam.conf파일이나 /etc/pam.d/ 디렉토리내의 파일들 중 하나에 들어있다. 이 장에서는 이 파일들이 참조하는 내용에 관한 올바른 문법과 옵션에 대해 설명할 것이다.

4.1. 설정 파일 문법(Configuration file syntax)

이 파일에서 Linux-PAM고유의 단어(토큰)들은 대소문자 구분이 없다는것을 유념하기 바란다. 그러나, 모듈 경로(path)는 파일 이름을 가르키는 것이고 전형적인 Linux 파일 시스템의 대소문자 구분에 따라 모듈 경로 역시 대소문자를 구분한다. 모듈에게 주어지는 인자(argument)들의 대소문자 구분은 모듈이 정한바에 따른다.

아래 설명된 것들외에, 시스템 관리자의 편의를 위해 두개의 특별한 문자가 제공된다: '#'으로 시작되는 문장은 주석이고 줄의 끝까지 유효하다. 모듈의 설정행에서 줄 끝에 '\'를 사용하면 다음줄도 앞과 같은 하나의 문장으로 처리된다.

/etc/pam.conf파일의 일반적인 설정 문장은 아래의 형태이다:

service-name   module-type   control-flag   module-path   arguments

아래에 이 각각의 단어들의 의미를 설명한다. Linux-PAM을 설정하는 두번째 방법(최근에 적용된 것이다.)은 /etc/pam.d/디렉토리내의 파일들을 사용하는 것이다. 위의 단어들의 의미를 설명한 다음에 이 방법에 대해 설명하겠다.

service-name

이 설정문장과 관련한 서비스의 이름이다. 주로 해당 응용프로그램의 일반적인 이름을 사용한다. 예를 들면, 'ftpd', 'rlogind', 'su' 이다.

디폴트 인증 방법을 정의하기 위해 정의된 특별한 서비스 이름이 있다. 'OTHER'라는 것이 이것인데, 대소문자 구별없이 쓸 수 있다. 만약 어떤 서비스의 인증 모듈 설정이 이미 되어 있으면 'OTHER'항목은 무시된다.

module-type

네가지의(현재) 모듈 타입중 하나이다. 네가지는 다음과 같다:

  • auth: 이 모듈타입은 사용자 인증의 두가지 면을 제공한다. 첫째는, 응용프로그램이 사용자에게 패스워드를 물어보거나 다른 확인 방법을 사용하도록 해서 그 사용자가 자신이 주장하는 사람이 맞는지 확인하는 것이다. 두번째는, 그룹 멤버쉽을 주거나 (앞서 이야기한 /etc/groups파일에 있는 내용을 통해서) credential(신임)속성을 통해 다른 권한을 주는 것이다.

  • account: 이 모듈은 인증이 아닌 계정관리를 수행한다. 이것은 보통 시간/날짜나 현재의 시스템 자원 상황(최대 사용자수)이나 사용자의 위치('root'는 콘솔에서만 로그인이 가능하다)등에 따라 서비스에 대한 접근을 허가하거나 제한하는 것이다.

  • session: 주로, 이 모듈은 서비스를 사용하기 직전/직후에 필요한 작업과 관련이 있다. 이러한 것들은 사용자와 교환할 어떤 데이터들의 opening/closing과 관련한 정보들의 기록, 디렉토리의 마운트 등이 해당된다.

  • password: 이 마지막 모듈타입은 사용자와 연관된 인증토큰 (패스워드)들을 갱신할 때 필요하다. 보통, challenge/response 방식에 기반한 인증모듈 종류별로 각각 하나의 password모듈씩이 존재한다.

control-flag

control-flag은 관련되는 모듈의 성공/실패 결과에 따라 어떻게 PAM라이브러리가 반응할지를 지정한다. 모듈들이 쌓여(같은 타입의 모듈들이 순서대로 수행된다) 있기 때문에 control-flag는 각 모듈의 상대적인 중요도를 결정한다. 응용프로그램은 /etc/pam.conf에 열거된 모듈 각각의 성공/실패에 대해 알 수 없다. 대신에, Linux-PAM라이브러리로부터 요약된 성공/실패에 대한 결과를 받게된다. 모듈들의 수행 순서는 /etc/pam.conf파일에 열거된 순서대로 앞에 나온것이 뒤에것보다 먼저 수행된다. Linux-PAM v0.60부터, 이 control-flag은 두가지 문법중 하나로 정의할 수 있다.

보다 단순한(처음부터 있던) 문법은 특정 모듈별로 전체적인 성공/실패에 대해 주는 영향을 하나의 단어로 지시하는 것이다. 이것에는 네가지의 단어가 있다: required, requisite, sufficient, optional.

Linux-PAM 라이브러리는 이 단어들을 아래 설명과 같이 해석한다:

  • required: 이것은 해당 module_type이 전체적으로 성공하기 위해서는 이 모듈의 성공이 필요하다는 것을 말한다. 나머지 모듈(같은 module-type의)이 모두 다 수행되기 전까지 사용자가 이 모듈이 실패했는지 확실히 알 수 없다.

  • requisite: required와 비슷하나, 실패한 경우 제어가 바로 응용프로그램에게 넘어간다. 결과값은 처음의 실패한 requiredrequisite모듈의 결과값이다. 이 플래그는 사용자가 안전하지 않은 매체(medium)에서 패스워드를 입력할 경우에 대비해 사용할 수 있다. 이러한 행동은 크래커에게 시스템의 유효한 계정을 알려줄 수 있다. 이 가능성은 민감한 패스워드를 적대적인 환경에 노출시키는 것에 대한 사소하지 않은 염려와 비교해서 검토해야 한다.

  • sufficient: 이 모듈의 성공은 Linux-PAM라이브러리에게 이 module-type이 성공했다고 판단할만큼 충분하게 만족스럽다는 것이다. 이전의 required모듈이 실패하지 않았다면 더이상 이 type의 나머지 모듈들은 수행되지 않는다. (이경우에 뒤따르는 required모듈이 수행되지 않는것에 유의하라) 이 모듈의 실패는 이 module-type의 성공여부 판단에 치명적이지는 않은것으로 간주된다.

  • optional: 이름이 의미하듯이, 이 control-flag는 모듈이 서비스에 대한 응용프로그램의 성공/실패에 중요하지는 않다는 것이다. 보통, Linux-PAM은 모듈들의 성공/실패 판단시에 이런 모듈은 무시한다. 그러나, 이전/이후의 모듈들이 명확한 성공/실패가 없다면 이 모듈이 응용프로그램에게 주는 결과를 결정짓는다. 후자의 경우의 예로, 다른 모듈들이 PAM_IGNORE같은 것을 리턴할 경우이다.

좀더 정교한(새로운) 문법은 더욱 명확하고 시스템 관리자가 사용자를 어떻게 인증할지에 있어 더 많은 제어방법을 제공한다. 이 control-flag는 대괄호([])안에 value=action들이 나열되어 있는 형태이다:

    [value1=action1 value2=action2 ...]

valueI는 다음의 리턴값들 중 하나이다: success; open_err; symbol_err; service_err; system_err; buf_err; perm_denied; auth_err; cred_insufficient; authinfo_unavail; user_unknown; maxtries; new_authtok_reqd; acct_expired; session_err; cred_unavail; cred_expired; cred_err; no_module_data; conv_err; authtok_err; authtok_recover_err; authtok_lock_busy; authtok_disable_aging; try_again; ignore; abort; authtok_expired; module_unknown; bad_item; default. 마지막(default)것은 명확히 정의되지않은 리턴값들에 대한 action을 정하기 위해 사용된다.

actionI는 양의 정수나 다음의 토큰들 중 하나이다: ignore; ok; done; bad; die; reset. 양의 정수 J가 action으로 정해지면 같은 type의 모듈들중 다음의 J개 모듈들을 건너뛰게하는 것이다. 이 방법으로 관리자는 여러개의 서로 다른 실행과정을 갖는 정교한 모듈목록을 적절히 만들 수 있게 된다. 어느 경로가 될지는 각 모듈의 반응에 의해 결정된다.

  • ignore - 모듈의 결과값이 응용프로그램이 갖게될 결과값에 영향을 주지 않는다.

  • bad - 이것은 결과값이 모듈 실패의 표시로 생각해야 한다. 이모듈이 실패한 첫번째 모듈이면, 이 상태값은 전체 모듈의 결과로 사용될 것이다.

  • die - bad와 같지만 모듈 수행이 중지되고, PAM이 응용프로그램으로 바로 리턴한다는 것이 다르다.

  • ok - 이것은 PAM에게 관리자가 이 결과값이 모듈 전체의 결과 상태로 바로 사용되길 바란다고 알려주는 것이다. 즉, 모듈목록의 수행과정에서 앞까지의 상태가 PAM_SUCCESS이면 이 모듈의 결과값은 앞까지의 상태값을 덮어쓴다. 반면 앞까지의 상태가 실패라면 이 'ok'값은 상태를 덮어쓰지 않을 것이다.

  • done - ok와 같지만 모듈 수행이 중지되고 PAM이 응용프로그램에게 바로 리턴한다는 것이 다르다.

  • reset - 모듈들의 결과상태 기록을 지우고, 다음 모듈부터 새로 시작한다.

새로운 문법의 능력을 체감하기 위해, 이것으로 무엇을 할 수 있는지 보여주겠다. Linux-PAM-0.63부터 client plug-in agents라는 것이 소개되었다. 이것은 PAM이 client/server프로그램들이 고유하게 가지고 있는 전송 규약을 사용해서 서로다른 기계간의 인증을 지원하는 것을 가능하게 해 준다. ``[... value=action ...]'' 제어 문법으로 응용프로그램이 유순한 클라이언트 프로그램에게는 바이너리 프롬프트를 지원하지만 동시에 우아하게도 오래된 구식의 응용프로그램에게는 다른 인증모드를 선택하도록 설정할 수 있다. 유연하지 않은가?

module-path

동적으로 로드될 오브젝트 파일(모듈 자체)의 경로명이다. module path의 첫 문자가 '/'라면, 전체경로를 의미한다. 그렇지 않은경우에는 default module path(/usr/lib/security)를 붙여서 해석된다. (그렇지만 2장 내용을 참고하라).

args

args는 모듈이 불려질때 넘겨주는 토큰 리스트이다. 전형적인 Linux shell명령에 주는 인자들과 비슷하다. 보통, 유효한 인자는 옵션이고 특정 모듈에만 해당된다. 무효한 인자들은 모듈에 의해 무시되지만, 무효한 인자들을 보게되면 모듈은 syslog(3)에 에러를 보내도록 요구받는다. 일반적 generic옵션의 목록은 다음절(4.3)에서 볼 수 있다.

설정 파일의 어떤 줄이라도 제대로 작성되어있지 않을 경우 일반적으로 인증 절차가 실패하게 된다. 해당 에러는 syslog(3)를 통해 시스템 log파일에 기록된다.

4.2. 디렉토리에 설정파일을 기록할 때(Directory based configuration)

하나의 설정 파일보다 더 유연성을 갖기 위해 0.56버전 부터 /etc/pam.d/ 디렉토리의 파일들로 libpam을 설정하는것이 가능해졌다. 이경우에 그 디렉토리의 파일은 파일이름과 같은 이름(소문자)을 갖는 서비스에 대한 설정을 갖게 된다: 서비스 각각에 대한 설정 파일인 것이다.

Linux-PAM은 두가지 모드로 컴파일 할 수 있다. 추천하는 쪽은 /etc/pam.d//etc/pam.conf둘 중 하나만 사용하는 것이다. 하지만 둘다 같이 할 수는 없다. 즉, /etc/pam.d/디렉토리가 있다면, libpam은 그 디렉토리에 있는 파일들만을 사용한다. 그러나 /etc/pam.d/ 디렉토리가 없는 경우에는 /etc/pam.conf를 사용한다. 다른 쪽은(현재 RedHat 4.2이상에서 지원되고 있다) /etc/pam.d//etc/pam.conf를 순서대로 모두 사용하는 것이다. 이 때는 /etc/pam.conf의 내용보다 /etc/pam.d/의 내용이 우선적으로 사용된다.

/etc/pam.d/의 파일의 문법은 /etc/pam.conf의 문법과 비슷하다. 각 문장은 다음과 같은 형태이다:

module-type   control-flag   module-path   arguments

서비스 이름(service-name)이 없다는것 하나만 다르다. 서비스 이름(service-name)은 물론 설정파일의 이름이다. 예를 들어, /etc/pam.d/loginlogin서비스에 대한 설정을 가지고 있다.

이 설정 방법은 단일 파일로 하는 것에 비해 여러 장점을 갖는다. 어느 방법을 적용할지 선택하는데 도움을 주기 위해 여기에 그 장점을 나열한다:

4.3. 일반적인 옵션 인자들(generic optional arguments)

다음은 어떠한 모듈이든 인식할 수 있는 가능성이 큰 옵션 인자들이다. 인자들(이것들도 포함해서)은 대게 선택적(optional)이다.

debug

syslog(3) 호출을 사용해서 시스템 로그 파일에 디버그 정보를 남기도록 한다.

no_warn

모듈이 응용프로그램에게 경고(warning) 메시지를 보내지 않도록 한다.

use_first_pass

모듈이 사용자에게 패스워드를 요구하지 않도록 한다. 대신에, 이전에 입력받았던 패스워드(먼저 수행된 auth모듈 로부터)를 받아서 사용해야 한다. 패스워드가 없다면, 사용자는 인증을 받지 못하게 될 것이다.(이 옵션은 authpassword 모듈들만 적용된다.)

try_first_pass

모듈은 이전에 입력받은 패스워드(먼저 수행된 auth 모듈로부터)로 인증을 시도한다. 만일 패스워드가 없다면, 사용자에게 패스워드를 물어본다.(이 옵션은 auth모듈만 적용된다.)

use_mapped_pass

이 인자는 현재 배포되고 있는 Linux-PAM에 있는 어떤 모듈도 지원하지 않는다. 이는 미국 암호화 수출 제한과 관련하여 생길 수 있는 문제 때문이다. 미국내에서는 개발자들이 물론 자유롭게 이 기능을 구현할 수 있다. (다른 나라에서도 마찬가지이다.). 호환성의 이유로 DCE-RFC 86.0 (bibliography 장을 보라) 에서 제안된데로 이것의 사용을 기술한다.

use_mapped_pass인자는 암호화되지 않은 인증토큰을 요구하는 앞의 모듈로부터 인증 토큰을 받은후 다시 이것을 사용해 암호/복호 키를 생성하여 이 모듈에게 필요한 인증토큰을 안전하게 저장하고 읽을 수 있게 한다. 이런 방법으로, 사용자는 한번의 인증 토큰 입력만으로 여러개의 모듈에 의한 인증 과정을 조용히 통과할 수 있다. 안전하게 하기 위해 믿을만한 튼튼한 암호화를 요구하지만 편한 기능임은 분명하다. 이 인자는 authpassword모듈에만 적용된다.

expose_account

보통 사용자 계정에 관한 정보를 누설하는 것은 모듈이 채택할만한 안전한 보안정책이라 할 수 없다. 때때로, 사용자 이름이나 홈 디렉토리나 사용할 쉘에 대한 정보들은 사용자 계정을 공격하는데 사용될 수 있다. 그러나 어떤 상황에선 이런 종류의 정보가 위험요소가 될 것 같지는 않다: 보안이 유지된 환경에서 패스워드를 물어볼 때, 사용자의 실제 이름을 표시하는 것은 친근한 느낌을 준다고 볼 수도 있을 것이다. expose_account인자는 관리자에 의해 적절한 것 같은 계정 정보에 대해 덜 엄격하게 구분하도록 하는 표준 인자이다.

4.4. 설정파일 내용의 예(Example configuration file entries)

이 장에서는 Linux-PAM설정 파일에서 볼 수 있는 내용에 대한 예제 몇개를 설명한다. 시스템을 처음으로 설정할 때, 이것들을 구현하는 것보다 더 심각한 짓을 할지도 모른다.

4.4.1. 디폴트 정책(Default policy)

시스템이 안전해야한다고 생각되면, 'OTHER' 항목에 대해서 안전한 설정을 해야 좋을 것이다. 다음은 심하게 불신하도록 설정되어 있는 것이다(처음 시작하기에 나쁜 것은 아니다!):

#
# default; deny access
#
OTHER	auth	 required	/usr/lib/security/pam_deny.so
OTHER	account	 required	/usr/lib/security/pam_deny.so
OTHER	password required	/usr/lib/security/pam_deny.so
OTHER	session	 required	/usr/lib/security/pam_deny.so

근본적으로 안전한 반면, 잘못 설정된 시스템에게는 대단히 좋다고 말할 수 없다. 예를들어, 나머지 파일들이 잘못 씌여지면 모든 사용자들을 막아버릴 가능성이 있게된다.

pam_deny모듈(나중에 설명된다)은 설정하기에 좋지 않다. 예를 들어, 수행될때 로그를 전혀 남기지 않기때문에, 사용자가 서비스 프로그램을 사용하는데 실패를 했을때 관리자에게 알리지 않는다면 관리자는 시스템의 설정 실수에 대한 사실을 모른채로 오랫동안 지낼것 이다.

위의 예제와 같은 설정앞에 다음을 추가하면 관리자에게 적절한 경고 메시지를 줄 것이다.

#
# default; wake up! This application is not configured
#
OTHER   auth     required       /usr/lib/security/pam_warn.so
OTHER   password required       /usr/lib/security/pam_warn.so

두줄의 'OTHER auth'가 같은 type의 여러모듈 적층사용의 예이다.

/etc/pam.d/설정을 사용하는 시스템에서는 아래와 같은 파일이 위에서 얘기한 디폴트 설정이 된다:

#
# default configuration: /etc/pam.d/other
#
auth	 required	/usr/lib/security/pam_warn.so
auth	 required	/usr/lib/security/pam_deny.so
account	 required	/usr/lib/security/pam_deny.so
password required	/usr/lib/security/pam_warn.so
password required	/usr/lib/security/pam_deny.so
session	 required	/usr/lib/security/pam_deny.so

이게 /etc/pam.d/형태의 설정 방법의 예로 보여주는 유일한 예이다. 나머지 예들에서 이 설정 방법으로 변환하는 방법은 명확할 것이다.

덜 민감한 컴퓨터, 관리자가 Linux-PAM의 많은 기능들을 무시한채로 두고 싶은 경우는 다음의 줄들의 예 (/etc/pam.conf에서)가 전통적으로 친숙한 linux 설정을 모방한 설정이 될 수 있다.

#
# default; standard UNIX access
#
OTHER   auth     required       /usr/lib/security/pam_unix_auth.so
OTHER   account  required       /usr/lib/security/pam_unix_acct.so
OTHER   password required       /usr/lib/security/pam_unix_passwd.so
OTHER   session  required       /usr/lib/security/pam_unix_session.so

[역주: 지금 버젼에서는 pam_unix_auth, pam_unix_acct, pam_unix_passwd, pam_unix_session이 pam_unix.so로 통합되었고, 좀더 발전한 형태로 pam_pwdb.so가 존재한다.] 이 내용이 일반적으로 대부분의 응용프로그램에 대해 초기설정으로 사용될 수 있다. 불행하게도, 대부분이 모두라는 것은 아니다. ftpd같은 경우는 anonymous-ftp를 가능하게 하기 위해 추가적인 설정이 필요하다.

anonymous-ftp를 가능하게 하기 위해 다음의 줄이 디폴트(OTHER) 설정을 대체해서 사용할 수 있다. (*경고* 1996/12/28이후, 어떠한 ftpd와도 이 설정이 제대로 동작하지 않았다. 결과적으로 이 설명은 바뀌거나 응용프로그램이 고쳐질 것이다.)

#
# ftpd; add ftp-specifics. These lines enable anonymous ftp over
#       standard UNIX access (the listfile entry blocks access to
#	users listed in /etc/ftpusers)
#
ftpd	auth	sufficient  /usr/lib/security/pam_ftp.so
ftpd	auth	required    /usr/lib/security/pam_unix_auth.so use_first_pass
ftpd	auth	required    /usr/lib/security/pam_listfile.so \
			onerr=succeed item=user sense=deny file=/etc/ftpusers

/etc/pam.conf에 해당 서비스(여기서는 ftpd)의 설정파일이 있으면 디폴트 설정이 무시되기 때문에 두번째 줄이 필요하다. 다시 한번 이 예제는 authentication모듈에 있어서 같은 type의 여러 모듈을 적층해서 같이 사용될 수 있음을 보여준다. sufficient control-flag을 사용했음을 주목하라. 이것은 이 모듈이 사용자를 인증하면 이후의 auth모듈은 무시하라는 것이다. 또한 'use_first_pass' module-argument를 사용했음을 주목하라. 이것은 UNIX 인증 모듈이 사용자에게 패스워드를 물어보지 않고 앞서 실행된 ftp모듈에 의해 얻은 패스워드만을 사용하도록 설정한다.