보안 고도화 가이드
보안 고도화 가이드 (Security Hardening Guide)
이 가이드는 Apache Pinot 클러스터를 고도화(hardening)하기 위한 모범 사례를 제공해요. 엔드포인트 노출(Endpoint Exposure), mTLS, 접근 제어(Access Control), 시크릿 관리(Secrets Management)를 다뤄요.
출처: 문서
본문
제한 사항 표 | 제한 사항 | 이유 | |---|---| | Pinot의 controller / broker / server 포트를 인터넷에 직접 노출하고 싶지 않음 | Pinot에 대한 인증 없는 접근 방지 | | Pinot의 Zookeeper를 인터넷에 노출하고 싶지 않음 | Zookeeper 장애나 데이터 리셋 후 복구 | | ACL과 RLS를 통한 권한 있는 접근을 특정 Pinot 사용자로만 제한하고 싶음 | 권한 있는 개인에게만 접근 제한 | | server와 minion에서 /admin 엔드포인트를 노출하고 싶지 않음 | 공격 표면(attack surface) 축소 |
엔드포인트 노출 (외부 접근 제한) (Endpoint Exposure)
Pinot의 controller, broker, server는 HTTP/REST 엔드포인트를 노출해요. 이 엔드포인트들은 테이블 추가/제거, 클러스터 메타데이터 읽기, 데이터 쿼리 등 Pinot의 다양한 측면을 관리하게 해요. 프로덕션 환경에서 이 엔드포인트들을 공개 인터넷에 노출하는 것은 심각한 보안 위험이에요. 8096~8100, 9000, 9001, 9097, 9098 포트로 들어오는 모든 인바운드 트래픽을 차단하는 것을 권장해요.
방화벽 규칙 사용 (Using firewall rules)
더 엄격한 보안을 위해 내부 네트워크의 서브넷에서만 접근을 허용하는 방화벽 규칙을 고려하세요. 예를 들어 서브넷 10.0.1.0/24에서만 접근을 허용하려면:
sudo ufw allow from 10.0.1.0/24 to any port 8096:8100,9000,9001,9097,9098 proto tcp
내부 네트워크에서만 접근을 허용하는 것이 무단 접근에 대한 최선의 방어예요. AWS Security Groups, GCP VPC Firewall Rule, Azure network security groups 같은 어떤 방화벽으로도 방화벽 규칙을 설정할 수 있어요.
리버스 프록시 사용 (Using a reverse proxy)
Pinot 앞에 리버스 프록시를 두면 외부 접근을 더 제한하고 레이트 리미팅(rate limiting), 추가 인증 같은 부가 기능을 제공할 수 있어요.
Pinot은 OAuth2.0 및 기타 SSO(Single Sign-On)와의 통합을 위해 JWT(JSON Web Tokens)를 지원해요. 리버스 프록시 구성에 대한 자세한 내용은 이 문서를 참고하세요.
mTLS (상호 전송 계층 보안)
Pinot은 Pinot 클러스터 내부의 컴포넌트와 클라이언트를 인증하기 위해 양방향 TLS(상호 TLS, mTLS)를 지원해요. mTLS는 연결의 양쪽이 인증서로 서로를 인증하므로 단방향 TLS보다 더 강한 보장을 제공해요.
사전 요구사항 (Prerequisites)
- 모든 Pinot 컴포넌트가 0.11.0 이상으로 업그레이드되고 같은 ZooKeeper를 가리켜야 해요.
- 각 컴포넌트용 JKS 또는 PKCS12 키스토어/트러스트스토어가 생성되어 있어야 해요.
mTLS 활성화 (Enabling mTLS)
1. Controller에서 mTLS 활성화. 컨트롤러에 다음 구성을 설정하세요:
pinot.controller.mtls.enabled=true
pinot.controller.mtls.keystore.type=PKCS12
pinot.controller.mtls.keystore.path=/path/to/keystore.p12
pinot.controller.mtls.keystore.password=keystore_password
pinot.controller.mtls.truststore.type=PKCS12
pinot.controller.mtls.truststore.path=/path/to/truststore.p12
pinot.controller.mtls.truststore.password=truststore_password
2. Broker에서 mTLS 활성화. 브로커에 다음 구성을 설정하세요:
pinot.broker.mtls.enabled=true
pinot.broker.mtls.keystore.type=PKCS12
pinot.broker.mtls.keystore.path=/path/to/keystore.p12
pinot.broker.mtls.keystore.password=keystore_password
pinot.broker.mtls.truststore.type=PKCS12
pinot.broker.mtls.truststore.path=/path/to/truststore.p12
pinot.broker.mtls.truststore.password=truststore_password
3. Server에서 mTLS 활성화. 서버에 다음 구성을 설정하세요:
pinot.server.mtls.enabled=true
pinot.server.mtls.keystore.type=PKCS12
pinot.server.mtls.keystore.path=/path/to/keystore.p12
pinot.server.mtls.keystore.password=keystore_password
pinot.server.mtls.truststore.type=PKCS12
pinot.server.mtls.truststore.path=/path/to/truststore.p12
pinot.server.mtls.truststore.password=truststore_password
4. Minion에서 mTLS 활성화. 미니언에 다음 구성을 설정하세요:
pinot.minion.mtls.enabled=true
pinot.minion.mtls.keystore.type=PKCS12
pinot.minion.mtls.keystore.path=/path/to/keystore.p12
pinot.minion.mtls.keystore.password=keystore_password
pinot.minion.mtls.truststore.type=PKCS12
pinot.minion.mtls.truststore.path=/path/to/truststore.p12
pinot.minion.mtls.truststore.password=truststore_password
권장 mTLS 구성 (Recommended mTLS configuration)
- 세 컴포넌트(server, broker, controller)가 서로 다른 인증서 집합을 가질 수 있어요.
- 양쪽이 서로를 신뢰할 때만 연결이 수립돼요. 상호 신뢰가 실패하면 연결이 수립되지 않아요. 또한 업그레이드나 롤백 후 인증서를 교체(rotate)할 때, 교체 기간 동안 연결이 클러스터에 접속하지 못할 수 있어요. 이 교체는 유지보수 창(maintenance window)에 수행하는 것을 권장해요.
인증서 교체 참고: 각 컴포넌트가 현재 사용 중인 모든 인증서는 동시에 갱신해야 해요.
접근 제어 (Access Control)
이 섹션은 컨트롤 플레인(즉 관리 API)과 데이터 플레인(즉 쿼리) 접근을 모두 아우르는 종단간 접근 제어를 다뤄요.
역할 기반 접근 제어 (Role-based access control)
Pinot에서 접근 제어는 접근 제어 보안 주체 팩토리(principal factory)와 자격 증명 읽기/쓰기(reader/writer)를 통해 구현돼요. 보안 주체 팩토리는 컨트롤러에 구성되는 반면, 읽기/쓰기는 브로커에 구성돼요. server와 minion 같은 컴포넌트는 컨트롤러와 브로커 양쪽에 인증해야 해요.
1. Controller — 컨트롤러의 접근 제어 보안 주체 팩토리와 자격 증명을 설정하세요:
controller.admin.access.control.factory.class=org.apache.pinot.controller.api.access.Security
...
2. Broker — 브로커의 접근 제어를 구성해 들어오는 쿼리의 자격 증명을 검증하고 서버/미니언이 브로커에 인증하도록 하세요.
3. Server — 서버가 컨트롤러와 브로커 양쪽에 인증하도록 서버 구성에서 보안 자격 증명을 설정하세요.
4. Minion — 미니언이 컨트롤러와 브로커 양쪽에 인증하도록 미니언 구성에서 보안 자격 증명을 설정하세요.
핵심 원칙은 서버와 미니언이 항상 컨트롤러(관리 API)와 브로커(쿼리) 양쪽에 인증해야 한다는 거예요. 세부 구성 키와 예시는 Access Control 및 Basic Auth Access Control 문서를 참고하세요.
시크릿 관리 (Secrets Management)
plain-text 구성 파일의 자격 증명은 프로덕션에서 위험이에요. Pinot은 **동적 환경 구성(Dynamic Environment Configuration)**을 지원해서 properties 파일에 하드코딩하는 대신 환경 변수나 외부 저장소(예: Kubernetes Secrets, HashiCorp Vault)에서 시크릿을 주입할 수 있어요. controller.admin.access.control.principals.<principal>.password 같은 민감한 값을 env-var 참조로 대체할 수 있어요. 자세한 내용은 Dynamic Environment Configuration 참조를 참고하세요.
프로덕션 고도화 체크리스트 (Production hardening checklist)
- 방화벽 또는 보안 그룹으로 내부 네트워크에서만 8096~8100, 9000, 9001, 9097, 9098 포트 접근을 허용하세요.
- Zookeeper를 외부에서 노출하지 마세요.
- 컨트롤러, 브로커, 서버, 미니언에서 mTLS를 활성화하세요.
- 컨트롤러(관리)와 브로커(쿼리)에 Basic Auth나 OAuth2 기반 인증을 설정하세요.
- 테이블 수준 및 작업 수준 ACL과 필요한 경우 행 수준 보안(RLS)을 구성하세요.
- server와 minion의 /admin 엔드포인트 노출을 제한하세요.
- 자격 증명을 plain-text 파일 대신 외부 시크릿 스토어에서 주입하세요.
- 인증서 만료를 추적하고 유지보수 창에 교체를 계획하세요.