certbot実行時のエラー

certbot実行時にエラーが出るようになってしまった。原因と対処法のメモ。

現象

certbot実行時に次のようなエラーが出る。

Traceback (most recent call last):
  File "/usr/local/bin/certbot", line 33, in <module>
    sys.exit(load_entry_point('certbot==1.31.0', 'console_scripts', 'certbot')())
  File "/usr/local/bin/certbot", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/usr/local/lib/python3.9/importlib/metadata.py", line 86, in load
    module = import_module(match.group('module'))
  File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/usr/local/lib/python3.9/site-packages/certbot/main.py", line 6, in <module>
    from certbot._internal import main as internal_main
  File "/usr/local/lib/python3.9/site-packages/certbot/_internal/main.py", line 19, in <module>
    import josepy as jose
  File "/usr/local/lib/python3.9/site-packages/josepy/__init__.py", line 40, in <module>
    from josepy.json_util import (
  File "/usr/local/lib/python3.9/site-packages/josepy/json_util.py", line 14, in <module>
    from OpenSSL import crypto
  File "/usr/local/lib/python3.9/site-packages/OpenSSL/__init__.py", line 8, in <module>
    from OpenSSL import crypto, SSL
  File "/usr/local/lib/python3.9/site-packages/OpenSSL/crypto.py", line 14, in <module>
    from cryptography import utils, x509
  File "/usr/local/lib/python3.9/site-packages/cryptography/x509/__init__.py", line 6, in <module>
    from cryptography.x509 import certificate_transparency
  File "/usr/local/lib/python3.9/site-packages/cryptography/x509/certificate_transparency.py", line 10, in <module>
    from cryptography.hazmat.bindings._rust import x509 as rust_x509
ImportError: cannot import name 'x509' from 'cryptography.hazmat.bindings._rust' (unknown location)

思い当たる原因は、portmasterでパッケージを更新したこと。

原因

security/py-cryptographyの最新パッケージでは、lang/rustが必須となった。にもかかわらず、rustを含めてビルドするための設定がpy-cryptographyに含まれていないために、エラーが出る。

対処法

取れる対処法は、次のいずれか。

  1. certbotを捨てて、acme.shに移行する。
  2. py-cryptographyを38.0.1から3.4.8に戻す。
  3. py-cryptographyにパッチを当てて、rustと共にビルドする。
  4. portsのパッケージをアンインストールして、pipでインストールし直す。
  5. portsが修正されるのを気長に待つ。

acme.shを推す声が割と多い。依存関係が少ないので、トラブルが少ないから。この機会に乗り換えるのもいいかもしれない。

portsもいつかは修正されると思うけど、いつになったら修正されるかは……。修正される前に認証の有効期限が切れそうな気がしてならない。

対処法

acme.shへの移行と、portsの修正待ちについては省略。

py-cryptographyのバージョンを戻す

38.0.1から3.4.8に戻せばcertbotが動くようになる。

パッケージのバージョンを戻すなら、net/gitupを使うのが便利らしい。以前はportdowngradeが使われていたが、ソースのバージョン管理がSVNからgitに切り替わったのにともなって使えなくなった。

ただし、py-cryptographyのバージョンを戻すだけのためにgitupを設定するのもかったるい。というわけで、超邪道だけどpipを使ってお茶を濁すことにした。

# pip install cryptography==3.4.8

ただし、これをやっちゃうと、portmasterで管理されているバージョンと実際にインストールされているバージョンが食い違ってしまう。決してお薦めはできない。でも、とりあえず動くようにはなる。

いっそこれを機会に、Pythonパッケージは全部portsからではなくてpip管理に変更しちゃってもいいかもしれない。

py-cryptographyにパッチを当てる

FreeBSD Bugzillaの「Bug 254853 – security/py-cryptography: Update to 37.0.2」のAttachment「update to 38.0.1 with rust build」をファイルに保存して、次のようにコマンドを実行してパッチを当てる。パッチはRAW_UNIFIED.patchというファイルに保存したものとする。

# sudo patch -p1 --directory /usr/ports/ --input RAW_UNIFIED.patch
# cd /usr/ports/security/py-cryptography
# make install

ただし、このパッチはpy-opensslのバージョン22.00を必要とする。portsから入れたものは20.0なので、pipで更新する必要あり。

# pip install openssl=22.00

パッチを当てた上にpipで別バージョンを入れる必要があるので、py-cryptographyを単純に戻すだけの方が楽だと思う。

pipでインストールし直す

certbot関連のパッケージをすべてアンインストールする、または仮想環境上で、pipを使ってインストールし直せば、cryptographyが最新バージョンでもcertbotでエラーが出ることはない。

部分的にpipでインストールするよりは、もういっそcertbot用の仮想環境を作ってpipで管理する方がいいのかもしれない。

参考

この件に関する報告は、次のとおり。

タイトルとURLをコピーしました