리눅스 시스템에서는 어플리케이션과 서비스에 대한 동적인증을 PAM (Pluggable Authentication Modules) 을 통해 제공하며, 크게 아래의 4가지 모듈로 구성되어있습니다.
① Authentication : 인증 서비스 모듈
② Account : 계정 관리 모듈
③ Password : 패스워드 관리 모듈
④ Session : 세션 관리 모듈
위 네가지 모듈을 통해서 LDAP을 통한 Linux 인증을 구성할수 있습니다.
PAM 을 이용하는 서비스 목록은 /etc/pam.d/* 에서 확인할 수 있으며 , 지정되지 않은 서비스에 대한 인증은 other 파일의 설정 값에 적용됩니다.
[module_type] [control_flag] [module_path] [module_options]
먼저 [module_type]은 Linux에서 지원하는 PAM 모듈을 일커르며 위에서 말한 네가지 모듈 ( 인증, 계정 , 패스워드,세션)을 말합니다.
[control_flag] 의 경우 4가지 필드값을 제공하는데 아래를 참조하시어 사용하시기 바랍니다.
required | 인증을 위해서 반드시 이 모듈에 대한 결과가 성공으로 반환되어야합니다. 실행 결과가 중간에 실패하여도 모듈에 대한 내용을 모두 진행하지만 서비스 사용자는 결과만 알게될뿐 어느 지점에서 실패가 발생하였는지 알수없습니다. |
requisite | required와 동일하게 인증을 위해서 반드시 이 모듈에 대한 실행 결과가 성공으로 반환되어야합니다. 이 모듈에서 실패처리가 나게되면 이후 진행이 되지않고 바로 실패처리로 종료됩니다. |
sufficient | 이 모듈의 실행 결과가 ‘성공’일 경우 같은 interface에 대한 테스트는 더이상 수행하지 않고 ‘성공’으로 종료됩니다. |
optional | 이 모듈에 대한 테스트 결과는 Skip 됩니다. ( 성공 or 실패 모두 Skip)
단, 다른 모듈에 대한 테스트에서 이 optional 모듈에 대한 테스트 결과를 참조할 수 있습니다. |
include | 다른 flag와 달리 include의 경우 모듈명 대신에 다른 PAM 관련 서비스가 포함되며 해당 서비스 인증이 통과되어야만 해당 인터페이스에 대한 인증이 성공합니다. |
required 를 사용하게되면 어디서 실패가 발생했는지 로그에 남지 않아 추적이 어려우니 다른 Flag 옵션을 사용하여 진행하시길 바랍니다.
ldap과 연계하기 위해서는 pam_ldap.so 를 사용해야합니다. 해당 모듈을 사용하기위해서는 nslcd 데몬을 이용해야합니다.
1 |
yum install nss-pam-ldapd |
를 수행하여 설치가 가능하지만 최신버전을 설치하기 위해서는 아래 URL에서 다운로드하시길 바랍니다.
1 |
https://arthurdejong.org/nss-pam-ldapd/release-0-9-9 |
(※ 이전 버전에서는 지원하지 않는 기능들이 존재합니다.)
1) nss-pamd-ldapd 설치
Step 1. 다운로드 된 파일을 리눅스에 업로드하여 컴파일을 진행합니다.
1 2 3 4 5 |
% ./configure % make % make install |
Step 2. 구성 파일 수정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# This is the configuration file for the LDAP nameservice # switch library's nslcd daemon. It configures the mapping # between NSS names (see /etc/nsswitch.conf) and LDAP # information in the directory. # See the manual page nslcd.conf(5) for more information. # The user and group nslcd should run as. uid nslcd gid nslcd # The uri pointing to the LDAP server to use for name lookups. # Multiple entries may be specified. The address that is used # here should be resolvable without using LDAP (obviously). #uri ldap://127.0.0.1/ #uri ldaps://127.0.0.1/ #uri ldapi://%2fvar%2frun%2fldapi_sock/ # Note: %2f encodes the '/' used as directory separator #uri ldap://127.0.0.1/ # The LDAP version to use (defaults to 3 # if supported by client library) #ldap_version 3 # The distinguished name of the search base. #base dc=example,dc=com # The distinguished name to bind to the server with. # Optional: default is to bind anonymously. #binddn cn=proxyuser,dc=example,dc=com # The credentials to bind with. # Optional: default is no credentials. # Note that if you set a bindpw you should check the permissions of this file. #bindpw secret # The distinguished name to perform password modifications by root by. #rootpwmoddn cn=admin,dc=example,dc=com # The default search scope. #scope sub #scope one #scope base # Customize certain database lookups. #base group ou=Groups,c=kr base passwd ou=People,c=kr base shadow ou=People,c=kr #scope group onelevel #filter passwd (description=dsm) #scope hosts sub # Bind/connect timelimit. #bind_timelimit 30 # Search timelimit. #timelimit 30 # Idle timelimit. nslcd will close connections if the # server has not been contacted for the number of seconds. #idle_timelimit 3600 # Use StartTLS without verifying the server certificate. #ssl start_tls #tls_reqcert never # CA certificates for server certificate verification #tls_cacertdir /etc/ssl/certs #tls_cacertfile /etc/ssl/ca.cert # Seed the PRNG if /dev/urandom is not provided #tls_randfile /var/run/egd-pool # SSL cipher suite # See man ciphers for syntax #tls_ciphers TLSv1 # Client certificate and key # Use these, if your server requires client authentication. #tls_cert #tls_key # Mappings for Services for UNIX 3.5 #filter passwd (objectClass=User) #map passwd uid msSFU30Name #filter passwd (objectClass=User) #map passwd uid msSFU30Name #map passwd userPassword msSFU30Password #map passwd homeDirectory msSFU30HomeDirectory #map passwd homeDirectory msSFUHomeDirectory #filter shadow (objectClass=User) #map shadow uid msSFU30Name #map shadow userPassword msSFU30Password #filter group (objectClass=Group) #map group member msSFU30PosixMember # Mappings for Services for UNIX 2.0 #filter passwd (objectClass=User) #map passwd uid msSFUName #map passwd userPassword msSFUPassword #map passwd homeDirectory msSFUHomeDirectory #map passwd gecos msSFUName #filter shadow (objectClass=User) #map shadow uid msSFUName #map shadow userPassword msSFUPassword #map shadow shadowLastChange pwdLastSet #filter group (objectClass=Group) #map group member posixMember # Mappings for Active Directory #pagesize 1000 #referrals off #idle_timelimit 800 #filter passwd (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*)) #map passwd uid sAMAccountName #map passwd homeDirectory unixHomeDirectory #map passwd gecos displayName #filter shadow (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*)) #map shadow uid sAMAccountName #map shadow shadowLastChange pwdLastSet #filter group (objectClass=group) # Alternative mappings for Active Directory # (replace the SIDs in the objectSid mappings with the value for your domain) #pagesize 1000 #referrals off #idle_timelimit 800 #filter passwd (&(objectClass=user)(objectClass=person)(!(objectClass=computer))) #idle_timelimit 800 #filter passwd (&(objectClass=user)(objectClass=person)(!(objectClass=computer))) #map passwd uid cn #map passwd uidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820 #map passwd gidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820 #map passwd homeDirectory "/home/$cn" #map passwd gecos displayName #map passwd loginShell "/bin/bash" #filter group (|(objectClass=group)(objectClass=person)) #map group gidNumber objectSid:S-1-5-21-3623811015-3361044348-30300820 uri ldap://192.168.0.27:1389/ base ou=People,c=kr ssl no tls_cacertdir /etc/openldap/cacerts |
Step 1 을 진행하게되면, /etc 아래에 nslcd.conf 와 pam_ldap.conf 가 생성됩니다.
먼저 nslcd.conf를 위표처럼 맨 마지막라인으로 이동하여 uri, base, ssl 등을 설정해야합니다.
1 2 3 4 5 |
uri ldap://198.51.100.389 /* (필수 값) LDAP 접속 주소 */ base dc=example,dc=com /* (필수 값) LDAP 검색 BASE DN */ ssl no /* ssl 사용여부 */ uid nslcd /* nslcd 실행 uid */ gid nslcd /* nslcd 실행 gid */ |
Step 3) /etc/nsswitch .conf
LDAP을 통해 OS 인증을 진행하기위해서는 nsswitch.conf 를 수정해야합니다.
아래와 같이 passwd, group, shadow 에 ldap 항목을 추가해야합니다.
1 2 3 |
passwd: files ldap shadow: files ldap group: files ldap |
Step 4) /etc/pam.d/password-auth
PAM 라이브러리를 호출하는 모든 응용프로그램 및 서비스 데몬에 공통 구성파일을 제공하는 파일로 pam_ldap.so 를 추가하는 작업이 필요합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#%PAM-1.0 # This file is auto-generated. # User changes will be destroyed the next time authconfig is run. auth required pam_env.so auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid >= 500 quiet auth sufficient pam_ldap.so use_first_pass auth requisite pam_deny.so account required pam_unix.so broken_shadow account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 500 quiet account [default=bad success=ok user_unknown=ignore] pam_ldap.so account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 type= password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok password sufficient pam_ldap.so use_authtok nullok password requisite pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session optional pam_mkhomedir.so skel=/etc/skel umask=0022 session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so session requisite pam_ldap.so |
처음에 나열했던 [control_flag] 에 대한내용을 이곳에 적용하게됩니다.
auth 인터페이스 부분의 [pam_ldap.so] 라인을 확인해보시면 [sufficient] 로 설정되어있습니다.
[sufficient]는 해당 라인의 라이브러리가 성공으로 끝나면 해당 인터페이스의 내용은 모두 성공으로 처리한다는 내용입니다. [sufficient]로 설정하지 않으시면 이후 [pam_deny.so] 에서 실패가 발생함으로 인증에 실패하게됩니다.
[pam_ldap.so] 뒤에 작성되는 옵션에 대한 내용은 아래 URL에서 확인하실수 있습니다.
1 |
https://arthurdejong.org/nss-pam-ldapd/pam_ldap.8 |
Step 5) service nslcd start
위의 내용과 같이 진행하셧다면 /etc/init.d/nslcd 파일이 존재하지않아 Service 명령어를 통해 실행이 불가능할것임으로 아래 내용을 해당위치에 저장하여 사용하시기 바립니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
#!/bin/sh # # chkconfig: - 12 88 # description: Provides naming services using a directory server. # processname: sbin/nslcd # config: /etc/nslcd.conf # pidfile: /var/run/nslcd/nslcd.pid # ### BEGIN INIT INFO # Provides: nslcd # Required-Start: $network # Required-Stop: # Default-Start: # Default-Stop: # Short-Description: naming services LDAP client daemon # Description: Provides naming services using a directory server. ### END INIT INFO program=sbin/nslcd prog=${program##*/} pidfile=/var/run/nslcd/nslcd.pid if [ -f /etc/rc.d/init.d/functions ]; then . /etc/rc.d/init.d/functions fi RETVAL=0 start() { echo -n $"Starting $prog: " daemon $program RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog return $RETVAL } stop() { echo -n $"Stopping $prog: " killproc $program RETVAL=$? echo if [ $RETVAL -eq 0 ]; then rm -f /var/lock/subsys/$prog fi } restart() { stop start } # See how we were called. case "$1" in start) [ -f /var/lock/subsys/$prog ] && exit 0 $1 ;; stop) [ -f /var/lock/subsys/$prog ] || exit 0 $1 ;; restart) $1 ;; status) status -p $pidfile $program RETVAL=$? ;; condrestart|try-restart) [ -f /var/lock/subsys/$prog ] && restart || : ;; reload) echo "can't reload configuration, you have to restart it" RETVAL=3 ;; force-reload) restart ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" exit 1 ;; esac exit $RETVAL ~ |
Step 6) 기능 테스트
1 2 3 4 5 6 7 |
/etc/init.d/nscd start /etc/init.d/nslcd start getent passwd ldapuser /etc/init.d/nscd stop /etc/init.d/nslcd stop nslcd -d |
nscd를 함께 사용하면 데이터를 캐시에 저장하기때문에 LDAP에 요청하는 빈도가 낮아집니다. (debug 모드를 사용할 경우 stop 하셔야합니다.)
우선 nslcd 데몬을 실행하시고 getent 명령어가 제대로 수행되는지 확인해야합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
[root@dsm14 init.d]# getent passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin rtkit:x:499:499:RealtimeKit:/proc:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin haldaemon:x:68:68:HAL daemon:/:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin saslauth:x:498:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin dsm:x:500:500:dsm:/home/dsm:/bin/bash vboxadd:x:496:1::/var/run/vboxadd:/bin/false nscd:x:28:28:NSCD Daemon:/:/sbin/nologin nslcd:x:65:55:LDAP Client User:/:/sbin/nologin ldapuser1:x:1101:600:test11:/home/test11:/bin/bash |
위와 같이 기본 로컬에 저장된 계정뿐만아니라 LDAP에 저장되어있는 계정들까지 출력이 된다면 정상적으로 연결된것입니다.
위와같이 출력이 안되신다면 nslcd -d 옵션을 이용하여 디버그 모드로 확인 또는
/var/log/message , /var/log/secure 두 로그를 확인하시면 어디서 pam 모듈이 실패했는지 확인하실수 있습니다.