안녕하세요.
데이터 엔지니어링 & 운영 업무를 하는 중 알게 된 지식이나 의문점들을 시리즈 형식으로 계속해서 작성해나가며
새로 알게 된 점이나 잘 못 알고 있었던 점을 더욱 기억에 남기기 위해 글을 꾸준히 작성 할려고 합니다.
Kafka 의 경우 아파치 카프카 애플리케이션 프로그래밍 with 자바 카프카의 개념부터 스트림즈·커넥트·스프링 카프카까지 데이터 파이프라인 구축 따라하기
책을 많이 참고해 운영을 하고 있습니다.
반드시 글을 읽어 주실 때 잘 못 말하고 있는 부분은 정정 요청 드립니다.
저의 지식에 큰 도움이 됩니다. :)
Kafka 는 보통 사내망 안에서 스트림 처리를 하는 용도로 시작을 했기 때문에 기본적인 보안 설정을 가지고 있지 않습니다.
그러나 데이터는 내/외부 어떤 곳에서 생성 될 수 있고, 외부에서 접근할 때는 반드시 보안 적용이 필요합니다.
저희 환경에서도 외부 시스템에서 데이터 플랫폼을 향해 데이터를 실시간으로 전송하고 싶은 Needs 를 반영할 필요가 있었습니다.
그렇기 때문에 보안팀의 권고에 따라 Kafka Cluster 에 보안 적용을 하기로 계획 했습니다.
Kafka 는 아래 3가지 보안 요소를 적용할 수 있다고 합니다.
암호화
암호화된 통신을 활용하여 패킷을 가져가도 알 수 없도록 보안 적용하는 방법 (SSL)
인증
안전하다고 확인된 클라이언트만 접근할 수 있도록 설정 (SASL)
SASL 참고 : https://always-kimkim.tistory.com/entry/kafka101-security
권한
인증 받은 클라이언트의 권한을 제한 (ACL)
참고 : https://always-kimkim.tistory.com/entry/kafka101-security
저희는 Kafka Cluster 가 도메인을 가지고 있고, 그 도메인에 대한 SSL 인증서를 구매했기 때문에 SSL 을 적용하기로 했습니다. SSL 은 암호화된 메시지를 복호화 하는데 CPU 부하가 발생한다고 합니다.
참고 : https://always-kimkim.tistory.com/entry/kafka101-security
그래서 외부의 트래픽이 많이 발생할 경우에 SASL, ACL 적용을 고려해보기로 하고 프로젝트 진행을 위해 SSL 적용을 우선하기로 했습니다.
우선 SSL 이 어떻게 보안 적용이 되는 것이고 궁극적으로 어떤 것이 동작하는 지 명확하게 이해할 필요가 있습니다.
Secure Socket Layer(SSL) 프로토콜은 웹서버와 브라우저 사이의 보안을 위해 만들어졌습니다. Certificate Authority(CA)는 서드 파티로 부터 서버와 클라이언트의 인증을 하는데 사용 됩니다.
통신 내용이 공격자에게 노출되는 것을 막을 수 있습니다.
클라이언트가 접속하려는 서버가 신뢰할 수 있는 서버인지를 판단할 수 있습니다.
통신 내용의 악의적인 변경을 방지할 수 있습니다.
SSL 의 핵심은 암호화 입니다. 보안과 성능상의 이유로 두 가지 암호화 기법을 혼용해서 사용하고 있습니다.
대칭키 :
암호화를 할 때 사용하는 일종의 비밀번호를 키라고 합니다. 이 키를 활용해 복호화를 진행합니다. 대칭키는 동일한 키로 암호화와 복호화를 같이 할 수 있는 방식의 암호화 기법 입니다.
공개키 :
암호를 주고 받는 사람들 사이에 대칭키를 전달하는 것은 어렵고 유출시 복호화가 가능하기 때문에 공개키 방식이 등장했습니다.
공개키 방식은 두 개의 키를 가지며, A키를 암호화하면 B키로 복호화할 수 있고, B키로 암호화하면 A키로 복호화할 수 있는 방식 입니다. 이런 방식을 활용해서 비공개키는 자신만 가지고, 공개키를 타인에게 제공합니다. 공개키를 활용해 암호화된 정보는 비공개키로만 복호화 할 수 있습니다.
아래 순서대로 인증서를 만듭니다.
keystore 인증서 파일 준비
인증서를 구매한 기관에서 아래 파일과 비밀번호 수신
keystore, DigitCA.pem
p12 파일 변환
keytool -importkeystore -srckeystore keystore -destkeystore keystore.p12 -deststoretype PKCS12
# Enter destination keystore password: 비밀번호
# Re-enter new password: 비밀번호
# Enter source keystore password: 비밀번호
# Entry for alias root successfully imported.
# Entry for alias alias successfully imported.
# Entry for alias chain successfully imported.
# Import command completed: 3 entries successfully imported, 0 entries failed or cancelled
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype pkcs12
# Enter destination keystore password: 비밀번호
# Re-enter new password: 비밀번호
# Enter source keystore password: 비밀번호
# Entry for alias alias successfully imported.
# Entry for alias root successfully imported.
# Entry for alias chain successfully imported.
# Import command completed: 3 entries successfully imported, 0 entries failed or cancelled
keytool -export -alias alias -keystore keystore.p12 -rfc -file keystore.cer
# Enter keystore password: 비밀번호
# Certificate stored in file <keystore.cer>
keytool -import -alias alias -file keystore.cer -keystore sksiltron_truststore.jks
# Enter keystore password: 비밀번호
# Re-enter new password: 비밀번호
# ...
# Trust this certificate? [no]: yes
# Certificate was added to keystore
keytool -import -trustcacerts -keystore truststore.jks -storepass password -file DigitCA.pem -alias ca_alias
keystore.jks, truststore.jks 를 만들었다면, Kafka 의 config/server.properties 에 아래 옵션을 추가해 줍니다.
listner=PLAINTEXT://:9092,SSL://:9093
advertised.listeners=PLAINTEXT://HOST:9092,SSL://HOST:9093
ssl.keystore.location=/etc/keystore.jks
ssl.keystore.password=password
ssl.key.password=password
ssl.truststore.loaction=/etc/truststore.jks
ssl.truststore.password=password
ssl.client.auth=required
security.inter.broker.protocol=PLAINTEXT
ssl.endpoint.identification.algorithm
해당 옵션들을 작성하고 kafka cluster 를 재기동하면 SSL 이 적용됩니다.
SSL 은 사설망에서는 적용이 안되도록 구성을 하여 불가피하게 외부에 노출 되는 데이터만 SSL 이 적용 되도록 했습니다.
SSL은 암복호화가 들어가기 때문에 CPU 사용률이 증가하게 된다고 하며, 내부적으로 데이터를 처리할 때 이는 상당히 부하가 걸릴 것으로 예상 되기 때문입니다.
아래는 예시로 SSL 을 적용한 9093 포트로 토픽 리스트를 조회하는 구문 입니다.
kafka-topics.sh --list --bootstrap-server host1:9093 host2:9093 host3:9093 --command-config config/ssl.properties
SSL을 적용하기 위해 미리 작성해둔 properties 를 활용합니다.
properties 는 아래와 같습니다.
# ssl.propertes
security.protocol=SSL
ssl.truststore.location=/etc/truststore.jks
ssl.truststore.password=password
ssl.keystore.location=/etc/keystore.jks
ssl.keystore.password=password
ssl.key.password=pssword
Kafka cluster 에 보안을 적용하는 방법은 많지만 SSL 은 비교적 간단하게 보안 설정할 수 있는 방법입니다. 다만 SSL 적용으로 일어나는 부하를 어느정도 버틸 수 있는지에 대해서는 계속해서 지켜볼 필요가 있을 듯 합니다.