Skip to content

Instantly share code, notes, and snippets.

@HepplerDotNet
Last active June 10, 2016 11:32
Show Gist options
  • Save HepplerDotNet/064f6463d14fcf7d7a99f18f68a10684 to your computer and use it in GitHub Desktop.
Save HepplerDotNet/064f6463d14fcf7d7a99f18f68a10684 to your computer and use it in GitHub Desktop.
Renew Letsencrypt with TLSA Update
#!/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