소개
안녕하세요. 사람인에이치알 SRE팀 박용철입니다. 서버를 운영하다보면 서버계정과 관련된 업무도 하게되는데 서버가 많아질수록 계정 생성,삭제,권한부여등 여간 귀찮은(?) 작업이 아닐 수 없습니다. 이번 포스팅에서는 이부분을 개선하고 계정신청을 위한 내부 업무프로세스를 단순화하기 위해 구축한 IdM 에 대한 내용을 작성하고자 합니다.
도입사유
로컬계정을 사용하는 경우 개인계정별로 서버마다 아래와 같은 상황이 발생 할 수 있습니다.
- 개인계정의 아이디가 다른 경우
- UID/GID 가 다른 경우
- 패스워드 및 만료일이 다른 경우
- 서버마다 계정잠금상태가 다른 경우
- 사용자는 패스워드 만료된 경우 서버마다 패스워드 변경 필요
- 서버접근이 필요한 사용자는 입사시 계정신청, 서버추가시 계정신청
- 계정을 관리하는 관리자는 서버추가시 계정세팅, 입사/퇴사 등에 따른 계정관리 및 관리대장 작성
위와 같은 불편한 상황을 개선하고 싶었습니다.
FreeIPA
소개
Identity Management 를 위해 RedHat 에서 개발한 소프트웨어로 디렉토리서비스,인증서비스,인증서관리등 통합인증을 위한 여러 컴포넌트들이 포함되어 있으며 관리를 위한 cli, web ui 를 지원합니다.
Component | 용도 | 비고 |
---|---|---|
389 Directory Server | 디렉토리 서비스 | |
kerberos | 동일관리도메인에서 인증을 위한 프로토콜 | |
dogtag | 인증서 시스템 | |
certmonger | 인증서 갱신등의 관리 | |
DNS | 네임서버 | optional |
NTP | 타임서버 | optional |
apache, mod_wsgi, python | 웹관리콘솔, API |
sssd 는 IdM클라이언트를 위한 도구이며 nss와 pam responder 를 통해 NSS, PAM 서비스와 연결되며 provider 로 ad, ldap, ipa, krb5 를 지원합니다.
서버구성
서버별 역할 및 설치팩키지 와 명령어
호스트명 | 아이피 | 용도 | 설치할 팩키지 | IdM 설치 명령어 |
---|---|---|---|---|
idm1.test.local | 10.0.0.11 | IdM 서버 #1 | ipa-server | ipa-server-install |
idm2.test.local | 10.0.0.12 | IdM 서버 #2 | ipa-server | ipa-client-install, ipa-replica-install, ipa-ca-install |
server1.test.local | 10.0.0.21 | 클라이언트 서버 | ipa-client | ipa-client-install |
설정시 사용할 정보
- REALM : TEST.LOCAL
- 도메인 : test.local
- 389 Directory Server 관리자 : Directory Manager (기본값)
- IPA 관리자 : admin (기본값)
- 클라이언트가 IdM 과 연동하기 위해 사용되는 sssd 에는 자체적으로 FAILOVER 기능이 있어 별도의 LB 구성은 하지 않았습니다
- 사람인HR 은 별도의 내부용 네임서버와 타임서버를 운영중이므로 dns, ntp 관련 작업은 하지 않았습니다
사전작업
서버간 통신을 위한 방화벽 허용
IdM 연동을 위해 방화벽에서 역할별로 다음 내용을 참고하여 포트를 허용합니다 (편의상 IdM 서버간 통신은 전체 허용으로 가정)
IdM 서버 Inbound
프로토콜 | 포트 | 용도 |
---|---|---|
TCP/UDP | 88, 464 | Kerberos 인증 |
TCP | 389, 636 | LDAP 통신 |
IdM 클라이언트 Outbound
프토로콜 | 포트 | 용도 |
---|---|---|
TCP/UDP | 88, 464 | Kerberos 인증 |
TCP | 389, 636 | LDAP 통신 |
호스트네임 설정
[idm1] $ hostnamectl set-hostname idm1.test.local
[idm2] $ hostnamectl set-hostname idm2.test.local
nss hosts 에 idm1, idm2 등록 (/etc/hosts)
만약 test.local 이 아닌 실제 사용중인 도메인으로 한다면 dns 서버에 레코드 등록하는 작업으로 합니다
10.0.0.11 idm1.test.local idm1
10.0.0.12 idm2.test.local idm2
팩키지 설치
# 서버일 경우
[idm1] $ yum install ipa-server
[idm2] $ yum install ipa-server
# 클라이언트일 경우
[server1] $ yum install ipa-client
서버 설치 #1 (idm1.test.local)
주의) ipa-server-install 혹은 ipa-client-install 을 실행하면 hostname 으로 전달한 도메인명으로 서버의 호스트네임을 변경됩니다. 호스트네임 변경에 따른 서비스에 영향이 있다면 주의가 필요하며 이 경우 manual configuration 방식으로 진행해야 합니다
[idm1] $ ipa-server-install \
--unattended \
--ds-password='디렉토리서버관리자패스워드' \
--admin-password='IPA관리자패스워드' \
--domain=test.local \
--realm=TEST.LOCAL \
--hostname idm1.test.local \
--no-host-dns \
--no-ntp
별도의 DNS 및 NTP 를 운영중이므로 dns 및 ntp 관련 부분은 사용하지 않는 것으로 하였습니다
서버설치 #2 (idm.test.local)
client 설치를 먼저 하고 이후 replica 및 ca 구성을 진행합니다
# mkhomedir 옵션을 활성화하면 PAM 설정에 pam_oddjob_mkhomedir 모듈이 활성화되어
# 사용자의 홈디렉토리가 없을 경우 자동으로 생성합니다
[idm2] $ ipa-client-install \
--unattended \
--principal=admin@TEST.LOCAL \
--domain=test.local \
--server=idm1.test.local \
--realm=TEST.LOCAL \
--hostname=idm2.test.local \
--password='IPA관리자패스워드' \
--mkhomedir \
--no-ntp
replica 구성 (idm2.test.local)
# replica 구성
[idm2] $ ipa-replica-install \
--unattended \
--admin-password='IPA관리자패스워드' \
--domain=test.local \
--server=idm1.test.local \
--realm=TEST.LOCAL \
--hostname=idm2.test.local \
--principal=admin@TEST.LOCAL \
--no-host-dns \
--no-ntp
# CA 서비스 구성
[idm2] $ ipa-ca-install \
--unattended \
--no-host-dns \
--password='LDAP Directory Manager 패스워드' \
--admin-password='IPA관리자패스워드'
# ipa 명령어로 replica 상태를 확인하기 위해 kerberos 인증
[idm2] $ kinit admin
Password for admin@TEST.LOCAL:
[idm2] $ ipa-replica-manage list --no-lookup
idm2.test.local: master
idm1.test.local: master
replica 테스트 (idm1.test.local)
# 계정추가
[idm1] $ ipa user-add testuser --first=firstname --last=lastname --shell=/bin/bash --password
Password:
Enter Password again to verify:
# idm2 에서 확인
[idm2] $ kinit admin
[idm2] $ ipa user-show testuser --all
관리자가 계정을 생성하면서 입력한 초기패스워드는 만료일이 생성한 시점으로 설정되어 사용자는 최초 로그인후 패스워드를 변경해야합니다
클라이언트 (server1.test.local)
클라이언트 설치 및 설정
다음 명령을 실행시 hostname 옵션으로 전달한 값(server1.test.local)으로 호스트네임이 변경되므로 호스트네임변경에 따른 서비스 영향이 있다면 주의가 필요합니다
# ipa-client 설치 및 설정
[server1] $ ipa-client-install \
--unattended \
--principal=admin@TEST.LOCAL \
--domain=test.local \
--server=idm1.test.local \
--realm=TEST.LOCAL \
--hostname=server1.test.local \
--password='ipa_pass' \
--mkhomedir \
--no-ntp
sssd 설정
실제 연동을 담당하는 서비스로 nss, pam responder 를 지원하며 ad, ldap, ipa, krb5 provider 를 지원합니다.
ipa_server 옵션에 여러개의 서버를 지정하는 경우 FAILOVER 형태로 동작합니다. 그리고 sssd.conf 파일은 root 만 읽기/쓰기가 가능하도록 권한이 되어 있어야 합니다
[sssd]
config_file_version = 2
services = nss, sudo, pam, ssh
domains = test.local
[domain/test.local]
ipa_domain = test.local
ipa_hostname = server1.test.local
ipa_server = idm1.test.local, idm2.test.local
account_cache_expiration = 1
cache_credentials = True
krb5_store_password_if_offline = True
id_provider = ipa
auth_provider = ipa
access_provider = ipa
chpass_provider = ipa
ldap_tls_cacert = /etc/ipa/ca.crt
[nss]
fd_limit = 65535
[sudo]
fd_limit = 65535
연동여부 확인
ipa 서버에 생성한 testuser 가 있는지 getent 명령어를 사용하여 조회합니다
[server1] $ getent passwd testuser
testuser:*:997000001:997000001:firstname lastname:/home/testuser:/bin/bash
# 해당 계정으로 ssh 접속가능여부 테스트
[idm1] $ ssh testuser@10.0.0.21
IdM 서버의 설정 변경
기본적인 구축이 완료되면 몇가지 설정을 변경할 필요가 있습니다
HBAC 정책중 전체허용정책 비활성화
ipa 는 allow_all 이라는 HBAC 정책이 기본적으로 활성화 되어 있는데 이 정책은 모든 접근을 허용하는 규칙으로
계정별 혹은 그룹별 접근을 통제하기 위해 이 정책을 비활성화하는 것이 좋습니다.
아래 내용은 cli 기준으로 작성한 것으로 web ui 관리 콘솔에서도 가능합니다
# IPA 에서는 HBAC 룰이 기본적으로 전체 허용으로 되어 있습니다
[idm1] $ ipa hbacrule-show allow_all
Rule name: allow_all
User category: all
Host category: all
Service category: all
Description: Allow all users to access any host from any host
Enabled: TRUE
# 위 룰을 disable 합니다.
[idm1] $ ipa hbacrule-disable allow_all
------------------------------
Disabled HBAC rule "allow_all"
------------------------------
$ ipa hbacrule-show allow_all
Rule name: allow_all
User category: all
Host category: all
Service category: all
Description: Allow all users to access any host from any host
Enabled: FALSE
389 directory server 의 anonymous access 비활성화
기본적으로 anoymous access 가 활성화되어 디렉토리서버에 인증없이 조회가 가능하도록 되어 있어 이 부분을 비활성화합니다
# 현재 상태 조회
$ ldapsearch -x -LLL -D "cn=Directory Manager" -W -b cn=config -s base "(cn=config)" nsslapd-allow-anonymous-access
Enter LDAP Password:
dn: cn=config
nsslapd-allow-anonymous-access: on
# 상태 변경
$ ldapmodify -x -D "cn=Directory Manager" -W <<EOF
dn: cn=config
changetype: modify
replace: nsslapd-allow-anonymous-access
nsslapd-allow-anonymous-access: rootdse
EOF
Enter LDAP Password:
modifying entry "cn=config"
# 변경여부 확인
$ ldapsearch -x -LLL -D "cn=Directory Manager" -W -b cn=config -s base "(cn=config)" nsslapd-allow-anonymous-access
Enter LDAP Password:
dn: cn=config
nsslapd-allow-anonymous-access: rootdse
admin 계정의 shell 변경
IPA 관리용도의 admin 계정은 서버로그인이 필요하지 않으므로 shell 을 /sbin/nologin 으로 변경합니ㅏㄷ
$ ipa user-mod --shell=/sbin/nologin admin
---------------------
Modified user "admin"
---------------------
User login: admin
Last name: Administrator
Home directory: /home/admin
Login shell: /sbin/nologin
Principal alias: admin@TEST.LOCAL
UID: 997000000
GID: 997000000
Account disabled: False
Password: True
Member of groups: admins, trust admins
Kerberos keys available: True
참고사항
nscd
nscd 는 호스트정보등를 캐싱해주는 역할을 하지만 IdM 환경에서 nscd 를 사용하지 않는 것을 권장합니다. 만약 nscd 를 사용중이라면 호스트정보만 캐시하고 사용자,그룹등의 기타 정보는 캐시하지 않도록 변경해야합니다.
# /etc/nscd.conf
enable-cache passwd no
enable-cache group no
enable-cache hosts yes
enable-cache services no
enable-cache netgroup no
마치며
연동이 필요한 수백대 서버를 IdM replica 로 구성된 2대의 서버와 연동하였고 부하없이 이용중에 있습니다. 그리고 IPA 에서 제공하는 API 혹은 ldap 쿼리를 통해 입사/퇴사시의 계정생성/비활성화, 90일 이상 인증시도했던 기록이 없을 경우 계정 비활성화, 패스워드 만료 7일전 안내메일등 기존에 계정과 관련하여 진행된 신청절차 및 업무프로세스를 단순화 및 자동화하고 있습니다. FreeIPA 는 계정관리, HBAC, sudo, 패스워드정책등을 중앙에서 관리할 수 있게 해주며 관리콘솔 및 API 역시 지원하고 있어 SRE팀에서는 계정과 관련된 업무가 거의 없게 되었고 앞으로 기본적으로 제공하는 기능을 더욱 활용하거나 이용중 발생하는 이슈들이 있다면 개선할 예정입니다.
감사합니다.
참고자료
- https://man7.org/linux/man-pages/man5/nsswitch.conf.5.html
- http://www.linux-pam.org/
- https://www.freeipa.org/
- https://sssd.io/
- https://youtu.be/5N242XcKAsM
- https://access.redhat.com/documentation/ko-kr/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/con_data-flow-when-authenticating-as-a-user-with-sssd-in-idm_assembly_troubleshooting-authentication-with-sssd-in-idm