メインコンテンツへスキップ
見出し画像

無料のSSL証明書 Let's Encryptを使用してPythonでHTTPS通信してみた

    こんにちはRcatです。
    以下の記事でLINEのBOTを作ろうと思いましたが、なんとSSLを要求されてしまいました。
    仕組みを確認すれば当たり前っちゃ当たり前なんですが、今まで絶対的な必要性がなくてSSLには手を出してこなかったんですよね…。
    というわけで今回は必要になったので、PythonでSSL通信をしてみようと思います。そのための証明書を取得します。

    無料のSSL証明書Let's Encrypt

    LINEのbotを作る過程で、公式のリファレンスの中でこちらのサイトが紹介されていました。
    このサイトを使うことで、無料のSSL証明書を作ることができるみたいです。

    使い方

    サイトに入ると英語で色々書いてあるので、とりあえずチャットgptに聞いてみました。

    まとめるとこんな感じ。たった3行で証明書ができるみたい。

    sudo apt-get update
    sudo apt-get install certbot #ポート80を開ける (もちろんルーターも)
    sudo ufw allow 80
    sudo certbot certonly --standalone -d 自分のDNS

    2025/10/14追記:
    現在はこの3行で証明書ができます。
    ただし、80番のポート開放及びファイアウォールの解除を忘れずに。入力したドメインが本当に自分の物なのか確認するためにサーバーからアクセスがあります。

    エラーが発生(2025/10/14追記:しません)

    のはずだったが

    ModuleNotFoundError: No module named 'symbol'

    なんかエラーが出ました。
    それでこれチャットGPTに聞いてみると、symbolはPython3.9まではあったものの、以降廃止されてたっぽい。
    なるほど。このツールはPythonでできているのか
    私もLinuxに入ってるのは3.10だったので、それを使って本ツールは起動しようとしてエラーになったと考えられる。

    Python3.9のインストール

    というわけでsymbolライブラリが存在する。3.9をインストールします。
    私はUbuntuを使っているので、以下のコマンドでインストールしました。

    sudo add-apt-repository ppa:deadsnakes/ppa
    sudo apt update
    sudo apt install python3.9
    sudo apt install python3.9-distutils

    まだ何か足りない?

    さて、これで3.9をインストールできたんですが、なんとこれでもなんかライブラリが足りないみたいでエラーになります。
    エラーが出ているライブラリはcryptographyです。

    なぜかライブラリのアンインストールなどがうまくいかず、アップグレードもうまくできなかったので、仮想環境を作ってやり直すことにしました。
    こうすることでライブラリを新しくインストールし直してしまおうという試みです。

    sudo apt-get install python3.9-venv
    python3.9 -m venv venv
    source venv/bin/activate
    pip install cryptography
    pip install certbot

    やっと実行する

    準備が整いました。仮想環境内のcertonlyをダイレクトに起動します。
    引数はとりあえずキーを生成するために必要なスタンドアローンモードです。後ろには自分の家のDNSを入れてください。

    sudo ./venv/bin/certbot certonly --standalone -d 自分のDNS

    実行結果

    3度目の正直、やっと起動しましたね。
    (まあ、裏ではもっとたくさん試行してるんだけど…)

    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Enter email address (used for urgent renewal and security notices)
     (Enter 'c' to cancel): 自分のメアド
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Please read the Terms of Service at
    https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree in
    order to register with the ACME server. Do you agree?
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (Y)es/(N)o: Y
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Would you be willing, once your first certificate is successfully issued, to
    share your email address with the Electronic Frontier Foundation, a founding
    partner of the Let's Encrypt project and the non-profit organization that
    develops Certbot? We'd like to send you email about our work encrypting the web,
    EFF news, campaigns, and ways to support digital freedom.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (Y)es/(N)o: Y
    Account registered.
    Requesting a certificate for 自分のDNS
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Could not bind TCP port 80 because it is already in use by another process on
    this system (such as a web server). Please stop the program in question and then
    try again.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (R)etry/(C)ancel: 

    ちょっと失敗、ポートの80番を空けるように要求されました
    Difyが使っているので一旦落とします。
    あと、普段はあけてないので一瞬だけポート80も開けておきます。
    準備ができたら再試行

    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Requesting a certificate for 自分のDNS
    
    Successfully received certificate.
    Certificate is saved at: /etc/letsencrypt/live/自分のDNS/fullchain.pem
    Key is saved at:         /etc/letsencrypt/live/自分のDNS/privkey.pem
    This certificate expires on 2024-11-26.
    These files will be updated when the certificate renews.
    Certbot has set up a scheduled task to automatically renew this certificate in the background.
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    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
    画像

    キーが完成しました。有効期限は3ヶ月みたいですね。3ヶ月おきに作り直したいですが、ポート80あけっぱは嫌だな…。何か解決策がないか後で考えましょう。
    とりあえずはこれでBOTの方に戻れます。

    自動更新の無効化

    最後のメッセージの一文"Certbot has set up a scheduled task to automatically renew this certificate in the background."
    これ自動更新を有効にしましたと書いてあります。
    ポート80は開けっ放しにしないので自動でやってもらっても失敗するだけなので無効化します。

    こんな感じでスケジュールされていることが分かるので

    $systemctl list-timers | grep certbot
    Fri 2024-09-06 08:33:35 JST 8h left       Thu 2024-09-05 13:15:02 JST 11h ago    certbot.timer                  certbot.service

    こんな感じで無効にします

    $ sudo systemctl stop certbot.timer
    $ sudo systemctl disable certbot.timer

    更新の方法は別途考えます。
    確かUPnPを使えば自動でポート開放と閉鎖ができるのでその辺を利用しつつッて感じになりそうです。

    更新はこちらで行いました


    HTTPS通信のやり方

    以下の記事のテストコードをご確認ください

    そもそもDNSって?

    ちなみに当然のようにDNSとか言っていましたが、私はダイナミックDNSを使っています。

    DNSとはホスト名をIPアドレスに変換してくれるサービスのことです。
    通常個人のインターネット回線はオプションに加入していない限り、IPアドレスが変動する動的IPです。
    しかし、私のようにサーバーを持っている人間はIPアドレスが代わられると、外部からのアクセスができなくなり非常に困ります。
    こういう時助かるのがダイナミックDNSです。このサービスを使うことで、好きなホスト名と自分の家のIPアドレスを結びつけることができます。もちろんIPアドレスは自分の家から提出しなければならないので、更新するための設備は必要です。昔はラズパイやっていましたが、今は24時間のLinuxPCでやっています。

    証明書を作るにはホスト名が必要みたいなので、よろしければ使っているサービスを紹介しますので、皆さんも参考にしてみてください。

    ちなみに、このサービスを利用している理由はArduinoでeasyddnsというライブラリを使って更新できるからです。そういえば、ラズパイを使う前はESP32で更新してました。


    最後に

    利用規約

    情報や作品の活用時は事前に利用規約をご確認ください。

    コメントについて

    利用規約のガイドラインを確認の上コメントしてください


     
     
    モノづくりが趣味。 "売ってないなら自分で作ればいいじゃない"をコンセプトに、機械/電気/AI/プログラム/ネットワーク 全部やります。 記事執筆はAI不使用。 ご連絡や利用規約はプロフィール記事参照。

    あなたへのおすすめ