Oracle APEXにもOracle RDF Graph Serverにも直接は関係ありませんが、色々と作業があったので記録しておきます。
SSLやホスト名がDNSに登録されていないとREST APIを呼べない、というのはAutonomous Databaseの制約です。HTTPでIPアドレス指定でも(CSRFの対応は心配ですが)Oracle RDF Graph ServerのREST APIは動作すると思います。
以下よりJetty 9.xのSSL化にあたって行った作業を記載します。
最初にコンピュート・インスタンスに割り当てられたパブリックIPに割り当てるホスト名を決めて、DNSに登録します。次にSSLのサーバー証明書の取得を行います。以前にOracle REST Data ServicesをSSL化するために実施した手順と同じです。
Google DomainsとZero SSLのサービスを使用しています。
Zero SSLより証明書をcertificate.crt、中間証明書をca_bundle.crt、秘密鍵のファイルをprivate.keyとして入手しています。ルートCAの証明書は別途取得します。Zero SSLはUSERTrust RSA Certification AuthorityがルートCAなので、https://crt.sh/?id=1199354よりPEMをダウンロードしました。このファイルはサーバー証明書の取得先で変わります。
Oracle RDF Graph Serverを実行しているコンピュート・インスタンスに接続し、jetty.homeへ移動します。
[opc@rdfgs ~]$ cd jetty-distribution-9.4.44.v20210927/
[opc@rdfgs jetty-distribution-9.4.44.v20210927]$ pwd
/home/opc/jetty-distribution-9.4.44.v20210927
[opc@rdfgs jetty-distribution-9.4.44.v20210927]$
今までは、Jettyの設定はstart.iniにまとまっていました。SSLの設定がしにくいので、start.d以下のファイルに、それぞれのモジュール毎に記述する方法に変更します。start.iniは削除し、demo-base/start.dをコピーします。start.dに含まれているdemo.iniは不要なので消去します。
[opc@rdfgs jetty-distribution-9.4.44.v20210927]$ cp -r demo-base/start.d start.d
[opc@rdfgs jetty-distribution-9.4.44.v20210927]$ rm start.ini
[opc@rdfgs jetty-distribution-9.4.44.v20210927]$ rm start.d/demo.ini
/home/opc以下にsslというディレクトリを作成しcertificate.crt、ca_bundle.crt、private.key、1199354.crt(ルートCA証明書)の4つのファイルを配置します。
最初に証明書を1つのファイルに連結します。サーバー証明書、中間証明書、ルートCA証明書の順番で連結し、ファイルcertchain.crtを作成します。
cat certificate.crt ca_bundle.crt 1199354.crt > certchain.crt[opc@rdfgs ssl]$ cat certificate.crt ca_bundle.crt 1199354.crt > certchain.crt
OpenSSLを使用して証明書のファイルcertcachain.crtと秘密鍵private.keyより、PKCS#12形式のファイルを作成します。PKCS#12のファイル名はmy.p12にしています。
openssl pkcs12 -export -in certchain.crt -inkey private.key -out my.p12
ここで指定するパスワードは、次に実行するkeytoolで要求されるsource keystore passwordに与えます。
[opc@rdfgs ssl]$ openssl pkcs12 -export -inkey private.key -in certchain.crt -out my.p12
Enter Export Password: ********
Verifying - Enter Export Password: ********
[opc@rdfgs ssl]$
keytoolを使用してPKCS#12形式からJKS形式のキーストア・ファイルを生成します。destination keystore passwordは、この後に行うJettyのSSL設定に含めます。
keytool -importkeystore -srckeystore my.p12 -srcstoretype PKCS12 -destkeystore keystore.jks
[opc@rdfgs ssl]$ keytool -importkeystore -srckeystore my.p12 -srcstoretype PKCS12 -destkeystore keystore.jks
Importing keystore my.p12 to keystore.jks...
Enter destination keystore password: ++++++++
Re-enter new password: ++++++++
Enter source keystore password: ********
Entry for alias rdf.apexugj.dev successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled
Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12".
[opc@rdfgs ssl]$
作成したkeystore.jksをjetty.homeのetc以下に移動します。
mv keystore.jks /home/opc/jetty-distribution-9.4.44.v20210927/etc/
[opc@rdfgs ssl]$ mv keystore.jks /home/opc/jetty-distribution-9.4.44.v20210927/etc/
ユーザーopcのホームに戻り、destination keystore passwordの難読化を行います。OBFで始まる文字列をパスワードとして使用します。
[opc@rdfgs ~]$ cd
[opc@rdfgs ~]$ java -cp jetty-distribution-9.4.44.v20210927/lib/jetty-util-9.4.44.v20210927.jar org.eclipse.jetty.util.security.Password **********
2021-12-09 06:33:46.903:INFO::main: Logging initialized @382ms to org.eclipse.jetty.util.log.StdErrLog
oracle
OBF:1v*********************x151v1x
MD5:a189c633d9995e11bf8607170ec9a4b8
[opc@rdfgs ~]$
${jetty.home}/start.d以下にssl.iniを作成します。内容は以下になります。
--module=ssl
jetty.ssl.host=0.0.0.0
jetty.ssl.port=8443
jetty.https.port=8443
jetty.httpConfig.securePort=443
jetty.sslContext.keyStoreType=JKS
jetty.sslContext.keyStorePath=etc/keystore.jks
jetty.sslContext.trustStorePath=etc/keystore.jks
jetty.sslContext.keyStorePassword=OBF:1v2h****************151v1x
jetty.sslContext.keyManagerPassword=OBF:1v2h****************151v1x
jetty.sslContext.trustStorePassword=OBF:1v2h****************151v1x
以上でJettyの設定は完了です。
続いてfirewalldの設定を行います。443番ポートで接続の待ち受けを行うので、接続許可を与えます。443番ポートへの接続はJettyが動作しているポート8443番に転送します。最後に設定を永続化します。
firewall-cmd --add-port=443/tcpfirewall-cmd --add-forward-port=port=443:proto=tcp:toport=8443
firewall-cmd --runtime-to-permanent
[opc@rdfgs bin]$ sudo firewall-cmd --add-port=443/tcp
success
[opc@rdfgs bin]$ sudo firewall-cmd --add-forward-port=port=443:proto=tcp:toport=8443
success
[opc@rdfgs bin]$ sudo firewall-cmd --runtime-to-permanent
success
[opc@rdfgs bin]$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens3
sources:
services: ssh
ports: 8080/tcp 443/tcp
protocols:
masquerade: no
forward-ports:
port=443:proto=tcp:toport=8443:toaddr=
source-ports:
icmp-blocks:
rich rules:
[opc@rdfgs bin]$
パブリック・ネットワークのセキュリティ・リストに、443番ポートへの通信を許可するイングレス・ルールを作成します。
declare
l_clob clob;
l_url varchar2(400);
begin
l_url := 'https://ホスト名/orardf/api/v1/utils/user';
l_clob := apex_web_service.make_rest_request(
p_url => l_url
, p_http_method => 'GET'
, p_username => 'admin'
, p_password => 'admin'
);
dbms_output.put_line(l_clob);
end;