feat: support wildcard certificates
Use VerifyHostname instead of a string comparison, as it allows usage of wildcard certificate for every cluster member.
Release unique constraint on certificate, as in case of wildcard certificate it can be the same for all the cluster members.
Resolves #312
Hmm, the server certificate is supposed to be identifying for each cluster member. If they're all the same then this defeats the purpose as anyone under *.maas.internal could then communicate as a cluster member. Checking against a wildcard also breaks the requirement that a join token is destined for the particular host according to the name provided when generating the token. With a wildcard, anyone matching the wildcard could join the cluster with the token.
Canonical K8s had a workaround for this using the PreInit hook to replace each system's server.crt/key on startup with a modified cert with the correct SAN names applied in accordance with the microcluster cluster member name: https://github.com/canonical/k8s-snap/blob/f8e6934870c64f5535d925c597c6d1ce3c90bb9c/src/k8s/pkg/k8sd/app/hooks_preinit.go#L16-L56
Would something like that be useful here instead?
Hmm, the server certificate is supposed to be identifying for each cluster member.
I agree that this is the best practice when it comes to certificates. I also do understand that if all members share the same certificate, it could indeed compromise the security model because the certificate would no longer uniquely authenticate the host. But I don't think we should limit usage of wildcard certificates.
If they're all the same then this defeats the purpose as anyone under
*.maas.internalcould then communicate as a cluster member.
If they have correct private key and certificate, then they can connect, yes. Wildcards simplify hostname matching but do not bypass private key validation. Considering that there is a secure way to deliver private key to the host, this should not be an issue?
Checking against a wildcard also breaks the requirement that a join token is destined for the particular host according to the name provided when generating the token. With a wildcard, anyone matching the wildcard could join the cluster with the token.
I think this can be addressed by checking the name associated with the token against name coming from the request? https://github.com/canonical/microcluster/pull/313/commits/29cd383aff98c39ef67088434eb4d769c1eb3381
Canonical K8s had a workaround for this using the
PreInithook to replace each system'sserver.crt/keyon startup with a modified cert with the correct SAN names applied in accordance with the microcluster cluster member name: https://github.com/canonical/k8s-snap/blob/f8e6934870c64f5535d925c597c6d1ce3c90bb9c/src/k8s/pkg/k8sd/app/hooks_preinit.go#L16-L56Would something like that be useful here instead?
Thanks for the link! But that will still require a proper certificate for each host and won't work with wildcard certificates?
The reason I am asking for wildcard certificates support is because this is a good option for someone who doesn't want to have self-signed certificates per each host, but rather have a single certificate (yes, it is a bit less secure, but this is a good tradeoff when you don't want to deal with certificate management)
@troyanov as discussed I have created https://github.com/canonical/microcluster/issues/445 with an idea how we could achieve the logging/visibility you are looking for.