Skip to content

Commit 6ecc58d

Browse files
oliwerGopher Bot
authored andcommitted
BUG/MINOR: acme: fix saving certificates in a crt-store
When calling "dump ssl cert", dataplaneapi was using the storage name of the certificate, instead of the name passed by HAProxy, which caused the command to fail in case the certificate was part of a crt-store. This commit also reorganizes the acme tests to be closer to a real deployment.
1 parent 4a386b8 commit 6ecc58d

File tree

7 files changed

+30
-21
lines changed

7 files changed

+30
-21
lines changed

client-native/events.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ const maxRetryBackoff = 60 * time.Second
161161
func (h *HAProxyEventListener) listen(ctx context.Context) {
162162
defer close(h.done)
163163

164-
var err error
165164
retryAfter := 100 * time.Millisecond
166165
loggedDisconnect := false
167166

@@ -178,8 +177,7 @@ func (h *HAProxyEventListener) listen(ctx context.Context) {
178177
h.mu.Unlock()
179178

180179
if needsConnect {
181-
var el *runtime.EventListener
182-
el, err = newHAProxyEventListener(h.rt.SocketPath())
180+
el, err := newHAProxyEventListener(h.rt.SocketPath())
183181
if err != nil {
184182
if !loggedDisconnect {
185183
log.Warningf("event listener disconnected, reconnecting: %v", err)

client-native/events_acme.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,28 @@ func (h *HAProxyEventListener) handleAcmeNewCertEvent(args string) {
7474
return
7575
}
7676

77-
// Do not use the certificate name in args as a storage name.
78-
// It could be an alias, or the user could have split keys and certs storage.
77+
// The only argument is the certificate name, which could be a "virtual"
78+
// name like "@store/www1" in case of a crt-store.
79+
crtName := args
7980

80-
crt, err := h.rt.ShowCertificate(args)
81+
// Use "show ssl cert" to get the real filename of the certificate.
82+
crt, err := h.rt.ShowCertificate(crtName)
8183
if err != nil {
8284
log.Errorf("events: acme newcert %s: %s", args, err.Error())
8385
return
8486
}
8587

86-
storage, err := h.client.SSLCertStorage()
88+
// Use "dump ssl cert" to get the certificate contents in PEM format.
89+
// This command only works on sockets with level "admin"!
90+
pem, err := h.rt.DumpCertificate(crtName)
8791
if err != nil {
88-
log.Error(err)
92+
log.Errorf("events: acme newcert %s: dump cert: %s", args, err.Error())
8993
return
9094
}
9195

92-
// 'dump ssl cert' can only be issued on sockets with level "admin".
93-
pem, err := h.rt.DumpCertificate(crt.StorageName)
96+
storage, err := h.client.SSLCertStorage()
9497
if err != nil {
95-
log.Errorf("events: acme newcert %s: dump cert: %s", args, err.Error())
98+
log.Errorf("events: acme newcert %s: %s", args, err.Error())
9699
return
97100
}
98101

@@ -115,7 +118,7 @@ func (h *HAProxyEventListener) handleAcmeNewCertEvent(args string) {
115118
return
116119
}
117120

118-
log.Debugf("events: OK: acme newcert %s => %s", args, crt.StorageName)
121+
log.Debugf("events: OK: acme newcert %s => %s", args, storageName)
119122
}
120123

121124
// HAProxy needs dpapi to solve a dns-01 challenge.

e2e/tests/runtime_acme/data/container/var/lib/haproxy/dns01.sh renamed to e2e/tests/runtime_acme/data/container/usr/local/etc/haproxy/dns01.sh

File renamed without changes.

e2e/tests/runtime_acme/data/container/var/lib/haproxy/haproxy.pem renamed to e2e/tests/runtime_acme/data/container/usr/local/etc/haproxy/ssl/haproxy.pem

File renamed without changes.

e2e/tests/runtime_acme/data/container/var/lib/haproxy/haproxy2.pem renamed to e2e/tests/runtime_acme/data/container/usr/local/etc/haproxy/ssl/haproxy2.pem

File renamed without changes.

e2e/tests/runtime_acme/data/haproxy.cfg

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ defaults mydefaults
4040

4141
acme pebble
4242
directory https://pebble:14000/dir
43-
account-key /var/lib/haproxy/acme.account.key
43+
account-key /etc/haproxy/ssl/acme.account.key
4444
contact john.doe@example.com
4545
challenge HTTP-01
4646
keytype RSA
@@ -49,20 +49,25 @@ acme pebble
4949

5050
acme dnschall
5151
directory https://pebble:14000/dir
52-
account-key /var/lib/haproxy/acme.account.key
52+
account-key /etc/haproxy/ssl/acme.account.key
5353
contact john.doe@example.com
5454
challenge dns-01
5555
keytype ECDSA
5656
provider-name exec
57-
acme-vars "command=/var/lib/haproxy/dns01.sh"
57+
acme-vars "command=/etc/haproxy/dns01.sh"
58+
59+
crt-store certificates
60+
crt-base /etc/haproxy/ssl/
61+
key-base /etc/haproxy/ssl/
62+
load crt "haproxy.pem" acme pebble alias "www" domains "dataplaneapi-e2e"
5863

5964
frontend web
6065
bind *:1080
6166
bind *:1443 ssl
6267
http-request return status 200 content-type text/plain lf-string "%[path,field(-1,/)].%[path,field(-1,/),map(virt@acme)]\n" if { path_beg '/.well-known/acme-challenge/' }
63-
ssl-f-use crt "/var/lib/haproxy/haproxy.pem" acme pebble domains "dataplaneapi-e2e"
68+
ssl-f-use crt "@certificates/www"
6469

6570
frontend web2
6671
bind *:1444 ssl
6772
http-request return status 200
68-
ssl-f-use crt "/var/lib/haproxy/haproxy2.pem" acme dnschall domains "dns01.test"
73+
ssl-f-use crt "/etc/haproxy/ssl/haproxy2.pem" acme dnschall domains "dns01.test"

e2e/tests/runtime_acme/tests.bats

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ _RUNTIME_ACME_PATH="/services/haproxy/runtime/acme"
3030
@test "acme_runtime: Renew a certificate" {
3131
haproxy_version_ge "3.3" || skip
3232

33-
cert_name="/var/lib/haproxy/haproxy.pem"
33+
# @certificates/www
34+
cert_name="%40certificates/www"
3435

3536
# Send an 'acme renew' message to HAProxy.
3637
run dpa_curl PUT "$_RUNTIME_ACME_PATH?certificate=$cert_name"
@@ -53,7 +54,8 @@ _RUNTIME_ACME_PATH="/services/haproxy/runtime/acme"
5354
timeout=8 elapsed=0 inc=1 found=false
5455
while ((elapsed < timeout)); do
5556
sleep $inc && elapsed=$((elapsed + inc))
56-
if dpa_docker_exec 'ls -l /etc/haproxy/ssl/haproxy.pem'; then
57+
if ! dpa_diff_docker_file /etc/haproxy/ssl/haproxy.pem data/container/usr/local/etc/haproxy/ssl/haproxy.pem
58+
then
5759
found=true
5860
break
5961
fi
@@ -64,7 +66,7 @@ _RUNTIME_ACME_PATH="/services/haproxy/runtime/acme"
6466
@test "acme_runtime: dns-01 challenge" {
6567
haproxy_version_ge "3.3" || skip
6668

67-
cert_name="/var/lib/haproxy/haproxy2.pem"
69+
cert_name="/etc/haproxy/ssl/haproxy2.pem"
6870

6971
run dpa_curl PUT "$_RUNTIME_ACME_PATH?certificate=$cert_name"
7072
assert_success
@@ -74,7 +76,8 @@ _RUNTIME_ACME_PATH="/services/haproxy/runtime/acme"
7476
timeout=20 elapsed=0 inc=2 found=false
7577
while ((elapsed < timeout)); do
7678
sleep $inc && elapsed=$((elapsed + inc))
77-
if dpa_docker_exec 'ls -l /etc/haproxy/ssl/haproxy2.pem'; then
79+
if ! dpa_diff_docker_file /etc/haproxy/ssl/haproxy2.pem data/container/usr/local/etc/haproxy/ssl/haproxy2.pem
80+
then
7881
found=true
7982
break
8083
fi

0 commit comments

Comments
 (0)