1
0
Fork 0

Merge pull request #57 from ThaDaVos/master

#56 prototyped manual-auth-hook and different `preferred-challenges` support
This commit is contained in:
Joao M 2024-11-15 10:45:35 -06:00 committed by GitHub
commit 8850620a45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 86 additions and 45 deletions

View file

@ -1,20 +1,24 @@
FROM alpine:3.18 FROM alpine:3.20
ARG RELEASE_VERSION_ARG ARG RELEASE_VERSION_ARG
ENV RELEASE_VERSION=$RELEASE_VERSION_ARG ENV RELEASE_VERSION=$RELEASE_VERSION_ARG
ENV TZ="Etc/UTC" ENV TZ="Etc/UTC"
RUN apk add --no-cache haproxy bash python3 py3-pip py-yaml certbot openssl \
&& pip3 install --upgrade pip --break-system-packages
RUN openssl dhparam -out /etc/haproxy/dhparam 2048 \
&& openssl dhparam -out /etc/haproxy/dhparam-1024 1024
WORKDIR /scripts WORKDIR /scripts
COPY src/ /scripts/
COPY build/assets / COPY build/assets /
RUN apk add --no-cache haproxy bash python3 py3-pip py-yaml certbot openssl \ COPY src/ /scripts/
&& pip3 install --upgrade pip \
&& pip install -r requirements.txt \ RUN pip install -r requirements.txt --break-system-packages
&& pytest -s -vv tests/ \
&& openssl dhparam -out /etc/haproxy/dhparam 2048 \ RUN pytest -s -vv tests/
&& openssl dhparam -out /etc/haproxy/dhparam-1024 1024
CMD ["/usr/bin/python", "-u", "/scripts/main.py" ] CMD ["/usr/bin/python", "-u", "/scripts/main.py" ]

View file

@ -8,21 +8,25 @@ Most of the issuers offers Automatic Issuing free of cost.
## Environment Variables ## Environment Variables
To enable the ACME protocol we need to enable Certbot in EasyHAProxy by setting up to 4 environment variables: To enable the ACME protocol we need to enable Certbot in EasyHAProxy by setting up to the following environment variables:
| Environment Variable | Required? | Description | | Environment Variable | Required? | Description |
|----------------------------------|-----------|----------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------|-----------|----------------------------------------------------------------------------------------------------------------------------------|
| EASYHAPROXY_CERTBOT_EMAIL | YES | Your email in the certificate authority. | | EASYHAPROXY_CERTBOT_EMAIL | YES | Your email in the certificate authority. |
| EASYHAPROXY_CERTBOT_AUTOCONFIG | - | Will use pre-sets for your Certificate Authority (CA). See table below. | | EASYHAPROXY_CERTBOT_AUTOCONFIG | - | Will use pre-sets for your Certificate Authority (CA). See table below. |
| EASYHAPROXY_CERTBOT_SERVER | - | The ACME Endpoint of your certificate authority. If you use AUTOCONFIG, it is set automatically. See table below. | | EASYHAPROXY_CERTBOT_SERVER | - | The ACME Endpoint of your certificate authority. If you use AUTOCONFIG, it is set automatically. See table below. |
| EASYHAPROXY_CERTBOT_EAB_KID | - | External Account Binding (EAB) Key Identifier (KID) provided by your certificate authority. Some CA require it. See table below. | | EASYHAPROXY_CERTBOT_EAB_KID | - | External Account Binding (EAB) Key Identifier (KID) provided by your certificate authority. Some CA require it. See table below. |
| EASYHAPROXY_CERTBOT_EAB_HMAC_KEY | - | External Account Binding (EAB) HMAC Key provided by your certificate authority. Some CA require it. See table below. | | EASYHAPROXY_CERTBOT_EAB_HMAC_KEY | - | External Account Binding (EAB) HMAC Key provided by your certificate authority. Some CA require it. See table below. |
| EASYHAPROXY_CERTBOT_RETRY_COUNT | - | Wait 'n' requests before retrying issue invalid requests. Default 60. | | EASYHAPROXY_CERTBOT_RETRY_COUNT | - | Wait 'n' requests before retrying issue invalid requests. Default 60. |
| EASYHAPROXY_CERTBOT_PREFERRED_CHALLENGES | - | The preferred challenges for Certbot. Available: `http` |
| EASYHAPROXY_CERTBOT_MANUAL_AUTH_HOOK | - | The path to a script that will be executed (default: None) |
## Auto Config Certificate Authority (CA) ## Auto Config Certificate Authority (CA)
Here are detailed instructions per Certificate Authority (CA). If anyone is missing, please let's know. Here are detailed instructions per Certificate Authority (CA). If anyone is missing, please let's know.
Possible values for: `EASYHAPROXY_CERTBOT_AUTOCONFIG`
| CA | Auto Config | Free? | Account Required? | EAB KID? | EAB HMAC Key? | More Info | | CA | Auto Config | Free? | Account Required? | EAB KID? | EAB HMAC Key? | More Info |
|----------------------|------------------|-------|--------------------|----------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------| |----------------------|------------------|-------|--------------------|----------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Let's Encrypt | - | Yes | No | No | No | - | | Let's Encrypt | - | Yes | No | No | No | - |

