Skip to content
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

caddy tls key_type ignores rsa2048 #6574

Closed
nusnewob opened this issue Sep 15, 2024 · 5 comments
Closed

caddy tls key_type ignores rsa2048 #6574

nusnewob opened this issue Sep 15, 2024 · 5 comments

Comments

@nusnewob
Copy link

  • Description:

I have a caddy instance using Route53 ACME challenge to generate RSA2048 TLS cert for a legacy app, caddy seems to ignore tls { key_type rsa2048 } block.

  • Details

The caddy docker instance was built with Route53 module for Caddy.

Caddy version

$ caddy version
2024/09/15 10:59:40.301 WARN    failed to set GOMAXPROCS        {"error": "open /sys/fs/cgroup/cpu/cpu.cfs_quota_us: no such file or directory"}
v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

Dockerfile

FROM caddy:builder AS builder

RUN xcaddy build \
  --with github.com/caddy-dns/route53

FROM caddy:latest

RUN apk --no-cache add curl ca-certificates nss-tools \
  && update-ca-certificates \
  && rm -rf /var/cache/apk/*

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

Caddy config

{
	acme_dns route53
	log {
		format console
		level ERROR
	}
	admin 0.0.0.0:2019 {
		origins 127.0.0.1 localhost 0.0.0.0:2019
	}
	email [email protected]
	default_sni web.example.dev
}

web.example.dev {
	root /usr/share/caddy
	file_server
	respond /health 200
}

legacy.example.dev {
	tls {
		key_type rsa2048
	}
	root /usr/share/caddy
	file_server
}

AWS creds were configured correctly in /root/.aws/credentials and cert for web.example.dev was obtained correctly, however cert for legacy.example.dev with block tls { key_type rsa2048 } was ignored, the cert generated uses the same key type as web.example.dev using ed25519

  • Expected behaviour

Caddy generates cert for domain with tls { key_type rsa2048 } using key type rsa2048

  • Debug

console output

$ openssl s_client -connect 192.168.2.253:443 -servername legacy.example.dev
CONNECTED(00000003)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = E6
verify return:1
depth=0 CN = legacy.example.dev
verify return:1
---
Certificate chain
 0 s:CN = legacy.example.dev
   i:C = US, O = Let's Encrypt, CN = E6
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA384
   v:NotBefore: Sep 15 09:34:36 2024 GMT; NotAfter: Dec 14 09:34:35 2024 GMT
 1 s:C = US, O = Let's Encrypt, CN = E6
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   a:PKEY: id-ecPublicKey, 384 (bit); sigalg: RSA-SHA256
   v:NotBefore: Mar 13 00:00:00 2024 GMT; NotAfter: Mar 12 23:59:59 2027 GMT
---

Log

2024/09/15 10:50:45.363	INFO	tls.obtain	acquiring lock	{"identifier": "legacy.example.dev"}
2024/09/15 10:50:45.462	INFO	tls.obtain	lock acquired	{"identifier": "legacy.example.dev"}
2024/09/15 10:50:45.462	INFO	tls	storage cleaning happened too recently; skipping for now	{"storage": "FileStorage:/data/caddy", "instance": "2a5d3420-b3dd-4f98-83ba-7ab566f0b189", "try_again": "2024/09/16 10:50:45.462", "try_again_in": 86399.9999993}
2024/09/15 10:50:45.462	INFO	tls.obtain	obtaining certificate	{"identifier": "legacy.example.dev"}
2024/09/15 10:50:45.462	INFO	tls	finished cleaning storage units
2024/09/15 10:50:45.462	DEBUG	events	event	{"name": "cert_obtaining", "id": "424f06b9-996f-4415-8c5f-2727d3b7af79", "origin": "tls", "data": {"identifier":"legacy.example.dev"}}
2024/09/15 10:50:45.463	DEBUG	tls.obtain	trying issuer 1/2	{"issuer": "acme-v02.api.letsencrypt.org-directory"}
2024/09/15 10:50:45.463	INFO	tls.issuance.acme	waiting on internal rate limiter	{"identifiers": ["legacy.example.dev"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": "[email protected]"}
2024/09/15 10:50:45.463	INFO	tls.issuance.acme	done waiting on internal rate limiter	{"identifiers": ["legacy.example.dev"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": "[email protected]"}
2024/09/15 10:50:45.463	INFO	tls.issuance.acme	using ACME account	{"account_id": "https://acme-v02.api.letsencrypt.org/acme/acct/***********", "account_contact": ["mailto:[email protected]"]}
2024/09/15 10:50:45.827	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "GET", "url": "https://acme-v02.api.letsencrypt.org/directory", "headers": {"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["746"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:45 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:45.827	DEBUG	tls.issuance.acme.acme_client	creating order	{"account": "https://acme-v02.api.letsencrypt.org/acme/acct/***********", "identifiers": ["legacy.example.dev"]}
2024/09/15 10:50:45.937	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "HEAD", "url": "https://acme-v02.api.letsencrypt.org/acme/new-nonce", "headers": {"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Date":["Sun, 15 Sep 2024 10:50:45 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["4OmWUlyUVzYlSwlWSjQm3JEnKk54w2XXEd1bOUnjdzvUal7v1n0"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:46.196	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/new-order", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["***********"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["343"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:46 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/***********/***********"],"Replay-Nonce":["fCBw7MtQel7oZIQzn0tvh_DP4TXSZExtv4pybm4elOnfQ2YdFAA"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 201}
2024/09/15 10:50:46.313	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/authz-v3/***********", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["***********"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["515"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:46 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["fCBw7MtQoJvEnZMv2fmVLwKrNF3xlNveYWDrjr8kcPyeGZlISpM"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:46.313	DEBUG	tls.issuance.acme.acme_client	skipping challenge initiation because authorization is not pending	{"identifier": "legacy.example.dev", "authz_status": "valid"}
2024/09/15 10:50:46.313	INFO	tls.issuance.acme.acme_client	authorization finalized	{"identifier": "legacy.example.dev", "authz_status": "valid"}
2024/09/15 10:50:46.313	INFO	tls.issuance.acme.acme_client	validations succeeded; finalizing order	{"order": "https://acme-v02.api.letsencrypt.org/acme/order/***********/***********"}
2024/09/15 10:50:47.267	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/finalize/***********/***********", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["***********"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["447"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/***********/***********"],"Replay-Nonce":["fCBw7MtQ7HlWoDhlA-Dwy5MkRQhJlwK4NtF0zhKro-oyydBh9Mo"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.395	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["2852"],"Content-Type":["application/pem-certificate-chain"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]/1>;rel=\"alternate\""],"Replay-Nonce":["fCBw7MtQHxQNnTsBf3gLosTydRtRPXLrn_j62TykYbXiUCOKrHg"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.396	DEBUG	tls.issuance.acme.acme_client	getting renewal info	{"names": ["legacy.example.dev"]}
2024/09/15 10:50:47.513	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "GET", "url": "https://acme-v02.api.letsencrypt.org/draft-ietf-acme-ari-03/renewalInfo/[SOME_RANDOME_STRING]", "headers": {"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["121"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Retry-After":["21600"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.514	INFO	tls.issuance.acme.acme_client	got renewal info	{"names": ["legacy.example.dev"], "window_start": "2024/11/13 10:11:45.333", "window_end": "2024/11/15 10:11:45.333", "selected_time": "2024/11/13 13:45:12.000", "recheck_after": "2024/09/15 16:50:47.514", "explanation_url": ""}
2024/09/15 10:50:47.630	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]/1", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["2283"],"Content-Type":["application/pem-certificate-chain"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]/0>;rel=\"alternate\""],"Replay-Nonce":["fCBw7MtQYb2mYVTi6r_SgvmY9msQy7HrZ670OjbaZgkGEJ55Xp8"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.630	DEBUG	tls.issuance.acme.acme_client	getting renewal info	{"names": ["legacy.example.dev"]}
2024/09/15 10:50:47.771	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "GET", "url": "https://acme-v02.api.letsencrypt.org/draft-ietf-acme-ari-03/renewalInfo/[SOME_RANDOME_STRING]", "headers": {"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["121"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Retry-After":["21600"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.771	INFO	tls.issuance.acme.acme_client	got renewal info	{"names": ["legacy.example.dev"], "window_start": "2024/11/13 10:11:45.333", "window_end": "2024/11/15 10:11:45.333", "selected_time": "2024/11/15 03:32:18.000", "recheck_after": "2024/09/15 16:50:47.771", "explanation_url": ""}
2024/09/15 10:50:47.771	INFO	tls.issuance.acme.acme_client	successfully downloaded available certificate chains	{"count": 2, "first_url": "https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]"}
2024/09/15 10:50:47.771	DEBUG	tls.issuance.acme	selected certificate chain	{"url": "https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]"}
2024/09/15 10:50:47.772	INFO	tls.obtain	certificate obtained successfully	{"identifier": "legacy.example.dev", "issuer": "acme-v02.api.letsencrypt.org-directory"}
2024/09/15 10:50:47.772	DEBUG	events	event	{"name": "cert_obtained", "id": "b9fefa71-b24e-441a-b978-e674a60a18ff", "origin": "tls", "data": {"certificate_path":"certificates/acme-v02.api.letsencrypt.org-directory/legacy.example.dev/legacy.example.dev.crt","csr_pem":"[SOME_RANDOME_STRING]","identifier":"legacy.example.dev","issuer":"acme-v02.api.letsencrypt.org-directory","metadata_path":"certificates/acme-v02.api.letsencrypt.org-directory/legacy.example.dev/legacy.example.dev.json","private_key_path":"certificates/acme-v02.api.letsencrypt.org-directory/legacy.example.dev/legacy.example.dev.key","renewal":false,"storage_path":"certificates/acme-v02.api.letsencrypt.org-directory/legacy.example.dev"}}
2024/09/15 10:50:47.772	INFO	tls.obtain	releasing lock	{"identifier": "legacy.example.dev"}
2024/09/15 10:50:47.773	DEBUG	tls	loading managed certificate	{"domain": "legacy.example.dev", "expiration": "2024/12/14 09:52:16.000", "issuer_key": "acme-v02.api.letsencrypt.org-directory", "storage": "FileStorage:/data/caddy"}
2024/09/15 10:50:47.945	DEBUG	tls.cache	added certificate to cache	{"subjects": ["legacy.example.dev"], "expiration": "2024/12/14 09:52:16.000", "managed": true, "issuer_key": "acme-v02.api.letsencrypt.org-directory", "hash": "4d9c52e696575a523b0d18d2522be3a0db926a4cae5fdbe262104c7846eb443a", "cache_size": 31, "cache_capacity": 10000}
2024/09/15 10:50:47.945	DEBUG	events	event	{"name": "cached_managed_cert", "id": "299a86d7-f9c8-41c3-86c7-3952612c78e9", "origin": "tls", "data": {"sans":["legacy.example.dev"]}}
@mohammed90
Copy link
Member

I'm not able to replicate your experience. Here's my config and the log of OpenSSL:

{
	local_certs
	storage file_system ./data
}
localhost {
	tls {
		key_type rsa2048
	}
	respond "Ok"
}
$ openssl s_client -connect 127.0.0.1:443 -servername localhost
Connecting to 127.0.0.1
CONNECTED(00000384)
depth=1 CN=Caddy Local Authority - ECC Intermediate
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0
verify return:1
---
Certificate chain
 0 s:
   i:CN=Caddy Local Authority - ECC Intermediate
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: ecdsa-with-SHA256
   v:NotBefore: Sep 16 07:41:26 2024 GMT; NotAfter: Sep 16 19:41:26 2024 GMT
 1 s:CN=Caddy Local Authority - ECC Intermediate
   i:CN=Caddy Local Authority - 2024 ECC Root
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA256
   v:NotBefore: Sep 16 07:40:49 2024 GMT; NotAfter: Sep 23 07:40:49 2024 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICijCCAi+gAwIBAgIRALSti4Eqh/Bcj1jPS3/vgIYwCgYIKoZIzj0EAwIwMzEx
MC8GA1UEAxMoQ2FkZHkgTG9jYWwgQXV0aG9yaXR5IC0gRUNDIEludGVybWVkaWF0
ZTAeFw0yNDA5MTYwNzQxMjZaFw0yNDA5MTYxOTQxMjZaMAAwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC4fpbjQ9YIfNhnuf78r2z6HRP7iISc/iYYniWg
3RqieaLYw+42Ze4GtphehXtM10+W4gOrTDNXbMujJTyZipB6PBsKvk8ddpfj3gp2
KClm4bDhfP2RtfAXW+VcLSpwtbvj+x8QoO4LkdNle/C8dNvCKh6WXdiXK1XH7Fn8
+k/RX2xCPfJkOA/ZEwRES0p06cHqNlB9Mgi87rsqeEKEfmA7h4pQDDbjZhR/HjZE
O1c5+L75MfwSVq3qAcZQTshQEraEVYXNfzTR6u718qN80j9shOfxxTuXGgN1DS5i
xvuIJ3GLaZVPmxpmv1r9LVyrIfsb1bq73IdJLvbG2qXRQWR7AgMBAAGjgYswgYgw
DgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAd
BgNVHQ4EFgQUmXyrTElWUXosPFBbZ5s4yUL8e1swHwYDVR0jBBgwFoAUCD80F6zL
sNPbF75yS+ukbNo1+6wwFwYDVR0RAQH/BA0wC4IJbG9jYWxob3N0MAoGCCqGSM49
BAMCA0kAMEYCIQDRvImv6w1SAgQe6Diw2Q04JjCd1549nS6RI0h1jvyzBQIhAJ8r
a1EuaJ1fScnzoLr18J7GhBfyKFw8dOZMtsC52ZUp
-----END CERTIFICATE-----
subject=
issuer=CN=Caddy Local Authority - ECC Intermediate
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1659 bytes and written 388 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
Server public key is 2048 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 20 (unable to get local issuer certificate)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_128_GCM_SHA256
    Session-ID: 6940084ED105811887E02A47F45AC33726F890C4E4D631F320CCF69442C84802
    Session-ID-ctx:
    Resumption PSK: EBC61A79B9B0F217EC2AA6AC956B093437E685DF0579E47D5D250BCD43017F99
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 604800 (seconds)
    TLS session ticket:
    0000 - 2d 13 76 ef 1e fc fa d1-ab 8d 7c c3 dc a4 ed 0e   -.v.......|.....
    0010 - 03 2d 18 33 53 c9 0b 3f-4b e3 34 42 40 4f 09 9b   .-.3S..?K.4B@O..
    0020 - f8 db c1 1c 91 26 8b 11-a9 24 2b db 1e 38 ff 5a   .....&...$+..8.Z
    0030 - 42 9e 11 01 97 eb 0e 6a-34 9a eb 7c 58 16 19 4e   B......j4..|X..N
    0040 - af de 01 3a 8b a9 71 57-14 17 67 41 f1 a2 f6 73   ...:..qW..gA...s
    0050 - 79 8c 73 bc 76 17 57 f5-a2 a7 9c 9a fc 24 70 54   y.s.v.W......$pT
    0060 - 06 4a 81 8a 4a c7 6d ee-0f                        .J..J.m..

    Start Time: 1726472680
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: no
    Max Early Data: 0
---

Can you help out more with the replication? Let's try with the template, maybe it'll help zero down on the culprit. Ideally, we need to be able to reproduce the bug in the most minimal way possible. This allows us to write regression tests to verify the fix is working. If we can't reproduce it, then you'll have to test our changes for us until it's fixed -- and then we can't add test cases, either.

I've attached a template below that will help make this easier and faster! This will require some effort on your part -- please understand that we will be dedicating time to fix the bug you are reporting if you can just help us understand it and reproduce it easily.

This template will ask for some information you've already provided; that's OK, just fill it out the best you can. 👍 I've also included some helpful tips below the template. Feel free to let me know if you have any questions!

Thank you again for your report, we look forward to resolving it!

Template

## 1. Environment

### 1a. Operating system and version

```
paste here
```


### 1b. Caddy version (run `caddy version` or paste commit SHA)

```
paste here
```


### 1c. Go version (if building Caddy from source; run `go version`)

```
paste here
```


## 2. Description

### 2a. What happens (briefly explain what is wrong)




### 2b. Why it's a bug (if it's not obvious)




### 2c. Log output

```
paste terminal output or logs here
```



### 2d. Workaround(s)




### 2e. Relevant links




## 3. Tutorial (minimal steps to reproduce the bug)




Helpful tips

  1. Environment: Please fill out your OS and Caddy versions, even if you don't think they are relevant. (They are always relevant.) If you built Caddy from source, provide the commit SHA and specify your exact Go version.

  2. Description: Describe at a high level what the bug is. What happens? Why is it a bug? Not all bugs are obvious, so convince readers that it's actually a bug.

    • 2c) Log output: Paste terminal output and/or complete logs in a code block. DO NOT REDACT INFORMATION except for credentials.
    • 2d) Workaround: What are you doing to work around the problem in the meantime? This can help others who encounter the same problem, until we implement a fix.
    • 2e) Relevant links: Please link to any related issues, pull requests, docs, and/or discussion. This can add crucial context to your report.
  3. Tutorial: What are the minimum required specific steps someone needs to take in order to experience the same bug? Your goal here is to make sure that anyone else can have the same experience with the bug as you do. You are writing a tutorial, so make sure to carry it out yourself before posting it. Please:

    • Start with an empty config. Add only the lines/parameters that are absolutely required to reproduce the bug.
    • Do not run Caddy inside containers.
    • Run Caddy manually in your terminal; do not use systemd or other init systems.
    • If making HTTP requests, avoid web browsers. Use a simpler HTTP client instead, like curl.
    • Do not redact any information from your config (except credentials). Domain names are public knowledge and often necessary for quick resolution of an issue!
    • Note that ignoring this advice may result in delays, or even in your issue being closed. 😞 Only actionable issues are kept open, and if there is not enough information or clarity to reproduce the bug, then the report is not actionable.

Example of a tutorial:

Create a config file:
{ ... }

Open terminal and run Caddy:

$ caddy ...

Make an HTTP request:

$ curl ...

Notice that the result is ___ but it should be ___.

@mohammed90 mohammed90 added the needs info 📭 Requires more information label Sep 16, 2024
@nusnewob
Copy link
Author

I've replaced my FQDN with legacy.example.dev, I know local_certs works with key_type rsa2048.

1. Environment

1a. Operating system and version

# uname -a
Linux nas 4.4.302+ #69057 SMP Fri Jan 12 17:02:27 CST 2024 x86_64 GNU/Linux synology_v1000_1621+
# docker --version
Docker version 20.10.23, build 876964a

1b. Caddy version (run caddy version or paste commit SHA)

Built from docker image caddy:builder:sha256:d91078aba635bc14741e77a43d3d76be1b7facc6aed92764d85fc20af522a8b2 with github.com/caddy-dns/route53

$ caddy version
2024/09/15 10:59:40.301 WARN    failed to set GOMAXPROCS        {"error": "open /sys/fs/cgroup/cpu/cpu.cfs_quota_us: no such file or directory"}
v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

1c. Go version (if building Caddy from source; run go version)

N/A

2. Description

2a. What happens (briefly explain what is wrong)

Caddy ignores tls { key_type rsa2048 } block for a valid FQDN uses AWS Route53 ACME challenge and produces cert with default key type ed25519.

2b. Why it's a bug (if it's not obvious)

2c. Log output

2024/09/15 10:50:45.363	INFO	tls.obtain	acquiring lock	{"identifier": "legacy.example.dev"}
2024/09/15 10:50:45.462	INFO	tls.obtain	lock acquired	{"identifier": "legacy.example.dev"}
2024/09/15 10:50:45.462	INFO	tls	storage cleaning happened too recently; skipping for now	{"storage": "FileStorage:/data/caddy", "instance": "2a5d3420-b3dd-4f98-83ba-7ab566f0b189", "try_again": "2024/09/16 10:50:45.462", "try_again_in": 86399.9999993}
2024/09/15 10:50:45.462	INFO	tls.obtain	obtaining certificate	{"identifier": "legacy.example.dev"}
2024/09/15 10:50:45.462	INFO	tls	finished cleaning storage units
2024/09/15 10:50:45.462	DEBUG	events	event	{"name": "cert_obtaining", "id": "424f06b9-996f-4415-8c5f-2727d3b7af79", "origin": "tls", "data": {"identifier":"legacy.example.dev"}}
2024/09/15 10:50:45.463	DEBUG	tls.obtain	trying issuer 1/2	{"issuer": "acme-v02.api.letsencrypt.org-directory"}
2024/09/15 10:50:45.463	INFO	tls.issuance.acme	waiting on internal rate limiter	{"identifiers": ["legacy.example.dev"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": "[email protected]"}
2024/09/15 10:50:45.463	INFO	tls.issuance.acme	done waiting on internal rate limiter	{"identifiers": ["legacy.example.dev"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": "[email protected]"}
2024/09/15 10:50:45.463	INFO	tls.issuance.acme	using ACME account	{"account_id": "https://acme-v02.api.letsencrypt.org/acme/acct/***********", "account_contact": ["mailto:[email protected]"]}
2024/09/15 10:50:45.827	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "GET", "url": "https://acme-v02.api.letsencrypt.org/directory", "headers": {"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["746"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:45 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:45.827	DEBUG	tls.issuance.acme.acme_client	creating order	{"account": "https://acme-v02.api.letsencrypt.org/acme/acct/***********", "identifiers": ["legacy.example.dev"]}
2024/09/15 10:50:45.937	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "HEAD", "url": "https://acme-v02.api.letsencrypt.org/acme/new-nonce", "headers": {"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Date":["Sun, 15 Sep 2024 10:50:45 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["4OmWUlyUVzYlSwlWSjQm3JEnKk54w2XXEd1bOUnjdzvUal7v1n0"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:46.196	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/new-order", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["***********"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["343"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:46 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/***********/***********"],"Replay-Nonce":["fCBw7MtQel7oZIQzn0tvh_DP4TXSZExtv4pybm4elOnfQ2YdFAA"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 201}
2024/09/15 10:50:46.313	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/authz-v3/***********", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["***********"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["515"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:46 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["fCBw7MtQoJvEnZMv2fmVLwKrNF3xlNveYWDrjr8kcPyeGZlISpM"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:46.313	DEBUG	tls.issuance.acme.acme_client	skipping challenge initiation because authorization is not pending	{"identifier": "legacy.example.dev", "authz_status": "valid"}
2024/09/15 10:50:46.313	INFO	tls.issuance.acme.acme_client	authorization finalized	{"identifier": "legacy.example.dev", "authz_status": "valid"}
2024/09/15 10:50:46.313	INFO	tls.issuance.acme.acme_client	validations succeeded; finalizing order	{"order": "https://acme-v02.api.letsencrypt.org/acme/order/***********/***********"}
2024/09/15 10:50:47.267	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/finalize/***********/***********", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["***********"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["447"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/***********/***********"],"Replay-Nonce":["fCBw7MtQ7HlWoDhlA-Dwy5MkRQhJlwK4NtF0zhKro-oyydBh9Mo"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.395	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["2852"],"Content-Type":["application/pem-certificate-chain"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]/1>;rel=\"alternate\""],"Replay-Nonce":["fCBw7MtQHxQNnTsBf3gLosTydRtRPXLrn_j62TykYbXiUCOKrHg"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.396	DEBUG	tls.issuance.acme.acme_client	getting renewal info	{"names": ["legacy.example.dev"]}
2024/09/15 10:50:47.513	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "GET", "url": "https://acme-v02.api.letsencrypt.org/draft-ietf-acme-ari-03/renewalInfo/[SOME_RANDOME_STRING]", "headers": {"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["121"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Retry-After":["21600"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.514	INFO	tls.issuance.acme.acme_client	got renewal info	{"names": ["legacy.example.dev"], "window_start": "2024/11/13 10:11:45.333", "window_end": "2024/11/15 10:11:45.333", "selected_time": "2024/11/13 13:45:12.000", "recheck_after": "2024/09/15 16:50:47.514", "explanation_url": ""}
2024/09/15 10:50:47.630	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]/1", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["2283"],"Content-Type":["application/pem-certificate-chain"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]/0>;rel=\"alternate\""],"Replay-Nonce":["fCBw7MtQYb2mYVTi6r_SgvmY9msQy7HrZ670OjbaZgkGEJ55Xp8"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.630	DEBUG	tls.issuance.acme.acme_client	getting renewal info	{"names": ["legacy.example.dev"]}
2024/09/15 10:50:47.771	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "GET", "url": "https://acme-v02.api.letsencrypt.org/draft-ietf-acme-ari-03/renewalInfo/[SOME_RANDOME_STRING]", "headers": {"User-Agent":["Caddy/2.8.4 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["121"],"Content-Type":["application/json"],"Date":["Sun, 15 Sep 2024 10:50:47 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Retry-After":["21600"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/09/15 10:50:47.771	INFO	tls.issuance.acme.acme_client	got renewal info	{"names": ["legacy.example.dev"], "window_start": "2024/11/13 10:11:45.333", "window_end": "2024/11/15 10:11:45.333", "selected_time": "2024/11/15 03:32:18.000", "recheck_after": "2024/09/15 16:50:47.771", "explanation_url": ""}
2024/09/15 10:50:47.771	INFO	tls.issuance.acme.acme_client	successfully downloaded available certificate chains	{"count": 2, "first_url": "https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]"}
2024/09/15 10:50:47.771	DEBUG	tls.issuance.acme	selected certificate chain	{"url": "https://acme-v02.api.letsencrypt.org/acme/cert/[SOME_RANDOME_STRING]"}
2024/09/15 10:50:47.772	INFO	tls.obtain	certificate obtained successfully	{"identifier": "legacy.example.dev", "issuer": "acme-v02.api.letsencrypt.org-directory"}
2024/09/15 10:50:47.772	DEBUG	events	event	{"name": "cert_obtained", "id": "b9fefa71-b24e-441a-b978-e674a60a18ff", "origin": "tls", "data": {"certificate_path":"certificates/acme-v02.api.letsencrypt.org-directory/legacy.example.dev/legacy.example.dev.crt","csr_pem":"[SOME_RANDOME_STRING]","identifier":"legacy.example.dev","issuer":"acme-v02.api.letsencrypt.org-directory","metadata_path":"certificates/acme-v02.api.letsencrypt.org-directory/legacy.example.dev/legacy.example.dev.json","private_key_path":"certificates/acme-v02.api.letsencrypt.org-directory/legacy.example.dev/legacy.example.dev.key","renewal":false,"storage_path":"certificates/acme-v02.api.letsencrypt.org-directory/legacy.example.dev"}}
2024/09/15 10:50:47.772	INFO	tls.obtain	releasing lock	{"identifier": "legacy.example.dev"}
2024/09/15 10:50:47.773	DEBUG	tls	loading managed certificate	{"domain": "legacy.example.dev", "expiration": "2024/12/14 09:52:16.000", "issuer_key": "acme-v02.api.letsencrypt.org-directory", "storage": "FileStorage:/data/caddy"}
2024/09/15 10:50:47.945	DEBUG	tls.cache	added certificate to cache	{"subjects": ["legacy.example.dev"], "expiration": "2024/12/14 09:52:16.000", "managed": true, "issuer_key": "acme-v02.api.letsencrypt.org-directory", "hash": "4d9c52e696575a523b0d18d2522be3a0db926a4cae5fdbe262104c7846eb443a", "cache_size": 31, "cache_capacity": 10000}
2024/09/15 10:50:47.945	DEBUG	events	event	{"name": "cached_managed_cert", "id": "299a86d7-f9c8-41c3-86c7-3952612c78e9", "origin": "tls", "data": {"sans":["legacy.example.dev"]}}

2d. Workaround(s)

None.

2e. Relevant links

https://github.com/caddy-dns/route53

3. Tutorial (minimal steps to reproduce the bug)

create caddy config

{
	acme_dns route53
}

web.example.dev {
	respond /health 200
}

legacy.example.dev {
	tls {
		key_type rsa2048
	}
	respond "OK"
}

create .aws/credentials with your AWS access and secret key that has permission to update the hosted zone. the actual hosted zone is replaced with example.dev here.

build caddy with Dockerfile

FROM caddy:builder AS builder

RUN xcaddy build \
  --with github.com/caddy-dns/route53

FROM caddy:latest

RUN apk --no-cache add curl ca-certificates nss-tools \
  && update-ca-certificates \
  && rm -rf /var/cache/apk/*

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

run caddy

docker run -it --rm caddy

test cert

$ openssl s_client -connect 192.168.2.253:443 -servername legacy.example.dev
CONNECTED(00000003)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = E6
verify return:1
depth=0 CN = legacy.example.dev
verify return:1
---
Certificate chain
 0 s:CN = legacy.example.dev
   i:C = US, O = Let's Encrypt, CN = E6
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA384
   v:NotBefore: Sep 15 09:34:36 2024 GMT; NotAfter: Dec 14 09:34:35 2024 GMT
 1 s:C = US, O = Let's Encrypt, CN = E6
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   a:PKEY: id-ecPublicKey, 384 (bit); sigalg: RSA-SHA256
   v:NotBefore: Mar 13 00:00:00 2024 GMT; NotAfter: Mar 12 23:59:59 2027 GMT
---

@mohammed90
Copy link
Member

mohammed90 commented Sep 21, 2024

I can't reproduce it. When I specify a fresh site in the Caddyfile with a specific key_type, Caddy uses that key type. The only thing I observed, is that if I change the key type for an existing site, Caddy will not dispose it for a new key of the requested type until the next renewal. So I can only assume that you had the site running before with the default key type, but then changed the config to have that specific key type. I'm torn between working-as-intended or that Caddy should consider the change in key type when reloading config.

One workaround for that is to delete the existing certificate and key and restart Caddy so it'll generate the new key for a fresh certificate.

Any reason for changing the key type?

@mholt
Copy link
Member

mholt commented Sep 22, 2024

Thanks for opening an issue and for the details!

So it sounds to me like you expect that the certificate is replaced, with a new key, when the config specifies a different key type than what it is currently using.

That is a reasonable expectation. But we don't do this for two reasons:

  1. Obtaining certificates is an expensive operation (in terms of policy)
  2. Decoding certs and keys is an expensive operation (in terms of CPU)

So you can imagine what this would do for servers that are handling hundreds of certificates or more (which is quite common). So we defer changes of settings for certificates until when they would normally be renewed. You can force this by deleting the certs from storage, as Mohammed suggested, but I don't recommend this at scale. (Key type changes are very uncommon.)

@mholt
Copy link
Member

mholt commented Sep 25, 2024

I'll close this for now, but feel free to continue the discussion and we can reopen if needed.

@mholt mholt closed this as not planned Won't fix, can't repro, duplicate, stale Sep 25, 2024
@mholt mholt removed the needs info 📭 Requires more information label Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants