네트워크와 보안 (IP 필터, PrivateLink, PSC, SSO, RBAC, CMEK)
ClickHouse Cloud 서비스를 외부에 어떻게 열고 닫는지(IP 액세스 리스트, AWS PrivateLink, GCP Private Service Connect, Azure Private Link), 콘솔과 데이터베이스의 인증과 권한(SSO, SAML, 콘솔 역할, 커스텀 역할, 마스킹 정책), 암호화(TDE, CMEK) 와 감사 로그를 운영 체크리스트와 함께 정리합니다.
보안 계층 한눈에
ClickHouse Cloud 의 보안은 네 겹으로 보면 정리가 됩니다. 어디서 들어올 수 있는가(네트워크), 누가 콘솔에 들어오는가(콘솔 인증과 역할), 누가 데이터베이스에서 무엇을 할 수 있는가(DB 사용자와 권한), 저장된 데이터와 기록은 어떻게 보호되는가(암호화와 감사 로그) 입니다.
| 계층 | 기본 상태 | 운영에서 바꾸는 것 |
|---|---|---|
| 네트워크 | 서비스마다 IP 액세스 리스트, 기본은 "어디서나 허용" | CIDR 목록으로 좁히기, PrivateLink 나 PSC 로 공용 인터넷 차단 |
| 콘솔 인증 | 이메일 비밀번호(12자 이상), 소셜 로그인, MFA | SAML SSO(Enterprise), SCIM 프로비저닝 |
| 콘솔 권한 | 조직 역할과 서비스 역할 | 커스텀 역할과 데이터 정책 |
| 데이터베이스 | 사용자, 역할, GRANT | 최소 권한 역할, 마스킹 정책, JWT 인증 |
| 저장 데이터 | 저장 시 AES-256, 전송 시 TLS | TDE 와 고객 관리 키(CMEK), 백업 내보내기 |
| 기록 | 콘솔 감사 로그, system.query_log | SIEM 으로 보내기, 보존 기간 정하기 |
IP 액세스 리스트
서비스마다 접속을 허용할 IP 와 CIDR 목록을 둡니다. 새 서비스는 기본값이 "어디서나 허용(Allow from anywhere)" 이므로, 만든 직후 바로 좁히는 것이 첫 할 일입니다. 목록은 공용 인터넷에서 들어오는 연결에만 적용되고, PrivateLink 나 PSC 로 들어오는 연결은 거치지 않습니다. API 키에도 별도의 IP 액세스 리스트를 둘 수 있습니다.
# clickhousectl 로 허용 IP 추가 (사무실 고정 IP, 배치 서버 대역)
clickhousectl cloud service update "$SVC" \
--add-ip-allow "203.0.113.10/32" \
--add-ip-allow "10.20.0.0/16"- 사설 연결만 쓰는 서비스는 목록을 비워 공용 접근을 모두 막습니다(DenyAll). 그러면 콘솔 SQL 편집기도 공용 경로로는 안 붙으므로, 콘솔 접근이 필요한 운영자 IP 를 따로 넣습니다.
- NAT 뒤의 사무실은 외부 IP 가 바뀌면 끊깁니다. ISP 가 바뀌거나 재계약하는 날에 접속이 안 되면 이 목록을 먼저 봅니다.
- 유휴 종료를 켠 개발 서비스도 목록을 좁혀야 합니다. 열어 두면 포트 스캐너가 깨워서 요금이 나옵니다. 자세한 내용은 컴퓨트와 스케일링 의 유휴 종료 항목에 있습니다.
프라이빗 연결
클라우드 내부망으로만 서비스에 닿게 하는 기능입니다. Scale 이상 티어에서 쓸 수 있고, 트래픽이 공용 인터넷을 지나지 않으니 보안 심사에서 요구하는 "DB 는 사설 연결만" 조건을 만족합니다.
| 클라우드 | 기능 | 방향 | 리전 |
|---|---|---|---|
| AWS | PrivateLink | 고객 VPC 에서 Cloud 서비스로만 | 같은 리전 기본, 지원 리전 간 교차 리전 가능 |
| GCP | Private Service Connect | 고객 VPC 에서 Cloud 서비스로 | 같은 리전. 다른 리전은 같은 VPC 안에서 Global Access |
| Azure | Private Link | 고객 VNet 에서 Cloud 서비스로 | 같은 리전 |
AWS PrivateLink 는 네 단계로 붙입니다.
- 콘솔이나 API 에서 서비스의 엔드포인트 서비스 이름(com.amazonaws.vpce 로 시작)을 받습니다.
- 고객 VPC 에 그 서비스 이름으로 인터페이스 엔드포인트를 만들고, 프라이빗 DNS 를 켭니다.
- 만들어진 엔드포인트 ID(vpce-...) 를 조직에 등록합니다.
- 그 엔드포인트 ID 를 연결할 서비스의 허용 목록에 넣습니다. 서비스마다 따로 넣어야 합니다.
# Terraform 으로 엔드포인트 등록과 서비스 연결
resource "clickhouse_private_endpoint_registration" "vpce" {
cloud_provider = "aws"
region = "ap-northeast-2"
private_endpoint_id = aws_vpc_endpoint.ch.id
description = "prod vpc"
}
resource "clickhouse_service_private_endpoints_attachment" "prod" {
private_endpoint_ids = [clickhouse_private_endpoint_registration.vpce.id]
service_id = clickhouse_service.prod.id
}주의 PrivateLink 는 "고객 VPC 에서 ClickHouse 로" 한 방향입니다. ClickHouse 가 고객 VPC 안의 Kafka 나 PostgreSQL 로 나가는 연결(ClickPipes, 테이블 함수)은 별도 경로가 필요합니다. 그 쪽은 ClickPipes 의 고정 송신 IP 를 허용하거나, 리버스 프라이빗 엔드포인트를 쓰는지 서비스 문서에서 확인합니다.
팁 PrivateLink 를 붙인 뒤 공용 엔드포인트와 사설 엔드포인트의 호스트 이름이 다릅니다. 클라이언트 설정에 사설 호스트를 넣고, 모니터링 쿼리도 사설 쪽으로 보내는지 확인해야 IP 액세스 리스트를 비웠을 때 끊기지 않습니다.
콘솔 인증
- 비밀번호는 NIST 800-63B 기준으로 12자 이상이고, MFA(TOTP) 를 켤 수 있습니다. 조직 관리자는 모든 사용자에게 MFA 를 강제할 수 있습니다.
- 소셜 로그인은 Google 과 Microsoft 계정을 지원합니다.
- SAML SSO 는 Enterprise 에서 지원합니다. SAML 로 들어온 사용자는 기본으로 Member 역할을 받으므로, 들어온 뒤 필요한 서비스 역할을 따로 부여해야 합니다.
- SCIM 으로 Okta 와 Microsoft Entra 에서 사용자와 그룹을 자동 프로비저닝할 수 있습니다. 퇴사자 계정이 콘솔에 남는 문제를 줄입니다.
- API 키는 콘솔 로그인과 별개로 OpenAPI, Terraform, Query API 엔드포인트에 쓰이고, 역할과 IP 액세스 리스트를 따로 가집니다.
콘솔 역할과 커스텀 역할
콘솔 권한은 조직 역할과 서비스 역할로 나뉩니다.
| 종류 | 역할 | 할 수 있는 일 |
|---|---|---|
| 조직 | Admin | 모든 설정, 결제, 사용자 관리 |
| 조직 | Billing | 결제와 사용량 보기 |
| 조직 | Org API reader | 조직 정보 읽기(API 용) |
| 조직 | Member | 부여된 서비스 역할만. SAML 사용자 기본값 |
| 서비스 | Service admin | 서비스 설정 변경, 스케일링, 삭제 |
| 서비스 | Service reader | 서비스 보기 |
| 서비스 | Service API admin, Service API reader | API 로 같은 범위 |
| SQL 콘솔 | admin, read only | 콘솔 SQL 편집기의 DB 권한 |
커스텀 역할을 만들면 서비스별로 세밀하게 나눌 수 있고, 데이터 정책(Data policy) 을 붙이면 콘솔 SQL 편집기에서 그 사용자가 어떤 테이블을 어떤 권한으로 보는지까지 정합니다. 데이터 정책을 붙인 역할은 데이터베이스 안에 cloud:<역할이름> 형태의 역할로 나타나며, 26.4 이상 서비스에서 JWT 인증을 전제로 동작합니다. 과거의 sql-console-role:<이메일> 역할을 대체합니다.
-- 콘솔 커스텀 역할이 DB 안에 만든 역할 확인
SELECT name FROM system.roles WHERE name LIKE 'cloud:%';
SHOW GRANTS FOR ROLE `cloud:analyst-readonly`;팁 "분석가는 콘솔에서 읽기만, 운영자는 서비스 설정까지" 를 역할 두 개로 먼저 만들고, 사람은 역할에만 붙입니다. 사람에게 직접 권한을 주기 시작하면 퇴사자 정리가 어려워집니다.
데이터베이스 사용자와 권한
콘솔과 별개로 애플리케이션이 쓰는 DB 사용자는 SQL 로 만듭니다. 비밀번호는 12자 이상이어야 하고, SSH 키 인증과 JWT 인증도 가능합니다. 권한 모델은 오픈소스와 같습니다. 세부 문법은 서버 설정과 사용자 관리 를 참고하세요.
-- 최소 권한 역할 패턴: 적재용, 조회용을 분리
CREATE ROLE ingest_writer;
GRANT INSERT ON analytics.events TO ingest_writer;
CREATE ROLE dashboard_reader;
GRANT SELECT ON analytics.* TO dashboard_reader;
CREATE USER etl IDENTIFIED WITH sha256_password BY 'LongRandomPassword123!'
SETTINGS max_memory_usage = 20000000000 READONLY;
GRANT ingest_writer TO etl;
CREATE USER bi IDENTIFIED WITH sha256_password BY 'AnotherLongPassword456!'
DEFAULT ROLE dashboard_reader;
GRANT dashboard_reader TO bi;Cloud 25.12 이상에서는 마스킹 정책으로 역할에 따라 컬럼 값을 가려서 보여 줄 수 있습니다. 뷰를 따로 만들지 않아도 같은 테이블을 역할마다 다르게 보입니다.
CREATE MASKING POLICY mask_email ON analytics.users
UPDATE email = concat(left(email, 2), '***@', splitByChar('@', email)[2])
TO dashboard_reader;참고 콘솔 사용자(사람)와 DB 사용자(애플리케이션)를 섞지 않는 것이 뒤탈이 없습니다. 사람은 SSO 와 콘솔 역할로, 애플리케이션은 DB 사용자와 비밀 저장소(Secrets Manager 등)로 관리합니다.
암호화 (TDE 와 CMEK)
모든 서비스는 저장 시 클라우드 제공자 키로 AES-256 암호화되고, 전송 구간은 TLS 입니다. 여기에 Enterprise 티어는 투명 데이터 암호화(TDE)를 추가로 켤 수 있고, 키를 고객이 관리하는 CMEK 로 바꿀 수 있습니다.
- TDE 는 서비스를 만들 때만 켤 수 있고 뒤에 끌 수 없습니다. AWS 와 GCP 에서 지원하며, Azure 는 준비 중입니다.
- CMEK 는 AWS KMS 키 정책에 ClickHouse 의 암호화 역할 ID 를 넣어
kms:Encrypt,kms:Decrypt,kms:ReEncrypt*,kms:DescribeKey를 허용하거나, GCP KMS 에서 CryptoKey Encrypter/Decrypter 와 Viewer 를 부여하는 방식입니다. - 키를 비활성화하면 서비스가 멈추고, 키를 삭제하면 데이터와 백업을 복구할 수 없습니다.
{
"Sid": "AllowClickHouseCloud",
"Effect": "Allow",
"Principal": { "AWS": "<ClickHouse 가 콘솔에서 알려 주는 암호화 역할 ARN>" },
"Action": ["kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:DescribeKey"],
"Resource": "*"
}주의 KMS 키 교체(rotation) 와 키 삭제는 다릅니다. 교체는 안전하지만, 키를 "삭제 예약" 해 두고 잊으면 7일 뒤 서비스와 백업이 함께 사라집니다. 키에 삭제 보호 태그와 알람을 붙여 둡니다.
감사 로그와 컴플라이언스
- 콘솔 감사 로그는 사용자 초대, 역할 변경, 서비스 생성과 삭제, IP 목록 변경 같은 콘솔 행위를 기록합니다. 조직 설정에서 보고 내보낼 수 있습니다.
- 데이터베이스 행위는
system.query_log,system.session_log로 남습니다. 보존 기간은 TTL 로 조정하고, 장기 보관은 외부로 보냅니다. 방법은 모니터링 에 있습니다. - 인증 범위는 모든 티어에서 SOC 2 Type II 와 ISO 27001 이고, HIPAA(BAA 필요) 와 PCI DSS 는 Enterprise 의 지정 리전에서 지원합니다. 서울 리전은 Public, HIPAA, PCI, BYOC 가 모두 열려 있습니다.
-- 최근 24시간 실패한 로그인 시도
SELECT event_time, user, client_address, auth_type, failure_reason
FROM system.session_log
WHERE type = 'LoginFailure' AND event_time > now() - INTERVAL 1 DAY
ORDER BY event_time DESC LIMIT 50;운영 체크리스트
- 서비스를 만든 직후 IP 액세스 리스트를 좁힙니다. 개발 서비스도 예외로 두지 않습니다.
- 상용은 PrivateLink, PSC, Azure Private Link 로 붙이고 공용 접근은 운영자 IP 만 남기거나 비웁니다.
- 콘솔은 SSO 와 MFA, 퇴사 처리는 SCIM 으로 자동화합니다.
- 콘솔 역할은 최소 권한의 커스텀 역할 두세 개로 시작하고, 사람은 역할에만 붙입니다.
- DB 사용자는 애플리케이션별로 나누고 비밀번호는 비밀 저장소에서 주입합니다.
- 규제 대상 데이터는 Enterprise 에서 TDE 를 만들 때 켜고, 필요하면 CMEK 로 키를 가져옵니다.
- 감사 로그와
system.query_log보존 기간을 정하고 SIEM 으로 내보냅니다. - 백업을 자기 계정 버킷으로 내보내는 설정은 BYOC, 백업, Cloud API, Terraform 에서 확인합니다.