【问题标题】:pyinstaller of python daemon that uses cryptography throws exception: 'No module named '_hmacopenssl'使用加密的 python 守护程序的 pyinstaller 抛出异常:'没有名为 '_hmacopenssl' 的模块
【发布时间】:2023-08-20 09:30:01
【问题描述】:

您好 Stack Overflow 团队,

我有一个使用 daemon runner 用 python 编写的守护进程。即

from daemon import runner
import random
import time

class App():
    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/null'
        self.stderr_path = '/dev/null'
        self.pidfile_path = '/var/run/my_daemon.pid'
        self.pidfile_timeout = 5
    def run(self):
        seed = random.seed()
        rtime = random.randrange(21600,42300)
        count = 0
        while True:
            count += 1
            main()
            time.sleep(rtime)

app = App()
daemon_runner = runner.DaemonRunner(app)

在同一个守护程序中,当守护程序发现需要写入我们的远程数据库时,我使用:from cryptography.fernet import Fernet 来解密我们的数据库密码。 即

from cryptography.fernet import Fernet

def getTheIngredients(recipe):
    cipher_suite = Fernet(recipe['lock_smith'].encode())
    og_kush = cipher_suite.decrypt(recipe['og_kush_repro'].encode())
    raw_bacon = recipe['bacon'].encode()
    the_son_of_anton = Fernet(og_kush)
    bacon = the_son_of_anton.decrypt(raw_bacon)

    return bacon

我使用pyinstaller --onefile my_daemon.py 部署这个守护进程 并使用以下命令构建 rpm:rpmbuild -ba my_custom_daemon.spec

spec 文件的样子:

Name: my_daemon
Version: 1.1.1
Release:    0%{?dist}
Summary: my little daemon

Group: Miscellaneous
License: GPL
#URL:
Source0: my_daemon-1.1.1.tar.gz

BuildArch: x86_64
#BuildRequires: systemd
#Requires:

%description
my little daemon that does stuff :-)

%prep
%setup -q

%build

%install
rm -rf $RPM_BUILD_ROOT
install -d -m 0755 $RPM_BUILD_ROOT/usr/local/bin/
install -m 0755 my_daemon $RPM_BUILD_ROOT/usr/local/bin

mkdir -p %{buildroot}%{_unitdir}/
install -m 0644 %{name}.service %{buildroot}%{_unitdir}/

%post
%systemd_post %{name}.service

%clean
rm -rf $RPM_BUILD_ROOT

%files
%doc
/usr/local/bin/my_daemon
%{_unitdir}/my_daemon.service

%changelog
* Tue Jun 08 2021 M E <me@me.com> - 1.1.1-0
- stuff
- more stuff

当我的守护进程运行时,以下异常被捕获:

'No module named '_hmacopenssl'

而且我非常确定该异常与我添加用于为我解密的cryptography.fernet 有关。因为在我进行这些更改之前,我的守护进程运行良好。

所以在构建的 rpm 之外运行我的守护进程可以正常工作。 但是一旦我打包它并尝试通过安装的 rpm 运行它,它就会抛出该异常。

非常感谢您在这方面的任何帮助/指导。

【问题讨论】:

    标签: python cryptography pyinstaller rpm rpmbuild


    【解决方案1】:

    你必须添加

    Requires: python3-fernet
    

    但我猜在安装过程中你会点击“No such package python3-fernet”。所以你必须先打包那个。

    但它在 PyPI 上,所以使用 pyp2rpm --srpm fernet 应该很容易

    旁注:您的规范中还有其他几个问题,我建议您阅读https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/

    【讨论】:

    • 您好@msuchy,感谢您的建议。我能够将 python fernet 打包到一个 rpm 中并安装它,它也依赖于 python pyaes,所以我只是打包了它(在标准 repos 中不可用)并安装它的依赖项和 waalaaa,安装了 python3-fernet .这似乎已经解决了我在守护进程中的解密问题,因此它能够连接到我的远程数据库。但是,我仍然看到No module named '_hmacopenssl' 的异常被捕获在我的日志中...... :-( 关于如何解决这个问题的任何进一步的想法将不胜感激。
    • 也感谢您对我的规范文件的建议,我已经对其进行了一些调整:-) 我的小守护进程的构建方式是:pyinstaller --onefile my_daemon.py 它为我创建了一个二进制文件我与 systemd 服务一起使用。尽管欢迎任何进一步的建议来改进我的规范文件:-)
    • 您必须检查哪个 python 模块提供了 '_hmacopenssl',然后将其打包为 RPM 并由您的守护进程要求。