danb35
Hall of Famer
- Joined
- Aug 16, 2011
- Messages
- 15,504
Well, some progress, though I'm sure it makes for very ugly code. It uses your code to upload the cert, then pulls down the list, iterates through it to get the ID number of the cert we just uploaded, and then (attempts to) set the active cert to the correct one. But at that last point, it's erroring out. Here's the code as it is now:
But the part that tries to set the active cert errors out. Here's the output:
Edit: It's noted in the sig, but this is under 11.1-U1.
Edit 2: As is so often the case, RTFM. Setting the active takes a PUT, not a POST. I've made that change above, and the code seems to work with that change. Output is now:
Edit 3: One limitation I'm noticing is that the API function that updates the certificate doesn't reload the web server at the same time. Thus, even though you've uploaded and activated a new cert, the web GUI will still be serving the old one until it restarts for some other reason. I don't immediately see an API call to force this reload.
Code:
#!/usr/local/bin/python """ Import and activate a SSL/TLS certificate into FreeNAS 11.1 or later Uses the FreeNAS API to make the change, so everything's properly saved in the config database and captured in a backup. Requires paths to the cert (including the any intermediate CA certs) and private key, and username, password, and FQDN of your FreeNAS system. Your private key should only be readable by root, so this script must run with root privileges. And, since it contains your root password, this script itself should only be readable by root. """ import sys import json import requests from datetime import datetime PRIVATEKEY_PATH="/path/to/privkey.pem" FULLCHAIN_PATH="/path/to/fullchain.pem" USER="root" PASSWORD="ReallySecurePassword" DOMAIN_NAME="server_fqdn" now = datetime.now() cert = "letsencrypt-%s-%s-%s" %(now.year, now.month, now.day) # TODO: force two digits for month and day print cert # Load cert/key with open(PRIVATEKEY_PATH, 'r') as file: priv_key = file.read() with open(FULLCHAIN_PATH, 'r') as file: full_chain = file.read() # Update or create certificate r = requests.post( 'https://' + DOMAIN_NAME + '/api/v1.0/system/certificate/import/', auth=(USER, PASSWORD), headers={'Content-Type': 'application/json'}, data=json.dumps({ "cert_name": cert, "cert_certificate": full_chain, "cert_privatekey": priv_key, }), ) # TODO: Check response 201 and activate cert if r.status_code == 201: print ("Certificate import successful") else: print ("Error importing certificate!") print (r) sys.exit(1) # Download certificate list limit = {'limit': 0} # set limit to 0 to disable paging in the event of many certificates r = requests.get( 'https://' + DOMAIN_NAME + '/api/v1.0/system/certificate/', params=limit, auth=(USER, PASSWORD)) # print r.status_code # Should be 200 # print r.headers['content-type'] # print r.json() if r.status_code == 200: print ("Certificate list successful") else: print ("Error listing certificates!") print (r) sys.exit(1) # Parse certificate list to find the id that matches our cert name cert_list = r.json() for index in range(100): cert_data = cert_list[index] if cert_data['cert_name'] == cert: cert_id = cert_data['id'] break # Set our cert as active r = requests.put( 'https://' + DOMAIN_NAME + '/api/v1.0/system/settings/', auth=(USER, PASSWORD), headers={'Content-Type': 'application/json'}, data=json.dumps({ "stg_guicertificate": cert_id, }), ) if r.status_code == 200: print ("Setting active certificate successful") else: print ("Error setting active certificate!") print (r) sys.exit(1)
But the part that tries to set the active cert errors out. Here's the output:
Code:
root@freenas11:~ # ./deploy_freenas.py Certificate import successful Certificate list successful Cert ID: 7 Error setting active certificate! <Response [405]>
Edit: It's noted in the sig, but this is under 11.1-U1.
Edit 2: As is so often the case, RTFM. Setting the active takes a PUT, not a POST. I've made that change above, and the code seems to work with that change. Output is now:
Code:
root@freenas11:~ # ./deploy_freenas.py Certificate import successful Certificate list successful Cert ID: 8 Setting active certificate successful root@freenas11:~ #
Edit 3: One limitation I'm noticing is that the API function that updates the certificate doesn't reload the web server at the same time. Thus, even though you've uploaded and activated a new cert, the web GUI will still be serving the old one until it restarts for some other reason. I don't immediately see an API call to force this reload.
Last edited: