当收到太多请求时,gpg-agent“忘记”密钥密码

当收到太多请求时,gpg-agent“忘记”密钥密码

我正在运行 Ubuntu(通过 Regolith),登录时我的 gpg 密钥已解锁。我正在并行运行多个解密操作,我注意到,如果我得到 7 以上,gpg-agent将“忘记”密钥已解锁然后我被提示输入 pinentry。

❯ gpg --version
gpg (GnuPG) 2.2.27
libgcrypt 1.10.1

我做了一个最小的工作示例来在 python 中演示这一点。

创建一个测试文件来解密:echo "something" | gpg --encrypt -o test.gpg.在 shell 中运行gpg --decrypt test.gpg不会提示输入密码。

使用下面的脚本,如果将其WORKERNUM设置为低于 8(在我的机器上,但将其设置为 1,我想应该适用于任何机器),则脚本很乐意解密,而无需询问密码。但是,如果我将其提高到 8 或以上,我就会开始收到输入密码的请求,尽管似乎并非来自每个进程,而只是其中的一些进程。进程的执行显然也开始挂起(我假设它们正在等待gpg-agent)。

import subprocess
import multiprocessing as mp
import time



the_queue = mp.Queue()
WORKERNUM = 7

def worker_main(queue):
    while True:
        msg = queue.get(True)
        print(time.time(), msg)
        out = subprocess.run(["gpg", "--decrypt", "test.gpg"], capture_output=True)
        print(msg, time.time(), out.stdout)


the_pool = mp.Pool(WORKERNUM, worker_main, (the_queue,))

counter = 0
while True:
    counter += 1
    the_queue.put(counter)
    print(the_queue.qsize())
    while the_queue.qsize() > 10:
        time.sleep(0.1)

我尝试传递--batch给解密命令,但这并没有改变任何东西。我一直在浏览手册页gpg,看看gpg-agent是否提到了与此相关的内容,但我找不到任何内容。我有两个问题:

a)为什么会发生这种情况,b)我是否可以配置一些东西,这样就不必计算出处理池的最大大小来避免这种情况,而是gpg处理这个问题并且我没有得到 pinentry

答案1

经过仔细监测journalctl我发现实际的错误是Cannot allocate memory。基于这次讨论gpg-agent如果多个线程尝试访问安全内存,则可能会耗尽安全内存。设置auto-expand-secmem 100即可~/.gnupg/gpg-agent.conf解决问题。

       --auto-expand-secmem n                                                                                                                                  Allow Libgcrypt to expand its secure memory area as required. The optional
value n is a non-negative integer with a suggested size in bytes of each
additionally allocated secure memory area. The value is rounded up to the next
32 KiB; usual C style prefixes are allowed. For an heavy loaded gpg-agent with
many concurrent connection this option avoids sign or decrypt errors due to out
of secure memory error returns.

相关内容