diff --git a/docs/docker-environment.md b/docs/docker-environment.md index b78e829..54cb3e9 100644 --- a/docs/docker-environment.md +++ b/docs/docker-environment.md @@ -1,20 +1,22 @@ # Docker environment variables -| Environment Variable | Description | Default | -|------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------| -| EASYHAPROXY_DISCOVER | How the services will be discovered to create `haproxy.cfg`: `static`, `docker`, `swarm` or `kubernetes` | **required** | -| EASYHAPROXY_LABEL_PREFIX | (Optional) The key will search for matching resources. | `easyhaproxy` | -| EASYHAPROXY_CERTBOT_EMAIL | (Optional) The email will be used to request the certificate to Certbox | *empty* | -| EASYHAPROXY_CERTBOT_SERVER | (Optional) Can be `staging` or 'schema://domain.tld'. If set, will try to connect to the Certbot test server | *empty* | -| EASYHAPROXY_SSL_MODE | (Optional) `strict` supports only the most recent TLS version; `default` good SSL integration with recent browsers; `loose` supports all old SSL protocols for old browsers (not recommended). | `default` | -| EASYHAPROXY_REFRESH_CONF | (Optional) Check configuration every N seconds. | 10 | -| EASYHAPROXY_LOG_LEVEL | (Optional) The log level for EasyHAproxy messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG | -| CERTBOT_LOG_LEVEL | (Optional) The log level for Certbot messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG | -| HAPROXY_LOG_LEVEL | (Optional) The log level for HAProxy messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG | -| HAPROXY_USERNAME | (Optional) The HAProxy username to the statistics. | `admin` | -| HAPROXY_PASSWORD | (Optional) The HAProxy password to the statistics. If not set, statistics will be available with no password | *empty* | -| HAPROXY_STATS_PORT | (Optional) The HAProxy port to the statistics. If set to `false`, disable statistics | `1936` | -| HAPROXY_CUSTOMERRORS | (Optional) If HAProxy will use custom HTML errors. true/false. | `false` | +| Environment Variable | Description | Default | +|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------| +| EASYHAPROXY_DISCOVER | How the services will be discovered to create `haproxy.cfg`: `static`, `docker`, `swarm` or `kubernetes` | **required** | +| EASYHAPROXY_LABEL_PREFIX | (Optional) The key will search for matching resources. | `easyhaproxy` | +| EASYHAPROXY_CERTBOT_EMAIL | (Optional) The email will be used to request the certificate to Certbot | *empty* | +| EASYHAPROXY_CERTBOT_SERVER | (Optional) Can be `staging` or 'schema://domain.tld', if using other service than Letsencrypt. Might be necessary set EASYHAPROXY_CERTBOT_EAB_KID and EASYHAPROXY_CERTBOT_EAB_HMAC_KEY | *empty* | +| EASYHAPROXY_CERTBOT_EAB_KID | (Optional) eab-kid configuration when required. | *empty* | +| EASYHAPROXY_CERTBOT_EAB_HMAC_KEY | (Optional) eab-kid-hmac-key configuration when required. | *empty* | +| EASYHAPROXY_SSL_MODE | (Optional) `strict` supports only the most recent TLS version; `default` good SSL integration with recent browsers; `loose` supports all old SSL protocols for old browsers (not recommended). | `default` | +| EASYHAPROXY_REFRESH_CONF | (Optional) Check configuration every N seconds. | 10 | +| EASYHAPROXY_LOG_LEVEL | (Optional) The log level for EasyHAproxy messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG | +| CERTBOT_LOG_LEVEL | (Optional) The log level for Certbot messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG | +| HAPROXY_LOG_LEVEL | (Optional) The log level for HAProxy messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG | +| HAPROXY_USERNAME | (Optional) The HAProxy username to the statistics. | `admin` | +| HAPROXY_PASSWORD | (Optional) The HAProxy password to the statistics. If not set, statistics will be available with no password | *empty* | +| HAPROXY_STATS_PORT | (Optional) The HAProxy port to the statistics. If set to `false`, disable statistics | `1936` | +| HAPROXY_CUSTOMERRORS | (Optional) If HAProxy will use custom HTML errors. true/false. | `false` | diff --git a/src/easymapping/__init__.py b/src/easymapping/__init__.py index e17dcf5..c0db5f7 100644 --- a/src/easymapping/__init__.py +++ b/src/easymapping/__init__.py @@ -49,7 +49,7 @@ class HaproxyConfigGenerator: def __init__(self, mapping): self.mapping = mapping self.mapping.setdefault("ssl_mode", 'default') - self.mapping.setdefault("certbot", {"email": "", "staging": False}) + self.mapping.setdefault("certbot", {"email": "", "server": False, "eab_kid": False, "eab_hmac_key": False}) self.mapping["ssl_mode"] = self.mapping["ssl_mode"].lower() self.label = DockerLabelHandler(mapping['lookup_label'] if 'lookup_label' in mapping else "easyhaproxy") self.certbot_hosts = [] diff --git a/src/functions/__init__.py b/src/functions/__init__.py index 09b37d3..9713843 100644 --- a/src/functions/__init__.py +++ b/src/functions/__init__.py @@ -179,16 +179,32 @@ class DaemonizeHAProxy: class Certbot: - def __init__(self, certs, email, test_server): - self.certs = certs - self.email = email - self.test_server = self.set_test_server(test_server) + def __init__(self, certs): + env = ContainerEnv.read() - def set_test_server(self, test_server): - if test_server.lower() == "staging": + self.certs = certs + self.email = env["certbot"]["email"] + self.acme_server = self.set_acme_server(env["certbot"]["server"]) + self.eab_kid = self.set_eab_kid(env["certbot"]["eab_kid"]) + self.eab_hmac_key = self.set_eab_hmac_key(env["certbot"]["eab_hmac_key"]) + + def set_acme_server(self, acme_server): + if acme_server.lower() == "staging": return "--staging" - elif test_server.lower().startswith("http"): - return "--server " + test_server + elif acme_server.lower().startswith("http"): + return "--server " + acme_server + else: + return "" + + def set_eab_kid(self, eab_kid): + if eab_kid != "": + return "--eab-kid \"%s\"" % eab_kid + else: + return "" + + def set_eab_hmac_key(self, eab_hmac_key): + if eab_hmac_key != "": + return "--eab-hmac-key \"%s\"" % eab_hmac_key else: return "" @@ -224,7 +240,7 @@ class Certbot: except Exception as e: Functions.log(Functions.CERTBOT_LOG, Functions.ERROR, "Certificate %s error %s" % (host, e)) - certbot_certonly = ('/usr/bin/certbot certonly {test_server}' + certbot_certonly = ('/usr/bin/certbot certonly {acme_server}' ' --standalone' ' --preferred-challenges http' ' --http-01-port 2080' @@ -233,9 +249,12 @@ class Certbot: ' --no-eff-email' ' --non-interactive' ' --max-log-backups=0' - ' {certs} --email {email}'.format(certs=' '.join(request_certs), + ' {eab_kid} {eab_hmac_key}' + ' {certs} --email {email}'.format(eab_kid=self.eab_kid, + eab_hmac_key=self.eab_hmac_key, + certs=' '.join(request_certs), email=self.email, - test_server=self.test_server) + acme_server=self.acme_server) ) ret_reload = False diff --git a/src/main.py b/src/main.py index d251843..c50e0d2 100644 --- a/src/main.py +++ b/src/main.py @@ -22,7 +22,7 @@ def start(): haproxy.haproxy("start") haproxy.sleep() - certbot = Certbot(Consts.certs_certbot, os.getenv("EASYHAPROXY_CERTBOT_EMAIL"), os.getenv("EASYHAPROXY_CERTBOT_SERVER", "").lower()) + certbot = Certbot(Consts.certs_certbot) while True: if old_haproxy is not None: diff --git a/src/processor/__init__.py b/src/processor/__init__.py index 96e347d..9583c32 100644 --- a/src/processor/__init__.py +++ b/src/processor/__init__.py @@ -26,12 +26,14 @@ class ContainerEnv: } env_vars["lookup_label"] = os.getenv("EASYHAPROXY_LABEL_PREFIX") if os.getenv("EASYHAPROXY_LABEL_PREFIX") else "easyhaproxy" - if (os.getenv("EASYHAPROXY_CERTBOT_EMAIL")): - env_vars["certbot"] = { - "email": os.getenv("EASYHAPROXY_CERTBOT_EMAIL"), - "server": os.getenv("EASYHAPROXY_CERTBOT_SERVER", "false").lower() in ["true", "1", "yes"] - } - + + env_vars["certbot"] = { + "email": os.getenv("EASYHAPROXY_CERTBOT_EMAIL", ""), + "server": os.getenv("EASYHAPROXY_CERTBOT_SERVER", False), + "eab_kid": os.getenv("EASYHAPROXY_CERTBOT_EAB_KID", ""), + "eab_hmac_key": os.getenv("EASYHAPROXY_CERTBOT_EAB_HMAC_KEY", ""), + } + return env_vars diff --git a/src/tests/test_containerenv.py b/src/tests/test_containerenv.py index b583198..4b84810 100644 --- a/src/tests/test_containerenv.py +++ b/src/tests/test_containerenv.py @@ -6,7 +6,11 @@ def test_container_env_empty(): assert { "customerrors": False, "ssl_mode": "default", - "lookup_label": "easyhaproxy" + "lookup_label": "easyhaproxy", + "certbot": {"eab_hmac_key": "", + "eab_kid": "", + "email": "", + "server": False} } == ContainerEnv.read() # os.environ['CERTBOT_LOG_LEVEL'] = 'warn' @@ -17,7 +21,11 @@ def test_container_env_customerrors(): assert { "customerrors": True, "ssl_mode": "default", - "lookup_label": "easyhaproxy" + "lookup_label": "easyhaproxy", + "certbot": {"eab_hmac_key": "", + "eab_kid": "", + "email": "", + "server": False} } == ContainerEnv.read() finally: os.environ['HAPROXY_CUSTOMERRORS'] = '' @@ -28,7 +36,11 @@ def test_container_env_sslmode(): assert { "customerrors": False, "ssl_mode": "strict", - "lookup_label": "easyhaproxy" + "lookup_label": "easyhaproxy", + "certbot": {"eab_hmac_key": "", + "eab_kid": "", + "email": "", + "server": False} } == ContainerEnv.read() finally: os.environ['EASYHAPROXY_SSL_MODE'] = '' @@ -41,6 +53,10 @@ def test_container_env_stats(): "customerrors": False, "ssl_mode": "default", "lookup_label": "easyhaproxy", + "certbot": {"eab_hmac_key": "", + "eab_kid": "", + "email": "", + "server": False} } == ContainerEnv.read() finally: os.environ['HAPROXY_USERNAME'] = '' @@ -58,7 +74,11 @@ def test_container_env_stats_password(): "password": "xyz", "port": "1936" - } + }, + "certbot": {"eab_hmac_key": "", + "eab_kid": "", + "email": "", + "server": False} } == ContainerEnv.read() finally: os.environ['HAPROXY_PASSWORD'] = '' @@ -77,8 +97,11 @@ def test_container_env_stats_password(): "username": "abc", "password": "xyz", "port": "2101" - - } + }, + "certbot": {"eab_hmac_key": "", + "eab_kid": "", + "email": "", + "server": False} } == ContainerEnv.read() finally: os.environ['HAPROXY_USERNAME'] = '' @@ -86,7 +109,7 @@ def test_container_env_stats_password(): os.environ['HAPROXY_PASSWORD'] = '' -def test_container_env_stats_password(): +def test_container_env_certbot_email(): os.environ['EASYHAPROXY_CERTBOT_EMAIL'] = 'acme@example.org' try: assert { @@ -94,6 +117,8 @@ def test_container_env_stats_password(): "ssl_mode": "default", "lookup_label": "easyhaproxy", "certbot": { + 'eab_hmac_key': "", + 'eab_kid': "", "email": "acme@example.org", "server": False } @@ -101,9 +126,11 @@ def test_container_env_stats_password(): finally: os.environ['EASYHAPROXY_CERTBOT_EMAIL'] = '' -def test_container_env_certbot(): +def test_container_env_certbot_full(): os.environ['EASYHAPROXY_CERTBOT_EMAIL'] = 'acme@example.org' - os.environ['EASYHAPROXY_CERTBOT_SERVER'] = 'true' + os.environ['EASYHAPROXY_CERTBOT_SERVER'] = 'schema://url/a' + os.environ['EASYHAPROXY_CERTBOT_EAB_KID'] = 'eab_kid' + os.environ['EASYHAPROXY_CERTBOT_EAB_HMAC_KEY'] = 'eab_hmac_key' try: assert { "customerrors": False, @@ -111,7 +138,9 @@ def test_container_env_certbot(): "lookup_label": "easyhaproxy", "certbot": { "email": "acme@example.org", - "server": True + "server": "schema://url/a", + 'eab_hmac_key': 'eab_hmac_key', + 'eab_kid': 'eab_kid', } } == ContainerEnv.read() finally: