SASL을 이용한 인증

SASL을 이용한 인증 (Authentication using SASL)

이 페이지는 Kafka에서 SASL로 클라이언트·브로커 인증을 구성하는 전체 가이드예요. JAAS 설정, GSSAPI(Kerberos), PLAIN, SCRAM, OAUTHBEARER, 위임 토큰(Delegation Token)과, 실행 중인 클러스터에서 SASL 메커니즘을 바꾸는 방법까지 실제 코드 블록과 함께 설명해요.

출처: 문서

본문

JAAS 구성 (JAAS configuration)

Kafka는 SASL 구성에 Java Authentication and Authorization Service(JAAS)를 사용합니다.

Kafka 브로커를 위한 JAAS 구성

KafkaServer는 각 KafkaServer/Broker가 사용하는 JAAS 파일의 섹션 이름입니다. 이 섹션은 브로커가 브로커 간 통신을 위해 만드는 모든 SASL 클라이언트 연결을 포함해 브로커의 SASL 구성 옵션을 제공합니다. 여러 리스너가 SASL을 사용하도록 구성된 경우, 섹션 이름에 소문자 리스너 이름과 마침표를 접두사로 붙일 수 있습니다(예: sasl_ssl.KafkaServer).

브로커는 브로커 구성 속성 sasl.jaas.config로 JAAS를 구성할 수도 있습니다. 속성 이름은 SASL 메커니즘을 포함한 리스너 접두사로 시작해야 합니다. 즉, listener.name.{listenerName}.{saslMechanism}.sasl.jaas.config입니다. 구성 값에는 로그인 모듈 하나만 지정할 수 있습니다. 리스너에 여러 메커니즘이 구성되면 리스너와 메커니즘 접두사를 사용해 각 메커니즘에 대한 구성을 제공해야 합니다. 예를 들어,

        listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
            username="admin" \
            password="admin-secret";
        listener.name.sasl_ssl.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
            username="admin" \
            password="admin-secret" \
            user_admin="admin-secret" \
            user_alice="alice-secret";

JAAS 구성이 서로 다른 수준에서 정의되면 우선 순위 순서는 다음과 같습니다.

  • 브로커 구성 속성 listener.name.{listenerName}.{saslMechanism}.sasl.jaas.config
  • 정적 JAAS 구성의 {listenerName}.KafkaServer 섹션
  • 정적 JAAS 구성의 KafkaServer 섹션

GSSAPI(Kerberos), PLAIN, SCRAM 또는 비프로덕션/프로덕션 OAUTHBEARER의 브로커 구성 예는 각각을 참고하세요.

Kafka 클라이언트를 위한 JAAS 구성

클라이언트는 클라이언트 구성 속성 sasl.jaas.config 또는 브로커와 유사한 정적 JAAS 구성 파일로 JAAS를 구성할 수 있습니다.

클라이언트 구성 속성을 사용한 JAAS 구성

클라이언트는 실제 구성 파일을 만들지 않고 JAAS 구성을 프로듀서·컨슈머 속성으로 지정할 수 있습니다. 이 모드는 각 클라이언트에 다른 속성을 지정해 같은 JVM 내의 다른 프로듀서·컨슈머가 다른 자격 증명을 사용할 수 있게도 해줍니다. 정적 JAAS 구성 시스템 속성 java.security.auth.login.config와 클라이언트 속성 sasl.jaas.config가 모두 지정되면 클라이언트 속성이 사용됩니다.

GSSAPI(Kerberos), PLAIN, SCRAM 또는 비프로덕션/프로덕션 OAUTHBEARER의 클라이언트 구성 예는 각각을 참고하세요.

정적 구성 파일을 사용한 JAAS 구성

정적 JAAS 구성 파일로 클라이언트의 SASL 인증을 구성하려면:

KafkaClient {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/etc/security/keytabs/kafka_client.keytab"
    principal="[email protected]";
};
  • KafkaClient라는 클라이언트 로그인 섹션이 있는 JAAS 구성 파일을 추가합니다. 선택한 메커니즘에 대한 로그인 모듈을 KafkaClient에 구성합니다(GSSAPI(Kerberos), PLAIN, SCRAM 또는 비프로덕션/프로덕션 OAUTHBEARER 설정 예 참고). 예를 들어 GSSAPI 자격 증명은 다음과 같이 구성할 수 있습니다.
-Djava.security.auth.login.config=/etc/kafka/kafka_client_jaas.conf
  • JAAS 구성 파일 위치를 각 클라이언트 JVM의 JVM 파라미터로 전달합니다.

SASL 구성 (SASL configuration)

SASL은 전송 계층으로 PLAINTEXT 또는 SSL과 함께 각각 SASL_PLAINTEXT 또는 SASL_SSL 보안 프로토콜을 사용할 수 있습니다. SASL_SSL을 사용한다면 SSL도 구성해야 합니다.

SASL 메커니즘 (SASL mechanisms)

Kafka는 다음 SASL 메커니즘을 지원합니다.

  • GSSAPI (Kerberos)
  • PLAIN
  • SCRAM-SHA-256
  • SCRAM-SHA-512
  • OAUTHBEARER

Kafka 브로커를 위한 SASL 구성

listeners=SASL_PLAINTEXT://host.name:port
security.inter.broker.protocol=SASL_PLAINTEXT (or SASL_SSL)
  • 하나 이상의 쉼표로 구분된 값을 담는 listeners 파라미터에 SASL_PLAINTEXT 또는 SASL_SSL 중 적어도 하나를 추가해 server.properties에 SASL 포트를 구성합니다. SASL 포트만 구성하거나(또는 브로커가 서로 SASL로 인증하기를 원한다면) 브로커 간 통신에 같은 SASL 프로토콜을 설정했는지 확인하세요.
  • 브로커에서 활성화할 지원 메커니즘을 하나 이상 선택하고 해당 메커니즘에 대한 SASL 구성 단계를 따릅니다. 브로커에서 여러 메커니즘을 활성화하려면 여기의 단계를 따르세요.

Kafka 클라이언트를 위한 SASL 구성

SASL 인증은 새 Java Kafka 프로듀서와 컨슈머에서만 지원되며, 이전 API는 지원되지 않습니다.

클라이언트의 SASL 인증을 구성하려면 클라이언트 인증을 위해 브로커에서 활성화된 SASL 메커니즘을 선택하고 선택한 메커니즘에 대한 SASL 구성 단계를 따르세요.

참고: SASL로 브로커에 연결할 때 클라이언트는 브로커 주소의 역방향 DNS 조회를 수행할 수 있습니다. JRE가 역방향 DNS 조회를 구현하는 방식 때문에, 클라이언트의 bootstrap.servers와 브로커의 advertised.listeners 모두에 정규화된 도메인 이름을 사용하지 않으면 느린 SASL 핸드셰이크가 발생할 수 있습니다.

SASL/Kerberos를 이용한 인증 (Authentication using SASL/Kerberos)

사전 요구사항 (Prerequisites)

  • Kerberos: 조직에서 이미 Kerberos 서버(예: Active Directory)를 사용 중이라면 Kafka를 위해 새 서버를 설치할 필요가 없습니다. 그렇지 않으면 하나를 설치해야 합니다. Linux 벤더에 Kerberos 패키지와 설치·구성 가이드가 있을 것입니다(Ubuntu, Redhat). Oracle Java를 사용한다면 Java 버전에 맞는 JCE 정책 파일을 다운로드해 $JAVA_HOME/jre/lib/security에 복사해야 합니다.
  • Kerberos Principal 생성: 조직의 Kerberos·Active Directory 서버를 사용한다면 Kerberos 관리자에게 클러스터의 각 Kafka 브로커와 Kerberos 인증으로 Kafka에 접근할 각 운영체제 사용자(클라이언트와 도구를 통해)에 대한 principal을 요청하세요. 직접 Kerberos를 설치했다면 다음 명령으로 직접 만들 수 있습니다.
$ sudo /usr/sbin/kadmin.local -q 'addprinc -randkey kafka/{hostname}@{REALM}'
$ sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{keytabname}.keytab kafka/{hostname}@{REALM}"
  • 모든 호스트가 호스트 이름으로 도달 가능한지 확인하세요. Kerberos는 모든 호스트가 FQDN으로 해석될 수 있어야 한다는 요구사항입니다.

Kafka 브로커 구성 (Configuring Kafka Brokers)

KafkaServer {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/etc/security/keytabs/kafka_server.keytab"
    principal="kafka/[email protected]";
};
  • 아래와 유사하게 수정한 JAAS 파일을 각 Kafka 브로커의 구성 디렉터리에 추가합니다. 이 예제에서는 kafka_server_jaas.conf라고 부르겠습니다(각 브로커는 고유한 keytab을 가져야 함). JAAS 파일의 KafkaServer 섹션은 브로커가 어떤 principal을 사용할지, 그 principal이 저장된 keytab의 위치를 알려줍니다. 이 섹션에 지정된 keytab을 사용해 브로커가 로그인할 수 있게 합니다.
-Djava.security.krb5.conf=/etc/kafka/krb5.conf
-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
  • JAAS와 선택적으로 krb5 파일 위치를 각 Kafka 브로커의 JVM 파라미터로 전달합니다. JAAS 파일에 구성된 keytab이 kafka 브로커를 시작하는 운영체제 사용자에게 읽을 수 있는지 확인하세요.
listeners=SASL_PLAINTEXT://host.name:port
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=GSSAPI
sasl.enabled.mechanisms=GSSAPI
sasl.kerberos.service.name=kafka
  • 여기에 설명된 대로 server.properties에서 SASL 포트와 SASL 메커니즘을 구성합니다. 예를 들면 위와 같습니다. 또한 server.properties에서 서비스 이름을 구성해야 하는데, 이는 kafka 브로커의 principal 이름과 일치해야 합니다. 위 예에서 principal은 "kafka/[email protected]"이므로 다음과 같습니다.

Kafka 클라이언트 구성 (Configuring Kafka Clients)

클라이언트의 SASL 인증을 구성하려면:

        sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
            useKeyTab=true \
            storeKey=true  \
            keyTab="/etc/security/keytabs/kafka_client.keytab" \
            principal="[email protected]";
  • 클라이언트(프로듀서, 컨슈머, connect 워커 등)는 자신의 principal(보통 클라이언트를 실행하는 사용자와 같은 이름)로 클러스터에 인증합니다. 필요에 따라 이 principal을 얻거나 만드세요. 그런 다음 각 클라이언트에 대한 JAAS 구성 속성을 구성합니다. 한 JVM 내의 다른 클라이언트는 다른 principal을 지정해 다른 사용자로 실행될 수 있습니다. producer.properties 또는 consumer.properties의 속성 sasl.jaas.config는 프로듀서·컨슈머 같은 클라이언트가 어떻게 Kafka Broker에 연결할 수 있는지 설명합니다. keytab을 사용하는 클라이언트(장기 실행 프로세스 권장)의 예는 위와 같습니다.
  • kafka-console-consumer 또는 kafka-console-producer 같은 명령줄 유틸리티의 경우 kinit를 "useTicketCache=true"와 함께 사용할 수 있습니다.
           sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
               useTicketCache=true;
  • 클라이언트용 JAAS 구성은 브로커와 유사하게 JVM 파라미터로도 지정할 수 있습니다. 클라이언트는 KafkaClient라는 로그인 섹션을 사용합니다. 이 옵션은 한 JVM에서 모든 클라이언트 연결에 대해 한 사용자만 허용합니다. 2. JAAS 구성에 구성된 keytab이 kafka 클라이언트를 시작하는 운영체제 사용자에게 읽을 수 있는지 확인하세요. 3. 선택적으로 krb5 파일 위치를 각 클라이언트 JVM의 JVM 파라미터로 전달합니다.
           -Djava.security.krb5.conf=/etc/kafka/krb5.conf
        security.protocol=SASL_PLAINTEXT (or SASL_SSL)
        sasl.mechanism=GSSAPI
        sasl.kerberos.service.name=kafka
  • producer.properties 또는 consumer.properties에서 다음 속성을 구성합니다.

SASL/PLAIN을 이용한 인증 (Authentication using SASL/PLAIN)

SASL/PLAIN은 보안 인증을 구현하기 위해 보통 TLS와 함께 사용하는 간단한 사용자 이름/비밀번호 인증 메커니즘입니다. Kafka는 여기에 설명된 대로 프로덕션 사용으로 확장할 수 있는 SASL/PLAIN의 기본 구현을 지원합니다.

기본 principal.builder.class 구현에서는 사용자 이름이 ACL 구성 등에 사용되는 인증된 Principal로 사용됩니다.

