Trino 보안 완전 가이드 — 인증, 인가, TLS, 내부 통신
Trino 클러스터를 프로덕션에 안전하게 올리기 위한 보안 전 영역을 정리합니다. LDAP/OAuth2 인증, TLS, 내부 통신 공유 시크릿, 파일·Ranger·OPA 기반 인가, 컬럼 마스킹·행 필터, 시크릿 관리까지.
기본 설정으로 띄운 Trino 클러스터는 인증이 없습니다. 8080 포트에 접근할 수 있는 사람은 누구나 모든 카탈로그를 조회할 수 있고, 노드 간 통신도 평문입니다. PoC 단계에서는 편하지만, 프로덕션에서는 반드시 인증·인가·암호화를 모두 켜야 합니다.
이 글은 Trino 보안을 — 전송 암호화(TLS), 인증(Authentication), 인가(Authorization), 내부 통신(Internal Communication) — 으로 나누어, 각각을 실제 설정 파일과 함께 정리합니다.
1. 보안 한눈에 보기
[클라이언트: BI, JDBC, CLI]
│ ① TLS (HTTPS) + ② 인증
▼
┌──────────────────┐
│ Coordinator │ ③ 인가 (access control)
└──────────────────┘
│ ④ 내부 통신: 공유 시크릿 + (선택) TLS
┌─────────┼─────────┐
▼ ▼ ▼
Worker Worker Worker| 축 | 무엇을 막나 | 핵심 설정 |
|---|---|---|
| ① TLS | 평문 도청 | http-server.https.* |
| ② 인증 | 신원 위조 | http-server.authentication.type |
| ③ 인가 | 권한 없는 접근 | access-control.properties |
| ④ 내부 통신 | 워커 위장·내부 도청 | internal-communication.shared-secret |
중요한 전제: 대부분의 인증 방식은 TLS 를 먼저 켜야 동작합니다. 비밀번호를 평문으로 보낼 수는 없기 때문입니다. 따라서 TLS → 인증 → 인가 순으로 구성합니다.
2. TLS — 전송 암호화부터
코디네이터가 HTTPS 를 받도록 설정합니다. 키스토어(PKCS#12 또는 JKS)가 필요합니다.
# etc/config.properties (coordinator)
http-server.https.enabled=true
http-server.https.port=8443
http-server.https.keystore.path=/etc/trino/tls/keystore.p12
http-server.https.keystore.key=changeit
# 평문 8080 을 닫고 싶다면 (단, 헬스체크/내부 경로 고려)
http-server.http.enabled=falseCloudera 환경에서 쓰던 self-signed 또는 사내 CA 인증서를 그대로 활용할 수 있습니다. (인증서 발급 자체는 별도 글 "Cloudera 요구사항에 맞는 self-signed TLS 인증서 만들기"를 참고하세요.) Kubernetes 라면 보통 앞단의 Ingress/LoadBalancer 에서 TLS 를 종단하고, 클러스터 내부는 별도로 다룹니다.
3. 인증 — 누가 접속하는가
http-server.authentication.type 에 인증 방식을 지정합니다. 여러 개를 콤마로 나열하면 위에서부터 시도합니다(폴백 체인).
| 방식 | 값 | 용도 |
|---|---|---|
| 비밀번호(LDAP/파일) | PASSWORD | 사내 LDAP/AD 연동, 가장 흔함 |
| OAuth2 / OIDC | OAUTH2 | Okta·Keycloak·Azure AD SSO |
| Kerberos | KERBEROS | 기존 Cloudera/Hadoop Kerberos 자산 |
| 인증서(mTLS) | CERTIFICATE | 클라이언트 인증서 기반 |
| JWT | JWT | 토큰 발급 시스템과 연동 |
3.1 LDAP 인증 (PASSWORD)
가장 많이 쓰는 구성입니다. 사내 LDAP/AD 의 사용자/비밀번호로 로그인합니다.
# etc/config.properties
http-server.authentication.type=PASSWORD# etc/password-authenticator.properties
password-authenticator.name=ldap
ldap.url=ldaps://ldap.example.com:636
ldap.bind-dn=cn=trino-svc,ou=services,dc=example,dc=com
ldap.bind-password=${ENV:LDAP_BIND_PASSWORD}
ldap.user-base-dn=ou=users,dc=example,dc=com
ldap.group-auth-pattern=(&(objectClass=person)(uid=${USER}))ldaps://(LDAP over TLS)를 쓰는 것이 원칙입니다. LDAP 서버 인증서를 Trino 의 트러스트스토어에 등록해야 검증이 통과합니다.
3.2 파일 기반 비밀번호 (소규모/내부용)
LDAP 이 없을 때는 bcrypt 해시 파일로 간단히 인증할 수 있습니다.
# etc/password-authenticator.properties
password-authenticator.name=file
file.password-file=/etc/trino/password.db# htpasswd 로 bcrypt 해시 생성
htpasswd -B -C 10 -c /etc/trino/password.db alice3.3 OAuth2 / OIDC (SSO)
Keycloak·Okta·Azure AD 같은 IdP 와 연동해 브라우저 SSO 를 구성합니다.
# etc/config.properties
http-server.authentication.type=OAUTH2
http-server.authentication.oauth2.issuer=https://keycloak.example.com/realms/data
http-server.authentication.oauth2.client-id=trino
http-server.authentication.oauth2.client-secret=${ENV:OAUTH2_CLIENT_SECRET}
http-server.authentication.oauth2.scopes=openid,profile,email웹 UI 와 최신 클라이언트는 OAuth2 플로우를, 자동화/배치는 JWT 나 LDAP 폴백을 쓰는 혼합 구성이 흔합니다.
# 폴백 체인: OAuth2 우선, 실패 시 PASSWORD
http-server.authentication.type=OAUTH2,PASSWORD4. 인가 — 무엇을 할 수 있는가
인증된 사용자가 어떤 카탈로그·스키마·테이블·컬럼에 접근할 수 있는지를 결정합니다. etc/access-control.properties 에서 시스템 액세스 컨트롤을 선택합니다.
| 방식 | access-control.name | 특징 |
|---|---|---|
| 모두 허용(기본) | allow-all | 인가 없음. 프로덕션 금지 |
| 읽기 전용 | read-only | 모든 쓰기 차단 |
| 파일 기반 | file | JSON 규칙 파일. 중소 규모에 적합 |
| Apache Ranger | (플러그인) | 중앙 정책·감사, Cloudera 자산 재활용 |
| OPA | opa | Open Policy Agent, Rego 정책으로 세밀 제어 |
4.1 파일 기반 인가
# etc/access-control.properties
access-control.name=file
security.config-file=/etc/trino/rules.json{
"catalogs": [
{ "user": "admin", "catalog": ".*", "allow": "all" },
{ "group": "analysts", "catalog": "iceberg", "allow": "read-only" }
],
"schemas": [
{ "group": "analysts", "catalog": "iceberg", "schema": "analytics", "owner": false }
],
"tables": [
{
"group": "analysts",
"catalog": "iceberg",
"schema": "analytics",
"table": ".*",
"privileges": ["SELECT"]
}
]
}규칙은 위에서부터 첫 매칭을 적용합니다. 명시되지 않으면 거부가 기본입니다. tables 규칙에는 컬럼 마스킹·행 필터도 정의할 수 있습니다.
4.2 컬럼 마스킹 / 행 필터
민감 컬럼을 가리거나, 사용자별로 보이는 행을 제한합니다.
{
"tables": [
{
"group": "analysts",
"catalog": "iceberg",
"schema": "analytics",
"table": "users",
"privileges": ["SELECT"],
"columns": [
{ "name": "ssn", "mask": "'***-**-' || substr(ssn, 8)" }
],
"filter": "region = 'KR'"
}
]
}위 규칙은 analysts 그룹에게 ssn 의 앞자리를 마스킹해 보여주고, region = 'KR' 행만 노출합니다.
4.3 Ranger / OPA
기존에 Cloudera Ranger 로 정책·감사를 운영하던 조직은 Trino 용 Ranger 플러그인으로 정책을 이식해 중앙 관리·감사 로그를 유지할 수 있습니다. 정책을 코드로 관리(GitOps)하고 싶다면 OPA가 강력합니다 — Rego 로 "특정 시간대만 허용", "PII 컬럼은 특정 역할만" 같은 세밀한 규칙을 표현할 수 있습니다.
# etc/access-control.properties (OPA 예시)
access-control.name=opa
opa.policy.uri=http://opa.example.com:8181/v1/data/trino/allow5. 내부 통신 — 워커 위장과 내부 도청 방지
코디네이터와 워커는 서로를 신뢰합니다. 인증을 켜도 이 내부 채널을 보호하지 않으면, 같은 네트워크에 가짜 워커를 붙이거나 내부 트래픽을 가로챌 수 있습니다. 모든 노드에 동일한 공유 시크릿을 설정합니다.
# etc/config.properties (모든 코디네이터 + 워커 동일하게)
internal-communication.shared-secret=<랜덤한 긴 문자열># 시크릿 생성 예시
openssl rand -hex 32인증을 활성화하면 공유 시크릿은 필수입니다. 추가로 내부 통신까지 TLS 로 암호화하려면:
internal-communication.https.required=true
http-server.https.enabled=true흔한 실수: 외부 인증(LDAP)만 켜고 내부 공유 시크릿을 빠뜨리는 것. 이 경우 인증이 우회될 수 있으므로, 둘은 항상 한 세트로 설정하세요.
6. 시크릿 관리 — 평문 비밀번호 금지
LDAP bind 비밀번호, OAuth2 client secret, 키스토어 비밀번호 등을 설정 파일에 평문으로 두지 않습니다. Trino 는 환경변수 치환을 지원합니다.
ldap.bind-password=${ENV:LDAP_BIND_PASSWORD}
http-server.https.keystore.key=${ENV:KEYSTORE_PASSWORD}Kubernetes 라면 이 환경변수를 Secret 으로 주입하고, 베어메탈이라면 systemd EnvironmentFile 또는 Vault 연동으로 공급합니다. 설정 파일(Git)에는 비밀이 남지 않게 합니다.
7. 사용자 매핑과 그룹
인증된 주체(예: alice@EXAMPLE.COM, 인증서 CN)를 Trino 내부 사용자명으로 정규화하고, 그룹을 부여해 인가 규칙에 활용합니다.
# 인증 주체 → Trino 사용자명 매핑 (정규식)
http-server.authentication.password.user-mapping.pattern=(.*)@example\.com
# 그룹 공급자: 파일 또는 LDAP# etc/group-provider.properties (파일 기반 예시)
group-provider.name=file
file.group-file=/etc/trino/group.txt# group.txt : 그룹명:사용자1,사용자2
analysts:alice,bob
admins:carol인가 규칙에서 "group": "analysts" 로 참조하던 그룹이 여기서 정의됩니다.
8. 프로덕션 보안 체크리스트
- 코디네이터 TLS(HTTPS) 활성화, 평문 8080 외부 노출 차단
- 인증 방식 결정 및 활성화 (LDAP/OAuth2/Kerberos)
-
access-control.name을allow-all이 아닌 값으로 설정 - 민감 테이블에 컬럼 마스킹·행 필터 적용
-
internal-communication.shared-secret모든 노드에 동일 설정 - (필요 시) 내부 통신 TLS 활성화
- 모든 비밀번호/시크릿을 환경변수·Secret 으로 분리
- 사용자 매핑·그룹 공급자 구성
- 쿼리 감사 로그(이벤트 리스너) 수집 경로 확보
9. 정리
| 축 | 최소 구성 | 권장 구성 |
|---|---|---|
| 전송 | 코디네이터 HTTPS | 내부 통신까지 TLS |
| 인증 | 파일 비밀번호 | LDAP 또는 OAuth2 SSO |
| 인가 | 파일 기반 규칙 | Ranger/OPA + 컬럼 마스킹·행 필터 |
| 내부 통신 | 공유 시크릿 | 공유 시크릿 + TLS |
| 시크릿 | 환경변수 치환 | Vault/K8s Secret |
Trino 보안의 핵심은 "기본값은 안전하지 않다"는 사실을 인지하고, TLS → 인증 → 인가 → 내부 통신 순으로 빠짐없이 켜는 것입니다. 특히 외부 인증만 켜고 내부 공유 시크릿을 빠뜨리는 실수가 잦으니, 둘을 한 세트로 다루세요. 기존 Cloudera 의 LDAP·Kerberos·Ranger 자산은 대부분 재활용할 수 있어, 보안 측면에서의 마이그레이션 부담은 생각보다 작습니다.
이 글은 Trino 440번대 기준으로 작성되었습니다. 프로덕션 Trino 클러스터의 보안 설계·점검이 필요하시면 언제든 문의해 주세요.
— Data Dynamics 엔지니어링 팀