はじめに
こんにちは、技術部の内藤です。
OCIは非常に安くて伸びてきているクラウドですが、AWSなどと比べるとまだないサービスも複数あります。その中で私が重要と思われるものだと、AWSのACMのようなかんたんにTLS証明書を発行するサービスが2025年6月時点でまだありません。
「証明書サービス」は存在しますが、私が調べたり試した限りでは、プライベート証明書しか発行できず、端末にルート証明書をインストールしておく必要があります。つまり、公開するWebサイトのHTTPS化には使えません。辛い。
参考公式リンク
- SSLおよびTLS証明書 | Oracle Cloud Infrastructure(OCI) | Oracle 日本
- OCI技術資料 : 証明書サービス概要 - Speaker Deck
- プライベート認証局と証明書の発行 | Oracle Cloud Infrastructure チュートリアル
とはいえ、Let's Encryptを利用すれば無料でTLS証明書を発行できます。そこで今回は、Let's Encryptで証明書を発行するために利用するcertbotのOracle Linuxでのインストール方法と、実際にcertbotを使って証明書を発行する方法を紹介します。
必要なリソースの作成
VCNの作成方法やインスタンスの作成方法は割愛します。わからない方は、公式のチュートリアルをご覧ください。
その3 - インスタンスを作成する | Oracle Cloud Infrastructure チュートリアル
certbotのインストール
Let's Encryptの証明書を取得するためのツールであるcertbotをインスタンスにインストールします。
インスタンス作成時に登録したsshの公開鍵を使ってssh接続でopcユーザーにログインします。なお、sshの鍵を作成する際は、暗号アルゴリズムをRSAではなくed25519の鍵を作成しましょう。 ssh-keygen -t ed25519
で作成できます。
そして、以下のコマンドを実行していきます。
# メモリが少ない(1GBや2GB)場合でもOOMでインスタンスが落ちないように、swapファイルを作成しておく
# Oracle Linux は、デフォルトだとよく落ちます
# 確認
free --mega
# 4GBのスワップファイルを作成
sudo swapoff /.swapfile
sudo rm /.swapfile
sudo dd if=/dev/zero of=/.swapfile bs=1M count=4096
# ↑完了まで数十秒の待ち時間あり
sudo chmod 600 /.swapfile
sudo mkswap /.swapfile
sudo swapon /.swapfile
# 確認
free --mega
# パッケージを更新
sudo dnf upgrade -y
# certbotをインストールするためのsnapdをインストールします。
# Oracle Linux は RHEL(Red Hat Enterprise Linux系なので、RHELの手順を参考にします)
## ドキュメント https://snapcraft.io/docs/installing-snap-on-red-hat
sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
sudo dnf upgrade -y
sudo dnf -y install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
# snapを利用して、certbotをインストール
## ドキュメント https://certbot.eff.org/instructions?ws=nginx&os=snap&tab=wildcard
sudo snap install --classic certbot
# error: too early for operation, device not yet seeded or device model not acknowledged となったら、数秒待ってからもう一度実行する
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok
# 表示が出ればOK
certbot --version
DNSチャレンジでLet's Encryptの証明書を発行する
Let's Encryptで証明書を発行するには、ドメインの所有権を証明するチャレンジを行う必要があります。
Let's Encryptのチャレンジの主な方法には、HTTPとDNSチャレンジがあり、今回はワイルドカードの証明書も発行するため、DNSチャレンジを行います。
チャレンジの詳細は公式のページをご覧ください。
DNSのゾーンを作成しておく
今回証明書を発行するドメインは xxx.jp
として、OCIのDNSサービスにパブリックゾーンを作成しておきます。
コンソールのDNS管理>ゾーンから作成しましょう。
ゾーン作成後に存在しているNSレコードの値を、レジストラなど現在DNSを管理しているDNSサーバーに、以下のように登録します。
- レコード名:
xxx.jp
- レコードタイプ:
NS
- レコード値: OCIのDNSサービスで作成したゾーンのNSレコードの値
- TTL:
172800
(=2日。めったに変えることがない値なので長めがよい)
certbotコマンドを実行する
以下のコマンドで、証明書が発行できます。
sudo certbot certonly \
--manual \
--key-type ecdsa --elliptic-curve secp384r1 \
--preferred-challenges=dns \
-d xxx.jp \
-d '*.xxx.jp' \
-m xxx@xxx.jp \
--agree-tos \
--no-eff-email
# 以下はオプションの説明
sudo certbot certonly # 証明書の取得のみで。Webサーバーへの自動インストールは行わない
--manual # ドメイン所有権の検証(チャレンジ)を手動で行う
--key-type ecdsa --elliptic-curve secp384r1 # 暗号アルゴリズムを強力なECDSAの384bitにする
--preferred-challenges=dns # ワイルドカード証明書も発行するため(HTTPではなく)DNSチャンレンジで検証
-d xxx.jp # ドメイン指定
-d '*.xxx.jp' # ドメイン
-m xxx@xxx.jp # 通知先メールアドレス
--agree-tos # 規約の同意
--no-eff-email # メルマガ拒否
なお、証明書やログが出力されるディレクトリを以下のオプションで指定すれば、 sudo
を使わなくても実行できます。
--config-dir
--work-dir
--logs-dir
sudoなしで表示されるエラー
The following error was encountered:
[Errno 13] Permission denied: '/var/log/letsencrypt/.certbot.lock'
Either run as root, or set --config-dir, --work-dir, and --logs-dir to writeable paths.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /tmp/certbot-log-mhnr_r9j/log or re-run Certbot with -v for more details.
DNSレコードの登録・公開
コマンド実行後に出力されるメッセージです。
TXTレコードが一つ表示され、 Press Enter to Continue
でEnterを押すとさらにもう一つのTXTレコードが表示されます。
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for xxx.jp and *.xxx.jp
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:
_acme-challenge.xxx.jp.
with the following value:
<TXTレコードの値1>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
# ここでEnterを押すと次のTXTレコードが表示される
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:
_acme-challenge.xxx.jp.
with the following value:
<TXTレコードの値2>
(This must be set up in addition to the previous challenges; do not remove,
replace, or undo the previous challenge tasks yet. Note that you might be
asked to create multiple distinct TXT records with the same name. This is
permitted by DNS standards.)
Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.xxx.jp.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
# TXTレコードが公開されたことを確認できるまでは、ここでEnterを押さないように❗️
2つ目の Press Enter to Continue
で、DNSのTXTレコードが公開、浸透する前にEnterを押してしまうと、DNSチャレンジが失敗します。DNSチャレンジに複数回失敗すると、そのドメイン(ホスト名)での認証がしばらくできなくなるレート制限があるため、注意しましょう。
<TXTレコードの値1>
と <TXTレコードの値2>
の部分に、実際の値が表示されているので、TXTレコードをOCI DNSのさきほどのゾーンに登録してください。
レコードの管理
を押します。
レコードの追加
を押します。
以下の内容で追加します。
- 名前:
_acme-challenge
- タイプ:
TXT
- TTL:
60
から300
ほど - Text
<TXTレコードの値1>
<TXTレコードの値2>
注意点で、2つ目のTXTレコードを入力するときに、追加のText(テキスト)
ボタンを押すのではなく、別のレコード
ボタンを押してください。それぞれDNSの回答方法が違うので、追加のText(テキスト)
だと、一つのTXTレコードに2つの値が入ってしまい、DNSチャレンジが失敗します。。。
最後に 変更の公開
> 変更の公開の確認
と押して、終了です。
DNSレコードの確認
さきほどのcertbotの出力に以下があります。
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.xxx.jp.
このURL開いてみましょう。さきほど登録したTXTレコードが2つ表示されていれば、DNSの登録は成功しています。
TLS証明書の発行
最後に、Enterを押して証明書の発行を完了させます。
/etc/letsencrypt/live/xxx.jp/
に、証明書の各種ファイルが作成されています。
失敗したら、TXTレコードの値などを確認して、やり直してください。
おわりに
ACMのようなサービスがないのは辛いですが、Let's Encryptに慣れると無料で証明書を発行したり自動更新は割とかんたんにできます。
まだLet's Encryptを使ったことがない方は、ぜひ試してみてください。