証明書と Oracle ウォレットを使用した、UTL_HTTP アクセスの設定 - Amazon Relational Database Service

証明書と Oracle ウォレットを使用した、UTL_HTTP アクセスの設定

Amazon RDS は RDS for Oracle DB インスタンスでのアウトバウンドネットワークアクセスをサポートします。DB インスタンスをネットワークに接続するには、次の PL/SQL パッケージを使用できます。

UTL_HTTP

このパッケージでは、SQL および PL/SQL から HTTP 呼び出しを実行します。HTTP 経由でインターネット上のデータにアクセスするために使用できます。詳細については、Oracle ドキュメントの「UTL_MAIL」を参照してください。

UTL_TCP

このパッケージは、PL/SQL で TCP/IP クライアント側アクセス機能を提供します。このパッケージは、インターネットプロトコルと E メールを使用する PL/SQL アプリケーションに役立ちます。詳細については、Oracle ドキュメントの「UTL_TCP」を参照してください。

UTL_SMTP

このパッケージは、SMTP コマンドへのインターフェイスを提供します。これにより、クライアントが E メールを SMTP サーバーにディスパッチできるようにします。詳細については、Oracle ドキュメントの「UTL_SMTP」を参照してください。

次のタスクを完了すると、UTL_HTTP.REQUEST を設定できます。これにより、SSL ハンドシェイク中にクライアント認証の証明書を要求するウェブサイトを操作できます。また Oracle ウォレットの生成コマンドや、DBMS_NETWORK_ACL_ADMIN.APPEND_WALLET_ACE の手順を修正して、ウェブサイトへの UTL_HTTP アクセスに使用するパスワード認証を設定することもできます。詳細については、Oracle Database のドキュメントの「DBMS_NETWORK_ACL_ADMIN」を参照してください。

注記

UTL_SMTP に合わせ次のタスクを変更して、SSL/TLS 経由でメールを送信できるようにします (Amazon Simple Email Service を含む)。

UTL_HTTP アクセスを設定する際の考慮事項

アクセスを設定する前に、以下を考慮してください。

  • UTL_MAIL オプションで SMTP を使用することができます。詳細については、「Oracle UTL_MAIL」を参照してください。

  • リモートホストのドメインネームサーバー (DNS) の名は、以下のいずれかです:

    • パブリックに解決可能。

    • Amazon RDS DB インスタンスのエンドポイント。

    • 独自のDNS サーバーを介して解決可能。詳細については、「カスタム DNS サーバーのセットアップ」を参照してください。

    • 同じ VPC またはピアリング接続先 VPC の Amazon EC2 インスタンスのプライベート DNS 名。この場合、名前がカスタム DNS サーバーを介して解決可能であることを確認してください。また、VPC 設定の enableDnsSupport 属性を有効にし、VPC ピア接続の DNS 解決サポートを有効にすることで Amazon が提供する DNS を使用することもできます。詳細については、「VPC の DNS サポート」および「VPC ピア接続の変更」を参照してください。

    • リモート SSL/TLS リソースに安全に接続するには、カスタマイズされた Oracle ウォレット を作成し、アップロードすることをお勧めします。Amazon S3 を Amazon RDS for Oracle 機能と統合することで、Amazon S3 から Oracle DB インスタンスにウォレットをダウンロードします。Oracle 用の Amazon S3 の統合については、「Amazon S3 統合」を参照してください。

  • Oracle SSL オプションがインスタンスごとに構成されている場合は、SSL/TLS エンドポイントを介して Oracle DB インスタンス間にデータベースリンクを確立することができます。必要な設定はこれだけです。詳細については、「Oracle Secure Sockets Layer」を参照してください。

ステップ 1: ウェブサイトのルート証明書を取得する

RDS for Oracle DB インスタンスがウェブサイトへのセキュアな接続を確立するには、ルート CA 証明書を追加します。Amazon RDS はルート証明書を使用して、Oracle ウォレットにウェブサイトの証明書を署名します。

ルート証明書は、さまざまな方法で取得できます。例えば、次のオペレーションを実行できます。

  1. ウェブサーバーを使用して、証明書で保護されたウェブサイトにアクセスします。

  2. 署名に使われたルート証明書をダウンロードします。

AWS のサービスの場合、ルート証明書は通常、Amazon Trust Services リポジトリにあります。

ステップ 2: Oracle ウォレットを作成する

ウェブサーバー証明書とクライアント認証証明書の両方を含む Oracle ウォレットを作成します。RDS Oracle インスタンスは、ウェブサーバー証明書を使用して、ウェブサイトへの安全な接続を確立します。ウェブサイトでは、Oracle のデータベースユーザーを認証するために、クライアント証明書が必要です。

認証にクライアント証明書を使用せずに、セキュアな接続を構成したい場合があります。この場合、次の手順で Java キーストアのステップを省略できます。

Oracle ウォレットを作成するには
  1. ルート証明書とクライアント証明書を 1 つのディレクトリに配置してから、このディレクトリに移動します。

  2. .p12 クライアント証明書を、Java キーストアに変換します。

    注記

    認証にクライアント証明書を使用していない場合は、このステップを省略できます。

    次の例では、client_certificate.p12 という名前のクライアント証明書を、client_keystore.jks という名前の Java キーストアに変換します。その後、キーストアは Oracle ウォレットに入ります。キーストアのパスワードは P12PASSWORD です。

    orapki wallet pkcs12_to_jks -wallet ./client_certificate.p12 -jksKeyStoreLoc ./client_keystore.jks -jksKeyStorepwd P12PASSWORD
  3. 証明書のディレクトリとは別に、Oracle ウォレット用のディレクトリを作成します。

    例えば、次の例では /tmp/wallet ディレクトリを作成します。

    mkdir -p /tmp/wallet
  4. ウォレットディレクトリに、Oracle ウォレットを作成します。

    次の例では、Oracle ウォレット パスワードを P12PASSWORD に設定します。これは、前のステップで Java キーストアで使用したのと同じパスワードです。同じパスワードを使用すると便利ですが、必須ではありません。-auto_login パラメータが自動ログイン機能をオンにするため、アクセスするたびにパスワードを指定する必要はありません。

    注記

    セキュリティ上のベストプラクティスとして、ここに示されているプロンプト以外のパスワードを指定してください。

    orapki wallet create -wallet /tmp/wallet -pwd P12PASSWORD -auto_login
  5. Java キーストアを、Oracle ウォレットに追加します。

    注記

    認証にクライアント証明書を使用していない場合は、このステップを省略できます。

    次の例では、/tmp/wallet という Oracle ウォレットに、client_keystore.jks キーストアを追加します。この例では、Java キーストアと Oracle ウォレットに、同じパスワードを指定します。

    orapki wallet jks_to_pkcs12 -wallet /tmp/wallet -pwd P12PASSWORD -keystore ./client_keystore.jks -jkspwd P12PASSWORD
  6. Oracle ウォレットに、対象のウェブサイトのルート証明書を追加します。

    次の例では、Root_CA.cer という名前の証明書を追加します。

    orapki wallet add -wallet /tmp/wallet -trusted_cert -cert ./Root_CA.cer -pwd P12PASSWORD
  7. 中間証明書を追加します。

    次の例では、Intermediate.cer という名前の証明書を追加します。中間証明書をすべてロードするまで、この手順を必要な回数繰り返します。

    orapki wallet add -wallet /tmp/wallet -trusted_cert -cert ./Intermediate.cer -pwd P12PASSWORD
  8. 新しく作成した Oracle ウォレットに、必要な証明書があることを確認します。

    orapki wallet display -wallet /tmp/wallet -pwd P12PASSWORD

ステップ 3: RDS for Oracle インスタンスに、Oracle ウォレットをダウンロードする

このステップでは、まず Oracle ウォレットを Amazon S3 にアップロードし、次に Amazon S3 から RDS for Oracle インスタンスにウォレットをダウンロードします。

RDS for Oracle DB インスタンスに Oracle ウォレットをダウンロードするには
  1. Oracle との Amazon S3 統合の前提条件を満たしたら、S3_INTEGRATION オプションを Oracle DB インスタンスに追加します。使用している Amazon S3 バケットへのアクセス権が、オプションの IAM ルールにあることを確認します。

    詳細については、「Amazon S3 統合」を参照してください。

  2. マスターユーザーとして DB インスタンスにログインし、Oracle ウォレットを保持しておく Oracle ディレクトリを作成します。

    次の例では、WALLET_DIR という名前で Oracle のディレクトリを作成しています。

    EXEC rdsadmin.rdsadmin_util.create_directory('WALLET_DIR');

    詳細については、「主要データストレージ領域でのディレクトリの作成と削除」を参照してください。

  3. 作成した Oracle ウォレットを Amazon S3 バケットにアップロードします。

    サポートされているアップロード方法は、いずれも使用できます。

  4. Oracle ウォレットを再度アップロードする場合は、既存のウォレットを削除します。それ以外の場合は、次のステップに進みます。

    次の例では、cwallet.sso という名前の、既存のウォレットを削除します。

    EXEC UTL_FILE.FREMOVE ('WALLET_DIR','cwallet.sso');
  5. Amazon S3 バケットから Oracle DB インスタンスに Oracle ウォレットをダウンロードします。

    次の例では、cwallet.sso という名前のウォレットを、my_s3_bucket という名前の Amazon S3 バケットから、WALLET_DIR という名前の DB インスタンスディレクトリにダウンロードしています。

    SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3( p_bucket_name => 'my_s3_bucket', p_s3_prefix => 'cwallet.sso', p_directory_name => 'WALLET_DIR') AS TASK_ID FROM DUAL;
  6. (オプション) パスワードで保護された Oracle ウォレットをダウンロードします。

    このウォレットは、ウォレットを使用するたびにパスワードを要求する場合にのみ、ダウンロードしてください。次の例では、パスワードで保護された ewallet.p12 ウォレットをダウンロードしています。

    SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3( p_bucket_name => 'my_s3_bucket', p_s3_prefix => 'ewallet.p12', p_directory_name => 'WALLET_DIR') AS TASK_ID FROM DUAL;
  7. DB タスクのステータスを確認します。

    次の例では、前のステップで返されたタスク ID を、dbtask-1234567890123-4567.log に代入します。

    SELECT TEXT FROM TABLE(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-1234567890123-4567.log'));
  8. Oracle ウォレットの保存に使用している、ディレクトリの内容を確認します。

    SELECT * FROM TABLE(rdsadmin.rds_file_util.listdir(p_directory => 'WALLET_DIR'));

    詳細については、「DB インスタンスディレクトリ内のファイルのリスト化」を参照してください。

ステップ 4: ユーザーに Oracle ウォレットへのアクセス許可を付与する

データベースのユーザーを新しく作成するか、既存のユーザーを設定できます。いずれの場合も、証明書を使用したセキュアな接続や、クライアント認証のために、Oracle ウォレットにアクセスするようにユーザーを設定する必要があります。

Oracle ウォレットのユーザーアクセス許可を付与するには
  1. RDS for Oracle DB インスタンスに、マスターユーザーとしてログインします。

  2. 既存のデータベースユーザーを設定しない場合は、新しいユーザーを作成します。それ以外の場合は、次のステップに進みます。

    次の例では、my-user という名前のデータベースユーザーを作成します。

    CREATE USER my-user IDENTIFIED BY my-user-pwd; GRANT CONNECT TO my-user;
  3. データベースユーザーに、Oracle ウォレットのあるディレクトリに対するアクセス許可を付与します。

    次の例では、my-user ユーザーに対して、WALLET_DIR ディレクトリへの読み取りアクセス権限を付与します。

    GRANT READ ON DIRECTORY WALLET_DIR TO my-user;
  4. データベースユーザーに対して、UTL_HTTP パッケージを使用するアクセス許可を付与します。

    次の PL/SQL プログラムは、my-user ユーザーに対して、UTL_HTTP へのアクセス許可を付与します。

    BEGIN rdsadmin.rdsadmin_util.grant_sys_object('UTL_HTTP', UPPER('my-user')); END; /
  5. データベースユーザーに対して、UTL_FILE パッケージを使用するアクセス許可を付与します。

    次の PL/SQL プログラムは、my-user ユーザーに対して、UTL_FILE へのアクセス許可を付与します。

    BEGIN rdsadmin.rdsadmin_util.grant_sys_object('UTL_FILE', UPPER('my-user')); END; /

ステップ 5: DB インスタンスからウェブサイトへのアクセスを設定する

このステップでは、UTL_HTTP やアップロードした Oracle ウォレット、クライアント証明書を使用して、対象のウェブサイトに接続できるように、Oracle データベースユーザーを設定します。詳細については、Oracle Database のドキュメントの「Configuring Access Control to an Oracle Wallet」(Oracle Wallet に対するアクセス制御の設定) を参照してください。

RDS for Oracle DB インスタンスからウェブサイトへのアクセスを設定するには
  1. RDS for Oracle DB インスタンスに、マスターユーザーとしてログインします。

  2. セキュアなポートで、ユーザーと対象のウェブサイトの Host Access Control Entry (ACE) を作成します。

    次の例では、my-user ユーザーが、セキュアなポート 443 経由で secret.encrypted-website.com にアクセスできるように設定します。

    BEGIN DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( host => 'secret.encrypted-website.com', lower_port => 443, upper_port => 443, ace => xs$ace_type(privilege_list => xs$name_list('http'), principal_name => 'my-user', principal_type => xs_acl.ptype_db)); -- If the program unit results in PLS-00201, set -- the principal_type parameter to 2 as follows: -- principal_type => 2)); END; /
    重要

    前述のプログラムユニットでは、次のエラーが発生する可能性があります: PLS-00201: identifier 'XS_ACL' must be declared。このエラーが返された場合は、principal_type に値を割り当てる行を次の行に置き換えてから、プログラムユニットを再実行します。

    principal_type => 2));

    PL/SQL パッケージ XS_ACL の定数の詳細については、Oracle Database ドキュメントの「Real Application Security Administrator's and Developer's Guide」を参照してください。

    詳細については、Oracle Database のドキュメントの「Configure Access Control Lists (ACLs) to External Network Services」(外部ネットワークサービスへのアクセス制御リスト (ACL) の構成) を参照してください。

  3. (オプション) 標準のポートで、ユーザーと対象のウェブサイトの ACE を作成します。

    一部のウェブページが、セキュアポート (443) ではなく標準のウェブサーバーのポート (80) から提供される場合は、標準のポートを使用する必要がある場合があります。

    BEGIN DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( host => 'secret.encrypted-website.com', lower_port => 80, upper_port => 80, ace => xs$ace_type(privilege_list => xs$name_list('http'), principal_name => 'my-user', principal_type => xs_acl.ptype_db)); -- If the program unit results in PLS-00201, set -- the principal_type parameter to 2 as follows: -- principal_type => 2)); END; /
  4. アクセスコントロールエントリが存在することを確認します。

    SET LINESIZE 150 COLUMN HOST FORMAT A40 COLUMN ACL FORMAT A50 SELECT HOST, LOWER_PORT, UPPER_PORT, ACL FROM DBA_NETWORK_ACLS ORDER BY HOST;
  5. データベースユーザーに対して、UTL_HTTP パッケージを使用するアクセス許可を付与します。

    次の PL/SQL プログラムは、my-user ユーザーに対して、UTL_HTTP へのアクセス許可を付与します。

    BEGIN rdsadmin.rdsadmin_util.grant_sys_object('UTL_HTTP', UPPER('my-user')); END; /
  6. 関連するアクセスコントロールリストが存在することを確認します。

    SET LINESIZE 150 COLUMN ACL FORMAT A50 COLUMN PRINCIPAL FORMAT A20 COLUMN PRIVILEGE FORMAT A10 SELECT ACL, PRINCIPAL, PRIVILEGE, IS_GRANT, TO_CHAR(START_DATE, 'DD-MON-YYYY') AS START_DATE, TO_CHAR(END_DATE, 'DD-MON-YYYY') AS END_DATE FROM DBA_NETWORK_ACL_PRIVILEGES ORDER BY ACL, PRINCIPAL, PRIVILEGE;
  7. クライアント認証で証明書を使用し、接続で Oracle ウォレットを使用するためのアクセス許可を、データベースユーザーに付与します。

    注記

    認証にクライアント証明書を使用していない場合は、このステップを省略できます。

    DECLARE l_wallet_path all_directories.directory_path%type; BEGIN SELECT DIRECTORY_PATH INTO l_wallet_path FROM ALL_DIRECTORIES WHERE UPPER(DIRECTORY_NAME)='WALLET_DIR'; DBMS_NETWORK_ACL_ADMIN.APPEND_WALLET_ACE( wallet_path => 'file:/' || l_wallet_path, ace => xs$ace_type(privilege_list => xs$name_list('use_client_certificates'), principal_name => 'my-user', principal_type => xs_acl.ptype_db)); END; /

