Letsencrypt: certbot_plugin_gandi を用いてSSL証明書を更新

June 24, 2019 – 9:27 am

ほぼ2ヶ月半前に取得したLetsecnryptのSSL証明書(「Letsencryptワイルドカード証明祖の取得と反映」)を更新したので、更新手続きをメモしておいた。

ワイルドカードにする前は、コマンド(“certbot renew”)で簡単に更新することができたが、ワイルドカードの証明書では一筋縄にはいかなかった。更新時に、ドメインを登録しているDNSの書き換えを必要にするため、それなりの手続きを必要とした。

いろいろ調べたみると、我がサイトを登録しているgandiのDNSn向けの certbot_plugin_gandiがあり、これを活用できれば、ワイルドカードでも自動的に更新可能になることがわかった。

この記事では、certbot_plugin_gandi を導入した際の手続き、ログをメモしておいた。gandiのドメインサービスを受けているひとには役立つ情報かもしれない。

ワイルドカード証明書は”certbot renew”では更新できない
“certbot renuew”で更新しようとすると、失敗。失敗したときのログを以下に掲げる:

[root@localhost ~]# certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/yamasnet.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
Attempting to renew cert (yamasnet.com) from /etc/letsencrypt/renewal/yamasnet.com.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/yamasnet.com/fullchain.pem (failure)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/yamasnet.com/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)

コマンド “cerbot renyew” で更新するには –manual-auth-hook オプションでユーz-が自分で認証用手続きを準備することが必要。私の実力では、これを作るだけの実力はない。この手続き、ドメインサービスの特徴を反映することになる筈なので、我がサイトの利用しているドメインサービス gandi-netに関係するLetsencryptの更新情報を調査することにした。

プラグイン certbot_plugin_gandi
いろいろ Google上で検索するなかで、Certbot plugin for authentication using Gandi LiveDNSを見つけ、これに沿って、SSL証明書の更新を行うことにする。

このドキュメントで記述されている手続きは以下の4段階:

  1. Obtain a Gandi API token (see Gandi LiveDNS API)
  2. Install the plugin using:
    pip install certbot-plugin-gandi
  3. Create a gandi.ini config file with the following contents and apply chmod 600 gandi.ini on it:
    certbot_plugin_gandi:dns_api_key=APIKEY
  4. Run certbot and direct it to use the plugin for authentication and to use the config file previously created:
    certbot certonly -a certbot-plugin-gandi:dns –certbot-plugin-gandi:dns-credentials gandi.ini -d domain.com

基本的には上記手続きに沿って更新作業を完了。ただ、わがサーバ(Centos7)上でpipの動作環境を整えるなどが必要になる。以下、pipのインストールから、更新作業を記述。

pip のインストール

[root@server01 ~]# yum install --enablerepo=epel python-pip
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.nara.wide.ad.jp
 * epel: mirror01.idc.hinet.net
 * extras: ftp.nara.wide.ad.jp
 * nux-dextop: mirror.li.nux.ro
 * updates: ftp.nara.wide.ad.jp
Resolving Dependencies
--> Running transaction check
---> Package python2-pip.noarch 0:8.1.2-8.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=====================================================================================================================================
 Package                           Arch                         Version                             Repository                  Size
=====================================================================================================================================
Installing:
 python2-pip                       noarch                       8.1.2-8.el7                         epel                       1.7 M

Transaction Summary
=====================================================================================================================================
Install  1 Package

Total download size: 1.7 M
Installed size: 7.2 M
Is this ok [y/d/N]: y
Downloading packages:
python2-pip-8.1.2-8.el7.noarch.rpm                                                                            | 1.7 MB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python2-pip-8.1.2-8.el7.noarch                                                                                    1/1 
  Verifying  : python2-pip-8.1.2-8.el7.noarch                                                                                    1/1 

Installed:
  python2-pip.noarch 0:8.1.2-8.el7

pipを最新版にupgrade:

[root@server01 ~]# pip install --upgrade pip
Collecting pip
  (省 略)
Installing collected packages: pip
  Found existing installation: pip 8.1.2
    Uninstalling pip-8.1.2:
      Successfully uninstalled pip-8.1.2
Successfully installed pip-19.1.1

[root@localhost letsencrypt]# pip --version
pip 19.1.1 from /usr/lib/python2.7/site-packages/pip (python 2.7)

certbot-plugin-gandi をインストール:

[root@server01 ~]# pip install certbot-plugin-gandi
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Collecting certbot-plugin-gandi
  Downloading https://files.pythonhosted.org/packages/cb/9f/4ba23296cb5b87a9a186170db0437b5b51aa816d38fdf517095de12c76b5/certbot-plugin-gandi-1.1.1.tar.gz
Requirement already satisfied: certbot in /usr/lib/python2.7/site-packages (from certbot-plugin-gandi) (0.31.0)
Requirement already satisfied: zope.interface in /usr/lib64/python2.7/site-packages (from certbot-plugin-gandi) (4.0.5)
Requirement already satisfied: requests>=2.4.2 in /usr/lib/python2.7/site-packages (from certbot-plugin-gandi) (2.6.0)
Requirement already satisfied: acme>=0.29.0 in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (0.31.0)
Requirement already satisfied: ConfigArgParse>=0.9.3 in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (0.11.0)
Requirement already satisfied: configobj in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (4.7.2)
Requirement already satisfied: cryptography>=1.2.3 in /usr/lib64/python2.7/site-packages (from certbot->certbot-plugin-gandi) (1.7.2)
Requirement already satisfied: josepy in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (1.1.0)
Requirement already satisfied: mock in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (1.0.1)
Requirement already satisfied: parsedatetime>=1.3 in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (2.4)
Requirement already satisfied: pyrfc3339 in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (1.0)
Requirement already satisfied: pytz in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (2016.10)
Requirement already satisfied: setuptools in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (0.9.8)
Requirement already satisfied: zope.component in /usr/lib/python2.7/site-packages (from certbot->certbot-plugin-gandi) (4.1.0)
Requirement already satisfied: PyOpenSSL>=0.13.1 in /usr/lib64/python2.7/site-packages (from acme>=0.29.0->certbot->certbot-plugin-gandi) (0.13.1)
Requirement already satisfied: requests-toolbelt>=0.3.0 in /usr/lib/python2.7/site-packages (from acme>=0.29.0->certbot->certbot-plugin-gandi) (0.8.0)
Requirement already satisfied: six>=1.9.0 in /usr/lib/python2.7/site-packages (from acme>=0.29.0->certbot->certbot-plugin-gandi) (1.9.0)
Requirement already satisfied: idna>=2.0 in /usr/lib/python2.7/site-packages (from cryptography>=1.2.3->certbot->certbot-plugin-gandi) (2.4)
Requirement already satisfied: pyasn1>=0.1.8 in /usr/lib/python2.7/site-packages (from cryptography>=1.2.3->certbot->certbot-plugin-gandi) (0.1.9)
Requirement already satisfied: enum34 in /usr/lib/python2.7/site-packages (from cryptography>=1.2.3->certbot->certbot-plugin-gandi) (1.0.4)
Requirement already satisfied: ipaddress in /usr/lib/python2.7/site-packages (from cryptography>=1.2.3->certbot->certbot-plugin-gandi) (1.0.16)
Requirement already satisfied: cffi>=1.4.1 in /usr/lib64/python2.7/site-packages (from cryptography>=1.2.3->certbot->certbot-plugin-gandi) (1.6.0)
Requirement already satisfied: future in /usr/lib/python2.7/site-packages (from parsedatetime>=1.3->certbot->certbot-plugin-gandi) (0.16.0)
Requirement already satisfied: zope.event in /usr/lib/python2.7/site-packages (from zope.component->certbot->certbot-plugin-gandi) (4.0.3)
Requirement already satisfied: pycparser in /usr/lib/python2.7/site-packages (from cffi>=1.4.1->cryptography>=1.2.3->certbot->certbot-plugin-gandi) (2.14)
Installing collected packages: certbot-plugin-gandi
  Running setup.py install for certbot-plugin-gandi ... done
Successfully installed certbot-plugin-gandi-1.1.1

更新用コマンドの実行(実行時にError発生)

[root@localhost letsencrypt]# certbot certonly -a certbot-plugin-gandi:dns --certbot-plugin-gandi:dns-credentials gandi.ini -d *.yamasnet.com -d yamasnet.com 
Traceback (most recent call last):
  File "/bin/certbot", line 9, in 
    load_entry_point('certbot==0.31.0', 'console_scripts', 'certbot')()
  File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 378, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 2566, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 2260, in load
    entry = __import__(self.module_name, globals(),globals(), ['__name__'])
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 21, in 
    from certbot import client
  File "/usr/lib/python2.7/site-packages/certbot/client.py", line 16, in 
    from acme import client as acme_client
  File "/usr/lib/python2.7/site-packages/acme/client.py", line 37, in 
    requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3()  # type: ignore
  File "/root/.local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 118, in inject_into_urllib3
    _validate_dependencies_met()
  File "/root/.local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 155, in _validate_dependencies_met
    raise ImportError("'pyOpenSSL' module missing required functionality. "
ImportError: 'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer.

Error に対応するため pipを条件付きでupgrade:
上述のErrorに対応するためGoogle情報を検索したところ、「CentOS7に入れたLet’s EncryptでImportError」に pipを条件付きでupgradeすることで問題が解決することが示唆されていた。これにそって、以下のように pipを条件付きでupgrade。

[root@localhost letsencrypt]# pip install requests --ignore-installed
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Collecting requests
  Downloading https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl (57kB)
     |????????????????????????????????| 61kB 1.6MB/s 
Collecting chardet<3.1.0,>=3.0.2 (from requests)
  Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)
     |????????????????????????????????| 143kB 5.9MB/s 
Collecting idna<2.9,>=2.5 (from requests)
  Downloading https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl (58kB)
     |????????????????????????????????| 61kB 20.2MB/s 
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests)
  Using cached https://files.pythonhosted.org/packages/e6/60/247f23a7121ae632d62811ba7f273d0e58972d75e58a94d329d51550a47d/urllib3-1.25.3-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests)
  Downloading https://files.pythonhosted.org/packages/69/1b/b853c7a9d4f6a6d00749e94eb6f3a041e342a885b87340b79c1ef73e3a78/certifi-2019.6.16-py2.py3-none-any.whl (157kB)
     |????????????????????????????????| 163kB 3.1MB/s 
Installing collected packages: chardet, idna, urllib3, certifi, requests
Successfully installed certifi-2019.6.16 chardet-3.0.4 idna-2.8 requests-2.22.0 urllib3-1.25.3

[root@localhost letsencrypt]# pip install --upgrade --force-reinstall 'requests==2.6.0'
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Collecting requests==2.6.0
  Downloading https://files.pythonhosted.org/packages/73/63/b0729be549494a3e31316437053bc4e0a8bb71a07a6ee6059434b8f1cd5f/requests-2.6.0-py2.py3-none-any.whl (469kB)
     |????????????????????????????????| 471kB 2.1MB/s 
Installing collected packages: requests
  Found existing installation: requests 2.22.0
    Uninstalling requests-2.22.0:
      Successfully uninstalled requests-2.22.0

更新コマンドの実行とSSL証明書更新の確認:

[root@localhost letsencrypt]# certbot certonly -a certbot-plugin-gandi:dns --certbot-plugin-gandi:dns-credentials gandi.ini -d *.yamasnet.com -d yamasnet.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator certbot-plugin-gandi:dns, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
You have an existing certificate that contains a portion of the domains you
requested (ref: /etc/letsencrypt/renewal/yamasnet.com.conf)

It contains these names: *.yamasnet.com

You requested these names for the new certificate: *.yamasnet.com, yamasnet.com.

Do you want to expand and replace this existing certificate with the new
certificate?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(E)xpand/(C)ancel: E
Renewing an existing certificate
Performing the following challenges:
dns-01 challenge for yamasnet.com
Starting new HTTPS connection (1): dns.api.gandi.net
Starting new HTTPS connection (1): dns.api.gandi.net
Starting new HTTPS connection (1): dns.api.gandi.net
Waiting 10 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges
Starting new HTTPS connection (1): dns.api.gandi.net
Starting new HTTPS connection (1): dns.api.gandi.net
Resetting dropped connection: acme-v02.api.letsencrypt.org

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/yamasnet.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/yamasnet.com/privkey.pem
   Your cert will expire on 2019-09-18. 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

コマンド実行後、数時間後、yamasnet.comサイトにアクセスし、証明書が更新(更新期限が変更)されていることを確認。

関連ポスト:


Post a Comment