はじめに
Oracle Functions を使用して、自動的にSSL証明書を発行する自動化(oci-lego-sslupdate)を作りました。
Let's Encrypt からSSL証明書を発行し、OCIのLoadBalancerに設定し、ObjectStorageへ保存することが出来ます。
Oracle Functions を使用しているので、ComputeInstanceを必要としないサーバレスなアーキテクチャとなっています。
この記事では、使い方と、技術的な解説を書きます。
作成した自動化(oci-lego-sslupdate)は、GItHubにアップロードしているので、適宜ご利用ください。
https://github.com/Sugi275/oci-lego-sslupdate
概要
- OCIR (Docker Registry) にアップロードしている、自動化用の DockerImage を Oracle Functions に Pull
- Fn 上でDockerImageを実行
- Let's Encryptから新たなSSL証明書を取得
- OCIのLoadBalancerに、新たなSSL証明書を設定
- OCIのObjectStorageに、新たなSSL証明書と、SSL証明書に紐づく秘密鍵を保存
使い方
前提条件
-
取得したいSSL証明書のドメインを、OCIのDNSにあるZoneで管理していること。設定方法例はこちら を参照 (Let's Encryptの認証方式をDNS-01としているため)
-
OCI上にLoadBalancerを作成して、SSL用のListenerを作成していること
-
Oracle Functions を使用可能なこと。設定方法はこちらを参照
oci-lego-sslupdateを Oracle Functions に設定
Gitからoci-lego-sslupdateをclone
git clone https://github.com/Sugi275/oci-lego-sslupdate.git
Oracle Functions 用の設定ファイルを、必要に応じて変更します
> cat func.yaml
schema_version: 20180708
name: oci-lego-sslupdate <=== Functionの名前を変更したい場合は変更する
version: 0.0.20 <=== バージョンも変更したい場合は変更する
runtime: docker
entrypoint: ./func
format: http-stream
timeout: 120
Oracle Functions のコンソール画面で、適当なアプリケーション(枠組み)を作成します。今回の例では、env-app
という名前を使用しています。
アプリケーションを作成後、fn deploy コマンドで、Oracle Functions にデプロイします
fn --verbose deploy --app env-app
function 一覧を確認します。oci-lego-sslupdate が存在していることを確認します
> fn ls functions env-app
NAME IMAGE ID
custom_runtime phx.ocir.io/<tenancy>/oracle-function/custom_runtime:0.0.2 ocid1.fnfunc.oc1.phx.aaaaaaaaadizxuar3gv6ubeoztffm5l2nfnujna6vbnkc67g7td2c722jg2a
env-print phx.ocir.io/<tenancy>/oracle-function/env-print:0.0.7 ocid1.fnfunc.oc1.phx.aaaaaaaaadu6qtn6zyn754zbiqi3boavtunsdbkwfllggixg7hkwjihfo5ma
oci-lb-list phx.ocir.io/<tenancy>/oracle-function/oci-lb-list:0.0.24 ocid1.fnfunc.oc1.phx.aaaaaaaaaaialw3wgcnm2ytn7cveaaqmlmtaniilu3qy7k2bmxkbn2tgnpiq
oci-lego-sslupdate phx.ocir.io/<tenancy>/oracle-function/oci-lego-sslupdate:0.0.21 ocid1.fnfunc.oc1.phx.aaaaaaaaaaz4bvn4oz2sp4d3zzfuaefkui2be7b5vp4cgayrdmltj6f7yeuq <=== 表示されていればおk
test phx.ocir.io/<tenancy>/oracle-function/test:0.0.6 ocid1.fnfunc.oc1.phx.aaaaaaaaaatajmkauwajgxbjjm2p23kiu2do7nz76psxcldwv5w2palfatpq
function に環境変数を設定します。以下に例を記載します。適宜環境に合わせて変更をする必要があります
bashの場合
# oci
export OCI_PRIVKEY_BASE64=`base64 $HOME/.oci/oci_api_key.pem`
fn config func env-app oci-lego-sslupdate OCI_PRIVKEY_BASE64 $OCI_PRIVKEY_BASE64
# fnでは値が空白だと、反映されない。パスフレーズを指定する場合はコメントアウトを外して指定
# fn config func env-app oci-lego-sslupdate OCI_PRIVKEY_PASS ""
fn config func env-app oci-lego-sslupdate OCI_TENANCY_OCID 'ocid1.tenancy.oc1..secret'
fn config func env-app oci-lego-sslupdate OCI_USER_OCID 'ocid1.user.oc1..secret'
fn config func env-app oci-lego-sslupdate OCI_PUBKEY_FINGERPRINT '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00'
fn config func env-app oci-lego-sslupdate OCI_REGION 'us-phoenix-1'
fn config func env-app oci-lego-sslupdate OCI_COMPARTMENT_OCID 'ocid1.tenancy.oc1..secret'
# lego (let's encrypt client)
fn config func env-app oci-lego-sslupdate OCI_TTL 1
fn config func env-app oci-lego-sslupdate OCI_PROPAGATION_TIMEOUT 120
fn config func env-app oci-lego-sslupdate OCI_POLLING_INTERVAL 10
fn config func env-app oci-lego-sslupdate LETSENCRYPT_DOMAINS 'sugi.tokyo,*.sugi.tokyo'
fn config func env-app oci-lego-sslupdate LETSENCRYPT_MY_MAILADDRESS 'myaddress@mail.com'
# fn config func env-app oci-lego-sslupdate LETSENCRYPT_CA_URL 'https://acme-staging-v02.api.letsencrypt.org/directory'
# oci lb
fn config func env-app oci-lego-sslupdate OCI_LB_OCID 'ocid1.loadbalancer.oc1.phx.secret'
fn config func env-app oci-lego-sslupdate OCI_LISTENERS 'listener1,listener2'
# oci ObjectStorage
fn config func env-app oci-lego-sslupdate OCI_OS_NAMESPACE '<tenancy>'
fn config func env-app oci-lego-sslupdate OCI_OS_BUCKETNAME 'lego-certificate4'
fishの場合は、若干書式を変更する必要があります
# oci
set IFS
set -x OCI_PRIVKEY_BASE64 (base64 $HOME/.oci/oci_api_key.pem)
set IFS \n" "\t
# fnでは値が空白だと、反映されない。パスフレーズを指定する場合はコメントアウトを外して指定
# fn config func env-app oci-lego-sslupdate OCI_PRIVKEY_PASS ""
fn config func env-app oci-lego-sslupdate OCI_PRIVKEY_BASE64 $OCI_PRIVKEY_BASE64
fn config func env-app oci-lego-sslupdate OCI_TENANCY_OCID 'ocid1.tenancy.oc1..secret'
fn config func env-app oci-lego-sslupdate OCI_USER_OCID 'ocid1.user.oc1..secret'
fn config func env-app oci-lego-sslupdate OCI_PUBKEY_FINGERPRINT '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00'
fn config func env-app oci-lego-sslupdate OCI_REGION 'us-phoenix-1'
fn config func env-app oci-lego-sslupdate OCI_COMPARTMENT_OCID 'ocid1.tenancy.oc1..secret'
# lego (let's encrypt client)
fn config func env-app oci-lego-sslupdate OCI_TTL 1
fn config func env-app oci-lego-sslupdate OCI_PROPAGATION_TIMEOUT 120
fn config func env-app oci-lego-sslupdate OCI_POLLING_INTERVAL 10
fn config func env-app oci-lego-sslupdate LETSENCRYPT_DOMAINS 'sugi.tokyo,*.sugi.tokyo'
fn config func env-app oci-lego-sslupdate LETSENCRYPT_MY_MAILADDRESS 'myaddress@mail.com'
# fn config func env-app oci-lego-sslupdate LETSENCRYPT_CA_URL 'https://acme-staging-v02.api.letsencrypt.org/directory'
# oci lb
fn config func env-app oci-lego-sslupdate OCI_LB_OCID 'ocid1.loadbalancer.oc1.phx.secret'
fn config func env-app oci-lego-sslupdate OCI_LISTENERS 'listener1,listener2'
# oci ObjectStorage
fn config func env-app oci-lego-sslupdate OCI_OS_NAMESPACE '<tenancy>'
fn config func env-app oci-lego-sslupdate OCI_OS_BUCKETNAME 'lego-certificate4'
環境変数について
各環境変数の説明を記載します
Key | 内容 | 必須 or 任意 | Default値 |
---|---|---|---|
OCI_PRIVKEY_BASE64 | OCIに接続するための秘密鍵をbase64でエンコードした文字列 | 必須 | なし |
OCI_PRIVKEY_PASS | 秘密鍵のパスフレーズ | 必須 | なし |
OCI_TENANCY_OCID | 操作するテナンシーのOCID | 必須 | なし |
OCI_USER_OCID | OCIで公開鍵を設定した、ユーザのOCID | 必須 | なし |
OCI_PUBKEY_FINGERPRINT | 公開鍵のフィンガープリント | 必須 | なし |
OCI_REGION | リージョン名 | 必須 | なし |
OCI_COMPARTMENT_OCID | コンパートメントのOCID | 必須 | なし |
OCI_TTL | Let's Encryptでdns-01認証をする際に、一時的に作成するレコードのTTL | 任意 | 30 |
OCI_PROPAGATION_TIMEOUT | Let's Encryptでdns-01認証をするときの、タイムアウト | 任意 | 60 |
OCI_POLLING_INTERVAL | Let's Encryptでdns-01認証をするときの、インターバル | 任意 | 2 |
LETSENCRYPT_DOMAINS | SSL証明書を取得したいドメイン名。カンマ区切りで複数指定可能 | 必須 | なし |
LETSENCRYPT_MY_MAILADDRESS | SSL証明書に紐づくメールアドレス | 必須 | なし |
LETSENCRYPT_CA_URL | Let's Encrypt を始めとしたCA URLを指定。動作確認をするときには、stagingを指定すると便利 | 任意 | https://acme-v02.api.letsencrypt.org/directory |
OCI_LB_OCID | SSL証明書を設定したいLoadBalancerのOCID | 必須 | なし |
OCI_LISTENERS | SSL証明書を設定したいLoadBanancerに所属している、ListenerのOCID | 必須 | なし |
OCI_OS_NAMESPACE | ObjectStorageのネームスペース名 | 必須 | なし |
OCI_OS_BUCKETNAME | ObjectStorageにSSL証明書や秘密鍵を保存するときのバケット名。指定したバケットが存在しない場合は、自動的にPrivateバケットを作成 | 任意 | lego-cert |
loggingの設定 (任意)
現在、Oracle Functions は Limited Available となっており、logを確認したい場合は、logging用のsyslogを用意する必要があります。
Papertrail というサービスを使うことで、簡単に無料でsyslogを表示することが出来ます。
設定方法などは、こちらを参照してください。
今回の自動SSL設定は、2分くらい実行時間が必要なので、loggingしておくと進捗がわかって便利です。
Functionの実行
fn invoke コマンドで、Functionを実行できます。実行してから2分弱ほど経過すると、成功した旨のメッセージが表示されます。
また、実行中の経過はloggingを確認するとよいです。
fn invoke env-app oci-lego-sslupdate
なお、現在のOracle Functions では、定期実行することは制限されていて出来ませんが、GAされれば定期実行できるため、非常にお手軽にSSL証明書を自動的に更新し続けることが出来ます。