Open bgK opened 11 months ago
There might be some overlap here with #38242 where we are looking to support directory glob patterns. If the order of the certificates isn't important we might be able to support something like this:
spring:
ssl:
bundle:
pem:
client:
truststore:
certificate: "/my/certs/allowed-*.crt"
select: all
I hadn't seen #38242. Indeed, it fills almost the same need. It's nice in that the properties are backwards compatible and makes it easy to have large numbers of certificates.
Here's a use case that I don't think is easily covered by #38242. A Spring Boot app deployed in Kubernetes. It calls an external service for which some instances are hosted in the same cluster, some instances are scaled out to an external provider. The internal instances are exposed using the Kubernetes CA, the other instances use some other CA. Kubernetes bind mounts the CA at a fixed location inside the pod /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
:
spring:
ssl:
bundle:
pem:
client:
truststore:
certificates:
- "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
- "classpath:other-ca.crt"
IMO, me both #38754 and this are good enhancements.
Add to this ticket about a similar but not same use case:
to allow multiple certs from a folder for different hostnames. This may open the possibility to support one Spring Boot application serving traffic for multiple domains.
Underlying TomCat 8.5 already "allows multiple certificates with different names to be associated with a single TLS connector" (link).
@dopsun Spring Boot 3.3 added support for configuring SSL bundles for hostnames (SNI). Does this meet your requirement?
@scottfrederick Thanks for sharing this, I have not been aware of this feature yet. A quick look at the link you shared, it seems what I'm waiting for. Will try it out ASAP.
I also need to be able to add multiple PEM format certificates to the truststore. Being able to add them in with wildcard or by name would be very helpful.
Having it be limited per hostname is not useful in my case and, my case would be covered by the other two options. I can see how mapping certs to specific hostnames is a good and useful config in other situations.
I hadn't seen #38242. Indeed, it fills almost the same need. It's nice in that the properties are backwards compatible and makes it easy to have large numbers of certificates.
Here's a use case that I don't think is easily covered by #38242. A Spring Boot app deployed in Kubernetes. It calls an external service for which some instances are hosted in the same cluster, some instances are scaled out to an external provider. The internal instances are exposed using the Kubernetes CA, the other instances use some other CA. Kubernetes bind mounts the CA at a fixed location inside the pod
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
:spring: ssl: bundle: pem: client: truststore: certificates: - "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" - "classpath:other-ca.crt"
IMO, me both #38754 and this are good enhancements.
That's a great idea. I'd also like to add a little bit of salt here. Suppose that your application has 2 well-known potential client services, foo and bar and you want to support mTLS. Each client service has a specific intermediate CA. Client services are dynamically installed/removed from the cluster. For improved resiliency/manageability, you dont want to change the deployment of your application whenever a new client service is installed in the cluster: the client CAs must be dynamically added/removed to your server truststore as their services installed/removed from the cluster.
With k8s you should be able to mount the volumes as optional:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: myimage
volumeMounts:
- name: foo-ca
mountPath: /var/run/secrets/foo/ca.crt
- name: bar-ca
mountPath: /var/run/secrets/bar/ca.crt
volumes:
- name: foo-ca
secret:
secretName: foo-ca
optional: true
- name: bar-ca
secret:
secretName: bar-ca
optional: true
In this scenario, there should be a way to flag the SSLBundle API that the CA is optional, and when not available it should still attempt to load the other CAs and not prevent the service from starting.
As the client services are installed/uninstalled, the secrets and mounts will be updated and a new SSLBundle should be emitted via SslBundles.addBundleUpdateHandler
callback so components supporting hot-reload will be able to reconfigure themselves. In the absence of the CAs (in case none of the services are installed), we should consider whatever the default behavior is, i.e: not trust any CA.
For supporting this feature we can extend your proposal with something like:
spring: ssl: bundle: pem: client: truststore: certificates: - "optional:/var/run/secrets/foo/ca.crt" - "optional:/var/run/secrets/bar/ca.crt"
Regarding my comment above, we currently have an in-house component for supporting this and we are willing to contribute if thats acceptable from spring team side. Please let me know your views on this so we can start.
At the moment, PEM
SslBundle
s can be instantiated through the following properties:Where
client.crt
can contain multiple certificates.In some situations, multiple very different certificates need to be trusted. For instance:
While concatenating all the trusted certificates in the same file is an option, it makes it quite hard to see at a glance which certificates are trusted, as they are PEM-encoded. It would be nice to be able to use file names to identify the certificates: