※ 本記事は、Martin Bachによる”Using the Operating System’s certificate store instead of an Oracle wallet in Oracle Database 23c“を翻訳したものです。

2023年10月13日


ネットワークとファイルI/Oは両方ともセキュリティに敏感な部分です。そのため、事前に設定作業を行わずに、Oracle Databaseでファイルに書き込んだり、ネットワーク接続を開いたりすることはないはずです。たとえば、UTL_HTTPを介してネットワークI/Oを実行しようとする開発者は、ファイングレイン・アクセス制御設定を定義する必要があります。または、この操作を管理者に対して実行するよう依頼します。ネットワークI/Oの場合、DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE()をコールしてアクセス制御エントリ(ACE)の定義をします。

使用するWebリソースがTransport Layer Security (TLS)を使用する必要がある場合、Oracle Database 23c以前は、Webリソースの証明書をOracleウォレットに追加する必要がありました。ただ、Autonomous Databaseを使用することで、親切なエンジニアがウォレットに多くの証明書を提供してくれている場合を除きます。

Oracle Database 23c Freeでは、証明書をウォレットに格納する必要がありません。接続先のWebサービスがオペレーティング・システムによって「信頼されている」場合、接続プロセスは大幅に簡素化されます。どうしてか、わかりますか? ローテクな解決策は、cURLが接続先のURIを指すようにすることです。不明な証明書だ、といった文句がでない場合は、おそらく問題ありません。--insecureオプションは指定しないでください。それは不正行為です。

データベースのセキュリティやコンプライアンス上のすべての制限事項に注意が必要です。ネットワークI/Oは非常に機密性の高い問題であり、オラクルがデフォルトでこの機能を無効にしているのには、それなりの理由があります。データベースとのネットワークI/Oの実行を決定する前に、必ずセキュリティ、コンプライアンスまたはその領域を担当するチームに相談しておきましょう。導入を検討する前に、組織内の専門家による審査、検証、認定を受け、ゴム印を押してもらいましょう。用心するに越したことはありません。

設定

警告はさておき、Oracle Database 23cの新しい方法を試してみましょう。api.ipify.orgを使用して、現在のIPアドレスをJSON形式で取得します。これほどシンプルでアクセスしやすいWebサービスは見たことがありません。それほど複雑ではありませんが、概念を説明するには十分です。

コマンドラインでcurlを介してWebサービスを呼び出す場合、次のようになります:

$ curl 'https://api.ipify.org/?format=json'
{"ip":"1.2.3.4"}

cURLからの証明書について文句はありません。Oracleでは、オペレーティング・システムの証明書ストアを使用して、OracleでもこのURLにもアクセスできるはずです。最初に、開発者(demouser)がこのWebサービスに対してネットワークI/Oを実行できるようにする必要がありました。はじめに述べたように、アクセス制御リスト(ACL)にアクセス制御エントリ(ACE)を追加します。次に例を示します:

BEGIN
    DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
        host => 'api.ipify.org',
        ace  =>  xs$ace_type(
            privilege_list => xs$name_list('http'),
            principal_name => 'DEMOUSER',
            principal_type => xs_acl.ptype_db
        )
    );
END;
/

特権アカウントによって実行されるこのanonymous PL/SQLブロックは、api.ipify.orgに対してHTTPリクエストを発行する権利をdemouserに付与します。

UTL_HTTPを使用した例

次の例は、UTL_HTTP.REQUESTを使用してIPアドレスをフェッチする単純な参照を実行する方法を示しています:

SQL> select
  2    json_serialize(
  3      utl_http.request('https://api.ipify.org/?format=json')
  4      pretty
  5    ) as my_ip_address;

MY_IP_ADDRESS    
________________ 
{
  "ip":"1.2.3.4"
}

以前に、オペレーティングシステムが api.ipify.orgを信頼していることを確立していたので、読み取ることに問題はありませんでした。必要に応じて、UTL_HTTPのほとんどの関数/プロシージャで、wallet_pathをsystem: (コロンを含む)に設定できます。

データベース内JavaScriptの使用例

Oracle Database 23c Freeは、GraalVMを搭載したMultilingual Engine (MLE)を備えています。この新機能により、開発者は、PL/SQLおよびJavaとともに、データベースの3番目のサーバー側プログラミング言語としてJavaScriptを使用できます。

JavaScriptフェッチAPIは、リモート・ソースから情報を読み取るための非常に一般的な方法を提供します。前述のUTL_HTTP.REQUESTへのコールは、JavaScriptで次のように記述できます:

create or replace function fetch_me_if_you_can
return JSON
as mle language javascript
q'~
    await import ("mle-js-fetch");
    const response = await fetch('https://api.ipify.org/?format=json');
    if (response.ok) {
        const data = await response.json();
        return data;
    } else {
        throw new Error(
          'unexpected network error trying to query the web server'
        );
    }
~';
/

前述のコード・スニペットで、自分のスキーマに新しい関数が作成されるので、次の問い合せができます:

SQL> select
  2    json_serialize(
  3      fetch_me_if_you_can
  4      pretty
  5    ) as my_ip_address;

MY_IP_ADDRESS    
________________ 
{
  "ip":"1.2.3.4"
}

とても簡単です。

まとめ

オペレーティング・システムの証明書ストアの使用は、少なくとも私の意見では、非常に生産性向上に貢献します。TLSで保護されたWebリソースにアクセスするためにウォレットを作成するかわりに、かわりにオペレーティング・システムの証明書ストアを利用できます。