Skip to content
Snippets Groups Projects
Commit d1894ff9 authored by Max Adamo's avatar Max Adamo
Browse files

using manual-hook script

parent 09d7baa8
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python3
""" Add Acme challenges to Infoblox """
import os
import time
import configparser
import requests
def create_acme(iblox_domain, acme_token, iblox_user, iblox_pw):
""" upload txt record """
post_req = requests.post(
'https://infoblox.geant.org/wapi/v2.6.1/record:txt',
auth=(iblox_user, iblox_pw),
data={
'name': '_acme-challenge.{}'.format(iblox_domain),
'text': acme_token,
'ttl': '60',
"view": "External"
}
)
return post_req.status_code
# Here we Go.
if __name__ == "__main__":
CONFIG = configparser.RawConfigParser()
CONFIG.read_file(open('/root/.geant_acme.ini'))
IBLOX_PASS = CONFIG.get('geant_acme', 'iblox_pass')
IBLOX_USER = CONFIG.get('geant_acme', 'iblox_user')
ARGS = os.sys.argv
_ = ARGS.pop(0)
for host in ARGS:
if ARGS.index(host) % 2 == 0:
token = ARGS.index(host)+1
http_code = create_acme(host, ARGS[token], IBLOX_USER, IBLOX_PASS)
if http_code != 201:
print('could not create {} for {}'.format(ARGS[token], host))
os.sys.exit(1)
time.sleep(10)
#!/usr/bin/env python3
"""Geant Acme
Usage:
geant_acme.py --domain <DOMAIN>... (--client <CLIENT>... | --wildcard) [--verbose]
geant_acme.py (-h | --help)
Options:
-h --help Show this screen.
-c CLIENT --client=CLIENT Client
-d DOMAIN --domain=DOMAIN Domain
-w --wildcard Use wildcard
-v --verbose Print out messages
"""
import os
import subprocess as sp
import configparser
from docopt import docopt
import requests
BASE_URL = 'https://infoblox.geant.org/wapi/v2.6.1'
def os_exit(verbose=None):
""" exit """
if verbose:
print('+' + 72*'-' + '+')
os.sys.exit()
def get_reference(iblox_domain, iblox_user, iblox_pw, verbose=None):
""" grab reference for txt object """
ref_obj = requests.get(
'{}/record:txt?name=_acme-challenge.{}&_return_as_object=1'.format(
BASE_URL, iblox_domain),
auth=(iblox_user, iblox_pw)
)
if ref_obj.status_code != 200:
return 'error'
try:
ref = ref_obj.json()['result'][0]['_ref']
except IndexError:
ref = None
if verbose:
if ref:
print('got reference object: {}'.format(ref))
else:
print('{} empty reference object: no challenge to delete'.format(
iblox_domain))
print('+' + 72*'-' + '+')
return ref
def delete_challenge(object_reference, iblox_user, iblox_pw, verbose=None):
""" delete txt record """
del_req = requests.delete(
'{}/{}'.format(BASE_URL, object_reference),
auth=(iblox_user, iblox_pw)
)
if verbose:
print('delete challenge - http code (200 expected): {}'.format(del_req.status_code))
print('+' + 72*'-' + '+')
return del_req.status_code
def create_challenge(iblox_domain, acme_token, iblox_user, iblox_pw, verbose=None):
""" upload txt record """
if verbose:
print('+' + 72*'-' + '+')
print('creating challenge _acme-challenge.{}'.format(iblox_domain))
post_req = requests.post(
'{}/record:txt'.format(BASE_URL),
auth=(iblox_user, iblox_pw),
data={
'name': '_acme-challenge.{}'.format(iblox_domain),
'text': acme_token,
'ttl': '30',
"view": "External"
}
)
if verbose:
print('create challenge - http code (201 expected): {} {}'.format(
post_req.status_code, post_req.reason))
print('+' + 72*'-' + '+')
return post_req.status_code
def run_certbot(cbot_domain, wild_card=None, verbose=None):
""" get certificate from letsencrypt """
if wild_card:
domain_list = '*.{}'.format(cbot_domain)
else:
domain_list = ' -d '.join(list(reversed(cbot_domain)))
cbot_cmd = '/usr/local/bin/certbot certonly -c /etc/letsencrypt/cli.ini' \
+ ' --manual-auth-hook=/root/bin/create_challenge.py' \
+ ' --cert-name {} -d {}'.format(cbot_domain[0], domain_list)
if verbose:
print('+' + 72*'-' + '+')
print('running: {}'.format(cbot_cmd))
cbot_child = sp.Popen(cbot_cmd, stdout=sp.PIPE, stderr=sp.PIPE, shell=True)
cbot_out, cbot_err = cbot_child.communicate()
if cbot_child.returncode != 0:
msg = "error running certbot: {}".format(cbot_err.decode("utf-8"))
else:
decoded_msg = cbot_out.decode("utf-8")
msg = decoded_msg[:decoded_msg.rfind('\n')]
if verbose:
print('\n{}'.format(msg))
return msg
# Here we Go.
if __name__ == "__main__":
ARGS = docopt(__doc__)
DOMAIN = ARGS['--domain']
CLIENTS = ARGS['--client']
WILDCARD = ARGS['--wildcard']
VERBOSE = ARGS['--verbose']
CONFIG = configparser.RawConfigParser()
CONFIG.read_file(open('/root/.geant_acme.ini'))
IBLOX_PASS = CONFIG.get('geant_acme', 'iblox_pass')
IBLOX_USER = CONFIG.get('geant_acme', 'iblox_user')
if WILDCARD:
REAL_DOMAIN = 'domain *.{}'.format(DOMAIN[0])
else:
REAL_DOMAIN = 'host {}'.format(DOMAIN[0])
if VERBOSE:
print('+' + 72*'-' + '+')
# Maybe there is an Acme challenge left over. We try to delete it first.
for domain_item in DOMAIN:
REF_OBJ = get_reference(domain_item, IBLOX_USER, IBLOX_PASS, VERBOSE)
if REF_OBJ == 'error':
print('error retrieving reference object')
os_exit(VERBOSE)
if REF_OBJ:
DEL_STATUS = delete_challenge(
REF_OBJ, IBLOX_USER, IBLOX_PASS, VERBOSE)
if DEL_STATUS != 200:
print('{}: {} error deleting challenge on Infoblox'.format(
domain_item, DEL_STATUS))
os_exit(VERBOSE)
# run certbot
run_certbot(DOMAIN, WILDCARD, VERBOSE)
if VERBOSE:
print('+' + 72*'-' + '+')
# remove the Acme challenges from Infoblox
for domain_item in DOMAIN:
REF_OBJ = get_reference(domain_item, IBLOX_USER, IBLOX_PASS, VERBOSE)
if REF_OBJ == 'error':
print('error retrieving reference object')
os_exit(VERBOSE)
if REF_OBJ:
DEL_STATUS = delete_challenge(
REF_OBJ, IBLOX_USER, IBLOX_PASS, VERBOSE)
if DEL_STATUS != 200:
print('{}: {} error deleting challenge on Infoblox'.format(
domain_item, DEL_STATUS))
os_exit(VERBOSE)
# if we are here, everything went fine and we can upload the certificates
if WILDCARD:
UPLOADER = '/root/bin/upload_wildcards.py'
if VERBOSE:
UPLOADER += ' -v'
os.system(UPLOADER)
else:
for client in CLIENTS:
UPLOADER = '/root/bin/geant_acme_uploader.py -d {} -c {}'.format(
DOMAIN[0], client)
if VERBOSE:
UPLOADER += ' -v'
os.system(UPLOADER)
os_exit(VERBOSE)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment