kjh00n의 기록저장소
Linux 인증 모듈 PAM 본문
PAM (Pluggable Authentication Modules)
● 응용 프로그램에서 사용자 인증을 수행할 수 있게 공통적인 인증 방법을 제공하는 인증 모듈
● 인증 모듈의 교체 및 추가/삭제가 용이
● Linux에서 제공하는 인증 기능
● 서버에 있는 각각의 서비스(ftp, ssh, web)에서 인증을 받는 것이 아닌 Server의 OS에서의 인증기능을 PAM이라고 한다.
● 개발자가 작성한 코드에 의한 인증이 아닌 시스템 관리자가 직접 응용프로그램의 인증 동작을 제어
- 응용 프로그램(서비스)에서 PAM을 호출하여 인증 처리 요청
- 응용 프로그램 개발자가 사용자 인증에 신경 X, 시스템 관리자가 직접 응용 프로그램의 인증 동작의 세밀한 제어 가능
PAM 동작 원리
● 프로그램에서 사용자 인증 필요시 PAM 라이브러리 함수 호출
● PAM 호출 시 호출한 응용프로그램의 인증 설정 파일 검사
PAM 인증 절차
① 사용자가 서비스를 이용받기 위해 접근
② 프로세스(로컬, 데몬)는 PAM에 인증 요청
③ 인증방법, 순서, 과정이 담긴 설정파일을 통해서 검사한다.(/etc/pam.d/설정파일)
- /etc/pam.d/설정파일이 인증방법과 인증순서를 결정
- 인증에 필요한 기능이 담긴 Module들이 /etc/pam.d/설정파일에 담긴다.
- 각각 서비스하는 프로그램마다 설정파일이 모두 다르게 설정되어 있다.
④ 설정 파일의 구문에 의해 PAM 라이브러리 호출 및 결과 메시지 생성 후 프로세스에 반환
⑤ 프로세스는 반환된 결과에 의해 적절한 행동 수행
PAM 구성 파일
↑특정 Module을 설정해야 할 때 설정하는 파일들↑
PAM 설정 파일
● 하나의 라인(줄) 당 하나의 설정
● 하나의 설정에 들어가는 데이터는 총 4개로 구분
- Type
- Control
- Module_Path
- Module_Argument
Type
● 설정의 종류
★auth | 인증을 수행하는 Type (계정정보, 패스워드, 시간, 특정 조건에 맞는 데이터인지 아닌지 확인) |
account | 계정정보를 확인하는 Type (인증과 상관없이 해당 계정이 해당 서비스에 유효한지 확인하거나 패스워드 기간이 만료되었는지 확인 등 유효여부를 확인) |
password | 패스워드 변경 시 사용하는 Type |
session | 사용자가 인증을 받기 전이나 인증 후에 추가로 수행해야 하는 작업을 결정하는 Type (로그인/로그아웃, 마운팅, 언마운팅, 서비스 내용 변경같은 추가적인 작업을 수행해야 하는 경우 사용하는 Type으로 보통 Log 남기는 경우에 많이 사용) |
Control
● 최종적인 인증의 성공, 실패 여부를 결정하는 설정
● Module에서 출력되는 결과에 따라 인증 성공 or 인증 실패를 결정하는 설정
sufficient | ● Module에서 출력되는 결과가 성공이면 최종 인증 결과를 성공으로 결정하고 다음 추가 인증없이 종료 ● Module에서 출력되는 결과가 실패이면 최종 인증 결과를 결정하지 못하고 다음 추가 인증 수행 |
required | ● Module에서 출력되는 결과가 성공이면 최종 인증 결과를 결정하지 못하고 다음 추가 인증 수행 ● Module에서 출력되는 결과가 실패이면 최종 인증 결과를 실패라고 결정하고 다음 추가 인증 수행 → 다음 추가 인증 중에서 최종 인증 결과가 성공이라고 나온다고 해도 이미 앞에서 최종 인증 결과가 실패로 결정되었기 때문에 성공이 무의미하다. → 다음 추가 인증의 결과가 최종 인증 결과에 영향을 미칠 수 없다. ● required의 존재 이유는 실패 지점을 숨기기 위해서 사용한다. (로그인 할 때 ID가 틀린건지 PW가 틀린건지) |
requisite | ● Module에서 출력되는 결과가 성공이면 최종 인증 결과를 결정하지 못하고 다음 추가 인증 수행 ● Module에서 출력되는 결과가 실패이면 최종 인증 결과를 실패로 결정하고 다음 추가 인증없이 종료 |
optional | ● Module에서 출력되는 결과가 성공이든 실패이든 최종 인증 결과에 영향없이 다음 추가 인증 수행 ● 모든 인증 과정을 진행한 이후에도 최종 인증 결과를 결정하지 못하는 경우 최종적으로 optional의 결과를 따라간다. |
include | ● 다른 인증 설정 파일을 불러오는 Control ● 패스워드를 확인하는 인증과정을 매번 다른 설정파일마다 중복해서 적용하면 설정이 너무 많음 ● 패스워드를 확인하는 인증과정 설정을 하나의 인증 설정파일로 구성하고 필요할 때마다 include를 이용하여 해당 설정을 불러낸다. |
substack | ● include와 거의 동일하다. ● substack은 인증 설정 중 특정 설정인 control flag를 사용가능 ● control flag는 정해진 control 형식이 아닌 다른 형식으로 표현 가능 ● system-auth를 불러온다 ● vim system-auth |
Module_Path
● 해당 설정에서 동작할 Module을 지정 → Module의 이름 작성
● Module에서의 성공, 실패가 최종적인 결과의 성공, 실패와는 관련없다
(최종 결과는 Control에서 판별)
pam_permit.so | ● 항상 성공을 반환하는 Module(어떤 상황, 데이터라도 무조건 성공을 반환) ● requisite, required와 같이 사용하는 경우 의미가 없다. ● 특정 시점이나 순서에 무조건 인증을 성공하고 싶은 경우 sufficient와 조합하여 사용 |
pam_env.so | ● 환경변수를 불러오는 Module ● 항상 성공을 반환 |
pam_deny.so | ● 항상 실패를 반환하는 Module(어떤 상황, 데이터라도 무조건 실패를 반환) ● sufficient와 같이 사용하는 경우 의미가 없다. ● 특정 시점이나 순서에 무조건 인증을 실패하고 싶은 경우 requisite, require와 조합하여 사용 |
pam_rootok.so | ● 인증을 요청하는 계정이 root인 경우 무조건 성공을 반환 (root가 아닌 경우 무조건 실패) ● root가 다른 계정으로 전환할 때는 성공, 다른 계정이 root로 전환할 때는 실패 (su) ● 인증을 요청하는 계정을 구분할 수 있냐 없냐가 중요 ● 일반적인 인증 상황(login)에서 사용되는 Module이 아니라 이미 인증이 완료되어있는 시점에서 추가로 인증을 수행하는 경우 사용되는 Module |
★pam_succeed_if.so |
● 성공이나 실패 반환이 정해진 것이 없다. ● 해당 Module 뒤에 나오는 Module_Argument 값에 따라 성공, 실패를 반환하는 Module ● Module 뒤에 나오는 조건이 참이면 성공 반환, 조건이 거짓이면 실패 반환 ● 조건 작성 방법 → [주체] [조건식] [인자] ● 주체 : user, uid, gid, shell, service ● 조건식 : <, >, <=, >=, eq(=), ne(!=) ● 인자 : 숫자, 문자 |
pam_listfile.so |
● 특정 파일 안에 해당 정보가 있는지 없는지에 따라 성공, 실패를 반환하는 Module ● 인자 값으로 4개가 있다. ①item (주체 = user, group, rhost, ruser 등) ②sense (주체가 파일에 있는 경우, 아니면 없는 경우 동작할 방식 = allow, deny) ③file (주체가 있는지 없는지 확인하고자 하는 파일 경로) ④onerr (file이 없는 경우 동작할 방식 지정 = succeed, fail) EX) pam_listfile.so item=user sense=allow file=/root/hello onerr=fail → 해당 파일에 계정이 있으면 성공 반환 pam_listfile.so item=user sense=deny file=/root/hello onerr=succeed → 해당 파일에 계정이 있으면 실패 반환 → vim /etc/pam.d/vsftpd (ftpusers에 계정명이 있으면 접속을 거부) |
pam_access.so | ● 사용자 계정과 접속이나 접근을 요청하는 위치(주소)등을 확인하여 성공, 실패를 반환 ● 인증에 동작하는 Module은 아니고 접근제어 Module이다. ● auth type이 아닌 account type을 사용해야 한다. ● 허용, 차단할지에 대한 설정이 추가로 들어가야되서 따로 추가 설정 파일에 저장해야된다. → /etc/security/access.conf permission:users:origins 로 구성해야 된다. ①permission = 허용 or 차단 (+는 허용, -는 차단) ②users = 계정 이름 ③origins = 주소 EX) +:ALL:10.10.10.1 → 모든 계정이 10.10.10.1에서 접근하는 것을 허용 -:ALL:10.10.10.1 → 모든 계정이 10.10.10.1에서 접근하는 것을 차단 +:root:10.10.10.100 → root로 10.10.10.100에서 접근하는 것을 허용 -:ALL EXCEPT root:10.10.10.200 → root를 제외한 모든 계정이 10.10.10.200에서 접근하는 것을 차단 +:ALL EXCEPT ktest:ALL → ktest를 제외한 모든 계정의 어디서든 접근하는 것을 차단 +:root:10.10.10.1 10.10.10.2 10.10.10.3 → root로 10.1 , 10.2 , 10.3에서 접근하는 것을 허용 -:root:10.10.10.0/24 (=10.10.10.0/255.255.255.0 , = 10.10.10.까지만 입력) → root로 10.대역에서 접근하는 것을 차단 ● 설정에 포함이 안되어있는 경우에는 기본 허용이다. ● 적용 범위가 중복되는 경우에는 위에서부터 아래로 순서대로 적용이 된다. |
pam_time.so | ● 인증의 성공, 실패 여부와 상관없이 시간에 따라 접근 여부를 결정하는 Module ● 설정하지 않은 시간대는 차단된다. ● acoount 사용 ● 특정 계정이 특정 시간에 접근제어를 허용, 차단할지 설정해야 하기 때문에 추가 설정 파일 필요 → /etc/security/time.conf services;ttys;users;times 로 구성해야 된다. ① services = 접속하는 서비스 ② ttys = 연결 종류 ③ users = 계정 이름 - !root = root를 제외한 모든 계정 - root | ktest = root거나 ktest일 때 - !root & !ktest = root가 아니면서 ktest가 아닐때 ④ times = 시간 요일-시간범위 - Al0000-2400 = 모든 요일, 모든 시간 허용 - Mo0000-2400 = 월요일 모든 시간 허용 - Wk0000-2400 = 평일 모든 시간 허용 - Su1000-1500 = 일요일 오전 10시부터 오후 3시까지 허용 - WeWk0900-1800 = 수요일 제외 평일 오전 9시부터 오후 6시까지 허용 - WkWe0900-1800 = 수요일 제외 평일 오전 9시부터 오후 6시까지 허용 (해당 범위 안에 요일이 들어가면 그 요일은 제외시킨다.) (범위 = 평일, 주말, 모두) - WeWd0800-1700 = 수요일, 주말 오전 8시부터 오후 5시까지 허용 - SuAl0000-2400 = 일요일 제외한 모든 시간 허용 → 월,화,수,목,금,토,일,평일,주말,모두 sshd;*;root;Al0000-2400 → root 사용자가 하루 24시간 언제든지 SSH 접속을 허용하는 설정을 의미합니다. 월요일 오전 11시~13시, 수요일 오전 8시~11시 허용 → Mo1100~1300|We0800~1100 으로 붙여서 쓴다. 사이에 | 가 사용된다. 월요일을 제외한 모든 시간 허용 = 월요일 모든 시간 차단 → !Mo0000-2400 평일에서 월요일과 화요일을 제외한 요일의 모든 시간 허용 → MoTuWk0000-2400 |
pam_unix.so | ● 패스워드를 확인하거나 변경하는데 사용하는 Module ● /etc/passwd, /etc/shadow 파일 확인 ● 어떤 type을 지정하여 Module을 쓰느냐에 따라 동작이 달라지는 Module ● auth type = 사용자가 입력한 패스워드 확인 → 패스워드가 맞으면 성공 아니면 실패를 반환 ● account type = 패스워드 변경해야 하는지 확인 → 변경해야되는데 안하면 접근 거부 ● password type = 사용자 패스워드 변경 동작 ● pam_unix.so에서 사용하는 인자값 ① use_first_pass = 해당 Module이 나오기 전에 이미 패스워드를 입력받았다면 해당 패스워드를 사용하여 확인 => 틀린경우 재입력 요청하지 않는다. ② try_first_pass = 해당 Module이 나오기 전에 이미 패스워드를 입력받았다면 해당 패스워드를 사용하여 확인 => 틀린경우 재입력 요청한다. ③ nullok = 패스워드 공백 사용 가능 |
pam_usertype.so | ● 계정의 type을 확인하는 Module → isregular = 계정이 일반 계정이면 성공 → issystem = 계정이 시스템 계정이면 성공 ↓ 얘는 별개로 설명함 (pam_usertype.so에 사용되는 것이 아님) (pam_usertype.so isregular가 성공하면 Control에서 success=ok가 동작하고 실패하면 ignore=ignore가 작동하고 성공,실패도 아니면 default=1이 동작한다) ① success=ok는 인증을 계속 실행하겠다는 의미 (최종 인증 결과를 결정 X) success=die는 인증 실패라는 의미 (최종 인증 결과로 실패를 반환) ② ignore=ignore는 반환된 결과를 무시하고 다음 인증을 실행한다. ③ default=1은 밑에 있는 1줄을 건너뛰겠다는 의미이다. |
pam_localuser.so |
● /etc/passwd에 있는 사용자인지 아닌지 확인하는 Module / 있으면 성공 없으면 실패 |
pam_sss.so | ● SSSD(System Security Service Demon) Module에서 이미 입력된 패스워드를 다른 PAM에서 사용할 수 있도록 임시 저장하는 Module |
pam_pwquality.so | ● password type에서 사용가능한 Module ● password의 복잡성을 설정하기 위한 Modulw ● 복잡성 설정을 추가로 설정해야 하기 때문에 추가 설정 파일을 작성해야 한다. → /etc/security/pwquality.conf pwquality.conf 옵션 ● retry = 재입력 횟수 지정 (기본값은 1회) ● difok = 새로운 패스워드가 기존 패스워드와 몇글자 다르게 설정해야 하는지 제한 설정 (기존 패스워드보다 절반 이상 다른 경우 허용) ● minlen = 새로운 패스워드의 최소 글자 설정 (기본값은 10) → 최소 6글자 이상으로 설정해야 된다. (Linux 자체 제한) ● dcredit = 새로운 패스워드에 숫자가 입력되어야 하는 크기 (강제 X/강제는 음수로 작성) ● ucredit = 새로운 패스워드에 대문자가 입력되어야 하는 크기 (강제 X/강제는 음수로 작성) ● lcredit = 새로운 패스워드에 소문자가 입력되어야 하는 크기 (강제 X/강제는 음수로 작성) ● ocredit = 새로운 패스워드에 특수문자가 입력되어야 하는 크기 (강제 X/강제는 음수로 작성) ● enforce_for_root = root 계정 password 정책 강제 적용 (주석 처리 해제하면 적용된다) ※root는 password 정책을 모두 무시한다. |
pam_succeed_if.so 예시
pam_succeed_if.so user=root use_uid → 인증을 요청하는 계정이 root이면 성공 (? → root) (인증하기 전)
pam_succeed_if.so user=root → 로그인한 계정이 root이면 성공 (root → ?) (인증한 후)
pam_succeed_if.so user in root:ktest → 로그인한 계정이 root, ktest이면 성공
pam_succeed_if.so user notin root:ktest → 로그인한 계정이 root, ktest가 아니면 성공
pam_succeed_if.so uid >= 1000 quiet → quiet은 Log를 남기지 않겠다는 설정
pam_succeed_if.so uid >= 1000 quiet_success → 성공했을 때 Log를 남기지 않겠다
pam_succeed_if.so uid >= 1000 quiet_fail → 실패했을 때 Log를 남기지 않겠다
pam_succeed_if.so uid >= 1000 debug → 기록을 상세하게 남기겠다
pam_access.so 예시
pam_time.so 예시
vim /etc/security/time.conf
vim /etc/security/time.conf
vim /etc/security/time.conf에 설정이 안되어있는 계정은 접근 허용된다.
하지만 적혀있지 않은 시간대는 차단된다.
pam_pwquality.so 예시
vim /etc/security/pwquality.conf의 마지막 줄에 추가
비밀번호 최소 글자를 5글자로 설정
linux에서 기본 설정되어 있는 값이 6이다.(설정파일에서 6보다 큰 값으로 설정해야 된다.)
최소 글자는 12글자, 숫자는 최소 1개, 소문자가 최소 1개, 특수문자가 최소 1개 이상 설정되어야 한다.
Module_Argument
● 앞에 Module의 종류에 따라서 결정
● [주체] [조건식] [인자]
● 주체 : user, uid, gid, shell, service
● 조건식 : <, >, <=, >=, eq(=), ne(!=)
● 인자 : 숫자, 문자
use_uid | 인증을 요청하는 계정으로 확인 |
debug | Log 기록 시 세세하게 기록 |
quiet | 최종 결과 성공, 실패 상관 없이 Log 기록하지 않음 |
quiet_success | 조건 성공 시 Log 기록하지 않음 |
quiet_fail | 조건 실패 시 Log 기록하지 않음 |
trust | 조건 상관없이 성공 반환 |
간단 실습