S3 허용 세션 설정
S3 허용 세션 설정 (s3_allow_*)
이 페이지에서는 S3 처리에서 허용 여부를 제어하는 s3_allow_* 세션 설정들을 다뤄요. 멀티파트 복사, 병렬 업로드, 서버 관리 자격증명 사용 등을 허용할지 결정해요. 특히 s3_allow_server_credentials_in_user_queries는 보안 관점에서 중요한 설정이에요.
출처: 문서
본문
이 설정들은 system.settings에서 확인할 수 있으며 소스에서 자동 생성돼요.
s3_allow_multipart_copy
S3에서 멀티파트 복사를 허용해요.
s3_allow_parallel_part_upload
s3 멀티파트 업로드에 여러 스레드를 사용해요. 메모리 사용량이 약간 더 높아질 수 있어요.
s3_allow_server_credentials_in_user_queries
사용자 SQL에서 시작되는 S3 접근이 서버 관리 자격증명을 사용하도록 허용해요.
비활성화되면(기본값) s3/s3Cluster 테이블 함수, S3/S3Queue 엔진, S3 named collection, 동적 디스크(type=s3, ...) 정의, BACKUP/RESTORE TO S3, DataLake 테이블 데이터 읽기, DataLakeCatalog 데이터베이스(Glue, BigLake)는 환경, 인스턴스 메타데이터(IMDS), IRSA, ECS, 인스턴스 프로파일, SSO, AWS config/credentials 파일, GCP OAuth 메타데이터 서비스에서 자격증명을 확인할 수 없어요. 사용 가능한 명시적 자격증명을 제공하지 않고 그러한 서버 관리 소스를 요청하는 요청(예: use_environment_credentials = 1 또는 http_client = gcp_oauth)은 ACCESS_DENIED로 거부돼요. 그 중 어느 것도 요청하지 않는 요청은 NOSIGN이 주어진 것과 동일하게 서명 없이(익명으로) 전송돼요.
role_arn 기반 STS assume-role(extra_credentials(role_arn = '...'))은 이 설정이 비활성화된 경우에도 허용돼요: 대상 역할은 서버가 실행되는 ID를 명시적으로 신뢰해야 하며, 쿼리의 S3 요청에 서명하는 것은 오직 가정된 역할의 자격증명뿐이므로 서버 자신의 자격증명이 쿼리에 노출되지 않아요. 이것이 ClickHouse Cloud에 프라이빗 버킷 접근을 부여하는 문서화된 방법이에요. 쿼리가 완전한 키 쌍을 제공하면 역할은 쿼리 자신의 기본 키로 가정되고, 그렇지 않으면 STS AssumeRole 호출이 서버의 주변(ambient) ID로 서명돼요. 서버 <s3>/endpoint config 또는 named collection의 정적 키는 쿼리 제공 역할의 STS 기본으로 절대 사용되지 않으며, 서버 <s3> config에 구성된 role_arn은 사용자 쿼리에 전혀 적용되지 않아요. 동적 디스크(type=s3, role_arn=...) 정의는 계속 제한의 적용을 받아요.
자격증명 없는 요청이 환경 자격증명을 요청하는지 여부는 use_environment_credentials로 결정돼요. Named collection은 이를 기본적으로 0으로 설정하므로, URL만 지정하는 collection은 익명으로 읽어요. s3/s3Cluster 테이블 함수와 S3/S3Queue 엔진은 서버 <s3> config가 달리 정하지 않는 한 내장 기본값(1)을 사용해요. 자격증명 없는 읽기도 기본적으로 익명으로 만들려면 <s3><use_environment_credentials>0</use_environment_credentials></s3>를 설정해요(그렇지 않으면 그러한 요청은 거부되며 NOSIGN을 사용해야 해요). 서버 구성에 정의된 디스크는 영향을 받지 않고 기본값으로 환경 자격증명을 계속 사용해요. 사용자가 만든 동적 디스크(type = s3, ...) 정의는 제한의 적용을 받으며(위 참조) 기본/환경 자격증명에 의존하면 거부돼요.
이것은 인증된 사용자가 서버 자신의(주변) 자격증명으로 서버가 S3에 접근하게 하는 것을 방지해요. 명시적으로 제공된 자격증명은 영향을 받지 않아요: 쿼리에 전달된 키, named collection(SQL로 생성되거나 config에 정의된)의 정적 키, 서버 <s3> config의 키는 모두 계속 동작해요.
사용자 쿼리에 S3 접근을 주는 권장 방법은 명시적 자격증명(공용 버킷에는 NOSIGN)이 있는 named collection이에요: 키가 쿼리 텍스트에 남지 않고, 각 collection 사용은 RBAC(GRANT NAMED COLLECTION ON <name> TO <user>)로 제어되므로 서버 자신의 ID를 노출하는 대신 특정 사용자에게 특정 버킷을 부여할 수 있어요.
범위(의도적으로 범위 밖): 이 설정은 위에 나열된 서버의 주변 자격증명 소스만 차단해요. 서버 <s3> config 또는 config 정의 named collection의 운영자가 프로비저닝한 정적 access_key_id/secret_access_key는 차단하지 않아요: 그것들은 명시적 자격증명으로 처리되어 계속 동작해요. 단, access_header나 서버 측 암호화 키 같은 config 요청 자료는 여기서 자격증명으로 취급되지 않는다는 점에 유의해요: 그러한 자료만 담고 명시적 키 쌍이 없는 요청(그리고 기본 use_environment_credentials = 1)은 여전히 거부되는데, 그렇지 않으면 서버의 주변 자격증명으로 폴백되기 때문이에요. 그러한 엔드포인트는 명시적 키, NOSIGN, use_environment_credentials = 0, 또는 아래의 탈출구(escape hatch)도 제공해야 해요.
신뢰할 수 있는 관리 클라이언트는 합법적인 작업(예: SQL로 s3_plain_rewritable 디스크에 시스템 테이블을 연결)을 위해 서버 관리 자격증명이 필요할 수 있어요. 해당 클라이언트의 세션이나 설정 프로필에서 이 설정을 활성화해서 허용해요.
BACKUP/RESTORE ... ON CLUSTER의 경우 이니시에이터의 이 설정 값이 다른 호스트로 전파되어 그대로 사용돼요. 그 호스트들은 분산 DDL 큐를 통해 호스트별 연속 작업을 실행하는데, 기본적으로 이니시에이터의 사용자 없이 실행되므로, 그렇지 않으면 자신의 기본 프로필에 대해 제한을 평가하게 돼요. 대신 이니시에이터의 값이 보존되는데, 그 이유는 이미 제한된 자신의 설정으로 같은 백업 대상을 열었기 때문이에요. 이니시에이터에 대한 readonly 제약은 여전히 적용돼요(신뢰할 수 없는 이니시에이터는 자신의 온-클러스터 백업에 대해 이 설정을 활성화할 수 없음). 따라서 제한이 약화되지 않아요.
영구 S3 및 S3Queue 테이블의 내구성: 이 기능을 세션 또는 프로필에서만 활성화하는 것은 재시작 후에도 지속되지 않아요. 서버가 저장된 정의에서 그러한 테이블을 다시 로드할 때(시작 또는 RESTORE) S3 클라이언트를 다시 빌드하고 시작 컨텍스트로 제한을 다시 적용하므로, 서버 관리 자격증명에 의존하고 세션/프로필 s3_allow_server_credentials_in_user_queries = 1에서만 생성된 테이블은 생성은 성공하지만 재시작 후 접근할 수 없게 돼요(테이블은 그 자리에 남고, 자격증명이 허용된 소스로 다시 해결될 때까지 쿼리는 실패해요). 서버 자체는 계속 시작돼요. 그러한 테이블에 지속적인 접근을 원하면 명시적 자격증명을 주거나, 서버 전체에서 이 설정을 활성화하면 모든 재로드에서 계속 로드되지만 모든 재로드에 대해 제한이 완화되는 비용이 들어요.
신뢰할 수 없는 사용자에 대해 비활성화로 유지하려면, 값과 readonly를 모두 명시적으로 설정하여 그들의 프로필에 고정해요:
<profiles>
<untrusted>
<!-- 명시적 값이 필요해요: `readonly` 제약만으로는 직접 변경만 차단하지만,
이 설정이 도입되기 전 버전의 `compatibility`는 그렇지 않으면
기존의(허용하는) 기본값을 복원할 수 있어요. 값을 명시적으로 설정하면 `compatibility`를 무력화해요. -->
<s3_allow_server_credentials_in_user_queries>0</s3_allow_server_credentials_in_user_queries>
<constraints>
<s3_allow_server_credentials_in_user_queries>
<readonly/>
</s3_allow_server_credentials_in_user_queries>
</constraints>
</untrusted>
</profiles>
이 설정은 사용자가 운영자인 clickhouse-local에서는 효과가 없어요.
DataLakeCatalog 데이터베이스(Glue, BigLake)도 한 가지 차이점을 두고 적용돼요. 카탈로그 객체는 한 번 생성되어 데이터베이스의 모든 사용자가 공유하므로 값을 쿼리별로 읽을 수 없어요. CREATE DATABASE(또는 사용자 ATTACH DATABASE)를 실행하는 세션에서 캡처돼요. 이 설정이 활성화된 동안 생성된 데이터베이스(예: 신뢰할 수 있는 세션이나 프로필에서)는 카탈로그에 서버의 주변 자격증명을 사용할 수 있으며, 그 데이터베이스를 쿼리할 수 있는 모든 사용자가 이를 공유하게 돼요. 기본값으로 생성되면 누가 쿼리하든 카탈로그는 모든 사람에게 제한돼요. 서버가 자신의 메타데이터에서 이미 생성된 데이터베이스를 로드할 때(시작, RESTORE) 영구 S3/S3Queue 테이블과 마찬가지로 제한이 시작 컨텍스트로 다시 적용돼요: 서버 관리 자격증명을 확인하는 카탈로그는 사용 불가로 남고 데이터베이스는 재시작 후 접근할 수 없게 돼요(서버는 계속 시작되고, 데이터베이스는 s3_load_table_anonymously_if_credentials_restricted에 따라 사용 불가 카탈로그와 함께 로드되며, 쿼리는 제한을 보고해요). 명시적 자격증명(Glue: aws_access_key_id와 aws_secret_access_key; BigLake: 완전한 Google ADC 트리플)이 주어진 카탈로그는 무관하게 동작하며 재시작 후에도 지속돼요.