ÿØÿà JFIF ÿá Exif MM * ÿÛ C
Server IP : 199.250.214.225 / Your IP : 18.191.237.146 Web Server : Apache System : Linux vps64074.inmotionhosting.com 3.10.0-1160.105.1.vz7.214.3 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : nicngo5 ( 1001) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /opt/dedrads/ |
Upload File : |
#!/opt/imh-python/bin/python3 """ AutoSSL Sync Created by Jeff Sh. Copy the SSLs files for a given domain to the provided folder so that it can be used by 3rd party applications and update as AutoSSL updates them. TODO: Only run if the ssl is newer than the current one, or otherwise invalid TODO: Check if self-signed, and prevent replacing DCV with self-signed """ # Imports import sys import os import argparse import errno import logging import logging.handlers import cpapis class MyVars: """ Main/Global variables can be defined here. """ VERSION = "1.0.1" LOG_FILENAME = '/var/log/autossl_sync.log' # Make sure the backup directory exists. If not, abort. def check_dir(dir_path, logger): """ Check to make sure the backup directory exists. If not, create it. Abort if there's a file that exists, but it's not a directory. """ if not os.path.isfile(dir_path): if not os.path.exists(dir_path): try: os.makedirs(dir_path) except OSError as error: if error.errno != errno.EEXIST: logger.error( f"Failed to create directory {dir_path}: {error}" ) else: logger.error( f"A failure occured while trying to create the \ directory {dir_path}." ) logger.error(f"Reported error: {error}") sys.exit(1) else: if not os.path.isdir(dir_path): logger.error( f"{dir_path} already exists, but it's not a directory." ) logger.error("ABORTING.") sys.exit(1) def copy_ssls(domain, folder, pem, logger): """ Given a domain name, we need to get the data to a point that we can use it. The Python JSON module imports the data as a dict, then it's a list, which then puts it into a dict again. So, we have to drill down to get to what we need. """ try: ssl_data = cpapis.whmapi1( "fetch_ssl_certificates_for_fqdns", {"domains": f"{domain}"} ) except IndexError as error: logger.error(f"Unable to load domain data for {domain} from whmapi1.") logger.error("Is the domain a valid domain on this server?") logger.error(f"Reported error was: {error}") sys.exit(1) # ssl_data keys are all located at data -> payload -> index 0 and then: # crt = Certificate # key = Private Key # cab = CA Bundle check_dir(folder, logger) with open(f"{folder}/{domain}.crt", "w", encoding='utf-8') as crt_file: crt_file.write(ssl_data['data']['payload'][0]['crt']) with open(f"{folder}/{domain}.key", "w", encoding='utf-8') as key_file: key_file.write(ssl_data['data']['payload'][0]['key']) with open(f"{folder}/{domain}.cab", "w", encoding='utf-8') as cab_file: cab_file.write(ssl_data['data']['payload'][0]['cab']) logger.info("Files written to the following paths:") logger.info(f"Certificate: {folder}/{domain}.crt") logger.info(f"Private Key: {folder}/{domain}.key") logger.info(f"CA Bundle : {folder}/{domain}.cab") if pem: convert_pem(domain, folder, logger) def convert_pem(domain, folder, logger): """ The PEM file is the CRT, KEY and CA Bundle in one file. Nothing more since the files in WHM are already X.509 formatted. """ cmd = f"cat {folder}/{domain}.crt > {folder}/{domain}.pem &&" cmd = f"cat {folder}/{domain}.key >> {folder}/{domain}.pem &&" cmd = f"cat {folder}/{domain}.cab >> {folder}/{domain}.pem " os.system(cmd) logger.info("PEM file format written to the following location:") logger.info(f"Privacy-Enhanced Mail (PEM): {folder}/{domain}.pem") def main(): """ We need to require the domain and the path to save the files to. No need to allow file names, we'll just use <tld_name>.crt, <tld_name>.key and <tld_name>.cab Set up parsing for the CLI arguments that can be passed and help text. """ # Optional Arguments parser = argparse.ArgumentParser( description=f"AutoSSL Sync v{MyVars.VERSION}" ) parser.add_argument( "--cron", action="store_true", dest="cron", default=False, help="Suppress all output, excluding errors, for CRON.", ) parser.add_argument( "-P", "--pem", action="store_true", dest="pem", default=False, help="Convert the files to PEM format after creation.", ) # Required Arguments required_arg = parser.add_argument_group('**REQUIRED arguments') required_arg.add_argument( "-d", "--domain", action='store', dest='domain', required=True, help="The FQDN domain to obtain SSL information on \ and sync. Subdomains can be used.", ) required_arg.add_argument( "-f", "--folder", action='store', dest='folder', required=True, help="The full path to the folder where the AutoSSL \ files should be copied to. Do not include a trailing slash!", ) # If no argument is passed, display help and exit. if len(sys.argv) == 1: parser.print_help(sys.stderr) print(__doc__) sys.exit(1) args = parser.parse_args() # Setup Logging - Rotate logs when 10MB, keep 6 copies and the current one. logging.basicConfig( level=logging.INFO, format="[%(asctime)s] - %(levelname)s - %(message)s", handlers=[ logging.handlers.RotatingFileHandler( MyVars.LOG_FILENAME, "a", 10485760, 6 ) ], ) logger = logging.getLogger(f'AutoSSL Sync v{MyVars.VERSION}') # Don't print to stdout when running with CRON argument, still send to log. cron_handler = logging.StreamHandler(sys.stdout) if not args.cron: logger.addHandler(cron_handler) else: logger.info("Running CRON Process for AutoSSL Sync v%s", MyVars.VERSION) copy_ssls(args.domain, args.folder, args.pem, logger) sys.exit(0) if __name__ == '__main__': main()