Kafka 브로커 구성 (Configuring Kafka Brokers)

        KafkaServer {
            org.apache.kafka.common.security.plain.PlainLoginModule required
            username="admin"
            password="admin-secret"
            user_admin="admin-secret"
            user_alice="alice-secret";
        };
  • 아래와 유사하게 수정한 JAAS 파일을 각 Kafka 브로커의 구성 디렉터리에 추가합니다. 이 예제에서는 kafka_server_jaas.conf라고 부르겠습니다. 이 구성은 admin과 alice 두 사용자를 정의합니다. KafkaServer 섹션의 usernamepassword 속성은 브로커가 다른 브로커에 연결을 시작할 때 사용합니다. 이 예에서 admin은 브로커 간 통신 사용자입니다. user__userName_ 속성 집합은 브로커에 연결하는 모든 사용자의 비밀번호를 정의하며, 브로커는 다른 브로커의 연결을 포함한 모든 클라이언트 연결을 이 속성들로 검증합니다. 2. JAAS 구성 파일 위치를 각 Kafka 브로커의 JVM 파라미터로 전달합니다.
           -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
        listeners=SASL_SSL://host.name:port
        security.inter.broker.protocol=SASL_SSL
        sasl.mechanism.inter.broker.protocol=PLAIN
        sasl.enabled.mechanisms=PLAIN
  • 여기에 설명된 대로 server.properties에서 SASL 포트와 SASL 메커니즘을 구성합니다. 예를 들면 위와 같습니다.

Kafka 클라이언트 구성 (Configuring Kafka Clients)

클라이언트의 SASL 인증을 구성하려면:

        sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
            username="alice" \
            password="alice-secret";
  • producer.properties 또는 consumer.properties에서 각 클라이언트에 대한 JAAS 구성 속성을 구성합니다. 로그인 모듈은 프로듀서·컨슈머 같은 클라이언트가 어떻게 Kafka Broker에 연결할 수 있는지 설명합니다. PLAIN 메커니즘에 대한 클라이언트 구성 예는 위와 같습니다. usernamepassword 옵션은 클라이언트가 클라이언트 연결용 사용자를 구성하는 데 사용됩니다. 이 예에서 클라이언트는 사용자 alice로 브로커에 연결합니다. 한 JVM 내의 다른 클라이언트는 sasl.jaas.config에서 다른 사용자 이름·비밀번호를 지정해 다른 사용자로 연결할 수 있습니다.

클라이언트용 JAAS 구성은 브로커와 유사하게 JVM 파라미터로도 지정할 수 있습니다. 클라이언트는 KafkaClient라는 로그인 섹션을 사용합니다. 이 옵션은 한 JVM의 모든 클라이언트 연결에 대해 한 사용자만 허용합니다.

        security.protocol=SASL_SSL
        sasl.mechanism=PLAIN
  • producer.properties 또는 consumer.properties에서 다음 속성을 구성합니다.

프로덕션에서의 SASL/PLAIN 사용 (Use of SASL/PLAIN in production)

  • SASL/PLAIN은 평문 비밀번호가 암호화 없이 네트워크로 전송되지 않도록 전송 계층으로 SSL과 함께만 사용해야 합니다.
  • Kafka의 기본 SASL/PLAIN 구현은 여기에 표시된 대로 JAAS 구성 파일에 사용자 이름과 비밀번호를 지정합니다. Kafka 2.0부터 sasl.server.callback.handler.classsasl.client.callback.handler.class 구성 옵션으로 외부 소스에서 사용자 이름과 비밀번호를 얻는 자체 콜백 핸들러를 구성해 평문 비밀번호를 디스크에 저장하는 것을 피할 수 있습니다.
  • 프로덕션 시스템에서 외부 인증 서버가 비밀번호 인증을 구현할 수 있습니다. Kafka 2.0부터 sasl.server.callback.handler.class를 구성해 비밀번호 검증에 외부 인증 서버를 사용하는 자체 콜백 핸들러를 연결할 수 있습니다.

SASL/SCRAM을 이용한 인증 (Authentication using SASL/SCRAM)

Salted Challenge Response Authentication Mechanism(SCRAM)은 PLAIN이나 DIGEST-MD5 같은 사용자 이름/비밀번호 인증을 수행하는 전통적 메커니즘의 보안 문제를 해결하는 SASL 메커니즘 계열입니다. 이 메커니즘은 RFC 5802에 정의되어 있습니다. Kafka는 TLS와 함께 사용해 보안 인증을 수행할 수 있는 SCRAM-SHA-256과 SCRAM-SHA-512를 지원합니다. 기본 principal.builder.class 구현에서는 사용자 이름이 ACL 구성 등에 사용되는 인증된 Principal로 사용됩니다. Kafka의 기본 SCRAM 구현은 SCRAM 자격 증명을 메타데이터 로그에 저장합니다. 자세한 내용은 보안 고려 사항을 참고하세요.

SCRAM 자격 증명 생성 (Creating SCRAM Credentials)

Kafka의 SCRAM 구현은 메타데이터 로그를 자격 증명 저장소로 사용합니다. 자격 증명은 kafka-storage.sh 또는 kafka-configs.sh로 메타데이터 로그에 만들 수 있습니다. 활성화된 각 SCRAM 메커니즘에 대해 메커니즘 이름으로 구성을 추가해 자격 증명을 만들어야 합니다. 브로커 간 통신을 위한 자격 증명은 Kafka 브로커를 시작하기 전에 만들어야 합니다. kafka-storage.sh는 초기 자격 증명으로 저장소를 포맷할 수 있습니다. 클라이언트 자격 증명은 동적으로 만들고 업데이트할 수 있으며, 업데이트된 자격 증명은 새 연결을 인증하는 데 사용됩니다. kafka-configs.sh는 Kafka 브로커가 시작된 후 자격 증명을 만들고 업데이트하는 데 사용할 수 있습니다.

password admin-secret으로 user admin에 대한 초기 SCRAM 자격 증명 생성:

        $ bin/kafka-storage.sh format -t $(bin/kafka-storage.sh random-uuid) -c config/server.properties --add-scram 'SCRAM-SHA-256=[name="admin",password="admin-secret"]'

password alice-secret으로 user alice에 대한 SCRAM 자격 증명 생성(클라이언트 구성은 Kafka 클라이언트 구성 참고):

        $ bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=alice-secret]' --entity-type users --entity-name alice --command-config client.properties

반복 횟수를 지정하지 않으면 기본 반복 횟수 4096이 사용됩니다. 지정하지 않으면 랜덤 salt가 생성됩니다. salt, 반복 횟수, StoredKey, ServerKey로 구성된 SCRAM identity는 메타데이터 로그에 저장됩니다. SCRAM identity와 각 필드에 대한 자세한 내용은 RFC 5802를 참고하세요.

기존 자격 증명은 --describe 옵션으로 나열할 수 있습니다.

        $ bin/kafka-configs.sh --bootstrap-server localhost:9092 --describe --entity-type users --entity-name alice --command-config client.properties

자격 증명은 --alter --delete-config 옵션으로 하나 이상의 SCRAM 메커니즘에 대해 삭제할 수 있습니다.

        $ bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --delete-config 'SCRAM-SHA-256' --entity-type users --entity-name alice --command-config client.properties

Kafka 브로커 구성 (Configuring Kafka Brokers)

        KafkaServer {
            org.apache.kafka.common.security.scram.ScramLoginModule required
            username="admin"
            password="admin-secret";
        };
  • 아래와 유사하게 수정한 JAAS 파일을 각 Kafka 브로커의 구성 디렉터리에 추가합니다. 이 예제에서는 kafka_server_jaas.conf라고 부르겠습니다. KafkaServer 섹션의 usernamepassword 속성은 브로커가 다른 브로커에 연결을 시작할 때 사용합니다. 이 예에서 admin은 브로커 간 통신 사용자입니다. 2. JAAS 구성 파일 위치를 각 Kafka 브로커의 JVM 파라미터로 전달합니다.
           -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
        listeners=SASL_SSL://host.name:port
        security.inter.broker.protocol=SASL_SSL
        sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256 (or SCRAM-SHA-512)
        sasl.enabled.mechanisms=SCRAM-SHA-256 (or SCRAM-SHA-512)
  • 여기에 설명된 대로 server.properties에서 SASL 포트와 SASL 메커니즘을 구성합니다. 예를 들면 위와 같습니다.

Kafka 클라이언트 구성 (Configuring Kafka Clients)

클라이언트의 SASL 인증을 구성하려면:

        sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
            username="alice" \
            password="alice-secret";
  • producer.properties 또는 consumer.properties에서 각 클라이언트에 대한 JAAS 구성 속성을 구성합니다. 로그인 모듈은 프로듀서·컨슈머 같은 클라이언트가 어떻게 Kafka Broker에 연결할 수 있는지 설명합니다. SCRAM 메커니즘에 대한 클라이언트 구성 예는 위와 같습니다. usernamepassword 옵션은 클라이언트가 클라이언트 연결용 사용자를 구성하는 데 사용합니다. 이 예에서 클라이언트는 사용자 alice로 브로커에 연결합니다. 한 JVM 내의 다른 클라이언트는 sasl.jaas.config에서 다른 사용자 이름·비밀번호를 지정해 다른 사용자로 연결할 수 있습니다.

클라이언트용 JAAS 구성은 브로커와 유사하게 JVM 파라미터로도 지정할 수 있습니다. 클라이언트는 KafkaClient라는 로그인 섹션을 사용합니다. 이 옵션은 한 JVM의 모든 클라이언트 연결에 대해 한 사용자만 허용합니다.

        security.protocol=SASL_SSL
        sasl.mechanism=SCRAM-SHA-256 (or SCRAM-SHA-512)
  • producer.properties 또는 consumer.properties에서 다음 속성을 구성합니다.

SASL/SCRAM 보안 고려 사항 (Security Considerations for SASL/SCRAM)

  • Kafka의 기본 SASL/SCRAM 구현은 SCRAM 자격 증명을 메타데이터 로그에 저장합니다. 이는 KRaft 컨트롤러가 안전하고 사설 네트워크에 있는 설치의 프로덕션 사용에 적합합니다.
  • Kafka는 최소 반복 횟수 4096의 강력한 해시 함수 SHA-256과 SHA-512만 지원합니다. 강력한 해시 함수를 강력한 비밀번호와 높은 반복 횟수와 결합하면 KRaft 컨트롤러 보안이 침해되더라도 무차별 공격을 방어합니다.
  • SCRAM은 SCRAM 교환의 가로채기를 막기 위해 TLS 암호화와 함께만 사용해야 합니다. 이는 사전·무차별 공격과, KRaft 컨트롤러 보안이 침해될 때의 사칭을 방어합니다.
  • Kafka 2.0부터 KRaft 컨트롤러가 안전하지 않은 설치에서 sasl.server.callback.handler.class를 구성해 기본 SASL/SCRAM 자격 증명 저장소를 커스텀 콜백 핸들러로 오버라이드할 수 있습니다.
  • 보안 고려 사항에 대한 자세한 내용은 RFC 5802를 참고하세요.

SASL/OAUTHBEARER을 이용한 인증 (Authentication using SASL/OAUTHBEARER)

OAuth 2 Authorization Framework는 "리소스 소유자와 HTTP 서비스 사이의 승인 상호작용을 조율하거나, 타사 애플리케이션 스스로 접근을 얻도록 함으로써, 타사 애플리케이션이 리소스 소유자를 대신해 HTTP 서비스에 대한 제한된 접근을 얻을 수 있게" 합니다. SASL OAUTHBEARER 메커니즘은 이 프레임워크를 SASL(즉 비-HTTP) 컨텍스트에서 사용할 수 있게 하며, RFC 7628에 정의되어 있습니다. Kafka의 기본 OAUTHBEARER 구현은 Unsecured JSON Web Tokens를 만들고 검증하며, 비프로덕션 Kafka 설치에만 적합합니다. 자세한 내용은 보안 고려 사항을 참고하세요. 최신 Apache Kafka 버전은 OAuth 2.0 표준 호환 ID 공급자와의 상호작용을 지원하는 프로덕션 준비 OAUTHBEARER 구현을 추가했습니다. 두 모드를 모두 아래에 설명합니다.

기본 principal.builder.class 구현에서는 OAuthBearerTokenprincipalName이 ACL 구성 등에 사용되는 인증된 Principal로 사용됩니다.

비프로덕션 Kafka 브로커 구성 (Configuring Non-production Kafka Brokers)

Kafka의 기본 SASL/OAUTHBEARER 구현은 Unsecured JSON Web Tokens를 만들고 검증합니다. 비프로덕션 사용에만 적합하지만 DEV·TEST 환경에서 임의 토큰을 만드는 유연성을 제공합니다.

        KafkaServer {
            org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required
            unsecuredLoginStringClaim_sub="admin";
        };
  • 아래와 유사하게 수정한 JAAS 파일을 각 Kafka 브로커의 구성 디렉터리에 추가합니다. 이 예제에서는 kafka_server_jaas.conf라고 부르겠습니다. KafkaServer 섹션의 unsecuredLoginStringClaim_sub 속성은 브로커가 다른 브로커에 연결을 시작할 때 사용합니다. 이 예에서 admin은 subject(sub) 클레임에 나타나며 브로커 간 통신 사용자가 됩니다.

Unsecured JSON Web Token 검증을 위해 브로커 측에서 지원되는 JAAS 모듈 옵션은 다음과 같습니다.

Unsecured Token 검증용 JAAS 모듈 옵션 설명
unsecuredValidatorPrincipalClaimName="value" principal 이름을 담는 특정 String 클레임의 존재를 확인하려면 비어 있지 않은 값으로 설정. 기본값은 'sub' 클레임의 존재를 확인.
unsecuredValidatorScopeClaimName="value" 토큰 스코프를 담는 String 또는 String List 클레임의 이름을 'scope'가 아닌 다른 이름으로 하려면 커스텀 클레임 이름으로 설정.
unsecuredValidatorRequiredScope="value" 토큰 스코프를 담는 String/String List 클레임이 특정 값을 포함하는지 확인하려면 공백으로 구분된 스코프 값 목록으로 설정.
unsecuredValidatorAllowableClockSkewMs="value" 일부 양의 밀리초만큼의 시계 오차를 허용하려면 양의 정수로 설정(기본값 0).
        -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
  • JAAS 구성 파일 위치를 각 Kafka 브로커의 JVM 파라미터로 전달합니다.
        listeners=SASL_SSL://host.name:port (or SASL_PLAINTEXT if non-production)
        security.inter.broker.protocol=SASL_SSL (or SASL_PLAINTEXT if non-production)
        sasl.mechanism.inter.broker.protocol=OAUTHBEARER
        sasl.enabled.mechanisms=OAUTHBEARER
  • 여기에 설명된 대로 server.properties에서 SASL 포트와 SASL 메커니즘을 구성합니다. 예를 들면 위와 같습니다.

프로덕션 Kafka 브로커 구성 (Configuring Production Kafka Brokers)

        KafkaServer {
            org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required ;
        };
  • 아래와 유사하게 수정한 JAAS 파일을 각 Kafka 브로커의 구성 디렉터리에 추가합니다. 이 예제에서는 kafka_server_jaas.conf라고 부르겠습니다.
        -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
  • JAAS 구성 파일 위치를 각 Kafka 브로커의 JVM 파라미터로 전달합니다.
        listeners=SASL_SSL://host.name:port
        security.inter.broker.protocol=SASL_SSL
        sasl.mechanism.inter.broker.protocol=OAUTHBEARER
        sasl.enabled.mechanisms=OAUTHBEARER
        listener.name.<listener name>.oauthbearer.sasl.server.callback.handler.class=org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackHandler
        listener.name.<listener name>.oauthbearer.sasl.oauthbearer.jwks.endpoint.url=https://example.com/oauth2/v1/keys
  • 여기에 설명된 대로 server.properties에서 SASL 포트와 SASL 메커니즘을 구성합니다. 예를 들면 위와 같습니다.

OAUTHBEARER 브로커 구성에는 다음이 포함됩니다.

  • sasl.oauthbearer.clock.skew.seconds
  • sasl.oauthbearer.expected.audience
  • sasl.oauthbearer.expected.issuer
  • sasl.oauthbearer.jwks.endpoint.refresh.ms
  • sasl.oauthbearer.jwks.endpoint.retry.backoff.max.ms
  • sasl.oauthbearer.jwks.endpoint.retry.backoff.ms
  • sasl.oauthbearer.jwks.endpoint.url
  • sasl.oauthbearer.scope.claim.name
  • sasl.oauthbearer.sub.claim.name

비프로덕션 Kafka 클라이언트 구성 (Configuring Non-production Kafka Clients)

클라이언트의 SASL 인증을 구성하려면:

        sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
            unsecuredLoginStringClaim_sub="alice";
  • producer.properties 또는 consumer.properties에서 각 클라이언트에 대한 JAAS 구성 속성을 구성합니다. 로그인 모듈은 프로듀서·컨슈머 같은 클라이언트가 어떻게 Kafka Broker에 연결할 수 있는지 설명합니다. OAUTHBEARER 메커니즘에 대한 클라이언트 구성 예는 위와 같습니다. unsecuredLoginStringClaim_sub 옵션은 클라이언트가 클라이언트 연결용 사용자를 결정하는 subject(sub) 클레임을 구성하는 데 사용합니다. 이 예에서 클라이언트는 사용자 alice로 브로커에 연결합니다. 한 JVM 내의 다른 클라이언트는 sasl.jaas.config에서 다른 subject(sub) 클레임을 지정해 다른 사용자로 연결할 수 있습니다.

Kafka의 기본 SASL/OAUTHBEARER 구현은 Unsecured JSON Web Tokens를 만들고 검증합니다. 비프로덕션 사용에만 적합하지만 DEV·TEST 환경에서 임의 토큰을 만드는 유연성을 제공합니다.

Unsecured 토큰 생성용으로 클라이언트 측(그리고 OAUTHBEARER가 브로커 간 프로토콜이면 브로커 측)에서 지원되는 JAAS 모듈 옵션은 다음과 같습니다.

Unsecured Token 생성용 JAAS 모듈 옵션 설명
unsecuredLoginStringClaim_="value" 주어진 이름과 값의 String 클레임 생성. 'iat'와 'exp'를 제외한 유효한 클레임 이름을 지정할 수 있음(자동 생성).
unsecuredLoginNumberClaim_="value" 주어진 이름과 값의 Number 클레임 생성. 'iat'와 'exp' 제외.
unsecuredLoginListClaim_="value" 주어진 이름과 값에서 파싱된 String List 클레임 생성. 첫 문자가 구분자. 예: unsecuredLoginListClaim_fubar="|value1|value2". 'iat'와 'exp' 제외.
unsecuredLoginExtension_="value"
unsecuredLoginPrincipalClaimName principal 이름을 담는 String 클레임의 이름을 'sub'가 아닌 다른 이름으로 하려면 커스텀 클레임 이름으로 설정.
unsecuredLoginLifetimeSeconds 토큰 만료를 기본값 3600초(1시간)가 아닌 다른 값으로 하려면 정수 값으로 설정. 'exp' 클레임이 만료 시간을 반영해 설정.
unsecuredLoginScopeClaimName 토큰 스코프를 담는 String/String List 클레임의 이름을 'scope'가 아닌 다른 이름으로 하려면 커스텀 클레임 이름으로 설정.

클라이언트용 JAAS 구성은 브로커와 유사하게 JVM 파라미터로도 지정할 수 있습니다. 클라이언트는 KafkaClient라는 로그인 섹션을 사용합니다. 이 옵션은 한 JVM의 모든 클라이언트 연결에 대해 한 사용자만 허용합니다.

        security.protocol=SASL_SSL (or SASL_PLAINTEXT if non-production)
        sasl.mechanism=OAUTHBEARER
  • producer.properties 또는 consumer.properties에서 다음 속성을 구성합니다.
  • Kafka의 기본 SASL/OAUTHBEARER 구현은 jackson-databind 라이브러리에 의존합니다. 선택적 의존성이므로 사용자는 빌드 도구를 통해 이를 의존성으로 구성해야 합니다.

프로덕션 Kafka 클라이언트 구성 (Configuring Production Kafka Clients)

클라이언트의 SASL 인증을 구성하려면:

        sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required ;
  • producer.properties 또는 consumer.properties에서 각 클라이언트에 대한 JAAS 구성 속성을 구성합니다. 클라이언트용 JAAS 구성은 브로커와 유사하게 JVM 파라미터로도 지정할 수 있습니다. 클라이언트는 KafkaClient라는 로그인 섹션을 사용합니다.

  • producer.properties 또는 consumer.properties에서 다음 속성을 구성합니다. sasl.oauthbearer.jwt.retriever.class 속성은 기본적으로 DefaultJwtRetriever로, HTTP/HTTPS 토큰 엔드포인트 URL에는 ClientCredentialsJwtRetriever로, file:// URL에는 FileJwtRetriever로 자동 위임합니다. 대부분의 경우 이 속성을 명시적으로 설정할 필요는 없습니다.

예를 들어 OAuth client_credentials grant 유형을 client secret과 함께 사용해 OAuth ID 공급자와 통신한다면 구성은 다음과 같을 수 있습니다.

           security.protocol=SASL_SSL
           sasl.mechanism=OAUTHBEARER
           sasl.oauthbearer.client.credentials.client.id=jdoe
           sasl.oauthbearer.client.credentials.client.secret=$3cr3+
           sasl.oauthbearer.scope=my-application-scope
           sasl.oauthbearer.token.endpoint.url=https://example.com/oauth2/v1/token

또는 client_credentials grant 유형은 RFC 7523에 정의된 client assertion 인증도 지원합니다. 클라이언트 secret을 보내는 대신 클라이언트는 서명된 JWT assertion을 OAuth ID 공급자에게 제시해 인증합니다. 개인 키가 클라이언트를 절대 떠나지 않고 assertion이 단기적이므로 보안이 강화됩니다(변조 방지). 자세한 내용은 KIP-1258을 참고하세요.

동적으로 생성되는 JWT로 client assertion을 사용할 때(권장) 구성은 다음과 같을 수 있습니다.

           security.protocol=SASL_SSL
           sasl.mechanism=OAUTHBEARER
           sasl.oauthbearer.token.endpoint.url=https://example.com/oauth2/v1/token
           sasl.oauthbearer.assertion.private.key.file=/path/to/private-key.pem
           sasl.oauthbearer.assertion.algorithm=RS256
           sasl.oauthbearer.assertion.claim.iss=my-kafka-client
           sasl.oauthbearer.assertion.claim.sub=my-service-account
           sasl.oauthbearer.assertion.claim.aud=https://example.com
           sasl.oauthbearer.assertion.claim.exp.seconds=300
           sasl.oauthbearer.assertion.claim.jti.include=true
           sasl.oauthbearer.scope=my-application-scope

또는 미리 생성된 JWT assertion을 파일에서 읽을 수 있습니다. assertion이 외부 프로세스나 시크릿 매니저에 의해 생성될 때 유용합니다.

           security.protocol=SASL_SSL
           sasl.mechanism=OAUTHBEARER
           sasl.oauthbearer.token.endpoint.url=https://example.com/oauth2/v1/token
           sasl.oauthbearer.assertion.file=/path/to/assertion.jwt
           sasl.oauthbearer.scope=my-application-scope

동적으로 생성되는 assertion의 경우 sasl.oauthbearer.assertion.template.file을 사용해 JSON 템플릿 파일로 추가 정적 클레임을 제공할 수 있습니다. 템플릿은 생성된 JWT에 값이 병합되는 header와 payload 섹션을 지원합니다.

           {
             "header": {
               "kid": "my-key-id"
             },
             "payload": {
               "iss": "my-kafka-client",
               "sub": "my-service-account",
               "aud": "https://example.com"
             }
           }

client assertion과 client secret 구성이 모두 있으면 ClientCredentialsJwtRetriever는 3단계 선호 순서를 사용합니다.

  • 파일 기반 assertion(sasl.oauthbearer.assertion.file) — 최우선
  • 로컬 생성 assertion(sasl.oauthbearer.assertion.claim.iss + 개인 키) — 2순위
  • client secret(sasl.oauthbearer.client.credentials.client.secret) — 폴백

이 선택은 구성 시점에 이루어집니다. 한 번 선택된 메서드는 클라이언트 수명 동안 유지되며, 런타임 실패는 다른 메서드로 폴백되지 않습니다.

또는 OAuth urn:ietf:params:oauth:grant-type:jwt-bearer grant 유형을 사용해 OAuth ID 공급자와 통신한다면, 기본 리트리버가 ClientCredentialsJwtRetriever로 위임하므로 JwtBearerJwtRetriever를 명시적으로 구성해야 합니다.

           security.protocol=SASL_SSL
           sasl.mechanism=OAUTHBEARER
           sasl.oauthbearer.jwt.retriever.class=org.apache.kafka.common.security.oauthbearer.JwtBearerJwtRetriever
           sasl.oauthbearer.assertion.private.key.file=/path/to/private.key
           sasl.oauthbearer.assertion.algorithm=RS256
           sasl.oauthbearer.assertion.claim.exp.seconds=600
           sasl.oauthbearer.assertion.template.file=/path/to/template.json
           sasl.oauthbearer.scope=my-application-scope
           sasl.oauthbearer.token.endpoint.url=https://example.com/oauth2/v1/token

OAUTHBEARER 클라이언트 구성에는 다음이 포함됩니다.

  • sasl.oauthbearer.assertion.algorithm

  • sasl.oauthbearer.assertion.claim.aud

  • sasl.oauthbearer.assertion.claim.exp.seconds

  • sasl.oauthbearer.assertion.claim.iss

  • sasl.oauthbearer.assertion.claim.jti.include

  • sasl.oauthbearer.assertion.claim.nbf.seconds

  • sasl.oauthbearer.assertion.claim.sub

  • sasl.oauthbearer.assertion.file

  • sasl.oauthbearer.assertion.private.key.file

  • sasl.oauthbearer.assertion.private.key.passphrase

  • sasl.oauthbearer.assertion.template.file

  • sasl.oauthbearer.client.credentials.client.id

  • sasl.oauthbearer.client.credentials.client.secret

  • sasl.oauthbearer.header.urlencode

  • sasl.oauthbearer.jwt.retriever.class

  • sasl.oauthbearer.jwt.validator.class

  • sasl.oauthbearer.scope

  • sasl.oauthbearer.token.endpoint.url

  • Kafka의 기본 SASL/OAUTHBEARER 구현은 jackson-databind 라이브러리에 의존합니다. 선택적 의존성이므로 사용자는 빌드 도구를 통해 이를 의존성으로 구성해야 합니다.

SASL/OAUTHBEARER 토큰 갱신 (Token Refresh for SASL/OAUTHBEARER)

