首页 > 解决方案 > 使用 subprocess.run 进行 GRPC ssl 脚本编写时遇到问题 [Python]

问题描述

我在编写为 GRPC 服务生成 SSL 密钥和证书的 python 脚本时遇到了困难。我正在尝试编写一个函数,该函数可以通过将 ip 传递给该文件来运行该文件中的命令。这是我写的,但是我收到一个我看不懂的错误,我会在底部列出

我的功能:

def cert_create(ip):
    subprocess.run(['SERVER_CN=', ip])
    subprocess.run(['openssl', 'genrsa', '-passout', 'pass:1111', '-des3', '-out', 'ca.key', '4096'])
    subprocess.run(['openssl', 'req', '-passin', 'pass:1111', '-new', '-x509', '-days', '3650', '-key', 'ca.key', '-out', 'ca.crt', '-subj', '"/CN=${SERVER_CN}"'])
    subprocess.run(['openssl', 'genrsa', '-passout', 'pass:1111', '-des3', '-out', 'server.key', '4096'])
    subprocess.run(['openssl', 'req', '-passin', 'pass:1111', '-new', '-key', 'server.key', '-out', 'server.csr', '-subj', '"/CN=${SERVER_CN}"', '-config', 'ssl.cnf'])
    subprocess.run(['openssl', 'x509', '-req', '-passin', 'pass:1111', '-days', '3650', '-in', 'server.csr', '-CA', 'ca.crt', '-CAkey', 'ca.key', '-set_serial', '01', '-out', 'server.crt', '-extensions', 'req_ext', '-extfile', 'ssl.cnf'])
    subprocess.run(['openssl', 'pkcs8', '-topk8', '-nocrypt', '-passin', 'pass:1111', '-in', 'server.key', '-out', 'server.pem'])

错误:

Traceback (most recent call last):
  File "/home/nocnoc/Documents/deployment/ansible/cert_script.py", line 24, in <module>
    cert_create("HEYA")
  File "/home/nocnoc/Documents/deployment/ansible/cert_script.py", line 11, in cert_create
    subprocess.run(['SERVER_CN=', ip])
  File "/usr/lib/python3.8/subprocess.py", line 489, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'SERVER_CN='

有任何想法吗?

标签: pythongrpc

解决方案


您试图在不调用 shell 的情况下设置 shell 变量。

正确的方法是在 Python 脚本中设置变量。

import os

os.environ['SERVER_CN'] = ip

有了这个,你的大部分代码都可以工作,尽管你也需要改变

    subprocess.run(   # wrapped for legibility
        ['openssl', 'req', '-passin', 'pass:1111',
         '-new', '-key', 'server.key', '-out', 'server.csr',
         '-subj', '"/CN=${SERVER_CN}"', '-config', 'ssl.cnf'])

进入

    subprocess.run(
        ['openssl', 'req', '-passin', 'pass:1111',
         '-new', '-key', 'server.key', '-out', 'server.csr',
         '-subj', '/CN=' + ip, '-config', 'ssl.cnf'])

还要注意固定报价;在原始的 shell 脚本中,参数 to 周围的双引号-subj将被 shell 剥离,如果将它们放在没有 shell 的地方并剥离它们,则会产生错误。

(更直接地说,如果subprocess.run(['SERVER_CN=', ip])可行,它将SERVER_CN= ip使用空格运行,这也会在 shell 中产生相同的错误,或者如果您 SERVER_CN=PATH.


推荐阅读