diff --git a/.gitignore b/.gitignore index 057edb5..5874390 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ cert +aliases diff --git a/haproxy_ssl.conf b/haproxy_ssl.conf index 18862fa..0b307c8 100644 --- a/haproxy_ssl.conf +++ b/haproxy_ssl.conf @@ -9,7 +9,7 @@ global ca-base /etc/ssl/certs crt-base /crypt - ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL + ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:!RC4:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL ssl-default-bind-options no-sslv3 defaults diff --git a/list_domains.py b/list_domains.py index d669c46..91ba668 100644 --- a/list_domains.py +++ b/list_domains.py @@ -7,6 +7,7 @@ import json import signal import os from socket import getaddrinfo +import logging def get_if_available(dict, key, defValue): if key in dict: @@ -48,10 +49,15 @@ def handle_container(docker_client, id): def get_resolving_domains_from_containers(docker_client): container_ids = docker_client.containers(quiet=True) + + logging.info('list of containers: %s', str(container_ids)) + domains = [] for container_id in container_ids: domains.extend(handle_container(docker_client, container_id['Id'])) + logging.info('list of activated domains on containers: %s', str(domains)) + resolved_domains = [] for domain in domains: try: @@ -60,6 +66,8 @@ def get_resolving_domains_from_containers(docker_client): except Exception: pass + logging.info('list of resolved domains on containers: %s', str(resolved_domains)) + return resolved_domains if __name__ == '__main__': diff --git a/start.py b/start.py index 118325f..d192425 100644 --- a/start.py +++ b/start.py @@ -1,11 +1,13 @@ #!/usr/bin/python3.4 import os +import json import sys import signal import logging import time import hashlib +import threading import list_domains from docker import Client @@ -65,9 +67,6 @@ def is_haproxy_running(): def ssl_possible(): """Check if a certificate is available.""" - if not os.path.exists(cert_path): - logging.info('creating cert_path path: %s', cert_path) - os.mkdir(cert_path) if not os.path.isfile(cert_file): return False @@ -76,44 +75,19 @@ def ssl_possible(): def create_haproxy_cert(): """Combines the freshly created fullchain.pem and privkey.pem into /data/haproxy/cert.pem""" - os.system('DIR=`ls -td /data/config/live/*/ | head -1`; cat ${DIR}/fullchain.pem ${DIR}/privkey.pem > /data/haproxy/cert.pem') + logging.info('updating %s', cert_file) + os.system('DIR=`ls -td /data/config/live/*/ | head -1`; echo ${DIR}; mkdir -p /data/haproxy; cat ${DIR}/fullchain.pem ${DIR}/privkey.pem > /data/haproxy/cert.pem') def create_cert_data_standalone(domains): domains = " -d ".join(domains) - os.system('/letsencrypt/letsencrypt-auto --config letencrypt.conf certonly -d ' + domains) - -if __name__ == '__main__': - setup_logging() - - logging.info('starting') + os.system('/letsencrypt/letsencrypt-auto --config letencrypt.conf certonly --expand --force-renewal --duplicate --allow-subset-of-names --standalone-supported-challenges http-01 --http-01-port 54321 -d ' + domains) +def cert_watcher(): + SSL_RUNNING=True cert_file_hash = hash_cert_file() - - # try to start in SSL mode, no problem if that fails - logging.info('try in SSL mode') - SSL_RUNNING = start_haproxy_ssl() - if not SSL_RUNNING: - logging.info('SSL mode failed') - - if not is_haproxy_running(): - # tried to start haproxy and this failed, so we need to create a certificate and try again: - # - start non ssl haproxy to be able to get a valid cert - logging.info('try in NON SSL mode') - SSL_RUNNING = start_haproxy() - # - get all domains - client = Client(base_url='unix://var/run/docker.sock', version='1.15') - resolved_domains = list_domains.get_resolving_domains_from_containers(client) - # - create cert - create_cert_data_standalone(resolved_domains) - create_haproxy_cert() - - # now we should have it up and running or something weird happened. - if not is_haproxy_running(): - logging.error('could not start after generating cert. See output above.') - sys.exit(1) - while True: - time.sleep(10) + logging.info('ping') + time.sleep(60) if ssl_possible() and not SSL_RUNNING: kill_haproxy() start_haproxy_ssl() @@ -136,3 +110,49 @@ if __name__ == '__main__': start_haproxy() logging.info('SSL -> NON SSL') SSL_RUNNING=False + +if __name__ == '__main__': + setup_logging() + + logging.info('starting') + + if not os.path.exists(cert_path): + logging.info('creating cert_path path: %s', cert_path) + os.mkdir(cert_path) + client = Client(base_url='unix://var/run/docker.sock', version='1.15') + + cert_file_hash = hash_cert_file() + + # try to start in SSL mode, no problem if that fails + logging.info('try in SSL mode') + SSL_RUNNING = start_haproxy_ssl() + if not SSL_RUNNING: + logging.info('SSL mode failed') + + if not is_haproxy_running(): + # tried to start haproxy and this failed, so we need to create a certificate and try again: + # - start non ssl haproxy to be able to get a valid cert + logging.info('try in NON SSL mode') + SSL_RUNNING = start_haproxy() + # - get all domains + resolved_domains = list_domains.get_resolving_domains_from_containers(client) + # - create cert + create_cert_data_standalone(resolved_domains) + create_haproxy_cert() + + # now we should have it up and running or something weird happened. + if not is_haproxy_running(): + logging.error('could not start after generating cert. See output above.') + sys.exit(1) + + t = threading.Thread(target=cert_watcher) + t.start() + + for line in client.events(): + line_str = line.decode("utf-8") + event = json.loads(line_str) + + if event['Action'] in ['start', 'destroy']: + resolved_domains = list_domains.get_resolving_domains_from_containers(client) + create_cert_data_standalone(resolved_domains) + create_haproxy_cert()