3.2. S3 API를 사용하여 Ceph 오브젝트 게이트웨이 액세스


개발자는 Amazon S3 API를 사용하기 전에 Ceph Object Gateway 및 STS(Secure Token Service)에 대한 액세스를 구성해야 합니다.

사전 요구 사항

  • 실행 중인 Red Hat Ceph Storage 클러스터.
  • 실행 중인 Ceph 오브젝트 게이트웨이.
  • RESTful 클라이언트입니다.

3.2.1. S3 인증

Ceph Object Gateway에 대한 요청은 인증하거나 인증되지 않은 것일 수 있습니다. Ceph Object Gateway는 인증되지 않은 요청이 익명 사용자가 전송하는 것으로 가정합니다. Ceph Object Gateway에서는 카나리아 ACL을 지원합니다.

대부분의 사용 사례에서 클라이언트는 Amazon SDK의 AmazonS3Client for Java 및 Python Boto와 같은 기존 오픈 소스 라이브러리를 사용합니다. 오픈 소스 라이브러리를 사용하면 액세스 키와 시크릿 키를 간단히 전달하고 라이브러리가 요청 헤더 및 인증 서명을 빌드합니다. 그러나 요청을 작성하고 서명할 수도 있습니다.

요청을 인증하려면 요청에 액세스 키와 기본 64로 인코딩된 해시 기반 메시지 인증 코드(HMAC)를 Ceph Object Gateway 서버로 전송해야 합니다. Ceph Object Gateway는 S3 호환 인증 방법을 사용합니다.

예제

HTTP/1.1
PUT /buckets/bucket/object.mpeg
Host: cname.domain.com
Date: Mon, 2 Jan 2012 00:01:01 +0000
Content-Encoding: mpeg
Content-Length: 9999999

Authorization: AWS ACCESS_KEY:HASH_OF_HEADER_AND_SECRET

위의 예에서 ACCESS_KEY 를 액세스 키 ID 다음에 콜론(:)의 값으로 바꿉니다. HASH_OF_HEADER_AND_SECRET 을 표준 헤더 문자열의 해시 및 액세스 키 ID에 해당하는 시크릿으로 바꿉니다.

헤더 문자열 및 시크릿의 해시 생성

헤더 문자열 및 시크릿의 해시를 생성하려면 다음을 수행합니다.

  1. 헤더 문자열의 값을 가져옵니다.
  2. 요청 헤더 문자열을 표준 형식으로 정규화합니다.
  3. SHA-1 해시 알고리즘을 사용하여 HMAC를 생성합니다.
  4. hmac 결과를 base-64로 인코딩합니다.

Normalize 헤더

헤더를 표준 형식으로 정규화하려면 다음을 수행합니다.

  1. 모든 콘텐츠 헤더를 가져옵니다.
  2. content- typecontent-md5 를 제외한 모든 콘텐츠 헤더를 제거합니다.
  3. content- 헤더 이름이 소문자인지 확인합니다.
  4. 콘텐츠 헤더를 사전 순으로 정렬합니다.
  5. Date 헤더가 있고 지정된 날짜가 오프셋이 아닌 GMT를 사용하는지 확인합니다.
  6. 모든 헤더를 x-amz- 로 시작합니다.
  7. x-amz- 헤더가 모두 소문자인지 확인합니다.
  8. X -amz- 헤더를 사전 순으로 정렬합니다.
  9. 동일한 필드 이름의 여러 인스턴스를 단일 필드에 결합하고 필드 값을 쉼표로 구분합니다.
  10. 헤더 값의 공백과 줄 바꿈을 단일 공백으로 바꿉니다.
  11. 콜론 전후에 공백을 제거합니다.
  12. 각 헤더 뒤에 새 행을 추가합니다.
  13. 헤더를 요청 헤더에 다시 병합합니다.

HASH_OF_HEADER_AND_SECRET 을 base-64 인코딩 HMAC 문자열로 바꿉니다.

추가 리소스

3.2.2. S3-server-side 암호화

Ceph Object Gateway는 S3 애플리케이션 프로그래밍 인터페이스(API)에 대해 업로드된 오브젝트의 서버 측 암호화를 지원합니다. 서버 측 암호화는 S3 클라이언트에서 암호화되지 않은 형식으로 HTTP를 통해 데이터를 전송하고, Ceph Object Gateway는 해당 데이터를 Red Hat Ceph Storage 클러스터에 암호화된 형식으로 저장합니다.

참고

Red Hat은 S3 LO(static Large Object) 또는 DLO(Dynamic Large Object)의 S3 개체 암호화를 지원하지 않습니다.

중요

암호화를 사용하기 위해 클라이언트 요청은 SSL 연결을 통해 요청을 보냅니다. Ceph Object Gateway에서 SSL을 사용하지 않는 한 Red Hat은 클라이언트의 S3 암호화를 지원하지 않습니다. 그러나 테스트 목적으로 관리자는 ceph config set client.rgw 명령을 사용하여 rgw_crypt_require_ssl 구성 설정을 false 로 설정하고 Ceph Object Gateway 인스턴스를 다시 시작하여 테스트 중에 SSL을 비활성화할 수 있습니다.

프로덕션 환경에서는 SSL을 통해 암호화된 요청을 보낼 수 없습니다. 이러한 경우 서버 측 암호화가 있는 HTTP를 사용하여 요청을 보냅니다.

서버 측 암호화를 사용하여 HTTP를 구성하는 방법에 대한 자세한 내용은 아래의 추가 리소스 섹션을 참조하십시오.

암호화 키 관리를 위한 두 가지 옵션이 있습니다.

고객 제공 키

고객 제공 키를 사용하는 경우 S3 클라이언트는 암호화 키를 각 요청과 함께 암호화된 데이터를 읽거나 씁니다. 이러한 키를 관리하는 것은 고객의 책임입니다. 고객은 각 오브젝트를 암호화하는 데 사용되는 Ceph Object Gateway의 키를 알고 있어야 합니다.

Ceph Object Gateway는 Amazon SSE-C 사양에 따라 S3 API에서 고객 제공 키 동작을 구현합니다.

고객은 키 관리를 처리하고 S3 클라이언트가 키를 Ceph Object Gateway에 전달하므로 Ceph Object Gateway에서 이 암호화 모드를 지원하기 위한 특별한 구성이 필요하지 않습니다.

키 관리 서비스

키 관리 서비스를 사용하는 경우 보안 키 관리 서비스는 키를 저장하고 Ceph Object Gateway는 필요에 따라 키를 검색하여 데이터를 암호화하거나 암호 해독하는 요청을 제공합니다.

Ceph Object Gateway는 Amazon SSE-KMS 사양에 따라 S3 API에서 키 관리 서비스 동작을 구현합니다.

중요

현재 테스트된 유일한 키 관리 구현은 HashiCorp Vault 및 OpenStack Barbican입니다. 그러나 OpenStack Barbican은 기술 프리뷰이며 프로덕션 시스템에서 사용할 수 없습니다.

3.2.3. S3 액세스 제어 목록

Ceph Object Gateway는 S3 호환 ACL(액세스 제어 목록) 기능을 지원합니다. ACL은 사용자가 버킷 또는 오브젝트에서 수행할 수 있는 작업을 지정하는 액세스 권한 부여 목록입니다. 각 부여는 버킷에 적용할 때 오브젝트에 적용할 때 다른 의미가 있습니다.

표 3.1. 사용자 작업
권한bucket개체

READ

부여자는 버킷의 오브젝트를 나열할 수 있습니다.

권한 부여자는 오브젝트를 읽을 수 있습니다.

WRITE

부여자는 버킷의 오브젝트를 작성하거나 삭제할 수 있습니다.

해당 없음

READ_ACP

grantee는 버킷 ACL을 읽을 수 있습니다.

권한 부여자는 오브젝트 ACL을 읽을 수 있습니다.

WRITE_ACP

grantee는 버킷 ACL을 작성할 수 있습니다.

grantee는 오브젝트 ACL에 쓸 수 있습니다.

FULL_CONTROL

부여자는 버킷에 있는 오브젝트에 대한 전체 권한이 있습니다.

권한 부여자는 오브젝트 ACL을 읽거나 쓸 수 있습니다.

3.2.4. S3를 사용하여 Ceph Object Gateway에 대한 액세스 준비

게이트웨이 서버에 액세스하기 전에 Ceph Object Gateway 노드에서 몇 가지 사전 요구 사항을 따라야 합니다.

사전 요구 사항

  • Ceph Object Gateway 소프트웨어 설치
  • Ceph Object Gateway 노드에 대한 루트 수준 액세스.

절차

  1. root 로 방화벽에서 포트 8080 을 엽니다.

    [root@rgw ~]# firewall-cmd --zone=public --add-port=8080/tcp --permanent
    [root@rgw ~]# firewall-cmd --reload
  2. 오브젝트 게이트웨이 구성 및 관리 가이드에서 언급한 대로 게이트웨이에 사용 중인 DNS 서버에 와일드카드를 추가합니다.

    로컬 DNS 캐싱을 위해 게이트웨이 노드를 설정할 수도 있습니다. 이를 수행하려면 다음 단계를 실행합니다.

    1. 루트 로서 dnsmasq 를 설치하고 설정합니다.

      [root@rgw ~]# yum install dnsmasq
      [root@rgw ~]# echo "address=/.FQDN_OF_GATEWAY_NODE/IP_OF_GATEWAY_NODE" | tee --append /etc/dnsmasq.conf
      [root@rgw ~]# systemctl start dnsmasq
      [root@rgw ~]# systemctl enable dnsmasq

      IP_OF_GATEWAY_NODEFQDN_OF_GATEWAY_NODE 를 게이트웨이 노드의 IP 주소 및 FQDN으로 바꿉니다.

    2. 루트 로서 NetworkManager를 중지합니다.

      [root@rgw ~]# systemctl stop NetworkManager
      [root@rgw ~]# systemctl disable NetworkManager
    3. root 로 게이트웨이 서버의 IP를 네임서버로 설정합니다.

      [root@rgw ~]# echo "DNS1=IP_OF_GATEWAY_NODE" | tee --append /etc/sysconfig/network-scripts/ifcfg-eth0
      [root@rgw ~]# echo "IP_OF_GATEWAY_NODE FQDN_OF_GATEWAY_NODE" | tee --append /etc/hosts
      [root@rgw ~]# systemctl restart network
      [root@rgw ~]# systemctl enable network
      [root@rgw ~]# systemctl restart dnsmasq

      IP_OF_GATEWAY_NODEFQDN_OF_GATEWAY_NODE 를 게이트웨이 노드의 IP 주소 및 FQDN으로 바꿉니다.

    4. 하위 도메인 요청을 확인합니다.

      [user@rgw ~]$ ping mybucket.FQDN_OF_GATEWAY_NODE

      FQDN_OF_GATEWAY_NODE 를 게이트웨이 노드의 FQDN으로 바꿉니다.

      주의

      로컬 DNS 캐싱을 위해 게이트웨이 서버를 설정하는 것은 테스트 목적으로만 사용됩니다. 이 작업을 수행한 후에는 외부 네트워크에 액세스할 수 없습니다. Red Hat Ceph Storage 클러스터 및 게이트웨이 노드에 적절한 DNS 서버를 사용하는 것이 좋습니다.

  3. Object Gateway Configuration and Administration Guide 에서 언급한 대로 S3 액세스를 위해 radosgw 사용자를 신중하게 생성하고 생성된 access_keysecret_key 를 복사합니다. S3 액세스 및 후속 버킷 관리 작업을 위해서는 이러한 키가 필요합니다.

3.2.5. Ruby AWS S3를 사용하여 Ceph Object Gateway에 액세스

Ruby 프로그래밍 언어를 S3 액세스를 위해 aws-s3 gem과 함께 사용할 수 있습니다. Ruby AWS::S3 을 사용하여 Ceph Object Gateway 서버에 액세스하는 데 사용되는 노드에서 아래 단계를 실행합니다.

사전 요구 사항

  • Ceph 오브젝트 게이트웨이에 대한 사용자 수준 액세스.
  • Ceph Object Gateway에 액세스하는 노드에 대한 루트 수준 액세스.
  • 인터넷 접속.

절차

  1. ruby 패키지를 설치합니다.

    [root@dev ~]# yum install ruby
    참고

    위의 명령은 rubyruby-libs같은 필수 종속 항목을 설치합니다. 명령이 모든 종속 항목을 설치하지 않는 경우 별도로 설치합니다.

  2. aws-s3 Ruby 패키지를 설치합니다.

    [root@dev ~]# gem install aws-s3
  3. 프로젝트 디렉터리를 생성합니다.

    [user@dev ~]$ mkdir ruby_aws_s3
    [user@dev ~]$ cd ruby_aws_s3
  4. 연결 파일을 만듭니다.

    [user@dev ~]$ vim conn.rb
  5. 다음 콘텐츠를 conn.rb 파일에 붙여넣습니다.

    구문

    #!/usr/bin/env ruby
    
    require 'aws/s3'
    require 'resolv-replace'
    
    AWS::S3::Base.establish_connection!(
            :server            => 'FQDN_OF_GATEWAY_NODE',
            :port           => '8080',
            :access_key_id     => 'MY_ACCESS_KEY',
            :secret_access_key => 'MY_SECRET_KEY'
    )

    FQDN_OF_GATEWAY_NODE 를 Ceph Object Gateway 노드의 FQDN으로 바꿉니다. MY_ACCESS_KEYMY_SECRET_KEYRed Hat Ceph Storage 오브젝트 게이트웨이 구성 및 관리 가이드에서 언급한 대로 S3 액세스를 위해 radosgw 사용자를 생성할 때 생성된 access_key secret_key 로 바꿉니다.

    예제

    #!/usr/bin/env ruby
    
    require 'aws/s3'
    require 'resolv-replace'
    
    AWS::S3::Base.establish_connection!(
            :server            => 'testclient.englab.pnq.redhat.com',
            :port           => '8080',
            :access_key_id     => '98J4R9P22P5CDL65HKP8',
            :secret_access_key => '6C+jcaP0dp0+FZfrRNgyGA9EzRy25pURldwje049'
    )

    파일을 저장하고 편집기를 종료합니다.

  6. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x conn.rb
  7. 파일을 실행합니다.

    [user@dev ~]$ ./conn.rb | echo $?

    파일에 값을 올바르게 제공하면 명령의 출력은 0 입니다.

  8. 버킷을 생성하기 위한 새 파일을 생성합니다.

    [user@dev ~]$ vim create_bucket.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    AWS::S3::Bucket.create('my-new-bucket1')

    파일을 저장하고 편집기를 종료합니다.

  9. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x create_bucket.rb
  10. 파일을 실행합니다.

    [user@dev ~]$ ./create_bucket.rb

    명령 출력이 true 이면 버킷 my-new-bucket1 이 성공적으로 생성되었습니다.

  11. 소유된 버킷을 나열할 새 파일을 생성합니다.

    [user@dev ~]$ vim list_owned_buckets.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    AWS::S3::Service.buckets.each do |bucket|
            puts "{bucket.name}\t{bucket.creation_date}"
    end

    파일을 저장하고 편집기를 종료합니다.

  12. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x list_owned_buckets.rb
  13. 파일을 실행합니다.

    [user@dev ~]$ ./list_owned_buckets.rb

    출력은 다음과 같아야 합니다.

    my-new-bucket1 2020-01-21 10:33:19 UTC
  14. 오브젝트를 생성할 새 파일을 생성합니다.

    [user@dev ~]$ vim create_object.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    AWS::S3::S3Object.store(
            'hello.txt',
            'Hello World!',
            'my-new-bucket1',
            :content_type => 'text/plain'
    )

    파일을 저장하고 편집기를 종료합니다.

  15. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x create_object.rb
  16. 파일을 실행합니다.

    [user@dev ~]$ ./create_object.rb

    Hello World! 라는 문자열이 포함된 hello.txt 파일이 생성됩니다.

  17. 버킷의 콘텐츠를 나열할 새 파일을 생성합니다.

    [user@dev ~]$ vim list_bucket_content.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    new_bucket = AWS::S3::Bucket.find('my-new-bucket1')
    new_bucket.each do |object|
            puts "{object.key}\t{object.about['content-length']}\t{object.about['last-modified']}"
    end

    파일을 저장하고 편집기를 종료합니다.

  18. 파일을 실행 가능하게 만듭니다.

    [user@dev ~]$ chmod +x list_bucket_content.rb
  19. 파일을 실행합니다.

    [user@dev ~]$ ./list_bucket_content.rb

    출력은 다음과 같습니다.

    hello.txt    12    Fri, 22 Jan 2020 15:54:52 GMT
  20. 빈 버킷을 삭제하기 위한 새 파일을 생성합니다.

    [user@dev ~]$ vim del_empty_bucket.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    AWS::S3::Bucket.delete('my-new-bucket1')

    파일을 저장하고 편집기를 종료합니다.

  21. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x del_empty_bucket.rb
  22. 파일을 실행합니다.

    [user@dev ~]$ ./del_empty_bucket.rb | echo $?

    버킷이 성공적으로 삭제되면 명령에서 0 을 출력으로 반환합니다.

    참고

    create_bucket.rb 파일을 편집하여 빈 버킷을 생성합니다(예: my-new-bucket4,my-new-bucket5 ). 다음으로 빈 버킷을 삭제하기 전에 위에서 언급한 del_empty_bucket.rb 파일을 편집합니다.

  23. 비어 있지 않은 버킷을 삭제하는 새 파일을 생성합니다.

    [user@dev ~]$ vim del_non_empty_bucket.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    AWS::S3::Bucket.delete('my-new-bucket1', :force => true)

    파일을 저장하고 편집기를 종료합니다.

  24. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x del_non_empty_bucket.rb
  25. 파일을 실행합니다.

    [user@dev ~]$ ./del_non_empty_bucket.rb | echo $?

    버킷이 성공적으로 삭제되면 명령에서 0 을 출력으로 반환합니다.

  26. 오브젝트를 삭제할 새 파일을 생성합니다.

    [user@dev ~]$ vim delete_object.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    AWS::S3::S3Object.delete('hello.txt', 'my-new-bucket1')

    파일을 저장하고 편집기를 종료합니다.

  27. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x delete_object.rb
  28. 파일을 실행합니다.

    [user@dev ~]$ ./delete_object.rb

    그러면 hello.txt 오브젝트가 삭제됩니다.

3.2.6. Ruby AWS SDK를 사용하여 Ceph Object Gateway에 액세스

Ruby 프로그래밍 언어와 함께 aws-sdk gem을 S3 액세스를 위해 사용할 수 있습니다. Ruby AWS::SDK 를 사용하여 Ceph Object Gateway 서버에 액세스하는 데 사용되는 노드에서 아래 단계를 실행합니다.

사전 요구 사항

  • Ceph 오브젝트 게이트웨이에 대한 사용자 수준 액세스.
  • Ceph Object Gateway에 액세스하는 노드에 대한 루트 수준 액세스.
  • 인터넷 접속.

절차

  1. ruby 패키지를 설치합니다.

    [root@dev ~]# yum install ruby
    참고

    위의 명령은 rubyruby-libs같은 필수 종속 항목을 설치합니다. 명령이 모든 종속 항목을 설치하지 않는 경우 별도로 설치합니다.

  2. aws-sdk Ruby 패키지를 설치합니다.

    [root@dev ~]# gem install aws-sdk
  3. 프로젝트 디렉터리를 생성합니다.

    [user@dev ~]$ mkdir ruby_aws_sdk
    [user@dev ~]$ cd ruby_aws_sdk
  4. 연결 파일을 만듭니다.

    [user@dev ~]$ vim conn.rb
  5. 다음 콘텐츠를 conn.rb 파일에 붙여넣습니다.

    구문

    #!/usr/bin/env ruby
    
    require 'aws-sdk'
    require 'resolv-replace'
    
    Aws.config.update(
            endpoint: 'http://FQDN_OF_GATEWAY_NODE:8080',
            access_key_id: 'MY_ACCESS_KEY',
            secret_access_key: 'MY_SECRET_KEY',
            force_path_style: true,
            region: 'us-east-1'
    )

    FQDN_OF_GATEWAY_NODE 를 Ceph Object Gateway 노드의 FQDN으로 바꿉니다. MY_ACCESS_KEYMY_SECRET_KEYRed Hat Ceph Storage 오브젝트 게이트웨이 구성 및 관리 가이드에서 언급한 대로 S3 액세스를 위해 radosgw 사용자를 생성할 때 생성된 access_key secret_key 로 바꿉니다.

    예제

    #!/usr/bin/env ruby
    
    require 'aws-sdk'
    require 'resolv-replace'
    
    Aws.config.update(
            endpoint: 'http://testclient.englab.pnq.redhat.com:8080',
            access_key_id: '98J4R9P22P5CDL65HKP8',
            secret_access_key: '6C+jcaP0dp0+FZfrRNgyGA9EzRy25pURldwje049',
            force_path_style: true,
            region: 'us-east-1'
    )

    파일을 저장하고 편집기를 종료합니다.

  6. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x conn.rb
  7. 파일을 실행합니다.

    [user@dev ~]$ ./conn.rb | echo $?

    파일에 값을 올바르게 제공하면 명령의 출력은 0 입니다.

  8. 버킷을 생성하기 위한 새 파일을 생성합니다.

    [user@dev ~]$ vim create_bucket.rb

    다음 내용을 파일에 붙여넣습니다.

    구문

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    s3_client = Aws::S3::Client.new
    s3_client.create_bucket(bucket: 'my-new-bucket2')

    파일을 저장하고 편집기를 종료합니다.

  9. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x create_bucket.rb
  10. 파일을 실행합니다.

    [user@dev ~]$ ./create_bucket.rb

    명령 출력이 true 이면 버킷 my-new-bucket2 가 성공적으로 생성되었습니다.

  11. 소유된 버킷을 나열할 새 파일을 생성합니다.

    [user@dev ~]$ vim list_owned_buckets.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    s3_client = Aws::S3::Client.new
    s3_client.list_buckets.buckets.each do |bucket|
            puts "{bucket.name}\t{bucket.creation_date}"
    end

    파일을 저장하고 편집기를 종료합니다.

  12. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x list_owned_buckets.rb
  13. 파일을 실행합니다.

    [user@dev ~]$ ./list_owned_buckets.rb

    출력은 다음과 같아야 합니다.

    my-new-bucket2 2020-01-21 10:33:19 UTC
  14. 오브젝트를 생성할 새 파일을 생성합니다.

    [user@dev ~]$ vim create_object.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    s3_client = Aws::S3::Client.new
    s3_client.put_object(
            key: 'hello.txt',
            body: 'Hello World!',
            bucket: 'my-new-bucket2',
            content_type: 'text/plain'
    )

    파일을 저장하고 편집기를 종료합니다.

  15. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x create_object.rb
  16. 파일을 실행합니다.

    [user@dev ~]$ ./create_object.rb

    Hello World! 라는 문자열이 포함된 hello.txt 파일이 생성됩니다.

  17. 버킷의 콘텐츠를 나열할 새 파일을 생성합니다.

    [user@dev ~]$ vim list_bucket_content.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    s3_client = Aws::S3::Client.new
    s3_client.list_objects(bucket: 'my-new-bucket2').contents.each do |object|
            puts "{object.key}\t{object.size}"
    end

    파일을 저장하고 편집기를 종료합니다.

  18. 파일을 실행 가능하게 만듭니다.

    [user@dev ~]$ chmod +x list_bucket_content.rb
  19. 파일을 실행합니다.

    [user@dev ~]$ ./list_bucket_content.rb

    출력은 다음과 같습니다.

    hello.txt    12    Fri, 22 Jan 2020 15:54:52 GMT
  20. 빈 버킷을 삭제하기 위한 새 파일을 생성합니다.

    [user@dev ~]$ vim del_empty_bucket.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    s3_client = Aws::S3::Client.new
    s3_client.delete_bucket(bucket: 'my-new-bucket2')

    파일을 저장하고 편집기를 종료합니다.

  21. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x del_empty_bucket.rb
  22. 파일을 실행합니다.

    [user@dev ~]$ ./del_empty_bucket.rb | echo $?

    버킷이 성공적으로 삭제되면 명령에서 0 을 출력으로 반환합니다.

    참고

    create_bucket.rb 파일을 편집하여 빈 버킷을 생성합니다(예: my-new-bucket6,my-new-bucket7 ). 다음으로 빈 버킷을 삭제하기 전에 위에서 언급한 del_empty_bucket.rb 파일을 편집합니다.

  23. 비어 있지 않은 버킷을 삭제하기 위해 새 파일을 생성합니다.

    [user@dev ~]$ vim del_non_empty_bucket.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    s3_client = Aws::S3::Client.new
    Aws::S3::Bucket.new('my-new-bucket2', client: s3_client).clear!
    s3_client.delete_bucket(bucket: 'my-new-bucket2')

    파일을 저장하고 편집기를 종료합니다.

  24. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x del_non_empty_bucket.rb
  25. 파일을 실행합니다.

    [user@dev ~]$ ./del_non_empty_bucket.rb | echo $?

    버킷이 성공적으로 삭제되면 명령에서 0 을 출력으로 반환합니다.

  26. 오브젝트를 삭제할 새 파일을 생성합니다.

    [user@dev ~]$ vim delete_object.rb

    다음 내용을 파일에 붙여넣습니다.

    #!/usr/bin/env ruby
    
    load 'conn.rb'
    
    s3_client = Aws::S3::Client.new
    s3_client.delete_object(key: 'hello.txt', bucket: 'my-new-bucket2')

    파일을 저장하고 편집기를 종료합니다.

  27. 파일을 실행 가능으로 설정합니다.

    [user@dev ~]$ chmod +x delete_object.rb
  28. 파일을 실행합니다.

    [user@dev ~]$ ./delete_object.rb

    그러면 hello.txt 오브젝트가 삭제됩니다.

3.2.7. PHP를 사용하여 Ceph Object Gateway 액세스

S3 액세스를 위해 PHP 스크립트를 사용할 수 있습니다. 이 절차에서는 버킷 또는 오브젝트 삭제와 같은 다양한 작업을 수행하는 몇 가지 예제 PHP 스크립트를 제공합니다.

중요

아래 제공된 예제는 php v5.4.16aws-sdk v2.8.24 에서 테스트합니다.

사전 요구 사항

  • 개발 워크스테이션에 대한 루트 수준 액세스.
  • 인터넷 접속.

절차

  1. php 패키지를 설치합니다.

    [root@dev ~]# yum install php
  2. PHP용 aws-sdk 의 zip 아카이브를 다운로드하여 압축을 풉니다.
  3. 프로젝트 디렉터리를 생성합니다.

    [user@dev ~]$ mkdir php_s3
    [user@dev ~]$ cd php_s3
  4. 추출된 aws 디렉터리를 프로젝트 디렉터리에 복사합니다. 예를 들면 다음과 같습니다.

    [user@dev ~]$ cp -r ~/Downloads/aws/ ~/php_s3/
  5. 연결 파일을 만듭니다.

    [user@dev ~]$ vim conn.php
  6. conn.php 파일에 다음 내용을 붙여 넣습니다.

    구문

    <?php
    define('AWS_KEY', 'MY_ACCESS_KEY');
    define('AWS_SECRET_KEY', 'MY_SECRET_KEY');
    define('HOST', 'FQDN_OF_GATEWAY_NODE');
    define('PORT', '8080');
    
    // require the AWS SDK for php library
    require '/PATH_TO_AWS/aws-autoloader.php';
    
    use Aws\S3\S3Client;
    
    // Establish connection with host using S3 Client
    client = S3Client::factory(array(
        'base_url' => HOST,
        'port' => PORT,
        'key'      => AWS_KEY,
        'secret'   => AWS_SECRET_KEY
    ));
    ?>

    FQDN_OF_GATEWAY_NODE 를 게이트웨이 노드의 FQDN으로 바꿉니다. MY_ACCESS_KEYMY_SECRET_KEYRed Hat Ceph Storage 오브젝트 게이트웨이 구성 및 관리 가이드에서 언급한 대로 S3 액세스용 radosgw 사용자를 생성할 때 생성된 access_key secret_key 로 바꿉니다. PATH_TO_AWSphp 프로젝트 디렉터리에 복사한 추출된 aws 디렉터리의 절대 경로로 교체합니다.

    파일을 저장하고 편집기를 종료합니다.

  7. 파일을 실행합니다.

    [user@dev ~]$ php -f conn.php | echo $?

    파일에 값을 올바르게 제공하면 명령의 출력은 0 입니다.

  8. 버킷을 생성하기 위한 새 파일을 생성합니다.

    [user@dev ~]$ vim create_bucket.php

    다음 내용을 새 파일에 붙여넣습니다.

    구문

    <?php
    
    include 'conn.php';
    
    client->createBucket(array('Bucket' => 'my-new-bucket3'));
    
    ?>

    파일을 저장하고 편집기를 종료합니다.

  9. 파일을 실행합니다.

    [user@dev ~]$ php -f create_bucket.php
  10. 소유된 버킷을 나열할 새 파일을 생성합니다.

    [user@dev ~]$ vim list_owned_buckets.php

    다음 내용을 파일에 붙여넣습니다.

    구문

    <?php
    
    include 'conn.php';
    
    blist = client->listBuckets();
    echo "Buckets belonging to " . blist['Owner']['ID'] . ":\n";
    foreach (blist['Buckets'] as b) {
        echo "{b['Name']}\t{b['CreationDate']}\n";
    }
    
    ?>

    파일을 저장하고 편집기를 종료합니다.

  11. 파일을 실행합니다.

    [user@dev ~]$ php -f list_owned_buckets.php

    출력은 다음과 유사해야 합니다.

    my-new-bucket3 2020-01-21 10:33:19 UTC
  12. 먼저 hello.txt 라는 소스 파일을 만들어 오브젝트를 생성합니다.

    [user@dev ~]$ echo "Hello World!" > hello.txt
  13. 새 php 파일을 만듭니다.

    [user@dev ~]$ vim create_object.php

    다음 내용을 파일에 붙여넣습니다.

    구문

    <?php
    
    include 'conn.php';
    
    key         = 'hello.txt';
    source_file = './hello.txt';
    acl         = 'private';
    bucket      = 'my-new-bucket3';
    client->upload(bucket, key, fopen(source_file, 'r'), acl);
    
    ?>

    파일을 저장하고 편집기를 종료합니다.

  14. 파일을 실행합니다.

    [user@dev ~]$ php -f create_object.php

    이렇게 하면 my-new-bucket3 버킷에 hello.txt 오브젝트가 생성됩니다.

  15. 버킷의 콘텐츠를 나열할 새 파일을 생성합니다.

    [user@dev ~]$ vim list_bucket_content.php

    다음 내용을 파일에 붙여넣습니다.

    구문

    <?php
    
    include 'conn.php';
    
    o_iter = client->getIterator('ListObjects', array(
        'Bucket' => 'my-new-bucket3'
    ));
    foreach (o_iter as o) {
        echo "{o['Key']}\t{o['Size']}\t{o['LastModified']}\n";
    }
    ?>

    파일을 저장하고 편집기를 종료합니다.

  16. 파일을 실행합니다.

    [user@dev ~]$ php -f list_bucket_content.php

    출력은 다음과 유사합니다.

    hello.txt    12    Fri, 22 Jan 2020 15:54:52 GMT
  17. 빈 버킷을 삭제하기 위한 새 파일을 생성합니다.

    [user@dev ~]$ vim del_empty_bucket.php

    다음 내용을 파일에 붙여넣습니다.

    구문

    <?php
    
    include 'conn.php';
    
    client->deleteBucket(array('Bucket' => 'my-new-bucket3'));
    ?>

    파일을 저장하고 편집기를 종료합니다.

  18. 파일을 실행합니다.

    [user@dev ~]$ php -f del_empty_bucket.php | echo $?

    버킷이 성공적으로 삭제되면 명령에서 0 을 출력으로 반환합니다.

    참고

    create_bucket.php 파일을 편집하여 빈 버킷을 생성합니다(예: my-new-bucket4,my-new-bucket5 ). 다음으로 빈 버킷을 삭제하기 전에 위에서 언급한 del_empty_bucket.php 파일을 편집합니다.

    중요

    비어 있지 않은 버킷을 삭제하는 것은 현재 PHP 2 및 최신 버전의 aws-sdk 에서 지원되지 않습니다.

  19. 오브젝트를 삭제할 새 파일을 생성합니다.

    [user@dev ~]$ vim delete_object.php

    다음 내용을 파일에 붙여넣습니다.

    구문

    <?php
    
    include 'conn.php';
    
    client->deleteObject(array(
        'Bucket' => 'my-new-bucket3',
        'Key'    => 'hello.txt',
    ));
    ?>

    파일을 저장하고 편집기를 종료합니다.

  20. 파일을 실행합니다.

    [user@dev ~]$ php -f delete_object.php

    그러면 hello.txt 오브젝트가 삭제됩니다.

3.2.8. 보안 토큰 서비스

Amazon Web Services의 STS(Secure Token Service)는 사용자 인증을 위한 임시 보안 자격 증명 세트를 반환합니다.

Red Hat Ceph Storage Object Gateway는 IAM(Identity and Access Management)을 위한 Amazon STS API(애플리케이션 프로그래밍 인터페이스)의 하위 집합을 지원합니다.

사용자는 STS에 대해 먼저 인증하고 후속 요청에서 사용할 수 있는 수명이 짧은 S3 액세스 키 및 시크릿 키를 받습니다.

Red Hat Ceph Storage는 OIDC 공급자를 구성하여 Single Sign-On과 통합하여 S3 사용자를 인증할 수 있습니다. 이 기능을 사용하면 Object Storage 사용자가 로컬 Ceph Object Gateway 데이터베이스가 아닌 엔터프라이즈 ID 공급자에 대해 인증할 수 있습니다. 예를 들어 SSO가 백엔드의 엔터프라이즈 IDP에 연결된 경우 오브젝트 스토리지 사용자는 엔터프라이즈 자격 증명을 사용하여 Ceph Object Gateway S3 엔드포인트를 인증하고 액세스할 수 있습니다.

IAM 역할 정책 기능과 함께 STS를 사용하면 미세 조정된 권한 부여 정책을 생성하여 데이터에 대한 액세스를 제어할 수 있습니다. 이를 통해 개체 스토리지 데이터에 대한 RBAC(역할 기반 액세스 제어) 또는 ABAC( Attribute-Based Access Control) 권한 부여 모델을 구현할 수 있으므로 데이터에 액세스할 수 있는 사용자를 완전히 제어할 수 있습니다.

추가 리소스

3.2.8.1. Secure Token Service 애플리케이션 프로그래밍 인터페이스

Ceph Object Gateway는 다음과 같은 STS(Secure Token Service) API(애플리케이션 프로그래밍 인터페이스)를 구현합니다.

AssumeRole

이 API는 계정 간 액세스에 대한 임시 자격 증명 세트를 반환합니다. 이러한 임시 자격 증명을 사용하면 Assume Role API와 연결된 역할 및 정책과 연결된 권한 정책을 둘 다 사용할 수 있습니다. RoleArnRoleSessionName 요청 매개변수는 필수이지만 다른 요청 매개변수는 선택 사항입니다.

RoleArn
설명
길이가 20~ 2048자인 Amazon Resource Name(ARN)의 역할입니다.
유형
문자열
필수 항목
제공됨
RoleSessionName
설명
가정할 역할 세션 이름 식별. 역할 세션 이름은 다른 주체 또는 다른 이유로 인해 역할을 가정하는 경우 세션을 고유하게 식별할 수 있습니다. 이 매개변수의 값은 길이가 2~64자입니다. =, ,, .. . , @- 문자는 허용되지만 공백은 허용되지 않습니다.
유형
문자열
필수 항목
제공됨
정책
설명
인라인 세션에서 사용하기 위한 JSON 형식의 IAM(ID 및 액세스 관리 정책)입니다. 이 매개변수의 값은 길이가 1~ 2048자입니다.
유형
문자열
필수 항목
없음
DurationSeconds
설명
세션 지속 시간(초)이며 최소 값 900 초에서 최대 값 43200 초입니다. 기본값은 3600 초입니다.
유형
정수
필수 항목
없음
ExternalId
설명
다른 계정에 대한 역할을 가정할 때 사용 가능한 경우 고유한 외부 식별자를 제공합니다. 이 매개변수의 값은 길이가 2~1224자입니다.
유형
문자열
필수 항목
없음
serialnumber
설명
연결된 MFA(Multi-factor authentication) 장치의 사용자 식별 번호입니다. 매개 변수의 값은 하드웨어 장치 또는 가상 장치의 일련 번호이며 길이는 9에서 256자일 수 있습니다.
유형
문자열
필수 항목
없음
TokenCode
설명
신뢰 정책에 MFA가 필요한 경우 MFA(Multi-factor authentication) 장치에서 생성된 값입니다. MFA 장치가 필요하며 이 매개변수의 값이 비어 있거나 만료된 경우 AssumeRole 호출에서 "access denied" 오류 메시지를 반환합니다. 이 매개변수의 값은 고정된 길이가 6자입니다.
유형
문자열
필수 항목
없음

AssumeRoleWithWebIdentity

이 API는 애플리케이션에서 인증한 사용자(예: OpenID Connect 또는 OAuth 2.0 ID 공급자)에 대한 임시 자격 증명 세트를 반환합니다. RoleArnRoleSessionName 요청 매개변수는 필수이지만 다른 요청 매개변수는 선택 사항입니다.

RoleArn
설명
길이가 20~ 2048자인 Amazon Resource Name(ARN)의 역할입니다.
유형
문자열
필수 항목
제공됨
RoleSessionName
설명
가정할 역할 세션 이름 식별. 역할 세션 이름은 다른 주체 또는 다른 이유로 인해 역할을 가정하는 경우 세션을 고유하게 식별할 수 있습니다. 이 매개변수의 값은 길이가 2~64자입니다. =, ,, .. . , @- 문자는 허용되지만 공백은 허용되지 않습니다.
유형
문자열
필수 항목
제공됨
정책
설명
인라인 세션에서 사용하기 위한 JSON 형식의 IAM(ID 및 액세스 관리 정책)입니다. 이 매개변수의 값은 길이가 1~ 2048자입니다.
유형
문자열
필수 항목
없음
DurationSeconds
설명
세션 지속 시간(초)이며 최소 값 900 초에서 최대 값 43200 초입니다. 기본값은 3600 초입니다.
유형
정수
필수 항목
없음
ProviderId
설명
ID 공급자의 도메인 이름의 정규화된 호스트 구성 요소입니다. 이 매개변수 값은 OAuth 2.0 액세스 토큰에만 유효하며 길이는 4~ 2048자입니다.
유형
문자열
필수 항목
없음
WebIdentityToken
설명
ID 공급자에서 제공하는 OpenID Connect ID 토큰 또는 OAuth 2.0 액세스 토큰입니다. 이 매개변수의 값은 길이가 4~ 2048자입니다.
유형
문자열
필수 항목
없음

추가 리소스

3.2.8.2. 보안 토큰 서비스 구성

rgw_sts_key, rgw_s3_auth_use_sts 옵션을 설정하여 Ceph Object Gateway와 함께 사용할 STS(Secure Token Service)를 구성합니다.

참고

S3 및 STS API는 동일한 네임스페이스에 공존하고 둘 다 Ceph Object Gateway의 동일한 끝점에서 액세스할 수 있습니다.

사전 요구 사항

  • 실행 중인 Red Hat Ceph Storage 클러스터.
  • 실행 중인 Ceph 오브젝트 게이트웨이.
  • Ceph Manager 노드에 대한 루트 수준 액세스.

절차

  1. Ceph Object Gateway 클라이언트에 대해 다음 구성 옵션을 설정합니다.

    구문

    ceph config set RGW_CLIENT_NAME rgw_sts_key STS_KEY
    ceph config set RGW_CLIENT_NAME rgw_s3_auth_use_sts true

    rgw_sts_key 는 세션 토큰을 암호화하거나 해독하는 데 사용되는 STS 키이며 정확히 16진수 문자입니다.

    중요

    STS 키는 영숫자여야 합니다.

    예제

    [root@mgr ~]# ceph config set client.rgw rgw_sts_key 7f8fd8dd4700mnop
    [root@mgr ~]# ceph config set client.rgw rgw_s3_auth_use_sts true

  2. 추가된 키를 적용하려면 Ceph Object Gateway를 다시 시작합니다.

    참고

    NAME 열에 있는 ceph orch ps 명령의 출력을 사용하여 SERVICE_TYPE.ID 정보를 가져옵니다.

    1. 스토리지 클러스터의 개별 노드에서 Ceph Object Gateway를 다시 시작하려면 다음을 수행합니다.

      구문

      systemctl restart ceph-CLUSTER_ID@SERVICE_TYPE.ID.service

      예제

      [root@host01 ~]# systemctl restart ceph-c4b34c6f-8365-11ba-dc31-529020a7702d@rgw.realm.zone.host01.gwasto.service

    2. 스토리지 클러스터의 모든 노드에서 Ceph Object Gateway를 다시 시작하려면 다음을 수행합니다.

      구문

      ceph orch restart SERVICE_TYPE

      예제

      [ceph: root@host01 /]# ceph orch restart rgw

추가 리소스

3.2.8.3. OpenID Connect 공급자의 사용자 생성

Ceph Object Gateway와 OpenID Connect Provider 간의 신뢰를 구축하기 위해 사용자 엔티티와 역할 신뢰 정책을 생성합니다.

사전 요구 사항

  • Ceph Object Gateway 노드에 대한 사용자 수준 액세스.
  • 보안 토큰 서비스가 구성되어 있습니다.

절차

  1. 새 Ceph 사용자를 생성합니다.

    구문

    radosgw-admin --uid USER_NAME --display-name "DISPLAY_NAME" --access_key USER_NAME --secret SECRET user create

    예제

    [user@rgw ~]$ radosgw-admin --uid TESTER --display-name "TestUser" --access_key TESTER --secret test123 user create

  2. Ceph 사용자 기능을 구성합니다.

    구문

    radosgw-admin caps add --uid="USER_NAME" --caps="oidc-provider=*"

    예제

    [user@rgw ~]$ radosgw-admin caps add --uid="TESTER" --caps="oidc-provider=*"

  3. STS(Secure Token Service) API를 사용하여 역할 신뢰 정책에 조건을 추가합니다.

    구문

    "{\"Version\":\"2020-01-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Federated\":[\"arn:aws:iam:::oidc-provider/IDP_URL\"]},\"Action\":[\"sts:AssumeRoleWithWebIdentity\"],\"Condition\":{\"StringEquals\":{\"IDP_URL:app_id\":\"AUD_FIELD\"\}\}\}\]\}"

    중요

    위의 구문 예제의 app_id 는 들어오는 토큰의 AUD_FIELD 필드와 일치해야 합니다.

추가 리소스

3.2.8.4. OpenID Connect 공급자의 지문 가져오기

OpenID Connect 공급자의 (IDP) 구성 문서를 가져옵니다.

OIDC 프로토콜 표준을 따르는 모든 SSO는 Ceph Object Gateway에서 작동할 것으로 예상됩니다. Red Hat은 다음 SSO 공급자에서 테스트했습니다.

  • Red Hat Single Sing-on
  • Keycloak

사전 요구 사항

  • opensslcurl 패키지 설치

절차

  1. IDP URL에서 구성 문서를 가져옵니다.

    구문

    curl -k -v \
         -X GET \
         -H "Content-Type: application/x-www-form-urlencoded" \
         "IDP_URL:8000/CONTEXT/realms/REALM/.well-known/openid-configuration" \
       | jq .

    예제

    [user@client ~]$ curl -k -v \
         -X GET \
         -H "Content-Type: application/x-www-form-urlencoded" \
         "http://www.example.com:8000/auth/realms/quickstart/.well-known/openid-configuration" \
       | jq .

  2. IDP 인증서를 가져옵니다.

    구문

    curl -k -v \
         -X GET \
         -H "Content-Type: application/x-www-form-urlencoded" \
         "IDP_URL/CONTEXT/realms/REALM/protocol/openid-connect/certs" \
         | jq .

    예제

    [user@client ~]$ curl -k -v \
         -X GET \
         -H "Content-Type: application/x-www-form-urlencoded" \
         "http://www.example.com/auth/realms/quickstart/protocol/openid-connect/certs" \
         | jq .

    참고

    x5c 인증서는 SSO 공급자에 따라 /certs 경로 또는 /jwks 경로에서 사용할 수 있습니다.

  3. 이전 명령의 "x5c" 응답 결과를 복사하여 certificate.crt 파일에 붙여넣습니다. 시작 부분에 --BEGINECDHERTIFICATE-- 를 포함하고 끝에 --ENDECDHERTIFICATE-- 를 포함합니다.

    예제

    -----BEGIN CERTIFICATE-----
    
    MIIDYjCCAkqgAwIBAgIEEEd2CDANBgkqhkiG9w0BAQsFADBzMQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkwBwYDVQQKEwAxCTAHBgNVBAsTADE6MDgGA1UEAxMxYXV0aHN2Yy1pbmxpbmVtZmEuZGV2LnZlcmlmeS5pYm1jbG91ZHNlY3VyaXR5LmNvbTAeFw0yMTA3MDUxMzU2MzZaFw0zMTA3MDMxMzU2MzZaMHMxCTAHBgNVBAYTADEJMAcGA1UECBMAMQkwBwYDVQQHEwAxCTAHBgNVBAoTADEJMAcGA1UECxMAMTowOAYDVQQDEzFhdXRoc3ZjLWlubGluZW1mYS5kZXYudmVyaWZ5LmlibWNsb3Vkc2VjdXJpdHkuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAphyu3HaAZ14JH/EXetZxtNnerNuqcnfxcmLhBz9SsTlFD59ta+BOVlRnK5SdYEqO3ws2iGEzTvC55rczF+hDVHFZEBJLVLQe8ABmi22RAtG1P0dA/Bq8ReFxpOFVWJUBc31QM+ummW0T4yw44wQJI51LZTMz7PznB0ScpObxKe+frFKd1TCMXPlWOSzmTeFYKzR83Fg9hsnz7Y8SKGxi+RoBbTLT+ektfWpR7O+oWZIf4INe1VYJRxZvn+qWcwI5uMRCtQkiMknc3Rj6Eupiqq6FlAjDs0p//EzsHAlW244jMYnHCGq0UP3oE7vViLJyiOmZw7J3rvs3m9mOQiPLoQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCeVqAzSh7Tp8LgaTIFUuRbdjBAKXC9Nw3+pRBHoiUTdhqO3ualyGih9m/js/clb8Vq/39zl0VPeaslWl2NNX9zaK7xo+ckVIOY3ucCaTC04ZUn1KzZu/7azlN0C5XSWg/CfXgU2P3BeMNzc1UNY1BASGyWn2lEplIVWKLaDZpNdSyyGyaoQAIBdzxeNCyzDfPCa2oSO8WH1czmFiNPqR5kdknHI96CmsQdi+DT4jwzVsYgrLfcHXmiWyIAb883hR3Pobp+Bsw7LUnxebQ5ewccjYmrJzOk5Wb5FpXBhaJH1B3AEd6RGalRUyc/zUKdvEy0nIRMDS9x2BP3NVvZSADD
    
    -----END CERTIFICATE-----

  4. 인증서 지문을 가져옵니다.

    구문

    openssl x509 -in CERT_FILE -fingerprint -noout

    예제

    [user@client ~]$ openssl x509 -in certificate.crt -fingerprint -noout
    SHA1 Fingerprint=F7:D7:B3:51:5D:D0:D3:19:DD:21:9A:43:A9:EA:72:7A:D6:06:52:87

  5. SHA1 지문에서 모든 콜론을 제거하고 이를 IAM 요청에 IDP 엔티티를 생성하기 위한 입력으로 사용합니다.

추가 리소스

3.2.8.5. OpenID Connect 공급자 등록

OpenID Connect 공급자의 (IDP) 구성 문서를 등록합니다.

사전 요구 사항

  • opensslcurl 패키지 설치
  • 보안 토큰 서비스가 구성되어 있습니다.
  • OIDC 공급자용으로 생성된 사용자입니다.
  • OIDC의 지문을 가져옵니다.

절차

  1. 토큰에서 URL을 추출합니다.

    예제

    [root@host01 ~]# bash check_token_isv.sh | jq .iss
    
    "https://keycloak-sso.apps.ocp.example.com/auth/realms/ceph"

  2. Ceph Object Gateway에 OIDC 공급자를 등록합니다.

    예제

    [root@host01 ~]# aws --endpoint https://cephproxy1.example.com:8443 iam create-open-id-connect-provider --url https://keycloak-sso.apps.ocp.example.com/auth/realms/ceph --thumbprint-list 00E9CFD697E0B16DD13C86B0FFDC29957E5D24DF

  3. OIDC 공급자가 Ceph Object Gateway에 추가되었는지 확인합니다.

    예제

    [root@host01 ~]# aws --endpoint https://cephproxy1.example.com:8443 iam
    list-open-id-connect-providers
    
    {
     "OpenIDConnectProviderList": [
     {
     "Arn":
    "arn:aws:iam:::oidc-provider/keycloak-sso.apps.ocp.example.com/auth/realms/ceph"
     }
     ]
    }

3.2.8.6. IAM 역할 및 정책 생성

IAM 역할 및 정책을 생성합니다.

사전 요구 사항

  • opensslcurl 패키지 설치
  • 보안 토큰 서비스가 구성되어 있습니다.
  • OIDC 공급자용으로 생성된 사용자입니다.
  • OIDC의 지문을 가져옵니다.
  • Ceph Object Gateway의 OIDC 공급자가 등록되었습니다.

절차

  1. JWT 토큰을 검색하고 검증합니다.

    예제

    [root@host01 ~]# curl -k -q -L -X POST
    "https://keycloak-sso.apps.example.com/auth/realms/ceph/protocol/openid-connect/
    token" \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'client_id=ceph' \
    --data-urlencode 'grant_type=password' \
    --data-urlencode 'client_secret=XXXXXXXXXXXXXXXXXXXXXXX' \
    --data-urlencode 'scope=openid' \
    --data-urlencode "username=SSOUSERNAME" \
    --data-urlencode "password=SSOPASSWORD"

  2. 토큰을 확인합니다.

    예제

    [root@host01 ~]# cat check_token.sh
    USERNAME=$1
    PASSWORD=$2
    KC_CLIENT="ceph"
    KC_CLIENT_SECRET="7sQXqyMSzHIeMcSALoKaljB6sNIBDRjU"
    KC_ACCESS_TOKEN="$(./get_web_token.sh $USERNAME $PASSWORD | jq -r '.access_token')"
    KC_SERVER="https://keycloak-sso.apps.ocp.stg.local"
    KC_CONTEXT="auth"
    KC_REALM="ceph"
    curl -k -s -q \
    -X POST \
    -u "$KC_CLIENT:$KC_CLIENT_SECRET" \
    -d "token=$KC_ACCESS_TOKEN" \
    "$KC_SERVER/$KC_CONTEXT/realms/$KC_REALM/protocol/openid-connect/token/introspect" | jq .
    
    
    [root@host01 ~]# ./check_token.sh s3admin passw0rd | jq .sub
    "ceph"

    이 예에서 jq 필터는 토큰의 하위 필드에서 사용하며 ceph 로 설정됩니다.

  3. 역할 속성을 사용하여 JSON 파일을 생성합니다. Statement허용 으로 설정하고 ActionAssumeRoleWithWebIdentity 로 설정합니다. sub:ceph 와 조건을 일치하는 JWT 토큰을 사용하여 모든 사용자에게 액세스를 허용합니다.

    예제

    [root@host01 ~]# cat role-rgwadmins.json
    {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Federated": [
             "arn:aws:iam:::oidc-provider/keycloak-sso.apps.example.com/auth/realms/ceph"
           ]
         },
         "Action": [
           "sts:AssumeRoleWithWebIdentity"
         ],
         "Condition": {
           "StringLike": { "keycloak-sso.apps.example.com/auth/realms/ceph:sub":"ceph" }
         }
       }
     ]
    }

  4. JSON 파일을 사용하여 Ceph Object Gateway 역할을 생성합니다.

    예제

    [root@host01 ~]# radosgw-admin role create --role-name rgwadmins \
    --assume-role-policy-doc=$(jq -rc . /root/role-rgwadmins.json)

.

3.2.8.7. S3 리소스 액세스

S3 리소스에 액세스하려면 STS 자격 증명을 사용하여 Assume 역할을 확인합니다.

사전 요구 사항

  • opensslcurl 패키지 설치
  • 보안 토큰 서비스가 구성되어 있습니다.
  • OIDC 공급자용으로 생성된 사용자입니다.
  • OIDC의 지문을 가져옵니다.
  • Ceph Object Gateway의 OIDC 공급자가 등록되었습니다.
  • 생성된 IAM 역할 및 정책

절차

  1. 다음은 S3 리소스에 액세스하기 위해 STS를 사용하여 임시 액세스 및 시크릿 키를 가져오는 경우의 예입니다.

    [roo@host01 ~]# cat test-assume-role.sh
    #!/bin/bash
    export AWS_CA_BUNDLE="/etc/pki/ca-trust/source/anchors/cert.pem"
    unset AWS_ACCESS_KEY_ID
    unset AWS_SECRET_ACCESS_KEY
    unset AWS_SESSION_TOKEN
    KC_ACCESS_TOKEN=$(curl -k -q -L -X POST
    "https://keycloak-sso.apps.ocp.example.com/auth/realms/ceph/protocol/openid-connect/
    token" \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'client_id=ceph' \
    --data-urlencode 'grant_type=password' \
    --data-urlencode 'client_secret=XXXXXXXXXXXXXXXXXXXXXXX' \
    --data-urlencode 'scope=openid' \
    --data-urlencode "<varname>SSOUSERNAME</varname>" \
    --data-urlencode "<varname>SSOPASSWORD</varname>" | jq -r .access_token)
    echo ${KC_ACCESS_TOKEN}
    IDM_ASSUME_ROLE_CREDS=$(aws sts assume-role-with-web-identity --role-arn
    "arn:aws:iam:::role/$3" --role-session-name testbr
    --endpoint=https://cephproxy1.example.com:8443
    --web-identity-token="$KC_ACCESS_TOKEN")
    echo "aws sts assume-role-with-web-identity --role-arn "arn:aws:iam:::role/$3"
    --role-session-name testb --endpoint=https://cephproxy1.example.com:8443
    --web-identity-token="$KC_ACCESS_TOKEN""
    echo $IDM_ASSUME_ROLE_CREDS
    export AWS_ACCESS_KEY_ID=$(echo $IDM_ASSUME_ROLE_CREDS | jq -r
    .Credentials.AccessKeyId)
    export AWS_SECRET_ACCESS_KEY=$(echo $IDM_ASSUME_ROLE_CREDS | jq -r
    .Credentials.SecretAccessKey)
    export AWS_SESSION_TOKEN=$(echo $IDM_ASSUME_ROLE_CREDS | jq -r
    .Credentials.SessionToken)
  2. 스크립트를 실행합니다.

    예제

    [root@host01 ~]# source ./test-assume-role.sh s3admin passw0rd rgwadmins
    [root@host01 ~]# aws s3 mb s3://testbucket
    [root@host01 ~]# aws s3 ls

3.2.9. Keystone과 함께 STS Lite 구성 및 사용(기술 프리뷰)

Amazon STS(Secure Token Service) 및 S3 API는 동일한 네임스페이스에 공존합니다. STS 옵션은 Keystone 옵션과 함께 구성할 수 있습니다.

참고

S3 및 STS API는 Ceph Object Gateway에서 동일한 끝점을 사용하여 액세스할 수 있습니다.

사전 요구 사항

  • Red Hat Ceph Storage 5.0 이상.
  • 실행 중인 Ceph 오브젝트 게이트웨이.
  • Boto Python 모듈 설치, 버전 3 이상
  • Ceph Manager 노드에 대한 루트 수준 액세스.
  • OpenStack 노드에 대한 사용자 수준 액세스.

절차

  1. Ceph Object Gateway 클라이언트에 대해 다음 구성 옵션을 설정합니다.

    구문

    ceph config set RGW_CLIENT_NAME rgw_sts_key STS_KEY
    ceph config set RGW_CLIENT_NAME rgw_s3_auth_use_sts true

    rgw_sts_key 는 세션 토큰을 암호화하거나 해독하는 데 사용되는 STS 키이며 정확히 16진수 문자입니다.

    중요

    STS 키는 영숫자여야 합니다.

    예제

    [root@mgr ~]# ceph config set client.rgw rgw_sts_key 7f8fd8dd4700mnop
    [root@mgr ~]# ceph config set client.rgw rgw_s3_auth_use_sts true

  2. OpenStack 노드에서 EC2 인증 정보를 생성합니다.

    예제

    [user@osp ~]$ openstack ec2 credentials create
    
    +------------+--------------------------------------------------------+
    | Field      | Value                                                  |
    +------------+--------------------------------------------------------+
    | access     | b924dfc87d454d15896691182fdeb0ef                       |
    | links      | {u'self': u'http://192.168.0.15/identity/v3/users/     |
    |            | 40a7140e424f493d8165abc652dc731c/credentials/          |
    |            | OS-EC2/b924dfc87d454d15896691182fdeb0ef'}              |
    | project_id | c703801dccaf4a0aaa39bec8c481e25a                       |
    | secret     | 6a2142613c504c42a94ba2b82147dc28                       |
    | trust_id   | None                                                   |
    | user_id    | 40a7140e424f493d8165abc652dc731c                       |
    +------------+--------------------------------------------------------+

  3. 생성된 인증 정보를 사용하여 GetSessionToken API를 사용하여 임시 보안 자격 증명 세트를 다시 가져옵니다.

    예제

    import boto3
    
    access_key = b924dfc87d454d15896691182fdeb0ef
    secret_key = 6a2142613c504c42a94ba2b82147dc28
    
    client = boto3.client('sts',
    aws_access_key_id=access_key,
    aws_secret_access_key=secret_key,
    endpoint_url=https://www.example.com/rgw,
    region_name='',
    )
    
    response = client.get_session_token(
        DurationSeconds=43200
    )

  4. S3 호출을 수행하는 데 임시 인증 정보를 가져올 수 있습니다.

    예제

    s3client = boto3.client('s3',
      aws_access_key_id = response['Credentials']['AccessKeyId'],
      aws_secret_access_key = response['Credentials']['SecretAccessKey'],
      aws_session_token = response['Credentials']['SessionToken'],
      endpoint_url=https://www.example.com/s3,
      region_name='')
    
    bucket = s3client.create_bucket(Bucket='my-new-shiny-bucket')
    response = s3client.list_buckets()
    for bucket in response["Buckets"]:
      print "{name}\t{created}".format(
        name = bucket['Name'],
        created = bucket['CreationDate'],
      )

  5. S3Access 역할을 생성하고 정책을 구성합니다.

    1. 관리 CAPS가 있는 사용자를 할당합니다.

      구문

      radosgw-admin caps add --uid="USER" --caps="roles=*"

      예제

      [root@mgr ~]# radosgw-admin caps add --uid="gwadmin" --caps="roles=*"

    2. S3Access 역할을 생성합니다.

      구문

      radosgw-admin role create --role-name=ROLE_NAME --path=PATH --assume-role-policy-doc=TRUST_POLICY_DOC

      예제

      [root@mgr ~]# radosgw-admin role create --role-name=S3Access --path=/application_abc/component_xyz/ --assume-role-policy-doc=\{\"Version\":\"2012-10-17\",\"Statement\":\[\{\"Effect\":\"Allow\",\"Principal\":\{\"AWS\":\[\"arn:aws:iam:::user/TESTER\"\]\},\"Action\":\[\"sts:AssumeRole\"\]\}\]\}

    3. S3Access 역할에 권한 정책을 연결합니다.

      구문

      radosgw-admin role-policy put --role-name=ROLE_NAME --policy-name=POLICY_NAME --policy-doc=PERMISSION_POLICY_DOC

      예제

      [root@mgr ~]# radosgw-admin role-policy put --role-name=S3Access --policy-name=Policy --policy-doc=\{\"Version\":\"2012-10-17\",\"Statement\":\[\{\"Effect\":\"Allow\",\"Action\":\[\"s3:*\"\],\"Resource\":\"arn:aws:s3:::example_bucket\"\}\]\}

    4. 이제 다른 사용자가 gwadmin 사용자의 역할을 가정할 수 있습니다. 예를 들어 gwuser 사용자는 gwadmin 사용자의 권한을 가정할 수 있습니다.
    5. 가정하는 사용자의 access_keysecret_key 값을 기록해 둡니다.

      예제

      [root@mgr ~]# radosgw-admin user info --uid=gwuser | grep -A1 access_key

  6. AssumeRole API 호출을 사용하여 assume 사용자의 access_keysecret_key 값을 제공합니다.

    예제

    import boto3
    
    access_key = 11BS02LGFB6AL6H1ADMW
    secret_key = vzCEkuryfn060dfee4fgQPqFrncKEIkh3ZcdOANY
    
    client = boto3.client('sts',
    aws_access_key_id=access_key,
    aws_secret_access_key=secret_key,
    endpoint_url=https://www.example.com/rgw,
    region_name='',
    )
    
    response = client.assume_role(
    RoleArn='arn:aws:iam:::role/application_abc/component_xyz/S3Access',
    RoleSessionName='Bob',
    DurationSeconds=3600
    )

    중요

    AssumeRole API에는 S3Access 역할이 필요합니다.

추가 리소스

  • Boto Python 모듈 설치에 대한 자세한 내용은 Red Hat Ceph Storage Object Gateway GuideTest S3 Access 섹션을 참조하십시오.
  • 자세한 내용은 Red Hat Ceph Storage Object Gateway Guide사용자 생성 섹션을 참조하십시오.

3.2.10. Keystone에서 STS Lite를 사용하는 제한 사항 해결 (기술 프리뷰)

Keystone의 제한 사항은 STS(Secure Token Service) 요청을 지원하지 않는다는 것입니다. 또 다른 제한 사항은 페이로드 해시가 요청에 포함되지 않는다는 것입니다. 이 두 가지 제한 사항을 해결하려면 Boto 인증 코드를 수정해야 합니다.

사전 요구 사항

  • 실행 중인 Red Hat Ceph Storage 클러스터 버전 5.0 이상.
  • 실행 중인 Ceph 오브젝트 게이트웨이.
  • Boto Python 모듈 설치, 버전 3 이상

절차

  1. Boto의 auth.py 파일을 열고 편집합니다.

    1. 코드 블록에 다음 4행을 추가합니다.

      class SigV4Auth(BaseSigner):
        """
        Sign a request with Signature V4.
        """
        REQUIRES_REGION = True
      
        def __init__(self, credentials, service_name, region_name):
            self.credentials = credentials
            # We initialize these value here so the unit tests can have
            # valid values.  But these will get overriden in ``add_auth``
            # later for real requests.
            self._region_name = region_name
            if service_name == 'sts': 1
                self._service_name = 's3' 2
            else: 3
                self._service_name = service_name 4
    2. 다음 두 줄을 코드 블록에 추가합니다.

      def _modify_request_before_signing(self, request):
              if 'Authorization' in request.headers:
                  del request.headers['Authorization']
              self._set_necessary_date_headers(request)
              if self.credentials.token:
                  if 'X-Amz-Security-Token' in request.headers:
                      del request.headers['X-Amz-Security-Token']
                  request.headers['X-Amz-Security-Token'] = self.credentials.token
      
              if not request.context.get('payload_signing_enabled', True):
                  if 'X-Amz-Content-SHA256' in request.headers:
                      del request.headers['X-Amz-Content-SHA256']
                  request.headers['X-Amz-Content-SHA256'] = UNSIGNED_PAYLOAD 1
              else: 2
                  request.headers['X-Amz-Content-SHA256'] = self.payload(request)

추가 리소스

  • Boto Python 모듈 설치에 대한 자세한 내용은 Red Hat Ceph Storage Object Gateway GuideTest S3 Access 섹션을 참조하십시오.
Red Hat logoGithubRedditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

© 2024 Red Hat, Inc.