소개

안녕하세요. 사람인에이치알 SRE팀 박용철입니다. 서버를 운영하다보면 서버계정과 관련된 업무도 하게되는데 서버가 많아질수록 계정 생성,삭제,권한부여등 여간 귀찮은(?) 작업이 아닐 수 없습니다. 이번 포스팅에서는 이부분을 개선하고 계정신청을 위한 내부 업무프로세스를 단순화하기 위해 구축한 IdM 에 대한 내용을 작성하고자 합니다.

도입사유

로컬계정을 사용하는 경우 개인계정별로 서버마다 아래와 같은 상황이 발생 할 수 있습니다.

local_account.png

  • 개인계정의 아이디가 다른 경우
  • 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 를 지원합니다.

서버구성

centralized_account.png

서버별 역할 및 설치팩키지 와 명령어

호스트명 아이피 용도 설치할 팩키지 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