Kafka는 클라이언트가 브로커에 계속 연결할 수 있도록 어떤 토큰이든 만료되기 전에 주기적으로 갱신합니다. 갱신 알고리즘의 동작에 영향을 주는 파라미터는 producer/consumer/broker 구성의 일부로 지정되며 다음과 같습니다. 이 속성들에 대한 자세한 내용은 다른 곳의 문서를 참고하세요. 기본값이 보통 합리적이므로 명시적으로 설정할 필요가 없을 것입니다.

Producer/Consumer/Broker 구성 속성
sasl.login.refresh.window.factor
sasl.login.refresh.window.jitter
sasl.login.refresh.min.period.seconds
sasl.login.refresh.min.buffer.seconds

SASL/OAUTHBEARER의 보안/프로덕션 사용 (Secure/Production Use of SASL/OAUTHBEARER)

Kafka는 프로덕션 사용을 위한 내장 JWT 리트리버 구현을 제공합니다. client_credentials grant 유형용 ClientCredentialsJwtRetriever(client secret과 client assertion 인증 모두 지원)와 jwt-bearer grant 유형용 JwtBearerJwtRetriever입니다. 이들은 위 예에서처럼 sasl.oauthbearer.jwt.retriever.class로 구성할 수 있습니다. 또는 프로덕션 사용 사례는 org.apache.kafka.common.security.oauthbearer.OAuthBearerTokenCallback 인스턴스를 처리할 수 있는 org.apache.kafka.common.security.auth.AuthenticateCallbackHandler의 커스텀 구현을 제공하고, 비브로커 클라이언트에서는 sasl.login.callback.handler.class 구성 옵션으로, 브로커에서는 listener.name.sasl_ssl.oauthbearer.sasl.login.callback.handler.class 구성 옵션으로 이를 선언할 수 있습니다(OAUTHBEARER가 브로커 간 프로토콜인 경우).

프로덕션 사용 사례는 또한 org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallback 인스턴스를 처리할 수 있는 org.apache.kafka.common.security.auth.AuthenticateCallbackHandler 구현을 작성하고 listener.name.sasl_ssl.oauthbearer.sasl.server.callback.handler.class 브로커 구성 옵션으로 선언해야 합니다.

SASL/OAUTHBEARER 보안 고려 사항 (Security Considerations for SASL/OAUTHBEARER)

  • Kafka의 기본 SASL/OAUTHBEARER 구현은 Unsecured JSON Web Tokens를 만들고 검증합니다. 이는 비프로덕션 사용에만 적합합니다.
  • OAUTHBEARER는 토큰 가로채기를 막기 위해 프로덕션 환경에서 TLS 암호화와 함께만 사용해야 합니다.
  • 기본 unsecured SASL/OAUTHBEARER 구현은 위에서 설명한 대로 커스텀 로그인·SASL 서버 콜백 핸들러 또는 내장 JWT 리트리버 구현으로 오버라이드할 수 있습니다(그리고 프로덕션 환경에서는 반드시 오버라이드해야 합니다).
  • client assertion 인증을 사용할 때 개인 키는 client secret과 달리 클라이언트를 절대 떠나지 않고 네트워크로 전송되지 않습니다. 재전송 공격을 막기 위해 짧은 assertion 만료 시간(예: sasl.oauthbearer.assertion.claim.exp.seconds=300)을 사용하고 JTI 포함(sasl.oauthbearer.assertion.claim.jti.include=true)을 활성화하세요.
  • OAuth 2 보안 고려 사항의 일반적인 내용은 RFC 6749, 섹션 10을 참고하세요.

브로커에서 여러 SASL 메커니즘 활성화 (Enabling multiple SASL mechanisms in a broker)

     KafkaServer {
         com.sun.security.auth.module.Krb5LoginModule required
         useKeyTab=true
         storeKey=true
         keyTab="/etc/security/keytabs/kafka_server.keytab"
         principal="kafka/[email protected]";

         org.apache.kafka.common.security.plain.PlainLoginModule required
         username="admin"
         password="admin-secret"
         user_admin="admin-secret"
         user_alice="alice-secret";
     };
  • JAAS 구성 파일의 KafkaServer 섹션에서 모든 활성화된 메커니즘의 로그인 모듈에 대한 구성을 지정합니다. 예를 들면 위와 같습니다.
     sasl.enabled.mechanisms=GSSAPI,PLAIN,SCRAM-SHA-256,SCRAM-SHA-512,OAUTHBEARER
  • server.properties에서 SASL 메커니즘을 활성화합니다.
     security.inter.broker.protocol=SASL_PLAINTEXT (or SASL_SSL)
     sasl.mechanism.inter.broker.protocol=GSSAPI (or one of the other enabled mechanisms)
  • 필요하면 server.properties에서 브로커 간 통신에 대한 SASL 보안 프로토콜과 메커니즘을 지정합니다.
  • GSSAPI(Kerberos), PLAIN, SCRAM, 비프로덕션/프로덕션 OAUTHBEARER의 메커니즘별 단계를 따라 활성화된 메커니즘에 대한 SASL을 구성합니다.

실행 중인 클러스터에서 SASL 메커니즘 수정 (Modifying SASL mechanism in a Running Cluster)

SASL 메커니즘은 다음 순서를 사용해 실행 중인 클러스터에서 수정할 수 있습니다.

  • 각 브로커의 server.properties sasl.enabled.mechanisms에 메커니즘을 추가해 새 SASL 메커니즘을 활성화합니다. JAAS 구성 파일을 업데이트해 두 메커니즘을 모두 포함시킵니다(여기 참고). 클러스터 노드를 점진적으로 바운스(재시작)합니다.
  • 새 메커니즘을 사용해 클라이언트를 재시작합니다.
  • 브로커 간 통신의 메커니즘을 변경하려면(필요한 경우) server.properties의 sasl.mechanism.inter.broker.protocol을 새 메커니즘으로 설정하고 클러스터를 다시 점진적으로 바운스합니다.
  • 이전 메커니즘을 제거하려면(필요한 경우) server.properties의 sasl.enabled.mechanisms에서 이전 메커니즘을 제거하고 JAAS 구성 파일에서 이전 메커니즘 항목을 제거합니다. 클러스터를 다시 점진적으로 바운스합니다.

위임 토큰을 이용한 인증 (Authentication using Delegation Tokens)

위임 토큰(delegation token) 기반 인증은 기존 SASL/SSL 방법을 보완하는 경량 인증 메커니즘입니다. 위임 토큰은 kafka 브로커와 클라이언트 사이의 공유 비밀입니다. 위임 토큰은 2-way SSL을 사용할 때 Kerberos TGT/keytab이나 키스토어를 분배하는 추가 비용 없이, 처리 프레임워크가 보안 환경에서 사용 가능한 워커에 워크로드를 분산하는 데 도움이 됩니다. 자세한 내용은 KIP-48을 참고하세요.

