简体   繁体   中英

Python Shell Scripting. Chain Unix OpenSSL Commands

I am trying to write a simple Python shell script that will take user input of server name and port number and route it into an OpenSSL command that shows SSL certificate expiration info.

I am using the subprocess module, however I am unclear of the proper method of chaining the command with user entered information.

The full command is:

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

Output of command (which is what I want the script to output):

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

My code:

#!/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)

Any help is appreciated!

Unlike in a shell, standard in, standard out, and standard error are all handled by Popen 's stdin , stdout and stderr arguments. You can therefore discard the first two command elements ( echo | ). Then you'll want to run a separate process with the last command in the pipeline taking the output from the first command into its stdin . In general you don't use shell pipes when running in another language, but instead use the language's own piping (or streaming) mechanism.

@Han I realize I might be a little too late to the party to help you, so sorry for that, but this is for the other folks looking for this solution. I had to string together Popen() and check_output() functions, like so:

#!/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"))

This allowed me a quick and dirty audit of all of the servers I added to the list. My next iteration was to add monitoring/alerting to the output and never be surprised by an expired cert again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM