엔지니어링

Kerberos를 사용해 Elasticsearch 클러스터의 보안을 유지하는 방법

머리가 세 개인 무시무시한 경비견이 데이터 보안을 지키고 있습니다

Elasticsearch 6.4 버전에서는 플래티넘 구독에 Kerberos 인증 지원을 추가했습니다. 이는 완전한 Kerberized Elastic Stack으로 가는 첫 단계입니다. Kerberos는 분산 시스템에서 인증의 보안을 유지할 수 있도록 해주는 고급 기술입니다. Kerberos는 계속 반복해서 사용자 이름과 비밀번호를 제공할 필요 없이 여러 다른 서비스에 대해 싱글 사인온(SSO) 액세스를 제공해줍니다. 이 블로그에서는 HTTP 트래픽을 위한 Kerberos 인증을 지원하기 위해 Elasticsearch를 구성하는 방법에 대해 다뤄보겠습니다.

배포 개요

“앨리스"라는 사용자가 단일 노드 Elasticsearch 클러스터를 가지고 있다는 간단한 시나리오를 한 번 가정해 보겠습니다. 앨리스는 이미 Kerberos 영역인 demo.local이 있고 Kerberos 인증을 사용해 Elasticsearch 클러스터에 대한 보안을 유지하고 싶어합니다. Kerberos 인증 서버는 그 영역 내에서 사용자, 호스트 또는 서비스를 인증할 권한이 있습니다. 이 블로그에서 사용되는 명령어는 MIT Kerberos 실행을 참고하고 있습니다. 자세한 내용은 MIT Kerberos 설명서를 참조해 주세요.

이 간단한 시나리오에는 다음과 같이 세 개의 호스트 컴퓨터가 등장합니다.

  • 호스트-1(kdc.demo.local): Kerberos 키 배포 센터(Key Distribution Center, KDC)이며 평상 시에 인증 서버 및 티켓 발행 서버 역할을 합니다.
  • 호스트-2(es.demo.local): Elasticsearch 싱글 노드 클러스터가 있습니다.
  • 호스트-3(client.demo.local): Elasticsearch 클라이언트가 있습니다.

SimpleESKerberosDeployment

성공적인 Kerberos 인증 단계는 다음과 같습니다.

  1. 앨리스(alice@DEMO.LOCAL)가 자신의 자격 증명을 사용해 클라이언트 컴퓨터(client.demo.local)에 로그인합니다.
  2. 클라이언트 컴퓨터가 KDC 서버(kdc.demo.local)로부터 티켓 승인 티켓(Ticket Granting Ticket, TGT)을 요청합니다.
  3. 클라이언트는 Elasticsearch 서비스 https://es.demo.local:9200에 액세스하여 Unauthorized(401)의 HTTP의 상태 코드가 담긴 응답을 반환하며 여기에 WWW-Authenticate: Negotiate 헤더가 포함됩니다.
  4. 클라이언트는 Elasticsearch 서비스 사용자 HTTP/es.demo.local@DEMO.LOCAL에 대해 티켓 발행 서버(Ticket Granting Server, TGS)로부터 세션 티켓을 요청합니다. 서비스 액세스에 사용되는 URL에서 Elasticsearch 서비스 사용자 이름이 제공됩니다.
  5. 클라이언트는 인증을 위해 Elasticsearch 서비스에게 이 티켓을 제시합니다.
  6. Elasticsearch 서비스는 Kerberos 티켓을 확인하고 액세스를 허용합니다(티켓이 유효한 경우).

Kerberos 영역 구성

Elasticsearch Kerberos 영역을 활성화하려면 다음과 같이 Kerberos 인프라를 배치해야 합니다.

  • 도메인에 있는 모든 참여 컴퓨터의 시계 동기화
  • 모든 참여 컴퓨터에 대해 작동하는 DNS 도메인
  • KDC 서버
  • Kerberos 라이브러리와 kinit, klist 같은 구성 파일이 설치된 클라이언트 노드

Kerberos 인프라가 배치되었다는 전제 하에 다음 정보가 필요합니다.

  • Kerberos 구성 파일krb5.conf --- 이 파일에는 기본 영역, KDC 서버, 도메인 영역 매핑과 같은 Kerberos 환경에 대해 필요한 세부 사항이 담겨 있습니다. Linux 시스템에서는 이 파일이 통상적으로 /etc 디렉터리에 위치해 있습니다. JVM 시스템 속성 java.security.krb5.conf는 이 구성 파일의 전체 경로에 대해 설정되어야 합니다. JVM이 이 구성을 로드하여 필요할 때 필요한 정보를 찾는 데 사용하게 됩니다.
  • Elasticsearch HTTP 서비스keytab --- 키탭은 사용자와 암호화 키 쌍을 저장하는 파일입니다. 이것은 Elasticsearch HTTP 서비스가 클라이언트로부터 들어오는 티켓을 확인하기 위해 사용하는 키탭입니다. 대개 서비스 사용자 이름은 HTTP/es.demo.local@DEMO.LOCAL 형식입니다. HTTP는 서비스 클래스이고 es.demo.local은 Elasticsearch 호스트에 대해 정규화된 도메인 이름이며 DEMO.LOCAL은 Kerberos 영역입니다. 이 파일을 Elasticsearch 구성 디렉터리에 위치시켜야 합니다. 이 파일에 자격 증명이 들어있으니 Elasticsearch를 실행하는 사용자에게 반드시 읽기 전용 파일 권한만 부여하여 이 파일을 보호하세요. Kerberos 시스템 관리자는 서비스를 위해 키탭 파일을 제공해 드릴 수 있습니다.

이 두 파일을 갖추면 이제 Elasticsearch에서 Kerberos 영역을 구성할 준비가 되었습니다.

1. JVM 옵션 구성

먼저, JVM 옵션 파일(jvm.options)을 편집하여 Kerberos 구성 파일에 대한 JVM 시스템 속성을 구성해야 합니다.

# Kerberos configuration
-Djava.security.krb5.conf=/etc/krb5.conf

2. Kerberos를 위한 Elasticsearch 구성

다음으로, elasticsearch.yml 파일에서 Kerberos 영역을 추가해야 합니다.

# Kerberos realm
xpack.security.authc.realms.kerb1:
type: kerberos
    order: 1
    keytab.path: es.keytab

이것은 kerberos 유형, 영역 순서 1, 그리고 구성 디렉터리에서 Elasticsearch 서비스 키탭 파일(es.keytab)을 참조하는 keytab.path의 Kerberos 영역(kerb1)을 구성합니다. 자세한 정보는 kerberos 영역 구성 설명서를 참조하세요.

3. Elasticsearch 재시작

일단 구성이 배치되면 Elasticsearch 노드를 다시 시작해야 합니다.

4. Kerberos 사용자를 역할에 매핑

Kerberos는 인증 세부사항을 제공하지 않는 인증 프로토콜입니다. 승인을 하려면, 역할 매핑 API를 사용해 사용자를 역할에 매핑할 수 있습니다. 다음은 kerbrolemapping이라고 명명된 역할 매핑을 생성하여, 여기에서 monitoring_user 역할이 사용자 alice@DEMO.LOCAL에게 할당됩니다.

$ curl -u elastic -H "Content-Type: application/json" -XPOST http://es.demo.local:9200/_xpack/security/role_mapping/kerbrolemapping -d 

{
    "roles" : [ "monitoring_user" ],
    "enabled": true,
    "rules" : {
    "field" : { "username" : "alice@DEMO.LOCAL" }
    }
}

역할 매핑에 대한 자세한 내용은 사용자 및 그룹에게 역할 매핑 설명서를 참조하세요.

작동 확인!

클라이언트 컴퓨터에서 인증이 작동하는지 확인하려면, 티켓 승인 티켓을 받기 위한 kinit 명령어를 수행해야 합니다.

$ kinit alice@DEMO.LOCAL  
Password for alice@DEMO.LOCAL:  
$ klist  
Ticket cache: KEYRING:persistent:1000:krb_ccache_NvNtNgS  
Default principal: alice@DEMO.LOCAL  

Valid starting      Expires             Service principal
31/08/18 02:20:07   01/09/18 02:20:04   krbtgt/DEMO.LOCAL@DEMO.LOCAL

그 다음, negotiate 매개변수가 있는 curl을 호출하여 HTTP를 이용한 Kerberos 인증을 수행할 수 있습니다.

$ curl --negotiate -u : -XGET http://es.demo.local:9200/

and Voila!

{
    "name" : "Lw7K29R",
    "cluster_name" : "elasticsearch",
    "cluster_uuid" : "qd3iafXORLy0VCfVD_Hp9w",
    "version" : {
    "number" : "6.4.0",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "595516e",
    "build_date" : "2018-08-17T23:18:47.308994Z",
    "build_snapshot" : true,
    "lucene_version" : "7.4.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
    },
    "tagline" : "You Know, for Search"
}

결론

일단 서비스 사용자 키탭과 kerberos 구성 파일에 액세스하게 되면 Kerberos 영역을 쉽게 구성할 수 있다는 것을 보았습니다. Elasticsearch를 위해 필요한 Kerberos 영역 구성은 몇 줄 뿐입니다. Elasticsearch에서 Kerberos 지원은 이제 시작일 뿐입니다. 계속해서 향후 업데이트를 통해 다른 Elastic Stack 구성 요소를 단계적으로 지원해 나갈 예정이니, 지켜봐 주세요!