기본 principal.builder.class 구현에서는 위임 토큰의 소유자(owner)가 ACL 구성 등에 사용되는 인증된 Principal로 사용됩니다.

위임 토큰 사용의 일반적인 단계는 다음과 같습니다.

  • 사용자가 SASL 또는 SSL로 Kafka 클러스터에 인증하고 위임 토큰을 얻습니다. 이는 Admin API나 kafka-delegation-tokens.sh 스크립트로 할 수 있습니다.
  • 사용자가 위임 토큰을 Kafka 클러스터 인증용으로 Kafka 클라이언트에 안전하게 전달합니다.
  • 토큰 소유자/갱신자가 위임 토큰을 갱신/만료할 수 있습니다.

토큰 관리 (Token Management)

위임 토큰을 생성하고 검증하는 데 비밀(secret)이 사용됩니다. 이는 구성 옵션 delegation.token.secret.key로 제공됩니다. 같은 비밀 키가 모든 브로커에 구성되어야 합니다. 컨트롤러도 같은 구성 옵션으로 비밀을 구성해야 합니다. 비밀이 설정되지 않았거나 빈 문자열이면 위임 토큰 인증과 API 작업이 실패합니다.

토큰 세부 정보는 컨트롤러 노드의 다른 메타데이터와 함께 저장되며, 위임 토큰은 컨트롤러가 사설 네트워크에 있거나 브로커와 컨트롤러 사이의 모든 통신이 암호화될 때 사용하기에 적합합니다. 현재 이 비밀은 server.properties 구성 파일에 평문으로 저장됩니다. 향후 Kafka 릴리스에서 구성 가능하게 만들 계획입니다.

토큰에는 현재 수명(current life)과 최대 갱신 가능 수명(maximum renewable life)이 있습니다. 기본적으로 토큰은 최대 7일 동안 24시간마다 한 번씩 갱신되어야 합니다. 이는 delegation.token.expiry.time.msdelegation.token.max.lifetime.ms 구성 옵션으로 구성할 수 있습니다.

토큰은 명시적으로 취소할 수도 있습니다. 토큰의 만료 시간까지 갱신되지 않거나 최대 수명을 넘으면 모든 브로커 캐시에서 삭제됩니다.

위임 토큰 생성 (Creating Delegation Tokens)

토큰은 Admin API 또는 kafka-delegation-tokens.sh 스크립트로 만들 수 있습니다. 위임 토큰 요청(create/renew/expire/describe)은 SASL 또는 SSL 인증 채널에서만 발행해야 합니다. 초기 인증이 위임 토큰으로 이루어진 경우에는 토큰을 요청할 수 없습니다. --owner-principal 파라미터를 지정해 사용자가 자신 또는 다른 사용자를 위해 토큰을 만들 수 있습니다. 소유자/갱신자는 토큰을 갱신·만료할 수 있습니다. 소유자/갱신자는 항상 자신의 토큰을 describe할 수 있습니다. 다른 토큰을 describe하려면 토큰 소유자를 나타내는 User 리소스에 DESCRIBE_TOKEN 권한을 추가해야 합니다. kafka-delegation-tokens.sh 스크립트 예는 아래와 같습니다.

위임 토큰 생성:

        $ bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --create   --max-life-time-period -1 --command-config client.properties --renewer-principal User:user1

다른 소유자를 위한 위임 토큰 생성:

        $ bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --create   --max-life-time-period -1 --command-config client.properties --renewer-principal User:user1 --owner-principal User:owner1

위임 토큰 갱신:

        $ bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --renew    --renew-time-period -1 --command-config client.properties --hmac ABCDEFGHIJK

위임 토큰 만료:

        $ bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --expire   --expiry-time-period -1   --command-config client.properties  --hmac ABCDEFGHIJK

기존 토큰은 --describe 옵션으로 describe할 수 있습니다.

        $ bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --describe --command-config client.properties  --owner-principal User:user1

토큰 인증 (Token Authentication)

위임 토큰 인증은 현재 SASL/SCRAM 인증 메커니즘에 동승(piggyback)합니다. 여기에 설명된 대로 Kafka 클러스터에서 SASL/SCRAM 메커니즘을 활성화해야 합니다.

Kafka 클라이언트 구성:

        sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
            username="tokenID123" \
            password="lAYYSFmLs4bTjf+lTZ1LCHR/ZZFNA==" \
            tokenauth="true";
  • producer.properties 또는 consumer.properties에서 각 클라이언트에 대한 JAAS 구성 속성을 구성합니다. 로그인 모듈은 프로듀서·컨슈머 같은 클라이언트가 어떻게 Kafka Broker에 연결할 수 있는지 설명합니다. 토큰 인증에 대한 클라이언트 구성 예는 위와 같습니다. usernamepassword 옵션은 클라이언트가 토큰 id와 토큰 HMAC를 구성하는 데 사용합니다. tokenauth 옵션은 서버에게 토큰 인증임을 알리는 데 사용합니다. 이 예에서 클라이언트는 토큰 id: tokenID123으로 브로커에 연결합니다. 한 JVM 내의 다른 클라이언트는 sasl.jaas.config에서 다른 토큰 세부 정보를 지정해 다른 토큰으로 연결할 수 있습니다.

클라이언트용 JAAS 구성은 브로커와 유사하게 JVM 파라미터로도 지정할 수 있습니다. 클라이언트는 KafkaClient라는 로그인 섹션을 사용합니다. 이 옵션은 한 JVM의 모든 클라이언트 연결에 대해 한 사용자만 허용합니다.

수동 비밀 회전 절차 (Procedure to manually rotate the secret)

비밀을 회전해야 할 때는 재배포가 필요합니다. 이 과정에서 이미 연결된 클라이언트는 계속 작동합니다. 하지만 새 연결 요청과 이전 토큰으로의 renew/expire 요청은 실패할 수 있습니다. 단계는 아래와 같습니다.

  • 기존 토큰을 모두 만료시킵니다.
  • 롤링 업그레이드로 비밀을 회전합니다.
  • 새 토큰을 생성합니다.

이를 향후 Kafka 릴리스에서 자동화할 계획입니다.

더 알아보기 (Learn more)

  • SCRAM은 비밀번호를 네트워크로 평문 전송하지 않아 PLAIN보다 안전해요.
  • 위임 토큰은 Kerberos TGT·keytab을 분배하지 않고 프레임워크 워크로드를 분산하기 좋아요.
  • 인증 후 접근 제어는 인가와 ACL 문서를 참고하세요.
  • 전송 암호화는 SSL을 이용한 암호화와 인증에서 다뤄요.