Last active
July 23, 2018 23:15
-
-
Save robbiet480/fee60c5eec7bcfb31970fac4f8efb6ff to your computer and use it in GitHub Desktop.
A script to install Lets Encrypt certificates generated by Dehydrated into FreeNAS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python | |
""" | |
Import and activate a SSL/TLS certificate generated by dehydrated.sh 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. | |
Add `export FREENAS_PASSWORD="<YOUR_FREENAS_ROOT_PASSWORD>"` to | |
dehydrated's config. | |
Original source: https://github.com/danb35/deploy-freenas | |
Modifications by https://github.com/robbiet480 | |
""" | |
import os | |
import sys | |
import json | |
import requests | |
import subprocess | |
from datetime import datetime | |
now = datetime.now() | |
cert = "letsencrypt-{}".format(now.strftime("%Y-%m-%d")) | |
def deploy_cert(args): | |
if "FREENAS_PASSWORD" not in os.environ: | |
print("FREENAS_PASSWORD not set!") | |
sys.exit(1) | |
domain = args[0] | |
keyfile = args[1] | |
certfile = args[2] | |
fullchainfile = args[3] | |
chainfile = args[4] | |
timestamp = args[5] | |
s = requests.Session() | |
s.auth = ("root", os.environ["FREENAS_PASSWORD"]) | |
# Load cert/key | |
with open(keyfile, "r") as file: | |
priv_key = file.read() | |
with open(fullchainfile, "r") as file: | |
full_chain = file.read() | |
# Update or create certificate | |
r = s.post( | |
"https://" + domain + "/api/v1.0/system/certificate/import/", | |
headers={"Content-Type": "application/json"}, | |
data=json.dumps({"cert_name": cert, | |
"cert_certificate": full_chain, | |
"cert_privatekey": priv_key}) | |
) | |
if r.status_code == 201: | |
print("Certificate import successful") | |
else: | |
print("Error importing certificate!") | |
print(r) | |
print(r.json()) | |
sys.exit(1) | |
# Download certificate list | |
# set limit to 0 to disable paging in the event of many certificates | |
r = s.get("https://" + domain + "/api/v1.0/system/certificate/", | |
params={"limit": 0}) | |
if r.status_code == 200: | |
print("Certificate list successful") | |
else: | |
print("Error listing certificates!") | |
print(r) | |
print(r.json()) | |
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 = s.put("https://" + domain + "/api/v1.0/system/settings/", | |
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) | |
print(r.json()) | |
sys.exit(1) | |
# Reload nginx with new cert | |
restart_path = "/api/v1.0/system/settings/restart-httpd-all/" | |
r = s.post("https://{}{}".format(domain, restart_path)) | |
if r.status_code == 200: | |
print("Restarted the web servers") | |
else: | |
print("Error restarting the web servers!") | |
print(r) | |
print(r.json()) | |
sys.exit(1) | |
def main(argv): | |
ops = {"deploy_cert": deploy_cert} | |
if argv[0] in ops: | |
print(" + FreeNAS hook executing: {0}".format(argv[0])) | |
ops[argv[0]](argv[1:]) | |
if __name__ == "__main__": | |
main(sys.argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment