CARVIEW |
Navigation Menu
-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
haproxy deploy hook updates existing certificate over stats socket #4581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I just updated the PR, it now has the ability to add a new certificate in HAProxy without reloading as well as updating a previous one. |
Hey @wlallemand, this is AWESOME, thank you. I was getting ready to write this functionality and decided I should check if it already exists. I ran into a few issues I had to address to get it working for me.
|
@msimerson Thanks for your feedback, I'm going to fix the script to integrate properly your use case.
Indeed. I did not had any problem with the provider I used but that's a valid point, it could contains empty lines or comments between the certificate sections.
I hesitate to include directly the socat format into the variable, maybe I could add a variable to be able to chose any socat prefix.
Indeed that could be a problem, I will retest all of this. Also, I published a documentation on the haproxy wiki: https://github.com/haproxy/wiki/wiki/Letsencrypt-integration-with-HAProxy-and-acme.sh |
I'm curious how you think that having 2 socat variables is going to be easier for folks to grok and easier to support than having just one. It's not like the variable contents will ever be used separately. URIs evolved for a reason. :-) |
@msimerson problem is socat and haproxy doesn't have the same "URIs". I don't want the user to need to specify a socat format. Maybe I'll just check if the variable contains any / to select UNIX-CONNECT or TCP-CONNECT. |
I see. In looking again, you use
And anyone needing a different socat formula can specify it. |
Indeed, my mistake, I should also fix this. My first implementation was a little bit different and I probably forgot it.
I want to avoid this and find it dangerous, if for some reason the path is wrong and is not a UNIX socket, it would do a GOPEN and the certificate could be dumped on the filesystem. That's exactly why I set UNIX: in the first place.
That's why I suggested another variable, but to be honest there is not a lot of common setup. It's basically TCP with ipv4 and ipv6 and unix socket, some people could also want to use OPENSSL... I think I'll remove the prefix and adjust the documentation as you suggested in the first place, with a warning about not using a prefix. |
In this case, the certificate is already on the filesystem, right? If you're super worried about it, you can always do a |
Just wanted to chime in to say that we are not using chroot for haproxy, but running it inside a container. And pretty much the same situation arises there: paths outside the container (where acme.sh stores the certs) and inside the container (where haproxy looks for them) don't match. Is this something that could be supported? |
Thanks for the feedbacks, I'll rework the PR next week to better handle these cases. |
Hi folks, To get the script to work right on my setup (Debian 12, HaProxy 2.6.12-1) I had to make a small tweak. It seems like the stats socket doesn't read the entire input when passing in the file contents, instead stopping after reading an empty line, which means it doesn't read the CA certificate chain. This is what it looks like when running the deploy command with
The deploy script logs it as successful, but socat wasn't able to write everything (Broken pipe). openssl s_client shows that the certificate chain is incomplete:
#4788 mentions the same "Broken pipe" message but the related MR #4841 did not help and even seems to have made things worse, since the key no longers get imported when it's moved to the end of the PEM file. Only after removing the empty lines does command with hot update work correctly for me. This is the change I made: diff --git a/haproxy-wlallemand.sh b/usr/local/share/acme.sh/deploy/haproxy.sh
index a611ec8..bb2b6b1 100644
--- a/haproxy-wlallemand.sh
+++ b/usr/local/share/acme.sh/deploy/haproxy.sh
@@ -177,7 +177,7 @@ haproxy_deploy() {
# Create a temporary PEM file
_temppem="$(_mktemp)"
_debug _temppem "${_temppem}"
- cat "${_ckey}" "${_ccert}" "${_cca}" >"${_temppem}"
+ cat "${_ckey}" "${_ccert}" "${_cca}" | grep . >"${_temppem}"
_ret="$?"
# Check that we could create the temporary file Now the deploy command runs fine and the openssl s_client command shows the complete chain:
|
Sanitize the PEM of the haproxy deploy script by removing the '\n', this way it could be injected directly over the CLI.
Since version 2.2, HAProxy is able to update dynamically certificates, without a reload. This patch uses socat to push the certificate into HAProxy in order to achieve hot update. With this method, reloading is not required. This should be used only to update an existing certificate in haproxy. 2 new variables are available: - DEPLOY_HAPROXY_HOT_UPDATE="yes" update over the stats socket instead of reloading - DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock" set the path on the stats socket.
DEPLOY_HAPROXY_HOT_UPDATE="yes" now allows to add a new certificate within HAProxy instead of updating an existing one. In order to work, the ${DEPLOY_HAPROXY_PEM_PATH} value must be used as a parameter to the "crt" keyword in the haproxy configuration. The patch uses the following commands over HAProxy stats socket: - show ssl cert - new ssl cert - set ssl cert - commit ssl cert - add ssl crt-list
Small updates:
@Neilpang Any chance this can be merged? This is actually asked by a lot of people. |
I'll make more updates for chroot and wilcard as well as the master CLI instead of the stats socket, but probably in a separate PR. |
acmesh-official/acme.sh#4581 was updated, this patch update the haproxy repository with the update. the following changes were done: - sanitize the PEM to remove the '\n' (truncated certicate chain) - shellcheck fixes - socat format is directly used in the DEPLOY_HAPROXY_STATS_SOCKET variable
DEPLOY_HAPROXY_MASTER_CLI allows to use the HAProxy master CLI instead of a stats socket for DEPLOY_HAPROXY_HOT_UPDATE="yes" The syntax of the master CLI is slightly different, a prefix with the process number need to be added before any command. This patch uses ${_cmdpfx} in front of every socat commands which is filled when the master CLI is used.
By default acme.sh uses the '*' character in the filename for wildcard. That can be confusing within HAProxy since the * character in front of a filename in the stat socket is used to specified an uncommitted transaction. This patch replace the '*' by a '_' in the filename. This is only done when using the default filename, the name can still be forced with an asterisk.
update:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in #4581 (comment) I'm not sure about replacing the asterisk with an underscore, since some DNS servers allow underscore as a subdomain even though RFC1035 doesn't allow it.
Let's Encrypt for one doesn't issue certificates for underscore domains but I don't know about other acme server implementations.
Would love to see input from other people about this.
Otherwise I don't see any problems with the script.
Hi @wlallemand. I just stumbled upon this trying to configure OCSP Stapling in haproxy. Is it possible to use Le_OCSP_Staple info already present in haproxy.sh and add commands from https://www.haproxy.com/documentation/haproxy-runtime-api/reference/set-ssl-ocsp-response/ to the update commands if ocsp is present? Or even better, integrate https://www.haproxy.com/documentation/haproxy-configuration-tutorials/ssl-tls/#enable-ocsp-stapling somehow? Thanks in advance! |
Hello @krezovic,
|
Hi @wlallemand! Looking forward to proper support. Thanks for your reply! |
@dingensundso Any chance we could have this merged? This is stuck for a while now. |
please also update the usage here: |
Thanks, updated! |
Remove the acme.sh script since it was merged in acmesh-official/acme.sh#4581 So people don't try to download a script which is not up to date with the current acme.sh master.
Very nice job, it would be cool to have it available - maybe it's a good time for a new release? |
Since version 2.2, HAProxy is able to update dynamically certificates, without a reload.
This patch uses socat to push the certificate into HAProxy in order to achieve hot update. With this method, reloading is not required. This should be used only to update an existing certificate in haproxy.
2 new variables are available:
DEPLOY_HAPROXY_HOT_UPDATE="yes" update over the stats socket instead of reloading
DEPLOY_HAPROXY_STATS_SOCKET="UNIX:/run/haproxy/admin.sock" set the path on the stats socket.