0

I am having difficulties in writing a python script that generates SSL keys and certificates for GRPC services. I am trying to write a function that can run the commands in this file by having ip passed into it. This is what I wrote, but I receive an error that I do not understand, I will list it at the bottom

My function:

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'])

The error:

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='

Any ideas?

nocnoc
  • 337
  • 2
  • 12

1 Answers1

1

You are trying to set a shell variable without invoking a shell.

The proper way to do this is to set the variable in your Python script.

import os

os.environ['SERVER_CN'] = ip

With that, most of the rest of your code will work, though you will also need to change

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

into

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

Notice also the fixed quoting; in the original shell script, the double quotes around the argument to -subj will get stripped off by the shell, and will produce an error if you put them in where no shell is there and strips them.

(More tantentially, if subprocess.run(['SERVER_CN=', ip]) would work, it would run SERVER_CN= ip with a space, which will produce the same error in the shell, too, or if you have a command named SERVER_CN= in your PATH, run that with the IP address as its first argument.)

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Perhaps see also https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess – tripleee Feb 17 '21 at 12:29