View file

@ -1,19 +1,19 @@
# Docker environment variables # Docker environment variables
| Environment Variable | Description | Default | | Environment Variable | Description | Default |
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------| |--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| EASYHAPROXY_DISCOVER | How the services will be discovered to create `haproxy.cfg`: `static`, `docker`, `swarm` or `kubernetes` | **required** | | 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_LABEL_PREFIX | (Optional) The key will search for matching resources. | `easyhaproxy` |
| EASYHAPROXY_CERTBOT_* | (Optional) Enable Let's Encrypt or any other ACME certificate. See more: [acme](acme.md) | *empty* | | EASYHAPROXY_CERTBOT_* | (Optional) Enable Let's Encrypt or any other ACME certificate. See more: [acme](acme.md) | *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_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 for new containers/services every N seconds. | 10 | | EASYHAPROXY_REFRESH_CONF | (Optional) Check for new containers/services every N seconds. | 10 |
| EASYHAPROXY_LOG_LEVEL | (Optional) The log level for EasyHAproxy messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG | | EASYHAPROXY_LOG_LEVEL | (Optional) The log level for EasyHAproxy messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | INFO |
| CERTBOT_LOG_LEVEL | (Optional) The log level for Certbot 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_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_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_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_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` | | HAPROXY_CUSTOMERRORS | (Optional) If HAProxy will use custom HTML errors. true/false. | `false` |
---- ----

View file

@ -41,6 +41,8 @@ class ContainerEnv:
"eab_kid": os.getenv("EASYHAPROXY_CERTBOT_EAB_KID", ""), "eab_kid": os.getenv("EASYHAPROXY_CERTBOT_EAB_KID", ""),
"eab_hmac_key": os.getenv("EASYHAPROXY_CERTBOT_EAB_HMAC_KEY", ""), "eab_hmac_key": os.getenv("EASYHAPROXY_CERTBOT_EAB_HMAC_KEY", ""),
"retry_count": int(os.getenv("EASYHAPROXY_CERTBOT_RETRY_COUNT", 60)), "retry_count": int(os.getenv("EASYHAPROXY_CERTBOT_RETRY_COUNT", 60)),
"preferred_challenges": os.getenv("EASYHAPROXY_CERTBOT_PREFERRED_CHALLENGES", "http"),
"manual_auth_hook": os.getenv("EASYHAPROXY_CERTBOT_MANUAL_AUTH_HOOK", False),
} }
if env_vars["certbot"]["autoconfig"] != "" and not env_vars["certbot"]["server"] and env_vars["certbot"]["email"] != "": if env_vars["certbot"]["autoconfig"] != "" and not env_vars["certbot"]["server"] and env_vars["certbot"]["email"] != "":
@ -285,6 +287,8 @@ class Certbot:
self.eab_hmac_key = self.set_eab_hmac_key(env["certbot"]["eab_hmac_key"]) self.eab_hmac_key = self.set_eab_hmac_key(env["certbot"]["eab_hmac_key"])
self.freeze_issue = {} self.freeze_issue = {}
self.retry_count = env["certbot"]["retry_count"] self.retry_count = env["certbot"]["retry_count"]
self.certbot_preferred_challenges = env["certbot"]["preferred_challenges"]
self.certbot_manual_auth_hook = env["certbot"]["manual_auth_hook"]
@staticmethod @staticmethod
def set_acme_server(acme_server): def set_acme_server(acme_server):
@ -337,9 +341,7 @@ class Certbot:
renew_certs.append(host_arg) renew_certs.append(host_arg)
certbot_certonly = ('/usr/bin/certbot certonly {acme_server}' certbot_certonly = ('/usr/bin/certbot certonly {acme_server}'
' --standalone' ' --preferred-challenges {challenge}'
' --preferred-challenges http'
' --http-01-port 2080'
' --agree-tos' ' --agree-tos'
' --issuance-timeout 90' ' --issuance-timeout 90'
' --no-eff-email' ' --no-eff-email'
@ -350,9 +352,18 @@ class Certbot:
eab_hmac_key=self.eab_hmac_key, eab_hmac_key=self.eab_hmac_key,
certs=' '.join(request_certs), certs=' '.join(request_certs),
email=self.email, email=self.email,
challenge=self.certbot_preferred_challenges,
acme_server=self.acme_server) acme_server=self.acme_server)
) )
if 'http' in self.certbot_preferred_challenges:
certbot_certonly += (' --http-01-port 2080'
' --standalone'
)
if self.certbot_manual_auth_hook:
certbot_certonly += ' --manual --manual-auth-hook \'{hook}\''.format(hook=self.certbot_manual_auth_hook)
ret_reload = False ret_reload = False
return_code_issue = 0 return_code_issue = 0
return_code_renew = 0 return_code_renew = 0

View file

@ -63,8 +63,8 @@ def main():
Functions.log(Functions.INIT_LOG, Functions.INFO, " _ ") Functions.log(Functions.INIT_LOG, Functions.INFO, " _ ")
Functions.log(Functions.INIT_LOG, Functions.INFO, " ___ __ _ ____ _ ___| |_ __ _ _ __ _ _ _____ ___ _ ") Functions.log(Functions.INIT_LOG, Functions.INFO, " ___ __ _ ____ _ ___| |_ __ _ _ __ _ _ _____ ___ _ ")
Functions.log(Functions.INIT_LOG, Functions.INFO, "/ -_) _` (_-< || |___| ' \/ _` | '_ \ '_/ _ \ \ / || |") Functions.log(Functions.INIT_LOG, Functions.INFO, "/ -_) _` (_-< || |___| ' \\/ _` | '_ \\ '_/ _ \\ \\ / || |")
Functions.log(Functions.INIT_LOG, Functions.INFO, "\___\__,_/__/\_, | |_||_\__,_| .__/_| \___/_\_\\_, |") Functions.log(Functions.INIT_LOG, Functions.INFO, "\\___\\__,_/__/\\_, | |_||_\\__,_| .__/_| \\___/_\\_\\_, |")
Functions.log(Functions.INIT_LOG, Functions.INFO, " |__/ |_| |__/ ") Functions.log(Functions.INIT_LOG, Functions.INFO, " |__/ |_| |__/ ")
Functions.log(Functions.INIT_LOG, Functions.INFO, "Release: %s" % (os.getenv("RELEASE_VERSION"))) Functions.log(Functions.INIT_LOG, Functions.INFO, "Release: %s" % (os.getenv("RELEASE_VERSION")))

View file

@ -18,7 +18,9 @@ def test_container_env_empty():
"eab_kid": "", "eab_kid": "",
"email": "", "email": "",
"server": False, "server": False,
"retry_count": 60} "retry_count": 60,
"preferred_challenges": "http",
"manual_auth_hook": False}
} == ContainerEnv.read() } == ContainerEnv.read()
# os.environ['CERTBOT_LOG_LEVEL'] = 'warn' # os.environ['CERTBOT_LOG_LEVEL'] = 'warn'
@ -41,7 +43,9 @@ def test_container_env_customerrors():
"eab_kid": "", "eab_kid": "",
"email": "", "email": "",
"server": False, "server": False,
"retry_count": 60} "retry_count": 60,
"preferred_challenges": "http",
"manual_auth_hook": False}
} == ContainerEnv.read() } == ContainerEnv.read()
finally: finally:
del os.environ['HAPROXY_CUSTOMERRORS'] del os.environ['HAPROXY_CUSTOMERRORS']
@ -64,7 +68,9 @@ def test_container_env_sslmode():
"eab_kid": "", "eab_kid": "",
"email": "", "email": "",
"server": False, "server": False,
"retry_count": 60} "retry_count": 60,
"preferred_challenges": "http",
"manual_auth_hook": False}
} == ContainerEnv.read() } == ContainerEnv.read()
finally: finally:
del os.environ['EASYHAPROXY_SSL_MODE'] del os.environ['EASYHAPROXY_SSL_MODE']
@ -88,7 +94,9 @@ def test_container_env_stats():
"eab_kid": "", "eab_kid": "",
"email": "", "email": "",
"server": False, "server": False,
"retry_count": 60} "retry_count": 60,
"preferred_challenges": "http",
"manual_auth_hook": False}
} == ContainerEnv.read() } == ContainerEnv.read()
finally: finally:
del os.environ['HAPROXY_USERNAME'] del os.environ['HAPROXY_USERNAME']
@ -118,7 +126,9 @@ def test_container_env_stats_password():
"eab_kid": "", "eab_kid": "",
"email": "", "email": "",
"server": False, "server": False,
"retry_count": 60} "retry_count": 60,
"preferred_challenges": "http",
"manual_auth_hook": False}
} == ContainerEnv.read() } == ContainerEnv.read()
finally: finally:
del os.environ['HAPROXY_PASSWORD'] del os.environ['HAPROXY_PASSWORD']
@ -148,7 +158,9 @@ def test_container_env_stats_password_2():
"eab_kid": "", "eab_kid": "",
"email": "", "email": "",
"server": False, "server": False,
"retry_count": 60} "retry_count": 60,
"preferred_challenges": "http",
"manual_auth_hook": False}
} == ContainerEnv.read() } == ContainerEnv.read()
finally: finally:
del os.environ['HAPROXY_USERNAME'] del os.environ['HAPROXY_USERNAME']
@ -174,7 +186,9 @@ def test_container_env_certbot_email():
'eab_kid': "", 'eab_kid': "",
"email": "acme@example.org", "email": "acme@example.org",
"server": False, "server": False,
"retry_count": 60 "retry_count": 60,
"preferred_challenges": "http",
"manual_auth_hook": False
} }
} == ContainerEnv.read() } == ContainerEnv.read()
finally: finally:
@ -187,6 +201,8 @@ def test_container_env_certbot_full():
os.environ['EASYHAPROXY_CERTBOT_EAB_KID'] = 'eab_kid' os.environ['EASYHAPROXY_CERTBOT_EAB_KID'] = 'eab_kid'
os.environ['EASYHAPROXY_CERTBOT_EAB_HMAC_KEY'] = 'eab_hmac_key' os.environ['EASYHAPROXY_CERTBOT_EAB_HMAC_KEY'] = 'eab_hmac_key'
os.environ['EASYHAPROXY_CERTBOT_RETRY_COUNT'] = "10" os.environ['EASYHAPROXY_CERTBOT_RETRY_COUNT'] = "10"
os.environ['EASYHAPROXY_CERTBOT_PREFERRED_CHALLENGES'] = "dns"
os.environ['EASYHAPROXY_CERTBOT_MANUAL_AUTH_HOOK'] = "something_manual_auth_hook"
try: try:
assert { assert {
"customerrors": False, "customerrors": False,
@ -203,7 +219,9 @@ def test_container_env_certbot_full():
"server": "schema://url/a", "server": "schema://url/a",
'eab_hmac_key': 'eab_hmac_key', 'eab_hmac_key': 'eab_hmac_key',
'eab_kid': 'eab_kid', 'eab_kid': 'eab_kid',
'retry_count': 10 'retry_count': 10,
"preferred_challenges": "dns",
"manual_auth_hook": "something_manual_auth_hook"
} }
} == ContainerEnv.read() } == ContainerEnv.read()
finally: finally:
@ -212,6 +230,8 @@ def test_container_env_certbot_full():
del os.environ['EASYHAPROXY_CERTBOT_EAB_KID'] del os.environ['EASYHAPROXY_CERTBOT_EAB_KID']
del os.environ['EASYHAPROXY_CERTBOT_EAB_HMAC_KEY'] del os.environ['EASYHAPROXY_CERTBOT_EAB_HMAC_KEY']
del os.environ['EASYHAPROXY_CERTBOT_RETRY_COUNT'] del os.environ['EASYHAPROXY_CERTBOT_RETRY_COUNT']
del os.environ['EASYHAPROXY_CERTBOT_PREFERRED_CHALLENGES']
del os.environ['EASYHAPROXY_CERTBOT_MANUAL_AUTH_HOOK']
def test_container_log_level(): def test_container_log_level():
@ -234,7 +254,9 @@ def test_container_log_level():
'eab_kid': "", 'eab_kid': "",
"email": "", "email": "",
"server": False, "server": False,
"retry_count": 60 "retry_count": 60,
"preferred_challenges": "http",
"manual_auth_hook": False
} }
} == ContainerEnv.read() } == ContainerEnv.read()
finally: finally: