Describe the bug
When a TLS certificate is assigned to the HTTPS service
(set service https certificates certificate <name>), VyOS writes only the
leaf (server) certificate to the file nginx serves. It does not assemble the
intermediate CA chain from the PKI. An intermediate is included only if the
operator manually adds set service https certificates ca-certificate <name>,
and even then only that single CA is appended — the issuer chain is not followed.
nginx therefore presents an incomplete chain. Clients that do not already
cache/trust the issuing intermediate CA cannot build a path to a trusted root
and reject the connection. This is increasingly common with Let's Encrypt's
newer intermediates (E-series ECDSA / R-series RSA, chaining to ISRG Root
X1/X2), which are frequently absent from client trust stores.
Current behavior
src/conf_mode/service_https.py (generate()) writes only wrap_certificate(leaf),
optionally appending exactly one CA and only when ca-certificate is configured.
This is inconsistent with every other PKI/TLS consumer in VyOS — HAProxy,
OpenConnect, stunnel, SSTP, EAPoL/interfaces and the IKEv2 profile generator —
all of which build the full chain via vyos.pki.find_chain().
Expected behavior
The HTTPS service should serve the complete chain (leaf + all available
intermediate CAs up to the root) by discovering the issuer chain from the PKI,
the same way the other services do — without requiring ca-certificate to be
set manually.
Steps to reproduce
- Import leaf + issuing intermediate + root into the PKI: set pki ca ROOT certificate <...> set pki ca INTERMEDIATE certificate <...> set pki certificate LEAF certificate <...> set pki certificate LEAF private key <...>
- set service https certificates certificate LEAF
- commit
- openssl s_client -connect 127.0.0.1:443 -showcerts </dev/null → only the leaf is presented; the intermediate is missing.
Affected version(s): rolling (and current)
Proposed fix
Assemble the chain in service_https.py with vyos.pki.find_chain() over the
CA certificates present in the PKI, mirroring the existing consumers. Minimal,
self-contained; ca-certificate remains accepted for backward compatibility.