【问题标题】:Python Shell Scripting. Chain Unix OpenSSL CommandsPython Shell 脚本。链式 Unix OpenSSL 命令
【发布时间】:2023-06-29 01:02:01
【问题描述】:

我正在尝试编写一个简单的 Python shell 脚本,它将接受用户输入的服务器名称和端口号,并将其路由到显示 SSL 证书到期信息的 OpenSSL 命令。

我正在使用 subprocess 模块,但是我不清楚将命令与用户输入的信息链接的正确方法。

完整的命令是:

echo | openssl s_client -servername www.google.com -connect www.google.com:443 2>/dev/null | openssl x509 -noout -dates

命令的输出(这是我希望脚本输出的内容):

notBefore=May 31 16:57:23 2017 GMT
notAfter=Aug 23 16:32:00 2017 GMT

我的代码:

#!/usr/bin/env python
import subprocess 

server_name = raw_input("Enter server name: ")
port_number = raw_input("Enter port number: ")

def display_cert_info(servername, portnum):
    pn = str(server_name + ":" + port_number)
    cmd = ["echo", "|", "openssl", "s_client", "-servername", str(servername), "-connect", pn, "2>/dev/null", "|", "openssl", "x509", "-noout", "-dates"]

    info = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = info.communicate()[0]
    print(output)

display_cert_info(server_name, port_number)

感谢任何帮助!

【问题讨论】:

    标签: python shell unix subprocess pyopenssl


    【解决方案1】:

    与 shell 不同,标准输入、标准输出和标准错误都由Popenstdinstdoutstderr 参数处理。因此,您可以放弃前两个命令元素 (echo |)。然后,您需要运行一个单独 进程,管道中的最后一个命令将第一个命令的输出输入到其stdin。一般来说,在以另一种语言运行时,您不会使用 shell 管道,而是使用该语言自己的管道(或流式传输)机制。

    【讨论】:

      【解决方案2】:

      @Han 我意识到我可能有点太晚了,无法帮助你,很抱歉,但这是给正在寻找这个解决方案的其他人。我不得不将 Popen() 和 check_output() 函数串在一起,如下所示:

      #!/usr/bin/python3
      from subprocess import Popen, PIPE, check_output
      from os import open, O_WRONLY
      
      servers = [
          "server1.domain.com",
          "server2.domain.com",
          "server3.domain.com"
          ]
      
      for s in servers:
          print("querying {}".format(s))
          dn = open("/dev/null", O_WRONLY)
          q = Popen(["/usr/bin/openssl", "s_client", "-servername", s, "-connect","{}:443".format(s)], stdout=PIPE, stdin=PIPE, stderr=dn, shell=False)
          y = check_output(["/usr/bin/openssl", "x509", "-noout", "-dates"], stdin=q.stdout)
          print(y.decode("utf-8"))
      

      这让我可以对添加到列表中的所有服务器进行快速而肮脏的审核。我的下一个迭代是在输出中添加监控/警报,并且再也不会对过期的证书感到惊讶。

      【讨论】: