Kerberos 인증
안할래야 안할 수가 없는 인증
Cloud 환경에 Hadoop Ecosystem 을 구축할 때에 Kerberos 인증이 필수적으로 들어간다.(Cloudera의 경우)
Kerberos 인증이 뭔지 공부하고 개발 중 사용한 소소한 팁들도 남겨둘 겸 이번 주제는 kerberos로 잡았다.
이번 글에는 kerberos의 구성을 알아보고 사용자 입장에서 어떻게 인증하는지 알아보고자 한다.
(언젠간) 다음 글에서는 kerberos를 설치하는 방법을 알아볼 예정이다.
참고로 kerberos의 대칭키, 인증키 어쩌구 저쩌구 등등의 내용은 넣지 않으려 한다. 해당 내용은 개발자와 운영자가 kerberos의 전반적인 과정을 이해하고 사용하는데에 있어서 조금은 동떨어져 있는 내용이기에 오히려 헷갈리게 만들 여지가 있다고 생각한다. (내가 그랬음..)
Kerberos 인증
Kerberos is a network authentication protocol. It is designed to provide strong authentication for client/server applications by using secret-key cryptography.
Kerberos는 네트워크 인증 프로토콜입니다. 비밀키 암호화를 사용하여 클라이언트/서버 애플리케이션에 대한 강력한 인증을 제공하도록 설계되었습니다.
정의
Kerberos 인증은 MIT에서 개발한 클라이언트와 서버 애플리케이션 간의 인증을 하는 네트워크 인증 프로토콜 중 하나이다.
구성
Kerberos를 구성하기 위해서는 KDC (Key Distribution Center)만 있으면 된다.
KDC가 AS(인증 서버, Authentication Server) 와 TGS(티켓 부여 서버, Ticket-Granting Server)를 포함한다.
AS : 사용자의 초기 인증 요청을 처리하고, 임시 세션 키와 인증서를 제공
TGS : 사용자가 접근하려는 서비스에 대한 서비스 티켓을 발급
보통 AS와 TGS를 하나의 서버에 설치하기 때문에 KDC가 하나만 있으면 된다고 표현한 것이다. 간단히 도식화하면 아래와 같다.
이 외
Client : 사용자의 컴퓨터로, 인증 과정에 참여한다.
서비스 서버 : 사용자가 접근하려는 리소스나 애플리케이션을 호스팅하는 서버이다.
위 둘은 인증과정에 참여한다.
인증 과정
1. AS의 설명에 있듯이 AS는 "초기 인증"을 담당한다. 클라이언트가 인증하고싶어요~ 라고 날리면
2. AS는 DB에 사용자 ID가 있는지 확인하고 임시 세션키와 TGT(인증서, Ticket-Granting Ticket)를 사용자에게 준다.
클라이언트는 이제 이 두가지를 가지고 다른 서비스에 접근할 수 있는 준비를 마쳤다. 클라이언트의 역할은 여기서 끝.
3-1. 원하는 서비스에 접근하고자 명령어를 날리기만 하면
3-2. TGS에 임시 세션키와 TGT를 보내고 실제 서비스 티켓을 요청한다. 이 과정은 클라이언트가 직접하지 않는다. Kerberos가 내부적으로 해준다.
4. 그리고 TGS는 임시세션키와 TGT가 적절하다면 서비스 티켓을 제공해준다.
클라이언트는 이제 HDFS 서버에 잘 접근할 수 있게 되었다~ 다른 서비스에 접근할 때에도 임시세션키와 TGT의 유효기간이 끝나지 않았다면 자동으로 인증을 성공해서 서비스 티켓을 받을 수 있게 된다.
해당 과정을 명령어로 알아보자.
1. 사용자 인증을 시작하고, 임시 세션 키와 인증서(TGT)를 받는다. 이 명령어를 시행하면 비밀번호를 입력해야한다.
kinit [username]
2. 사실.. 이미 클라이언트의 역할은 끝났다. 하지만 내부적으로 수행되는 서비스 티켓을 받는 명령어는 아래와 같다.
kvno [service_principal_name]
3. klist 명령어를 통해 현재 로그인한 사용자의 인증서(TGT)와 서비스 티켓을 확인할 수도 있다. 위의 service_principal_name 또한 볼 수 있다.
아래 결과값은 현재 캡처할 수 없는 환경인지라 Chat GPT에게 klist의 결과값 예시를 물어서 나온 결과이다.
klist
#결과값
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: alice@example.com
Valid starting Expires Service principal
09/01/2023 09:00:00 09/01/2023 19:00:00 krbtgt/example.com@example.com
09/01/2023 09:15:00 09/01/2023 19:00:00 HTTP/webserver.example.com@example.com
첫번째 티켓은 TGT이고 두번째 티켓은 서비스에 접근할 수 있는 서비스 티켓이다.
편리한 방법들
1. keytab
스크립트 상에서 인증을 진행하려고 하면 kinit [username]으로는 힘들다. 비밀번호를 입력해야하기 때문이다. 이럴 때에 keytab 파일이 유용하다.
Keytab 파일은 Kerberos 인증 과정에서 사용자가 비밀번호를 입력하는 대신 키를 사용하여 인증하는 방법을 제공한다. Keytab 파일은 사용자나 서비스 계정의 Kerberos 주체(principal)와 연관된 암호화된 키를 포함하고 있다.
kinit -kt /path/to/keytabfile username
서버의 특정 경로에 keytab 파일을 저장해두고 해당 파일을 활용해서 인증하면 비밀번호 입력 없이 인증이 가능하다.
keytab 파일의 내부 내용은 아래와 같다.
주체(principal): 파일과 연관된 Kerberos 주체로, 사용자나 서비스의 고유한 식별자이다. 주체는 일반적으로 사용자 이름과 도메인 이름으로 구성된다 (예: alice@example.com).
키 버전 번호 (KVNO): 키가 변경될 때마다 증가하는 키 버전 번호. 이 번호는 키 변경 이력을 추적하고, 현재 사용 중인 키와 이전 키를 구분하는 데 사용한다.
암호화 키: 주체와 관련된 암호화된 키이다. 이 키는 인증 과정에서 Kerberos KDC와의 통신에 사용된다.
암호화 유형: 사용된 암호화 알고리즘의 종류를 나타낸다. Kerberos는 여러 가지 암호화 알고리즘을 지원하며, keytab 파일은 암호화 키와 함께 사용된 암호화 유형을 저장합니다.
2. KRB5CCNAME
TGT는 티켓 파일 캐시에 저장되는데 위치는(리눅스 기준) /tmp 이며 파일 이름은 krb5cc_uid 형식이다.
uid는 사용자의 고유 식별자이다.
위의 klist 결과에도 Ticket cache 내용이 적혀있는걸 확인할 수 있다.
YARN과 같은 리소스 매니저를 통해 여러 서버에서 작업이 실행되는 경우라면 어떨까? 작업이 실행되는 모든 서버가 티켓을 가지고 있어야 할 것이다. 이를 위해 스크립트 맨 위에 kinit -kt /path/to/keytabfile username 를 넣어주는 것이 하나의 방법이다.
다만 지금 말하려는건, 이 때 인증 받는 주체가 yarn, oozie 등 어떤게 될 지 상황에 따라서 다른다. 이럴 경우 캐시가 겹치면서 꼬일수도 있다고 한다.(나도 듣기만 한 얘기라서.. 나중에 케이스를 재현하게 되면 업뎃하러 오려고 한다)
export KRB5CCNAME=/tmp/krb5cc_$(date +%s%N)
이를 방지하기 위해 각기 다른 캐시네임을 주는 방법을 택할 수 있는데 현재 시간을 적는 걸로 변경해보았다.
이렇게 Kerberos의 구성, 사용 방법, 꿀팁을 알아보았다. cloudera를 cloud에 구축하면 자동으로 kerberos가 구성되기 떄문에 직접 구성하진 않고 사용만 해보았다. 이에 따라 사용자 입장에서 궁금했던 점, 사용하는 법 등을 정리하였는데 다음 번에 시간이 된다면 구성하는 방법에 대해서 알아보자..!