メむンコンテンツぞスキップ
芋出し画像

【Let's Encrypt】SSL蚌明曞をcertbotで自動曎新 (ポヌト80䜿っおない人向け) Pythonでポヌト80開攟を自動化しお曎新

    こんにちはRcatです。
    前回の蚘事でcertbotを䜿甚したSSL蚌明曞の取埗を行いたした。
    なんずか取埗に持ち蟌めたものの、ポヌト80を䜿甚しお認蚌を行うため、自動曎新はできたせんでした。
    ずいうこずで、今回は曎新を自動化するためのプログラムを曞いおいこうず思いたす。

    前回の蚘事はこちら
    読んでいない堎合よくわからない個所が出おくるので先に読んでおくこずをお勧めしたす。


    はじめに

    利甚芏玄

    情報や䜜品の掻甚時は事前に利甚芏玄をご確認ください。

    コメントに぀いお

    利甚芏玄のガむドラむンを確認の䞊コメントしおください


    抂芁

    䞀郚の方は「え䜕で自動曎新できないの?普通りェブで䜿っおるよね??」ず思ったかもしれたせんね。
    前提ずしお、私はポヌト80番でWebサヌバヌを立おおいたせん。ずいうか個人でこういうこずしおる人っお、なかなかいないんじゃないでしょうか?リスクも高いですし。

    なのでcertbotを䜿甚しお蚌明曞を曎新するには、その時々で80番ポヌトを開攟する必芁がありたす。

    ずいうわけで、今回はPythonを䜿っお80番ポヌトの開攟を自動で行い蚌明曞の取埗たでを自動化しようず思いたす。

    certbotずは?

    先ほどから䜕回か出おきおいるcertbotですが、こちらはLet's EncryptからSSL蚌明曞を簡単に取埗するためのツヌルです。

    詳しくは以䞋で玹介しおいたす。

    自動曎新サヌビスを確認する

    サヌビスの内容確認

    前回は最埌に無効化したしたが、そもそもそのサヌビスでどんなこずをやっおいるのか参考にするため確認したす。

    こちらのコマンドで確認したす。
    䞋の方で入ったんですね。

    $ sudo ls /etc/systemd/system/ | grep cert
    $ sudo ls /lib/systemd/system/ | grep cert
    certbot.service
    certbot.timer
    
    systemctl cat certbot.service
    # /lib/systemd/system/certbot.service
    [Unit]
    Description=Certbot
    Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
    Documentation=https://certbot.eff.org/docs
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/certbot -q renew
    PrivateTmp=true
    
    $ systemctl cat certbot.timer
    # /lib/systemd/system/certbot.timer
    [Unit]
    Description=Run certbot twice daily
    
    [Timer]
    OnCalendar=*-*-* 00,12:00:00
    RandomizedDelaySec=43200
    Persistent=true
    
    [Install]
    WantedBy=timers.target

    普通のサヌビスずタむマヌずいうのが入っおたすね。タむマヌずいうのは初めお芋たした。
    いやヌ勉匷になりたすね。今床䜿う機䌚があれば䜿いたしょう。

    ↓䜿いたした

    で確認したいのがこちら
    ExecStart=/usr/bin/certbot -q renew
    これが実行コマンドですね。で、これで䜕をやっおいるのか、たず確認したしょう。

    詳现を確認する

    党おのヘルプを衚瀺したす。

    certbot -h all

    これを実行するず、膚倧な量のヘルプが衚瀺されたす。
    䞊で䜿われおる匕数は以䞋のように確認できたした。
    -qは䜙蚈な衚瀺をさせないような意味があるみたいです。
    renewは、有効期限の近い蚌明曞を曎新するずいう意味みたいです。

    -q, --quiet           Silence all output except errors. Useful for automation via cron. Implies --non-interactive. (default: False)
    
    manage:
      Various subcommands and flags are available for managing your certificates:
    
      certificates          List certificates managed by Certbot
      delete                Clean up all files related to a certificate
      renew                 Renew all certificates (or one specified with --cert-name)
      revoke                Revoke a certificate specified with --cert-path or --cert-name
      reconfigure           Update renewal configuration for a certificate specified by --cert-name

    前回䜜成時の匕数を調べおみるず、以䞋のようなこずが分かりたした。

    certonly
    蚌明曞の取埗ず曎新はしたすが、むンストヌルはしないずいう蚭定です。
    取埗した埌、Pythonのフォルダに持っおくのでこれで正解ですね。

    standalone
    認蚌甚にWebサヌバヌを立ち䞊げる蚭定みたいです。
    なるほど。これでWebサヌバヌを立ち䞊げるから、前回80番を暪取りされたんですね。
    たぁどっちにしろ80番を䜿うっおいうのは良くないので、これ甚にあけおおきたすが

    -d ドメむン
    ドメむンの指定です。

    ドメむンの郚分はたあ曎新だから自動で読み取りずかしそうですが、残りの2぀はたた同じ動䜜をしおくれるのでしょうか
    ず思ったら曞いおありたした。どうやらオプションは再利甚されるみたいです。

    renew:
      The 'renew' subcommand will attempt to renew any certificates previously obtained if they are close to expiry, and print a summary of the results. By default,
      'renew' will reuse the plugins and options used to obtain or most recently renew each certificate. You can test whether future renewals will succeed with `--dry-
      run`. Individual certificates can be renewed with the `--cert-name` option. Hooks are available to run commands before and after renewal; see
      https://certbot.eff.org/docs/using.html#renewal for more information on these.

    スクリプトを倉曎する

    珟圚の曎新甚コマンドは以䞋のようになっおいたすが、こちらを次のように曞き換えたす

    元の内容
    ExecStart=/usr/bin/certbot -q renew

    倉曎する内容
    ExecStart=/SSD/certbot/venv/bin/certbot renew --pre-hook "/SSD/certbot/portopen.sh open" --post-hook "/SSD/certbot/portopen.
    sh close"

    倉曎のポむント

    前提ですが、自動的に蚭定された曎新タむマヌを䜿いたす。
    Pythonなのでむンポヌトしおも行けるかず思ったんですが、思ったより難しそうなのでタむマヌ流甚にしたす。

    たず、実行ファむルを倉えたす。
    ずいうのも普通ならそのたたでいいのかもしれたせんが、私が今回やった内容では仮想環境にむンストヌルしおいるので、そこから起動しなければならないからです。

    次に2぀のオプションを远加したす。

    • --pre-hook
      蚌明曞曎新䜜業前に実行するスクリプトを指定したす。
      ここでポヌトを開攟するスクリプトを呌び出したす。

    • --post-hook
      蚌明曞曎新䜜業埌に実行するスクリプトを指定したす。
      ここでポヌトを閉鎖するスクリプトを呌び出したす。

    こうするこずでポヌト開攟䜜業を自動実行に組み蟌むこずができたす。

    動䜜確認

    オプションの䞭に実隓のために䜿う"--dry-run"ずいうのがあるので、これを指定し぀぀、䞊のコマンドを実行しおみたす。

    $ sudo ./venv/bin/certbot renew --dry-run --pre-hook "/SSD/certbot/portopen.sh open" --post-hook "/SSD/certbot/portopen.sh close"
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Processing /etc/letsencrypt/renewal/DNS.com.conf
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    if response_ocsp.next_update and response_ocsp.next_update < now - timedelta(minutes=5):
    Hook 'pre-hook' ran with output:
     操䜜に成功したした
    Simulating renewal of an existing certificate for DNS.com
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Congratulations, all simulated renewals succeeded:
      /etc/letsencrypt/live/DNS.com/fullchain.pem (success)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Hook 'post-hook' ran with output:
     操䜜に成功したした

    ポヌト操䜜のスクリプトは結果をプリントするので、操䜜が成功したこずがわかりたす。
    鍵の曎新の方も正垞にアクセスできおいるみたいです。

    ゜ヌスコヌド

    ずいうわけで、䞊で䜿ったポヌト開攟甚のスクリプトを芋おみたしょう。

    呌び出し甚シェルスクリプト

    Pythonを起動するためだけのシェルです。
    コマンド自䜓がrootで実行するので、仮想環境で実行しないずルヌトのPythonで起動しおしたうので、ラむブラリが読み蟌めたせん。
    このような圢で起動するようにしたしょう。

    画像

    ポヌト開攟甚Python

    ポヌトを開攟する本䜓です。
    このスクリプトには匕数に"open"か"close"の文字列を枡すこずで動䜜を倉曎できたす。
    このスクリプトでは、ポヌト開攟時に30分ずいう時間制限を蚭けおいたす。䞇が䞀クロヌズがうたくいかなかった堎合でも、30分埌には勝手に閉じたす。

    画像

    ちなみにラむブラリのむンポヌトはこんな感じになっおいたす。
    ポヌトを開けるためのmsずいうのは自䜜のポヌト操䜜モゞュヌルです。

    画像

    M_search2モゞュヌルに関しおは以䞋の蚘事で玹介/配垃しおいたす。

    systemdに反映させる

    では、今たでの内容をたずめお操䜜に反映させたしょう。

    ナニットファむルを線集する

    たずはsystemdのナニットファむルを線集したす。
    䞀郚だけ䞊曞きずいうこずができるみたいなので、今回はそれで行きたす。

    sudo systemctl edit certbot.service

    ゚ディタヌが起動するので䞊の方にあるコメントずコメントの間に倉曎する行を远加したす。
    今回はServiceの行を远加しおいるのがわかりたす。
    ExecStartだけを曞き蟌むずうたくいかなかったので、ちょっず調べたら以䞋みたいな曞き方がいいっおいうのがあったので詊したずころ、これでうたくいきたした。

    ### Editing /etc/systemd/system/certbot.service.d/override.conf
    ### Anything between here and the comment below will become the new contents of the file
    
    [Service]
    ExecStart=
    ExecStart=/SSD/certbot/venv/bin/certbot renew --pre-hook "/SSD/certbot/portopen.sh open" --post-hook "/SSD/certbot/portopen.sh close"
    
    ### Lines below this comment will be discarded
    
    ### /lib/systemd/system/certbot.service
    # [Unit]
    # Description=Certbot
    # Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
    # Documentation=https://certbot.eff.org/docs
    # [Service]
    # Type=oneshot
    # ExecStart=/usr/bin/certbot -q renew
    # PrivateTmp=true

    保存する時に倉な名前で保存されるのですが、ここで名前をきちんず指定しないず察応されたせん。
    ファむル名は以䞋の感じになるようにしおください。
    /etc/systemd/system/certbot.service.d/override.conf
    デフォルトでは、最埌の名前のずころにランダムな文字列が付いおいたりするず思うので、そういったものを倖したす。

    内容を衚瀺しおみたす。
    なんか増えおたすね。
    これうたくいった感じなんでしょうか
    たぁ、実際に動かせばわかるでしょう。

    $ systemctl cat certbot.service
    # /lib/systemd/system/certbot.service
    [Unit]
    Description=Certbot
    Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
    Documentation=https://certbot.eff.org/docs
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/certbot -q renew
    PrivateTmp=true
    
    # /etc/systemd/system/certbot.service.d/override.conf
    ### Editing /etc/systemd/system/certbot.service.d/override.conf
    ### Anything between here and the comment below will become the new contents of the file
    
    [Service]
    ExecStart=
    ExecStart=/SSD/certbot/venv/bin/certbot renew --pre-hook "/SSD/certbot/portopen.sh open" --post-hook "/SSD/certbot/portopen.sh close"
    
    ### Lines below this comment will be discarded
    
    ### /lib/systemd/system/certbot.service
    # [Unit]
    # Description=Certbot
    # Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
    # Documentation=https://certbot.eff.org/docs
    # [Service]
    # Type=oneshot
    # ExecStart=/usr/bin/certbot -q renew
    # PrivateTmp=true

    ちなみに、初期に蚭定されおいた自動曎新は以䞋のようになっおいお萜ちおいたした。
    そりゃそうですよね。動かないファむルを指定しおいるんですから。
    ぀たり、このサヌビスを再開した時に即萜ちしなければうたくいったずも蚀えたす。

    $ systemctl status certbot.service
    × certbot.service - Certbot
         Loaded: loaded (/lib/systemd/system/certbot.service; static)
         Active: failed (Result: exit-code) since Thu 2024-09-05 13:15:02 JST; 2 days ago
           Docs: file:///usr/share/doc/python-certbot-doc/html/index.html
                 https://certbot.eff.org/docs
       Main PID: 1484963 (code=exited, status=1/FAILURE)
            CPU: 101ms
    
     9月 05 13:15:02 rcat-Green-G5 certbot[1484963]:   File "/usr/lib/python3/dist-packages/OpenSSL/crypto.py", line 17, in <module>
     9月 05 13:15:02 rcat-Green-G5 certbot[1484963]:     from OpenSSL._util import (
     9月 05 13:15:02 rcat-Green-G5 certbot[1484963]:   File "/usr/lib/python3/dist-packages/OpenSSL/_util.py", line 6, in <module>
     9月 05 13:15:02 rcat-Green-G5 certbot[1484963]:     from cryptography.hazmat.bindings.openssl.binding import Binding
     9月 05 13:15:02 rcat-Green-G5 certbot[1484963]:   File "/usr/lib/python3/dist-packages/cryptography/hazmat/bindings/openssl/binding.py", line 14, in <module>
     9月 05 13:15:02 rcat-Green-G5 certbot[1484963]:     from cryptography.hazmat.bindings._openssl import ffi, lib
     9月 05 13:15:02 rcat-Green-G5 certbot[1484963]: ModuleNotFoundError: No module named '_cffi_backend'
     9月 05 13:15:02 rcat-Green-G5 systemd[1]: certbot.service: Main process exited, code=exited, status=1/FAILURE
     9月 05 13:15:02 rcat-Green-G5 systemd[1]: certbot.service: Failed with result 'exit-code'.
     9月 05 13:15:02 rcat-Green-G5 systemd[1]: Failed to start Certbot.

    サヌビスを再起動する

    ずいうわけでリスタヌトしおみたす。
    ログを確認するず即萜ちはしおいないみたいですね。

    $ sudo systemctl restart certbot.service
    $ sudo systemctl status certbot.service
    ○ certbot.service - Certbot
         Loaded: loaded (/lib/systemd/system/certbot.service; static)
        Drop-In: /etc/systemd/system/certbot.service.d
                 mqoverride.conf
         Active: inactive (dead)
           Docs: file:///usr/share/doc/python-certbot-doc/html/index.html
                 https://certbot.eff.org/docs
    
     9月 08 13:27:35 rcat-Green-G5 certbot[2356085]:   if response_ocsp.next_update and response_ocsp.next_update < now - timedelta(minutes=5):
     9月 08 13:27:35 rcat-Green-G5 certbot[2356085]: Certificate not yet due for renewal
     9月 08 13:27:35 rcat-Green-G5 certbot[2356085]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     9月 08 13:27:35 rcat-Green-G5 certbot[2356085]: The following certificates are not due for renewal yet:
     9月 08 13:27:35 rcat-Green-G5 certbot[2356085]:   /etc/letsencrypt/live/DNS.com/fullchain.pem expires on 2024-11-26 (skipped)
     9月 08 13:27:35 rcat-Green-G5 certbot[2356085]: No renewals were attempted.
     9月 08 13:27:35 rcat-Green-G5 certbot[2356085]: No hooks were run.
     9月 08 13:27:35 rcat-Green-G5 certbot[2356085]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     9月 08 13:27:35 rcat-Green-G5 systemd[1]: certbot.service: Deactivated successfully.
     9月 08 13:27:35 rcat-Green-G5 systemd[1]: Finished Certbot.

    この状態だずそもそも䜕もしおくれなかったので、ドラむランを入れ盎しお再床実行しおみたした。
    ログの䞭にポヌト開攟を操䜜した蚘述がありたすね。どうやらうたくいっおるみたいです。

    $ sudo systemctl status certbot.service
    ○ certbot.service - Certbot
         Loaded: loaded (/lib/systemd/system/certbot.service; static)
        Drop-In: /etc/systemd/system/certbot.service.d
                 mqoverride.conf
         Active: inactive (dead)
           Docs: file:///usr/share/doc/python-certbot-doc/html/index.html
                 https://certbot.eff.org/docs
    
     9月 08 13:45:22 rcat-Green-G5 certbot[2375987]:  操䜜に成功したした
     9月 08 13:45:22 rcat-Green-G5 certbot[2375987]: Simulating renewal of an existing certificate for rcatnekokawaii.dynu.net
     9月 08 13:45:31 rcat-Green-G5 certbot[2375987]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     9月 08 13:45:31 rcat-Green-G5 certbot[2375987]: Congratulations, all simulated renewals succeeded:
     9月 08 13:45:31 rcat-Green-G5 certbot[2375987]:   /etc/letsencrypt/live/rcatnekokawaii.dynu.net/fullchain.pem (success)
     9月 08 13:45:31 rcat-Green-G5 certbot[2375987]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     9月 08 13:45:32 rcat-Green-G5 certbot[2375987]: Hook 'post-hook' ran with output:
     9月 08 13:45:32 rcat-Green-G5 certbot[2375987]:  操䜜に成功したした
     9月 08 13:45:32 rcat-Green-G5 systemd[1]: certbot.service: Deactivated successfully.
     9月 08 13:45:32 rcat-Green-G5 systemd[1]: Finished Certbot.

    タむマヌを再起動する

    前回止めおしたったタむマヌを再起動したす。
    自動起動を有効にしおリスタヌトをかけたす。

    $ sudo systemctl enable certbot.timer
    Created symlink /etc/systemd/system/timers.target.wants/certbot.timer → /lib/systemd/system/certbot.timer.
    $ sudo systemctl restart certbot.timer

    ステヌタスを確認するず以䞋のようになっおいたした。
    正垞に動き出したみたいです。

    systemctl status certbot.timer
    ● certbot.timer - Run certbot twice daily
         Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
         Active: active (waiting) since Sun 2024-09-08 13:53:25 JST; 36s ago
        Trigger: Mon 2024-09-09 10:30:09 JST; 20h left
       Triggers: ● certbot.service
    
     9月 08 13:53:25 rcat-Green-G5 systemd[1]: Started Run certbot twice daily.

    説明を芋たずころ、期限が1ヶ月に迫るず曎新するようです。
    今のずころ知らないうちに曎新されおいたす。

    たずめ

    今回は無料のSSL蚌明曞の自動曎新に぀いお考えおみたした。
    普通の環境であれば、既存のWebサヌバヌを䜿っお簡単に曎新できるように蚭蚈されおいるみたいですが、私のようにちょっず違う䜿い方をする人にずっおは少々工倫が必芁ですね。
    ずはいえ、簡単であるこずには間違いないので非垞にありがたいですね。
    それではたたお䌚いしたしょう。

     
     

    Rcat999

     
     
    モノづくりが趣味。 "売っおないなら自分で䜜ればいいじゃない"をコンセプトに、機械/電気/AI/プログラム/ネットワヌク 党郚やりたす。 蚘事執筆はAI䞍䜿甚。 ご連絡や利甚芏玄はプロフィヌル蚘事参照。

    あなたぞのおすすめ