CredentialProvider API 가이드
CredentialProvider API 가이드
CredentialProvider API는 **확장 가능한 자격 증명 제공자(credential provider)**를 플러그인할 수 있게 하는 SPI 프레임워크입니다. 자격 증명 제공자는 민감한 토큰, 비밀, 비밀번호의 사용을 그 저장·관리 세부사항으로부터 분리하는 데 사용됩니다. 이러한 자격 증명을 보호하기 위해 다양한 저장 메커니즘을 선택할 수 있다는 것은, 민감한 자산을 평문(clear text)에서 멀리, 호기심 많은 눈에서 멀리, 그리고 잠재적으로 타사 솔루션이 관리하도록 유지할 수 있게 해줍니다.
이 문서는 CredentialProvider API의 설계, 기본 제공(out of the box) 구현, 그것들이 어디에 사용되는지, 그리고 어떻게 채택하는지를 설명하는 것을 목표로 합니다.
사용법 (Usage)
사용법 개요
hadoop에서 비밀번호나 다른 민감한 토큰을 보호하기 위한 자격 증명 제공자 프레임워크 사용의 간단한 개요를 살펴보겠습니다.
왜 사용하나요?
클러스터 내에서 비밀번호 같은 민감한 토큰이 저장되고 관리되는 방식에 매우 민감한 배포가 있습니다. 예를 들어, 보안 모범 사례와 정책이 그러한 것들을 절대 평문으로 저장하지 말 것을 요구하는 경우가 있을 수 있습니다. 엔터프라이즈 배포는 자격 증명을 관리하기 위한 선호 솔루션 사용을 요구받을 수 있으며, 우리는 이를 위한 통합을 플러그인할 방법이 필요합니다.
일반 사용 패턴
Hadoop 프로젝트와 생태계에는 오늘날 자격 증명 제공자 API를 활용할 수 있는 수많은 곳이 있으며 그 수는 계속 늘어나고 있습니다. 일반적으로 사용 패턴은 동일한 요구 사항과 흐름으로 구성됩니다.
- 제공자별 저장소에 자격 증명을 프로비저닝합니다. 이 프로비저닝은
hadoop credential명령이나 제공자별 관리 도구를 통해 수행할 수 있습니다. - 자격 증명 제공자 경로 속성을 구성합니다. 제공자 경로 속성
hadoop.security.credential.provider.path는 자격 증명 별명(alias)을 해석하려고 할 때 탐색되는 하나 이상의 자격 증명 제공자 URI를 쉼표로 구분한 목록입니다. - 이 속성은
core-site.xml이나 core-site.xml과 병합되는 구성요소별 설정 파일에서 구성할 수 있습니다. - DistCp 같은 명령줄 인터페이스의 경우 이 속성을 hadoop 시스템 속성(
-D property=value)으로 추가하고 Configuration에 동적으로 추가할 수 있습니다. - 자격 증명을 해석하는 새
Configuration.getPassword메서드를 활용하는 기능이나 구성요소는 자격 증명 제공자 API에 대한 지원을 자동으로 채택합니다. - 기존 평문 비밀번호와 동일한 속성 이름을 사용함으로써, 이 메커니즘은 평문에 대한 역호환성을 제공하면서 자격 증명 제공자로의 마이그레이션을 허용합니다.
- config의 평문 비밀번호로 폴백하기 전에 전체 자격 증명 제공자 경로를 검사합니다.
- 설정에 Hadoop의
org.apache.hadoop.conf.Configuration클래스를 사용하지 않거나 자격 증명 제공자에 대한 다른 내부 용도가 있는 기능이나 구성요소는 자격 증명 제공자 API 자체를 사용할 수 있습니다. 사용 예시는Configuration.getPassword와 그 단위 테스트에서 찾을 수 있습니다.
자격 증명 프로비저닝 (Provision Credentials)
예시: ssl.server.keystore.password
hadoop credential create ssl.server.keystore.password -value 123 \
-provider localjceks://file/home/lmccay/aws.jceks
별명(alias) 이름은 Configuration.get() 메서드에서 자격 증명을 가져오는 데 사용된 설정 속성과 동일합니다.
제공자 경로 구성 (Configuring the Provider Path)
이제 이 프로비저닝된 자격 증명 저장소가 런타임에 Configuration.getPassword 메서드에 알려지도록 해야 합니다. 자격 증명 제공자 경로 설정이 없으면 Configuration.getPassword()는 자격 증명 제공자 API 검사를 건너뜁니다. 따라서 core-site.xml이나 구성요소의 해당 파일에 다음을 구성하는 것이 중요합니다.
<property>
<name>hadoop.security.credential.provider.path</name>
<value>localjceks://file/home/lmccay/aws.jceks</value>
<description>Path to interrogate for protected credentials.</description>
</property>
제공자 경로에 대해 주목할 만한 몇 가지 추가 사항:
- scheme은 제공자 유형을 나타내는 데 사용됩니다. 위 경우 localjceks 제공자는 Hadoop FileSystem API에 대한 의존성이 없습니다. 재귀적 의존성을 피하기 위해 때로 필요합니다.
jceks로 표시되는 다른 제공자는 Hadoop FileSystem API를 사용하며 HDFS나 다른 호환 파일시스템 내에 프로비저닝된 키스토어를 지원할 수 있습니다. 세 번째 제공자 유형은 user(사용자) 유형입니다. 이 제공자는 프로세스의 Credentials 파일에 저장된 자격 증명을 관리할 수 있습니다. - 경로 설정은 제공자 또는 자격 증명 저장소의 쉼표로 구분된 경로를 허용합니다.
Configuration.getPassword메서드는 별명을 해석하거나 목록을 소진할 때까지 각 제공자를 순서대로 조회합니다. 런타임 자격 증명 요구에 따라 확인할 제공자 체인을 구성해야 할 수 있습니다.
요약하면, 먼저 자격 증명을 제공자에 프로비저닝한 다음 기능이나 구성요소에서 사용하도록 제공자를 구성하면, 종종 Configuration.getPassword 메서드 사용을 통해 자동으로 채택됩니다.
지원되는 기능 (Supported Features)
| Feature\Component | Description | Link | | LDAPGroupsMapping | LDAPGroupsMapping is used to look up the groups for a given user in LDAP. The CredentialProvider API is used to protect the LDAP bind password and those needed for SSL. | LDAP Groups Mapping | | SSL Passwords | FileBasedKeyStoresFactory leverages the credential provider API in order to resolve the SSL related passwords. | TODO | | HDFS | DFSUtil uses Configuration.getPassword() use the credential provider API and/or fallback to the clear text value stored in ssl-server.xml. Zookeeper-based federation state store and failover controller use Configuration.getPassword to get the Zookeeper authentication info, with fallback provided to clear text auth info. | TODO | | YARN | WebAppUtils uptakes the use of the credential provider API through the new method on Configuration called getPassword. This provides an alternative to storing the passwords in clear text within the ssl-server.xml file while maintaining backward compatibility. Zookeeper based resource manager state store uses Configuration.getPassword to get the Zookeeper authentication info, with fallback provided to clear text auth info. | TODO | | KMS | Uses HttpServer2.loadSSLConfiguration that leverages Configuration.getPassword to read SSL related credentials. They may be resolved through Credential Provider and/or from the clear text in the config when allowed. | KMS | | HttpFS | Uses HttpServer2.loadSSLConfiguration that leverages Configuration.getPassword to read SSL related credentials. They may be resolved through Credential Provider and/or from the clear text in the config when allowed. | HttpFS Server Setup | | AWS S3A | Uses Configuration.getPassword to get the S3 credentials. They may be resolved through the credential provider API or from the config for backward compatibility. | AWS S3/S3A Usage | | Azure WASB | Uses Configuration.getPassword to get the WASB credentials. They may be resolved through the credential provider API or from the config for backward compatibility. | Azure WASB Usage | | Azure ADLS | Uses Configuration.getPassword to get the ADLS credentials. They may be resolved through the credential provider API or from the config for backward compatibility. | Azure ADLS Usage | | Apache Accumulo | The trace.password property is used by the Tracer to authenticate with Accumulo and persist the traces in the trace table. The credential provider API is used to acquire the trace.password from a provider or from configuration for backward compatibility. | TODO | | Apache Slider | A capability has been added to Slider to prompt the user for needed passwords and store them using CredentialProvider so they can be retrieved by an app later. | TODO | | Apache Hive | Protection of the metastore password, SSL related passwords and JDO string password has been added through the use of the Credential Provider API | TODO | | Apache HBase | The HBase RESTServer is using the new Configuration.getPassword method so that the credential provider API will be checked first then fall back to clear text - when allowed. | TODO | | Apache Oozie | Protects SSL, email and JDBC passwords using the credential provider API. | TODO | | Apache Ranger | Protects database, trust and keystore passwords using the credential provider API. | TODO |
자격 증명 관리 (Credential Management)
hadoop credential 명령
사용법: hadoop credential <subcommand> [options]
명령 옵션 상세는 Commands Manual을 참고하세요.
credential 명령은 특정 자격 증명 저장소 제공자에 비밀번호나 비밀을 프로비저닝하기 위한 것일 수 있습니다. 사용할 제공자 저장소를 명시적으로 나타내려면 -provider 옵션을 사용해야 합니다.
예시: hadoop credential create ssl.server.keystore.password -provider jceks://file/tmp/test.jceks
특정 제공자 유형과 위치를 나타내기 위해 사용자는 core-site.xml에 hadoop.security.credential.provider.path 설정 요소를 제공하거나 각 자격 증명 관리 명령에서 커맨드라인 옵션 -provider를 사용해야 합니다. 이 제공자 경로는 조회해야 할 제공자 목록의 유형과 위치를 나타내는 URL의 쉼표 구분 목록입니다. 예를 들어 다음 경로: user:///,jceks://file/tmp/test.jceks,jceks://[email protected]/my/path/test.jceks는 현재 사용자의 자격 증명 파일을 User Provider를 통해 조회해야 하고, /tmp/test.jceks에 있는 로컬 파일이 Java Keystore Provider이며, HDFS의 nn1.example.com에서 /my/path/test.jceks에 있는 파일도 Java Keystore Provider의 저장소임을 나타냅니다.
제공자 유형 (Provider Types)
- UserProvider는 제공자 URI
user:///로 표시되며 사용자의 Credentials 파일에서 자격 증명을 검색하는 데 사용됩니다. 이 파일은 실행 중인 작업과 애플리케이션에 필요한 다양한 토큰, 비밀, 비밀번호를 저장하는 데 사용됩니다. - JavaKeyStoreProvider는 제공자 URI
jceks://SCHEME/path-to-keystore로 표시되며 파일시스템<SCHEME>의 Java keystore 파일에서 자격 증명을 검색하는 데 사용됩니다. Hadoop 파일시스템 API의 기본 사용으로 자격 증명을 로컬 파일시스템이나 클러스터 저장소에 저장할 수 있습니다. - LocalJavaKeyStoreProvider는 제공자 URI
localjceks://file/path-to-keystore로 표시되며 로컬 파일시스템에 저장되어야 하는 Java keystore에서 자격 증명을 접근하는 데 사용됩니다. 이는 HDFS 접근에 대한 재귀적 의존성을 초래하는 자격 증명에 필요합니다. HDFS에 접근하는 데 자격 증명이 필요할 때마다, HDFS에서 자격 증명을 얻는 것에 의존할 수 없습니다. - BouncyCastleFIPSKeyStoreProvider는 제공자 URI
bcfks://SCHEME/path-to-keystore로 표시되며 파일시스템<SCHEME>의 Bouncy Castle FIPS keystore 파일에서 자격 증명을 검색하는 데 사용됩니다. Hadoop 파일시스템 API의 기본 사용으로 자격 증명을 로컬 파일시스템이나 클러스터 저장소에 저장할 수 있습니다. - LocalBcouncyCastleFIPSKeyStoreProvider는 제공자 URI
localbcfks://file/path-to-keystore로 표시되며 로컬 파일시스템에 저장되어야 하는 Bouncy Castle FIPS keystore에서 자격 증명을 접근하는 데 사용됩니다. 이는 HDFS 접근에 대한 재귀적 의존성을 초래하는 자격 증명에 필요합니다. HDFS에 접근하는 데 자격 증명이 필요할 때마다, HDFS에서 자격 증명을 얻는 것에 의존할 수 없습니다.
자격 증명이 파일시스템에 저장될 때 다음 규칙이 적용됩니다.
로컬 localjceks:// 또는 localbcfks:// 파일에 저장된 자격 증명은 설정을 읽는 프로세스에서 로드됩니다. YARN 애플리케이션에서 사용하는 경우 이는 호스트의 로컬 파일시스템에서 클러스터 전체에 보여야 함을 의미합니다.
jceks:// 또는 bcfks:// 제공자로 저장된 자격 증명은 클러스터 파일시스템에 저장될 수 있으므로 클러스터 전체에서 보입니다. 단, 접근에 특정 자격 증명을 요구하는 파일시스템에는 저장할 수 없습니다.
파일시스템 URI를 jceks URI로 감싸려면 다음 단계를 따르세요. Bouncy Castle FIPS 제공자는 jceks를 bcfks로 바꾸고 OS/JDK 레벨 FIPS 제공자를 구성하는 유사한 단계를 따릅니다.
hdfs://namenode:9001/users/alice/secrets.jceks같은 파일시스템 URI를 가져옵니다.- URL 앞에
jceks://를 배치합니다:jceks://hdfs://namenode:9001/users/alice/secrets.jceks - 두 번째
://문자열을@기호로 바꿉니다:jceks://hdfs@namenode:9001/users/alice/secrets.jceks
예시
로컬 파일시스템의 경우 file:///tmp/secrets.jceks 같은 경로는 jceks://file/tmp/secrets.jceks가 됩니다.
| Path URI | jceks URI | | hdfs://namenode.example.org:9001/user/alice/secret.jceks | jceks://[email protected]:9001/user/alice/secret.jceks | | file:///tmp/secrets.jceks | jceks://file/tmp/secret.jceks | | s3a://container1/secrets/secret.jceks | jceks://s3a@container1/secrets/secret.jceks | | wasb://account@container/secret.jceks | jceks://wasb@account@container/secret.jceks | | abfs://account@container/secret.jceks | jceks://abfs@account@container/secret.jceks | | https://user:pass@service/secret.jceks?token=aia | jceks://https@user:pass@service/secret.jceks?token=aia |
무한 재귀를 피하기 위해 abfs, s3a, adls, wasb 같은 파일시스템은 자체 파일시스템 scheme의 경로에 저장된 키스토어를 명시적으로 제외합니다. 조회되는 자격 증명과 다른 자격 증명 집합을 사용하는 컨테이너에 저장되어 있더라도 마찬가지입니다.
예를 들어, s3a://shared/secrets/secret.jceks에 저장된 자격 증명을 사용해 s3a://private/ 컨테이너의 자격 증명을 읽을 수 없습니다.
키스토어 비밀번호 (Keystore Passwords)
Java의 키스토어는 일반적으로 비밀번호로 보호됩니다. 키스토어 기반 자격 증명 제공자의 주요 보호 방법은 OS 레벨 파일 권한과 대상 파일시스템에 존재할 수 있는 기타 정책 기반 접근 보호입니다. 비밀번호가 보호의 일차 소스는 아니지만, 이러한 비밀번호를 관리하기 위한 메커니즘과 옵션을 이해하는 것은 매우 중요합니다. 또한 런타임에 키스토어를 소비하기 위해 키스토어 보호에 사용되는 비밀번호에 접근해야 하는 모든 당사자도 이해하는 것이 매우 중요합니다.
옵션 (Options)
| Option | Description | Notes | | Default password | This is a harcoded password of “none”. | This is a hardcoded password in an open source project and as such has obvious disadvantages. However, the mechanics section will show that it is simpler and consequently nearly as secure as the other more complex options. | | Environment variable | HADOOP_CREDSTORE_PASSWORD | This option uses an environment variable to communicate the password that should be used when interrogating all of the keystores that are configured in the hadoop.security.credential.provider.path configuration property. All of the keystore based providers in the path will need to be protected by the same password. | | Password-file | hadoop.security.credstore.java-keystore-provider.password-file | This option uses a “side file” that has its location configured in the hadoop.security.credstore.java-keystore-provider.password-file configuration property to communicate the password that should be used when interrogating all of the keystores that are configured in the hadoop.security.credential.provider.path configuration property. |
메커니즘 (Mechanics)
보호되는 자격 증명(mapreduce 작업/애플리케이션)의 모든 런타임 소비자가 키스토어 제공자를 보호하는 데 사용되는 비밀번호에 접근할 수 있어야 한다는 점을 고려하는 것이 매우 중요합니다. 이 비밀번호를 전달하는 방법은 여러 가지가 있으며 위 옵션 절에서 설명합니다.
| Keystore Password | Description | Sync Required | Clear Text | File Permissions | | Default Password | Hardcoded password is the default. Essentially, when using the default password for all keystore-based credential stores, we are leveraging the file permissions to protect the credential store and the keystore password is just a formality of persisting the keystore. | No | Yes | No (documented) | | Environment Variable | The HADOOP_CREDSTORE_PASSWORD environment variable must be set to the custom password for all keystores that may be configured in the provider path of any process that needs to access credentials from a keystore-based credential provider. There is only one env variable for the entire path of comma-separated providers. It is difficult to know the passwords required for each keystore and it is suggested that the same be used for all keystore-based credential providers to avoid this issue. Setting the environment variable will likely require it to be set from a script or some other clear text storage mechanism. Environment variables for running processes are available from various unix commands. | Yes | Yes | No | | Password File | hadoop.security.credstore.java-keystore-provider.password-file configuration property must be set to the location of the “side file” that contains the custom password for all keystores that may be configured in the provider path. Any process that needs to access credentials from a keystore-based credential provider will need to have this configuration property set to the appropriate file location. There is only one password-file for the entire path of comma separated providers. It is difficult to know the passwords required for each keystore and it is therefore suggested that the same be used for all keystore-based credential providers to avoid this issue. Password-files are additional files that need to be managed, store the password in clear text and need file permissions to be set such that only those that need access to them have it. If file permissions are set inappropriately the password to access the keystores is available in clear text. | Yes | Yes | Yes |
기본 비밀번호를 사용한다는 것은 런타임 소비자에게 추가 통신/동기화를 할 필요가 없다는 뜻입니다. 기본 비밀번호는 알려져 있지만 파일 권한이 키스토어의 일차 보호입니다.
파일 권한이 무력화될 때, "side file"과 달리 보호된 자격 증명을 노출할 수 있는 표준 도구가 없습니다. 비밀번호를 알더라도 마찬가지입니다. Keytool은 6자 이상의 비밀번호를 요구하며 키스토어에서 일반 비밀을 검색하는 방법을 모릅니다. 또한 PKI 키쌍으로 제한됩니다. 편집기는 키스토어에 저장된 비밀을 드러내지 않으며, cat, more 또는 다른 표준 도구도 마찬가지입니다. 이것이 키스토어 제공자가 자격 증명의 "side file" 저장보다 나은 이유입니다.
그렇긴 하지만, 누군가가 API를 사용해 키스토어 기반 자격 증명 제공자 내에 저장된 자격 증명에 접근하는 코드를 작성하는 것은 사소한 일입니다. 다시 말해 기본 비밀번호를 사용할 때 비밀번호는 키스토어 지속성의 형식일 뿐입니다. 유일한 보호는 파일 권한과 OS 레벨 접근 정책입니다.
사용자는 비밀번호 "side file"을 사용해 키스토어 자체의 비밀번호를 저장하기로 결정할 수 있으며, 이는 지원됩니다. 이 수준의 정확성을 위한 메커니즘을 인지하는 것이 정말 중요합니다.
평문으로의 폴백 비활성화
Credentials.getPassword() 연산은 자격 증명 제공자가 없거나 키를 찾을 수 없으면 설정 XML 파일의 항목 사용으로 폴백합니다.
이 동작은 설정 옵션 hadoop.security.credential.clear-text-fallback을 true에서 false로 변경해 비활성화할 수 있습니다:
<property>
<name>hadoop.security.credential.clear-text-fallback</name>
<value>false</value>
<description>
true or false to indicate whether or not to fall back to storing credential
password as clear text. The default value is true. This property only works
when the password can't not be found from credential providers.
</description>
</property>
설정되면 getPassword() API를 통해 조회되는 모든 설정 옵션은 자격 증명 제공자를 통해 제공되어야 합니다.