ステップ 6: DB インスタンスからウェブサイトへの接続をテストする

このステップでは、UTL_HTTP やアップロードした Oracle ウォレット、クライアント証明書を使用してウェブサイトに接続できるように、データベースユーザーを設定します。

RDS for Oracle DB インスタンスからウェブサイトへのアクセスを設定するには
  1. RDS for Oracle DB インスタンスに、UTL_HTTP へのアクセス許可を持つデータベースユーザーとしてログインします。

  2. 対象のウェブサイトへ接続する際に、ホストアドレスを解決できることを確認します。

    次の例では、secret.encrypted-website.com からホストアドレスを取得します。

    SELECT UTL_INADDR.GET_HOST_ADDRESS(host => 'secret.encrypted-website.com') FROM DUAL;
  3. 失敗した接続をテストします。

    UTL_HTTP は、証明書とともに Oracle ウォレットの場所を要求するため、次のクエリは失敗します。

    SELECT UTL_HTTP.REQUEST('secret.encrypted-website.com') FROM DUAL;
  4. UTL_HTTP.SET_WALLET を使用し、DUAL から選択した場合の、ウェブサイトへのアクセスをテストします。

    DECLARE l_wallet_path all_directories.directory_path%type; BEGIN SELECT DIRECTORY_PATH INTO l_wallet_path FROM ALL_DIRECTORIES WHERE UPPER(DIRECTORY_NAME)='WALLET_DIR'; UTL_HTTP.SET_WALLET('file:/' || l_wallet_path); END; / SELECT UTL_HTTP.REQUEST('secret.encrypted-website.com') FROM DUAL;
  5. (オプション) クエリを変数に保存し、EXECUTE IMMEDIATE を使用した場合の、ウェブサイトへのアクセスをテストします。

    DECLARE l_wallet_path all_directories.directory_path%type; v_webpage_sql VARCHAR2(1000); v_results VARCHAR2(32767); BEGIN SELECT DIRECTORY_PATH INTO l_wallet_path FROM ALL_DIRECTORIES WHERE UPPER(DIRECTORY_NAME)='WALLET_DIR'; v_webpage_sql := 'SELECT UTL_HTTP.REQUEST(''secret.encrypted-website.com'', '''', ''file:/' ||l_wallet_path||''') FROM DUAL'; DBMS_OUTPUT.PUT_LINE(v_webpage_sql); EXECUTE IMMEDIATE v_webpage_sql INTO v_results; DBMS_OUTPUT.PUT_LINE(v_results); END; /
  6. (オプション) ファイルシステム上で、Oracle ウォレットディレクトリの場所を検索します。

    SELECT * FROM TABLE(rdsadmin.rds_file_util.listdir(p_directory => 'WALLET_DIR'));

    前のコマンドからの出力を使用して、HTTP リクエストを作成します。例えば、ディレクトリが rdsdbdata/userdirs/01 である場合、次のクエリを実行します。

    SELECT UTL_HTTP.REQUEST('https://secret.encrypted-website.com/', '', 'file://rdsdbdata/userdirs/01') FROM DUAL;