3.2. S3 API を使用した Ceph Object Gateway へのアクセス


開発者は、Amazon S3 API の使用を開始する前に、Ceph Object Gateway および Secure Token Service (STS) へのアクセスを設定する必要があります。

前提条件

  • 稼働中の Red Hat Ceph Storage クラスターがある。
  • 実行中の Ceph Object Gateway。
  • RESTful クライアント。

3.2.1. S3 認証

Ceph Object Gateway への要求は、認証または認証解除のいずれかになります。Ceph Object Gateway は、認証されていないリクエストが匿名ユーザーによって送信されることを前提としています。Ceph Object Gateway は、固定 ACL をサポートしています。

ほとんどのユースケースでは、クライアントは、Java や Python Boto 用の Amazon SDK の AmazonS3Client などの既存のオープンソースライブラリーを使用します。オープンソースライブラリーでは、アクセスキーおよびシークレットキーを渡すだけで、ライブラリーはユーザーの要求ヘッダーおよび認証署名をビルドします。ただし、リクエストを作成して署名することもできます。

リクエストの認証には、アクセスキーとベース 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 としてエンコードします。

ヘッダーを正規化

ヘッダーを正規の形式に正規化するには、以下を行います。

  1. すべての content- ヘッダーを取得します。
  2. content-type および content-md5 以外の content- ヘッダーをすべて削除します。
  3. content- ヘッダー名が小文字であることを確認します。
  4. content- ヘッダーの辞書式で並べ替えます。
  5. Date ヘッダー AND があることを確認します。指定した日付が、オフセットではなく 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 サーバー側の暗号化

Ceph Object Gateway は、S3 アプリケーションプログラムインターフェイス (API) のアップロードされたオブジェクトのサーバー側の暗号化をサポートします。サーバー側の暗号化とは、S3 クライアントが暗号化されていない形式で HTTP 経由でデータを送信し、Ceph Object Gateway はそのデータを暗号化した形式で Red Hat Ceph Storage に保存することを意味します。

注記

Red Hat は、Static Large Object (SLO) または Dynamic Large Object (DLO) の S3 オブジェクト暗号化をサポートしません。

重要

暗号化を使用するには、クライアントリクエストは、SSL 接続上でリクエストを送信する 必要があります。Red Hat は、Ceph Object Gateway が SSL を使用しない限り、クライアントからの S3 暗号化をサポートしません。ただし、テストの目的で、管理者は ceph config set client.rgw コマンドを使用して、rgw_crypt_require_ssl 設定を false に設定してから、Ceph Object Gateway インスタンスを再起動することで、テスト中に SSL を無効にできます。

実稼働環境では、SSL 経由で暗号化された要求を送信できない場合があります。このような場合は、サーバー側の暗号化で HTTP を使用して要求を送信します。

サーバー側の暗号化で HTTP を設定する方法は、以下の関連情報セクションを参照してください。

暗号化キーの管理には、以下の 2 つのオプションがあります。

お客様提供のキー

お客様が提供する鍵を使用する場合、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 ユーザー操作
パーミッションバケットオブジェクト

READ

パーミッションを得たユーザーは、バケットのオブジェクトをリスト表示できます。

パーミッションを得たユーザーは、オブジェクトを読み取りできます。

WRITE

パーミッションを得たユーザーは、バケットのオブジェクトを書き込みまたは削除できます。

該当なし

READ_ACP

パーミッションを得たユーザーは、バケット ACL を読み取ることができます。

パーミッションを得たユーザーは、オブジェクト ACL を読み取ることができます。

WRITE_ACP

パーミッションを得たユーザーは、バケット ACL を書き込めます。

パーミッションを得たユーザーは、オブジェクト ACL に書き込めます。

FULL_CONTROL

Grantee にはバケットのオブジェクトに対する完全なパーミッションがあります。

パーミッションを得たユーザーは、オブジェクト 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. Object Gateway 設定および管理ガイド で説明されているように、ゲートウェイに使用する DNS サーバーにワイルドカードを追加します。

    ローカル DNS キャッシュ用のゲートウェイノードを設定することもできます。これを実行するには、以下の手順を実行します。

    1. rootdnsmasq をインストールおよび設定します。

      [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_NODE および FQDN_OF_GATEWAY_NODE は、ゲートウェイノードの IP アドレスと FQDN に置き換えます。

    2. root で 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_NODE および FQDN_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 の設定および管理ガイド に説明されているように、S3 アクセスに radosgw ユーザーを慎重に作成し、生成した access_key および secret_key をコピーします。S3 アクセス、およびそれ以降のバケット管理タスクには、これらのキーが必要です。

3.2.5. Ruby AWS S3 を使用した Ceph Object Gateway へのアクセス

Ruby プログラミング言語は、S3 アクセスに aws-s3 gem と共に使用できます。Ruby AWS::S3 で Ceph Object Gateway サーバーにアクセスするために使用されるノードで以下の手順を実行します。

前提条件

  • Ceph Object Gateway へのユーザーレベルのアクセス。
  • Ceph Object Gateway にアクセスするノードへのルートレベルのアクセス。
  • インターネットアクセス。

手順

  1. ruby パッケージをインストールします。

    [root@dev ~]# yum install ruby
    注記

    上記のコマンドは ruby と、rubygemsruby-libs などの基本的な依存関係をインストールします。コマンドによってすべての依存関係がインストールされていない場合は、個別にインストールします。

  2. Ruby パッケージ aws-s3 をインストールします。

    [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_KEY および MY_SECRET_KEY は、Red Hat Ceph Storage Object Gateway 設定および管理ガイド に従って 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-bucket4my-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 プログラミング言語は、S3 アクセスに aws-sdk gem と共に使用できます。Ruby AWS::SDK を使用して Ceph Object Gateway サーバーにアクセスするために使用されるノードで以下の手順を実行します。

前提条件

  • Ceph Object Gateway へのユーザーレベルのアクセス。
  • Ceph Object Gateway にアクセスするノードへのルートレベルのアクセス。
  • インターネットアクセス。

手順

  1. ruby パッケージをインストールします。

    [root@dev ~]# yum install ruby
    注記

    上記のコマンドは ruby と、rubygemsruby-libs などの基本的な依存関係をインストールします。コマンドによってすべての依存関係がインストールされていない場合は、個別にインストールします。

  2. Ruby パッケージ aws-sdk をインストールします。

    [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_KEY および MY_SECRET_KEY は、Red Hat Ceph Storage Object Gateway 設定および管理ガイド に従って 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-bucket6my-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.16 および aws-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_KEY および MY_SECRET_KEY は、Red Hat Ceph Storage Object Gateway 設定および管理ガイド に従って S3 アクセス用の radosgw ユーザーを作成したときに生成された、access_key および secret_key に置き換えます。PATH_TO_AWS は、php プロジェクトディレクトリーにコピーした、デプロイメントした 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-bucket4my-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 の Secure Token Service (STS) は、ユーザーを認証するための一時セキュリティー認証情報のセットを返します。

Red Hat Ceph Storage Object Gateway は、アイデンティティーおよびアクセス管理 (IAM) 用の Amazon STS アプリケーションプログラミングインターフェイス (API) のサブセットをサポートします。

ユーザーは最初に STS に対して認証し、後続の要求で使用できる有効期間の短い S3 アクセスキーとシークレットキーを受け取ります。

Red Hat Ceph Storage は、OIDC プロバイダーを設定してシングルサインオンと統合することで、S3 ユーザーを認証できます。この機能により、Object Storage ユーザーは、ローカルの Ceph Object Gateway データベースではなく、エンタープライズアイデンティティープロバイダーに対して認証できるようになります。たとえば、SSO がバックエンドのエンタープライズ IDP に接続されている場合、Object Storage ユーザーはエンタープライズ認証情報を使用して認証して、Ceph Object Gateway S3 エンドポイントにアクセスできます。

STS を IAM ロールポリシー機能と併用することで、細かく調整された認可ポリシーを作成してデータへのアクセスを制御できます。これにより、オブジェクトストレージデータにロールベースのアクセス制御 (RBAC) または属性ベースのアクセス制御 (ABAC) 認可モデルを実装できるようになり、どのユーザーがデータにアクセスできるかを完全に制御できるようになります。

STS を使用して S3 リソースにアクセスするワークフローを簡略化する

  1. ユーザーは、Red Hat Ceph Storage 内の S3 リソースにアクセスしたいと考えています。
  2. ユーザーは SSO プロバイダーに対して認証する必要があります。
  3. SSO プロバイダーは IDP と統合され、ユーザーの認証情報が有効か確認し、ユーザーが認証されると SSO がユーザーにトークンを提供します。
  4. ユーザーは、SSO によって提供されたトークンを使用して Ceph Object Gateway STS エンドポイントにアクセスし、S3 リソースへのアクセスをユーザーに提供する IAM ロールを引き受けるように要求します。
  5. Red Hat Ceph Storage ゲートウェイはユーザートークンを受け取り、SSO にトークンの検証を要求します。
  6. SSO がトークンを検証すると、ユーザーはロールを引き受けることができます。STS を通じて、ユーザーは一時的なアクセスと秘密鍵を取得し、S3 リソースにアクセスできるようになります。
  7. ユーザーが引き受けた IAM ロールにアタッチされたポリシーに応じて、ユーザーは S3 リソースセットにアクセスできます。
  8. たとえば、バケット A を読み取り、バケット B に書き込みます。
STS ワークフロー

関連情報

3.2.8.1. Secure Token Service アプリケーションのプログラミングインターフェイス

Ceph Object Gateway は、以下の Secure Token Service (STS) アプリケーションプログラミングインターフェイス (API) を実装します。

AssumeRole

この API は、アカウント間のアクセスのための一時的な認証情報のセットを返します。これらの一時的な認証情報により、Role と、AssumeRole API で割り当てられるポリシーの両方に割り当てられるパーミッションポリシーを使用することができます。RoleArn および RoleSessionName リクエストパラメーターは必須ですが、他の要求パラメーターは任意です。

RoleArn
説明
長さが 20 ~ 2048 文字の Amazon Resource Name (ARN) について想定するロール。
String
必須
はい
RoleSessionName
説明
仮定するロールセッション名を特定します。ロールセッション名は、異なるプリンシパルや別の理由がロールを想定する場合にセッションを一意に識別できます。このパラメーターの値は、2 文字から 64 文字までです。=,.@、および - 文字は使用できますが、スペースは使用できません。
String
必須
はい
ポリシー
説明
インラインセッションで使用する JSON 形式の ID およびアクセス管理ポリシー (IAM)。このパラメーターの値は 1 文字から 2048 文字までです。
String
必須
いいえ
DurationSeconds
説明
セッションの期間 (秒単位)。最小値は 900 秒で、最大値は 43200 秒です。デフォルト値は 3600 秒です。
Integer
必須
いいえ
ExternalId
説明
別のアカウントのロールを想定する場合には、利用可能な場合は一意の外部識別子を指定します。このパラメーターの値は、2 文字から 1224 文字までになります。
String
必須
いいえ
SerialNumber
説明
関連付けられたマルチファクター認証 (MFA) デバイスからのユーザーの識別番号。パラメーターの値は、9 文字から 256 文字までのハードウェアデバイスまたは仮想デバイスのシリアル番号になります。
String
必須
いいえ
TokenCode
説明
信頼ポリシーに MFA が必要な場合は、マルチファクター認証 (MFA) デバイスから生成された値。MFA デバイスが必要で、このパラメーターの値が空または期限切れの場合には、AssumeRole の呼び出しは "access denied" エラーメッセージを返します。このパラメーターの値には、固定長は 6 文字です。
String
必須
いいえ

AssumeRoleWithWebIdentity

この API は、OpenID Connect や OAuth 2.0 アイデンティティープロバイダーなどのアプリケーションによって認証されたユーザーの一時認証情報のセットを返します。RoleArn および RoleSessionName リクエストパラメーターは必須ですが、他の要求パラメーターは任意です。

RoleArn
説明
長さが 20 ~ 2048 文字の Amazon Resource Name (ARN) について想定するロール。
String
必須
はい
RoleSessionName
説明
仮定するロールセッション名を特定します。ロールセッション名は、異なるプリンシパルや別の理由がロールを想定する場合にセッションを一意に識別できます。このパラメーターの値は、2 文字から 64 文字までです。=,.@、および - 文字は使用できますが、スペースは使用できません。
String
必須
はい
ポリシー
説明
インラインセッションで使用する JSON 形式の ID およびアクセス管理ポリシー (IAM)。このパラメーターの値は 1 文字から 2048 文字までです。
String
必須
いいえ
DurationSeconds
説明
セッションの期間 (秒単位)。最小値は 900 秒で、最大値は 43200 秒です。デフォルト値は 3600 秒です。
Integer
必須
いいえ
ProviderId
説明
アイデンティティープロバイダーからのドメイン名の完全修飾ホストコンポーネント。このパラメーターの値は、長さが 4 ~ 2048 文字の OAuth 2.0 アクセストークンでのみ有効です。
String
必須
いいえ
WebIdentityToken
説明
アイデンティティープロバイダーから提供される OpenID Connect アイデンティティートークンまたは OAuth 2.0 アクセストークン。このパラメーターの値は、4 文字から 2048 文字までです。
String
必須
いいえ

関連情報

3.2.8.2. セキュアなトークンサービスの設定

rgw_sts_key および rgw_s3_auth_use_sts オプションを設定して、Ceph Object Gateway で使用する Ceph Object Gateway (STS) を設定します。

注記

S3 と STS API は同じ名前空間に共存し、いずれも Ceph Object Gateway の同じエンドポイントからアクセスできます。

前提条件

  • 稼働中の Red Hat Ceph Storage クラスターがある。
  • 実行中の Ceph Object Gateway。
  • 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 進数の 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. Secure Token Service (STS) 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 Sign-On
  • Keycloak

前提条件

  • openssl パッケージおよび curl パッケージがインストールされている。

手順

  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 ファイルに貼り付けます。冒頭に —–BEGIN CERTIFICATE—–、末尾に —–END CERTIFICATE—– を含めます。

    -----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) の設定ドキュメントを登録します。

前提条件

  • openssl パッケージおよび curl パッケージがインストールされている。
  • セキュアなトークンサービスが設定されている。
  • OIDC プロバイダー用にユーザーが作成されている。
  • OIDC のサムプリントを取得している。

手順

  1. トークンから URL を抽出します。

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

  2. OIDC プロバイダーを Ceph Object Gateway に登録します。

    [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 ロールとポリシーを作成します。

前提条件

  • openssl パッケージおよび curl パッケージがインストールされている。
  • セキュアなトークンサービスが設定されている。
  • 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 ファイルを作成します。StatementAllow に設定し、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 ロールを確認します。

前提条件

  • openssl パッケージおよび curl パッケージがインストールされている。
  • セキュアなトークンサービスが設定されている。
  • OIDC プロバイダー用にユーザーが作成されている。
  • OIDC のサムプリントを取得している。
  • Ceph Object Gateway の OIDC プロバイダーが登録されている。
  • IAM ロールとポリシーが作成されている。

手順

  1. 以下は、一時的なアクセスとシークレットキーを取得して S3 リソースにアクセスするための、STS を使用した assume ロールの例です。

    [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 Secure Token Service (STS) と S3 API は、同じ名前空間に共存します。STS オプションは、Keystone オプションと組み合わせて設定できます。

注記

S3 と STS の API の両方に、Ceph Object Gateway の同じエンドポイントを使用してアクセスできます。

前提条件

  • Red Hat Ceph Storage 5.0 以降
  • 実行中の Ceph Object Gateway。
  • 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 進数の 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_key および secret_key の値を書き留めておきます。

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

  6. AssumeRole API 呼び出しを使用し、仮定のユーザーから access_key および secret_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 ガイドS3 アクセスのテスト セクションを参照してください。
  • 詳細は、Red Hat Ceph Storage Object Gateway ガイドユーザーの作成 セクションを参照してください。

3.2.10. Keystone で STS Lite を使用するための制限の回避 (テクノロジープレビュー)

Keystone の制限は、Secure Token Service (STS) 要求をサポートしないことです。もう 1 つの制限は、ペイロードハッシュがリクエストに含まれていないことです。この 2 つの制限を回避するには、Boto 認証コードを変更する必要があります。

前提条件

  • 稼働中の Red Hat Ceph Storage クラスター (バージョン 5.0 以降)。
  • 実行中の Ceph Object Gateway。
  • 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. 以下の 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 ガイドS3 アクセスのテスト セクションを参照してください。
Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.