Oracle Cloud Infrastructure の DBCS上で動かしている APEX に フリーの証明書を入れる

# はじめに
Oracle Cloud Infrastructure(OCI) の DBCS上で Application Express（APEX）を動かしています。
SSLサーバ証明書に いわゆるオレオレ証明書を使っているのですが、それをやめて Let's Encrypt という認証局が無償で発行する証明書を入れたいと思います。Let's Encrypt 初めて使います。

# 手順
## 0. ドメインを取得します（ない場合）
無料でドメインを取得したい場合は、下の記事を参考に Freenom という無料ドメインプロバイダでドメインを取得します。Freenom も初めて使います。

https://qiita.com/Tomoki_OIOI/items/5b4092c3adb6052bc72f

ドメイン取得後、[Manage Freenom DNS]画面で、Targetの部分にはDBシステムのパブリックIPアドレスを入れておいてください。
## 1. snap からの certbot インストール
Let's Encrypt の証明書は certbot というのを使って取得するらしいです。
certbot は snap を使ってインストールするようです。
なので snap インストールと certbot インストールをまず行います。
https://snapcraft.io/docs/installing-snap-on-centos を参考に以下行います。
DBシステムにSSHでログインして、以下を実行します。

    $ sudo yum install snapd
    $ sudo systemctl enable --now snapd.socket
    $ sudo ln -s /var/lib/snapd/snap /snap
上実行後 DBシステムを再起動します。
https://certbot.eff.org/lets-encrypt/centosrhel7-other に従い以下実行します。

    $ sudo snap install core
    $ sudo snap refresh core
既存のcertbotがあれば削除します。

    $ sudo yum remove certbot
certbotをインストールします。

    $ sudo snap install --classic certbot
    $ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Firewallのポート80を開けます。やり方は下の記事の「4.ファイアーウォールの設定」を参考にし、今回は8443でなく80を開けてください(参考資料と同様、DBシステムのファイアーウォールとVCNのセキュリティリストの両方に設定が必要です）。

https://qiita.com/ayamakkk/items/e150b485fc64997b40bc

下はDBシステムのファイアーウォールの80番ポートを開ける例です。

    $ sudo iptables -I INPUT 8 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -m comment --comment "Required for certbot"
    $ sudo /sbin/service iptables save
## 2. certbot による証明書取得
以下実行します。途中でドメイン名を聞いてくると思うので、Freenom で取得したドメイン名を入れます（ちなみにドメイン名の代わりに IP Address入れてみたのですがダメでした）。

    $ sudo certbot certonly --standalone
完了すると、下のようなメッセージが出ると思います。

    IMPORTANT NOTES:
     - Congratulations! Your certificate and chain have been saved at:
       /etc/letsencrypt/live/<ドメイン名>/fullchain.pem
       Your key file has been saved at:
       /etc/letsencrypt/live/<ドメイン名>/privkey.pem
       Your certificate will expire on 202X-XX-XX. To obtain a new or
       tweaked version of this certificate in the future, simply run
       certbot again. To non-interactively renew *all* of your
       certificates, run "certbot renew"
     - If you like Certbot, please consider supporting our work by:

       Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
       Donating to EFF:                    https://eff.org/donate-le
`/etc/letsencrypt/live/<ドメイン名>/fullchain.pem` が証明書
`/etc/letsencrypt/live/<ドメイン名>/privkey.pem` が秘密鍵
のようです。
上のパスのうち、live ディレクトリのモードが0700なのと、privkey.pem の link先のファイルのモードが0600なので、変更する必要がありそうです。

    $ sudo chmod 0755 /etc/letsencrypt/live
    $ sudo chmod 0755 /etc/letsencrypt/archive
    $ sudo chmod 0644 /etc/letsencrypt/archive/<ドメイン名>/privkey1.pem
standalone.properties ファイルを編集します。
## 3. Oracle REST Data Service (ORDS) の構成ファイル変更
ORDSをスタンドアロン・モードで動かしている場合、下のマニュアルの「1.4.1.1 DERへの秘密キーの変換(LinuxおよびUNIX) 」の記述に従い、秘密鍵をDERへ変換し、standalone.properties に証明書と秘密鍵のエントリを変更します。

https://docs.oracle.com/cd/F35735_01/aelig/installing-REST-data-services.html#GUID-1E64886C-C85C-49B5-A98E-79B9EC8455B4

    $ cd /etc/letsencrypt/live/<ドメイン名>
    $ sudo openssl pkcs8 -topk8 -inform PEM -outform DER -in privkey.pem -out privkey.der -nocrypt

下の様にstandalone.properties を編集します。
https://qiita.com/ayamakkk/items/e150b485fc64997b40bc に従って APEX をインストールした場合だと、このファイルは $ORACLE_HOME/apex20/config/ords/standalone にあります。

    ssl.cert=/etc/letsencrypt/live/<ドメイン名>/fullchain.pem
    ssl.cert.key=/etc/letsencrypt/live/<ドメイン名>/privkey.der

ORDS をスタンドアロン・モードで起動します。

# 最後に
Let's Encrypt から発行される証明書の有効期限は90日ですが、期限内に更新すればずっと使えます。

    $ sudo certbot renew

で再発行されるようです（まだ試してません。テスト実行 `sudo certbot renew --dry-run` は行いました）。
（参考になる記事を参照しながら）いずれ cron を使って更新を自動化しようと思います。
ORDSスタンドアロン・モードの場合、自動化するなら証明書の更新だけでなく、秘密鍵をDERに変換するところも自動化する必要がありますね。