-
Notifications
You must be signed in to change notification settings - Fork 617
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
Auto-generated Vault certs #135
Comments
Not yet. I'll check what it takes to add that. |
I can manually issue a cert using the following:
In this example I've set up a pki backend with an internally generated root cert for *.server.dev and then I've created a role 'server-dev' that is allowed to serve certs for .server.dev based on the root cert. Using the above command will return both the private and public parts of the new cert as well as a copy of the CA. The |
I'd really like to see Vault's PKI backend supported, as well. I've been chewing on this for an hour or so and I think the model of multiple certs per cert store doesn't exactly mesh with Vault's PKI backend, but if each |
I'm curious how this would work independent of vault since you could mimic this with a script or LetsEncrypt or something else. The current CertSource model is that certificates exist and that fabio just picks them up. If a cert does not exist fabio will refuse the connection. In the model of a generated cert that would no longer happen unless the cert provider refuses to generate the cert. Who controls which certs are permissible? Can fabio just generate any cert? What if I announce |
The Vault operator defines what certificates can be issued on a given path. From fabios perspective there is almost no difference to fetching certs from the generic secret backend. In Go, it looks something like this: import "github.com/hashicorp/vault/api"
var client *api.Client
response, err := client.Logical().Write("pki-fabio/issue/example.com", map[string]interface{}{
"common_name": "foo.example.com",
"alt_names": "localhost,127.0.0.1",
"ttl": "24h", // uses Vault's default if omitted
})
pemKey := response.Data["private_key"].(string)
certChain := response.Data["certificate"].(string) + "\n"
for _, cert := range response.Data["ca_chain"].([]interface{}) {
certChain += cert.(string) + "\n"
} So very similar to what the current vault store does. client.Logical().Read is replaced with client.Logical().Write, and the data structure is a bit different from what the current store expects. The "pki-fabio/issue/com.example" path has to be configured in fabio (like for the Consul store). Each Write() call generates a new certificate. It will not return previously generated certs. Previously generates certs remain valid. This is different from how Letsencrypt works. For completeness, this is what a Vault operator might do in advance: # Mount a pki backend for fabio to use. Certificates will expire after 7 days
# by default (7*24=168), and attempting to issue certificates with a validity
# period of more than 30 days will be denied (30*24=720).
vault mount \
-path pki-fabio \
-default-lease-ttl=168h \
-max-lease-ttl=720h \
pki
# Define which certificates can be issued via the pki-fabio/issue/example.com path.
vault write pki-fabio/roles/example.com \
allowed_domains="example.com" \
allow_subdomains="true" \
allow_localhost="true" Many more role options are available. I omitted the commands for configuring the CA for the pki-fabio mount. Would you be interested in a PR with a rough draft for an implementation? |
Yes, a PR would be welcome. Generated certs need to be cached for as long as they're valid (or TTL/2) since this method is called per connection. I assume the base path defines the root domain for which you can generate certs. I think that's fine but you should take into account use-cases for multiple domains. |
In the "pki-fabio/issue/example.com" path, "pki-fabio" represents a single CA, and "example.com" represents the constraints for issuing certs from that CA, such as allowed domains (what Vault calls a role). |
The question is whether you want to allow one or all domains in the pki or whether you want to be able to restrict it to some (e.g. |
I don't know how to achieve that and whether that's something you can do within the vault config that fabio just has to send or whether there needs to be something to be done in fabio and/or whether we need to extend the config DSL. Just keep that in mind when creating the PR, please. |
Add a new cert.Source, VaultPKISource, that issues certficates on demand from HashiCorp Vault PKI backend.
Add a new cert.Source, VaultPKISource, that issues certficates on demand from a HashiCorp Vault PKI backend.
🍿 watching with excitement. Happy to help test. |
Regarding the authorization of the domain, I don't think fabio needs to be involved. If someone asks for foo.company.com and vault allows that cert to be fetched, fabio can serve the cert it fetches (and cache it). If vault doesn't allow it, fabio can serve a default cert or throw an error? |
That's exactly what the PR currently implements. If a cert cannot be issued fabio drops the request. There is no default cert because strictmatch is implied with the vault-pki source. |
Add a new cert.Source, VaultPKISource, that issues certficates on demand from a HashiCorp Vault PKI backend.
Add a new cert.Source, VaultPKISource, that issues certficates on demand from a HashiCorp Vault PKI backend.
I'm investigating hooking up Vault with Fabio and I'm a little confused about the cert store config. The documentation suggests Fabio will fetch certs dynamically from Vault but the config seems to imply that the certs are expected to be manually dropped into a generic 'secret' store in Vault. Is there also support for the PKI secret store and its ability to auto-generate certificates?
The text was updated successfully, but these errors were encountered: