Last active
June 10, 2016 11:32
-
-
Save HepplerDotNet/064f6463d14fcf7d7a99f18f68a10684 to your computer and use it in GitHub Desktop.
Renew Letsencrypt with TLSA Update
This file contains hidden or 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/bin/env python | |
# -*- coding: utf-8 -*- | |
__author__ = 'Patrick Heppler' | |
import urllib2, base64,json,requests,os | |
from subprocess import Popen, PIPE | |
from re import findall | |
api_url = 'https://rage4.com/rapi' | |
api_user = '[email protected]' | |
api_key = 'ABCD1234' | |
cert_path = '/etc/nginx/ssl' | |
def make_tlsa(): | |
der_cert_proc = Popen(['openssl', 'x509','-in',cert_path+'/'+certificate,'-outform','der'], stdout=PIPE, stderr=PIPE) | |
der_cert_output = der_cert_proc.communicate()[0].strip() | |
sha256_cert_proc = Popen(['openssl', 'sha256'], stdin=PIPE, stderr=PIPE,stdout=PIPE) | |
sha256_cert_proc.stdin.write(der_cert_output) | |
sha256_cert_output = sha256_cert_proc.communicate()[0].strip() | |
return sha256_cert_output.replace('(stdin)= ','') | |
def getzones(): | |
request = urllib2.Request(api_url+'/getdomains/') | |
base64string = base64.encodestring('%s:%s' % (api_user, api_key)).replace('\n', '') | |
request.add_header("Authorization", "Basic %s" % base64string) | |
zones = json.loads(urllib2.urlopen(request).read()) | |
for zone in zones: | |
getrecords(zone['id']) | |
def getrecords(zoneid): | |
request = urllib2.Request(api_url+'/getrecords/'+str(zoneid)) | |
base64string = base64.encodestring('%s:%s' % (api_user, api_key)).replace('\n', '') | |
request.add_header("Authorization", "Basic %s" % base64string) | |
records = json.loads(urllib2.urlopen(request).read()) | |
for record in records: | |
if record['type'] == 'TLSA': | |
updatetlsa(tlsa_hash,record['id'],record['name']) | |
def updatetlsa(tlsa,recordid,recordname): | |
base64string = base64.encodestring('%s:%s' % (api_user, api_key)).replace('\n', '') | |
auth_header = {"Authorization": "Basic %s" % base64string} | |
query_string = {'id':recordid,'name':recordname,'priority':'1','ttl':'600','content':'3 0 1 '+tlsa} | |
r = requests.get(api_url+'/updaterecord/',params=query_string,headers = auth_header) | |
e = json.loads(r.text)['error'] | |
if len(e) > 0: | |
exit(1) | |
def control_nginx(action): | |
nginx_proc = Popen(['systemctl', action,'nginx'], stdout=PIPE, stderr=PIPE) | |
nginx_output = nginx_proc.communicate() | |
if len(nginx_output[1]) > 0: | |
exit(1) | |
def letsencrypt(): | |
letsencrypt_proc = Popen(['/opt/letsencrypt/letsencrypt-auto', | |
'--csr',cert_path+'/heppler.net.csr', | |
'--cert-path',cert_path+'/heppler.net.crt', | |
'--chain-path',cert_path+'/heppler.net.chain.crt', | |
'--fullchain-path',cert_path+'/heppler.net.full.crt', | |
'--renew-by-default','certonly', | |
'--no-self-upgrade', | |
'--standalone'], stdout=PIPE, stderr=PIPE) | |
letsencrypt_output = letsencrypt_proc.communicate() | |
if len(letsencrypt_output[1]) > 0: | |
control_nginx('start') | |
print letsencrypt_output[1] | |
exit(1) | |
else: | |
global fullchain | |
global certificate | |
fullchain = findall(r'\d\d\d\d_heppler.net.full.crt',', '.join(letsencrypt_output[0].split('\n')))[0] | |
certificate = findall(r'\d\d\d\d',fullchain)[0]+'_heppler.net.crt' | |
make_symlink() | |
def make_symlink(): | |
ln_proc = Popen(['ln','-sf',cert_path+'/'+fullchain,'/etc/nginx/ssl/heppler.net.full.crt'], stdout=PIPE, stderr=PIPE) | |
ln_out = ln_proc.communicate() | |
if len(ln_out[1]) > 0: | |
print ln_out[1] | |
exit(1) | |
else: | |
control_nginx('start') | |
global tlsa_hash | |
tlsa_hash = make_tlsa() | |
getzones() | |
cleanup() | |
def cleanup(): | |
current_target = os.path.realpath('/etc/nginx/ssl/heppler.net.full.crt') | |
current_crt = current_target.split('/')[-1] | |
clean_proc = Popen(['find', '/etc/nginx/ssl/', '-type', 'f', '-not', '-name', '*.key', '-not', '-name', '*.csr', '-not', '-name', 'letsencrypt.conf','-not','-name',current_crt],stdout=PIPE,stderr=PIPE) | |
out = clean_proc.communicate()[0].split('\n') | |
for file in out: | |
if len(file) > 0: | |
rm_proc = Popen(['rm', '-f',file],stdout=PIPE,stderr=PIPE) | |
rm_proc.communicate() | |
control_nginx('stop') | |
letsencrypt() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment