From 0f846cf8dd877a43b5538542618423ec99202d18 Mon Sep 17 00:00:00 2001 From: max furman Date: Tue, 13 Nov 2018 12:47:07 -0800 Subject: [PATCH] Add Provisioner documentation --- README.md | 173 +++++++++++++++++---- docs/common-questions.md | 108 +++++++++++++ distribution.md => docs/distribution.md | 0 docs/recommendations.md | 193 ++++++++++++++++++++++++ 4 files changed, 443 insertions(+), 31 deletions(-) create mode 100644 docs/common-questions.md rename distribution.md => docs/distribution.md (100%) create mode 100644 docs/recommendations.md diff --git a/README.md b/README.md index b9903f92..240efaab 100644 --- a/README.md +++ b/README.md @@ -9,18 +9,31 @@ For more information and docs see [the Step website](https://smallstep.com/cli/) and the [blog post](https://smallstep.com/blog/zero-trust-swiss-army-knife.html) announcing Step Certificate Authority. +## Why? + +Managing your own *public key infrastructure* (PKI) can be tedious and error +prone. Good security hygiene is hard. Setting up simple PKI is out of reach for +many small teams, and following best practices like proper certificate revocation +and rolling is challenging even for experts. + +This project is part of smallstep's broader security architecture, which makes +it much easier to implement good security practices early, and incrementally +improve them as your system matures. + ### Table of Contents - [Installing](#installing) - [Documentation](#documentation) - [Terminology](#terminology) - [Getting Started](#getting-started) -- [I've Got a Running CA! Now What?](#now-what) +- [Commonly Asked Questions](docs/common-questions.md) +- [Recommended Defaults](docs/recommendations.md) - [Versioning](#versioning) -- [How To Create A New Release](./distribution.md) +- [How To Create A New Release](docs/distribution.md) - [LICENSE](./LICENSE) - [CHANGELOG](./CHANGELOG.md) + ## Installing These instructions will install an OS specific version of the `step` binary on @@ -62,7 +75,10 @@ Documentation can be found in three places: ### PKI - Public Key Infrastructure -Blah blah +A set of roles, policies, and procedures needed to create, manage, distribute, +use, store, and revoke digital certificates and manage public-key encryption. +The purpose of a PKI is to facilitate the secure electronic transfer of +information for a range of network activities. ### Provisioners @@ -192,13 +208,61 @@ To start the CA run: step-ca $STEPPATH/config/ca.step ``` -## [I've got a running CA! Now What?](#now-what) +Consider populating a `defaults.json` file with a few variables that will +make your command line experience much more pleasant. -Now that you have an online CA that authenticates requests before issuing -certificates you can begin automating the distribution and maintenance of your -PKI. +### Set your defaults -### Issuing x.509 certificates for TLS (HTTPS) +``` +$ cat > $STEPPATH/config/defaults.json +{ + "ca-url": "https://:", + "ca-config": "/home/user/.step/config/ca.json" + "root": "/home/user/.step/secrets/root_ca.crt" +} +``` + +**ca-curl**: Use the DNS name and port that you used when initializing the CA. +**root**: Path to the root certificate on the file system. + +You can always override these values with command-line flags. + +### Reload + +It is important that the CA be able to handle configuration changes with no downtime. +Our CA has a built in `reload` function allowing it to: + +1. Finish processing existing connections while blocking new ones. +2. Parse the configuration file and re-initialize the API. +3. Begin accepting blocked and new connections. + +`reload` is triggered by sending a SIGHUP to the PID (see `man kill` +for your OS) of the Step CA process. A few important details to note when using `reload`: + +* The location of the modified configuration must be in the same location as it +was in the original invocation of `step-ca`. So, if the original command was + +``` +$ step-ca ./.step/config/ca.json +``` + +then, upon `reload`, the Step CA will read it's new configuration from the same +configuration file. + +* Step CA requires the password to decrypt the intermediate certificate again +upon `reload`. You can auotmate this in one of two ways: + + * Use the `--password-file` flag in the original invocation. + * Use the top level `password` attribute in the `ca.json` configuration file. + +## Versioning + +We use [SemVer](http://semver.org/) for versioning. For the versions available, +see the [tags on this repository](https://github.com/smallstep/cli). + + + +### Let's issue a certificate! There are two steps to issuing a certificate at the command line: @@ -210,11 +274,10 @@ provides a single command that will prompt you to select and decrypt an authorized provisioner and then request a new certificate. ``` -$ step ca certificate "foo.example.com" foo.crt foo.key --ca-url https://ca.smallstep.com \ - --root /path/to/root_ca.crt +$ step ca certificate "foo.example.com" foo.crt foo.key ``` -If you would like to generate certificates on demand from an automated configuration +If you would like to generate certificates on demand from an automated configuration management solution (no user input) you would split the above flow into two commands. @@ -234,39 +297,87 @@ You can take a closer look at the contents of the certificate using `step certif $ step certificate inspect foo.crt ``` -## Hot Reload +### List|Add|Remove Provisioners -It is important that the CA be able to handle configuration changes with no downtime. -Our CA has a built in `reload` feature allowing it to: +The Step CA configuration is initialized with one provisioner; one entity +that is authorized by the CA to generate provisioning tokens for new certificates. +We encourage you to have many provisioners - ideally one for each entity in your +infrastructure. -1. Finish processing existing connections while blocking new ones. -2. Re-read the configuration file and initialize the API. -3. Begin accepting blocked and new connections. +**Why should I be using multiple provisioners?** -The `reload` feature is triggered by sending a SIGHUP to the PID (see `man kill` for your OS) of the -Step CA process. A few important details to note when using `reload`: +* Each certificate generated by the Step CA contains the ID of the provisioner +that issued the *provisioning token* authorizing the creation of the cert. This +ID is stored in the X.509 ExtraExtensions of the certificate under +`OID: 1.3.6.1.4.1.37476.9000.64.1` and can be inspected by running `step +certificate inspect foo.crt`. These IDs can and should be used to debug and +gather information about the origin of a certificate. If every member of your +ops team and the configuration management tools all use the same provisioner +to authorize new certificates you lose valuable visibility into the workings +of your PKI. +* Each provisioner should require a **unique** password to decrypt it's private key +-- we can generate unique passwords for you but we can't force you to use them. +If you only have one provisioner then every entity in the infrastructure will +need access to that one password. Jim from your dev ops team should not be using +the same provisioner/password combo to authorize certificates for debugging as +Chef is for your CICD - no matter how trustworthy Jim says he is. -* The location of the modified configuration must be in the same location as it -was in the original invocation of the `step-ca`. So, if the original command was +Let's begin by listing the existing provisioners: ``` -$ step-ca ./.step/config/ca.json +$ bin/step ca provisioner list ``` -then, upon reload, the Step CA will read it's new configuration from the same -configuration file. +Now let's add a provisioner for Jim. -* Step CA requires the password to decrypt the intermediate certificate again -upon `reload`. You can auotmate this in one of two ways: +``` +$ bin/step ca provisioner add jim@smallstep.com --create +``` - * Use the `--password-file` flag in the original invocation. - * Use the toplevel `password` attribute in the `ca.json` configuration file. +**NOTE**: This change will not affect the Step CA until a reload is forced by +sending a SIGHUP signal to the process. -## Versioning +List the provisioners again and you will see that nothing has changed. -We use [SemVer](http://semver.org/) for versioning. For the versions available, -see the [tags on this repository](https://github.com/smallstep/cli). +``` +$ bin/step ca provisioner list +``` +Now let's reload the CA. You will need to re-enter your intermediate +password unless it's in your `ca.json` or your are using `--password-file`. + +``` +$ ps aux | grep step-ca # to get the PID +$ kill -1 +``` + +Once the CA is running again, list the provisioners, again. + +``` +$ bin/step ca provisioner list +``` + +Boom! Magic. +Now suppose Jim forgets his password ('come on Jim!'), and he'd like to remove +his old provisioner. Get the `kid` (Key ID) of Jim's provisioner by listing +the provisioners and finding the appropriate one. Then run: + +``` +$ bin/step ca provisioner remove jim@smallstep.com --kid +``` + +Then reload the CA and verify that Jim's provisioner is no longer returned +in the provisioner list. + +We can also remove all of Jim's provisioners, supposing Jim forgot all the passwords +('really Jim?'), by running the following: + +``` +$ bin/step ca provisioner remove jim@smallstep.com --all +``` + +The same entity may have multiple provisioners for authorizing different +types of certs. Each of these provisioners must have unique keys. ## License diff --git a/docs/common-questions.md b/docs/common-questions.md new file mode 100644 index 00000000..a8fa124a --- /dev/null +++ b/docs/common-questions.md @@ -0,0 +1,108 @@ +# Commonly Asked Questions + +These are some commonly asked questions on the topics of PKI, TLS, X509, +cryptography, threshold-cryptography, etc. +We hope to reduce the amount of hand-waving in these responses as we add +more features to the Step toolkit over time. + +#### What's TLS & PKI? + +TLS stands for *transport layer security*. It used to be called *secure sockets +layer* (or SSL), but technically SSL refers to an older version of the protocol. +Normal TCP connections communicate in plain text, allowing attackers to +eavesdrop and spoof messages. If used properly, TLS provides *confidentiality* +and *integrity* for TCP traffic, ensuring that messages can only be seen by their +intended recipient, and cannot be modified in transit. + +TLS is a complicated protocol with lots of options, but the most common mode of +operation establishes a secure channel using *asymmetric cryptography* with +*digital certificates* (or just certificates for short). First, some quick definitions: +* *Asymmetric cryptography* (a.k.a., public key cryptography) is an underappreciated +gift from mathematics to computer science. It uses a *key pair*: a private key +known only to the recipient of the message, and a public key that can be broadly +distributed, even to adversaries, without compromising security. +* *Digital certificates* are data structures that map a public key to the +well-known name of the owner of the corresponding private key (e.g., a DNS host name). +They *bind* a name to the public key so you can address recipients by name instead of +using public keys directly (which are big random numbers). + +Briefly, there are two functions that can be achieved using asymmetric cryptography: +* Messages can be *encrypted* using the public key to ensure that only the +private key holder can *decrypt* them, and +* Messages can be *signed* using the private key so that anyone with the *public +key* knows the message came from the private key holder. +With digital certificates, you can replace "private key holder" with "named entity," +which makes things a whole lot more useful. It lets you use names, instead of +public keys, to address messages. + +PKI stands for *public key infrastructure*. Abstractly, it's a set of policies +and procedures for managing digital certificates (i.e., managing the bindings +between names and public keys). Without proper secure PKI, an attacker can fake +a binding and undermine security. + +#### What's a certificate authority? + +A certificate authority (CA) stores, issues, and signs digital certificates. CAs +have their own key pair, with the private key carefully secured (often offline). +The CA binds its name to its public key by signing a digital certificate using +its own private key (called *self signing*). The CA's self-signed certificate, +or *root certificate*, is distributed to all principals in the system (e.g., all +of the clients and servers in your infrastructure). + +So, the CA is tasked with securely binding names to public keys. Here's how that process works. +1. When a named principal wants a certificate, it generates its own key pair. +Nobody else ever needs to know the private key, not even the CA. +2. The principal creates a certificate signing request (CSR), containing its +name and public key (and some other stuff), and submits it to the CA. The CSR is +self-signed, like the root certificate, so the CA knows that the requestor has +the corresponding private key. +3. The CA performs some form of *identity proofing*, certifying that the request +is coming from the principal named in the CSR. +4. Once satisfied, the CA issues a certificate by using its own private key to +sign a certificate binding the name and public key from the CSR. + +Certificates signed by the CA are used to securely introduce principals that +don't already know one anothers' public keys. Assuming both principals agree on +a trusted CA, they can exchange digital certificates and authenticate the +signatures to gain some assurance that they are communicating with the named entity. + +Technically, smallstep's certificate authority is more than just a certificate +authority. It combines several PKI roles into one simple, flexible package. It +acts as a *registration authority*, accepting requests for digital certificates +and verifying the identity of the requesting entities before establishing bindings. +It also acts as a *central directory* and more generally as a *certificate +management system*, a secure location for storing and distributing key material. + +#### Why not just use Verisign, Entrust, Let's Encrypt, etc? + +The web's *open public key infrastructure* (web PKI), while far from perfect, +is an important foundation for securing the web. So why not use it for securing +communication for your own internal infrastructure? There are several reasons: +* It's expensive to provision certificates from a public CA for all of your services +* Public CAs can't handle client certificates (mutual TLS) +* It's much harder (and more expensive) to revoke or roll certificates from public CAs +* It relies on a third party that can subvert your security +More broadly, the answer is that web PKI was designed for the web. A lot of the +web PKI design decisions aren't appropriate for internal systems. + +#### How does identity proofing work? + +Good question. However you want it to. Details here. Give some options: simple +meat-space token-based method should probably be default. But we should also +support the use of a CI/CD pipeline or orchestrator as a *registration authority* +so you can automate certificate provisioning. + +Also talk about ACME, if we decide to support it. + +In general, trust will always flow back out to you, the operator of your system. +With that in mind, the simplest form of identity proofing is manual: [describe +token-based manual mechanism here]. As your system grows, this process can become +onerous. Automated identity proofing requires careful coordination between +different parts of your system. Smallstep provides additional tooling, and vetted +designs, to help with this. If you integrate with our other tools its easy to +start with a manual identity proofing mechanism and move to a more sophisticated +automated method as your system grows. + +#### I already have PKI in place. Can I use this with my own root certificate? + +Absolutely. [Details here]. diff --git a/distribution.md b/docs/distribution.md similarity index 100% rename from distribution.md rename to docs/distribution.md diff --git a/docs/recommendations.md b/docs/recommendations.md new file mode 100644 index 00000000..248bab7b --- /dev/null +++ b/docs/recommendations.md @@ -0,0 +1,193 @@ +## Sane Recommendations + +TLS, PKI, X509, HTTPS, etc. all require configuration. All of +these technologies allow the user to "shoot themselves in the foot" by +misconfiguring them and reducing their benefits significantly. Therefore, +offering an easy to use solution that works out of the box means choosing and +enforcing sane default configurations for all these technologies. + +Below we document some of the significant default configuration that we recommend. +This document is a moving target: security and cryptography are constanly +changing and evolving - vulnerabilities are found, new algorithms are created, +etc. We inted for this document be an accurate representation of current +best practices in the industry, and to have these practices codified as defaults +in the `certificates` code base. If you have questions, suggestions, or comments +about any of these decisions please let us know. + +### Keys + + ``` + // RSA keys don't scale very well. To get 128 bits of security, you need 3,072-bit + // RSA keys, which are noticeably slower. ECDSA keys provide an alternative + // that offers better security and better performance. At 256 bits, ECDSA keys + // provide 128 bits of security. A small number of older clients don't support + // ECDSA, but most modern clients do. + Default Key Type: ECDSA + Default Curve Bits: P-256 + + // Encryption algorithm for writing private keys to disk. We've chosen AES + // (aka Rijndael) because it was the official choice of the Advanced Encryption + // Standard contest. The three supported key sizes are 128, 192, and 256. Each + // of these is considered to be unbreakable for the forseeable future, therefore + // we chose 128 bits as our default because the performance is better + // (as compared to the greater key sizes) and because we agree, with the + // designers of the algorithm, that 128 bits are quite sufficient for most + // security needs. + Default PEMCipher: AES128 + ``` + +### X.509 Certificate Defaults + +* **root certificate** + + ``` + * Validity (10 year window) + * Not Before: Now + // A 10 year window seems advisable until software and tools can be written + // for rotating the root certificate. + * Not After: Now + 10 years + * Basic Constraints + // The root certificate is a Certificate Authority, it will be used to sign + // other Certificates. + * CA: TRUE + // The path length constraint expresses the number of possible intermediate + // CA certificates in a path built from an end-entity certificate up to the + // CA certificate. An absent path length constraint means that there is no + // limitation to the number of intermediate certificates from end-entity to + // the CA certificate. The smallstep PKI has only one intermediate CA + //certificate between end-entity certificates and the root CA certificcate. + * pathlen: 1 + * Key Usage // Describes how the keys can be used. + // Indicates that a certificate will be used with a protocol that encrypts keys. + * Key Encipherment + // Indicates that our root public key will be used to verify a signature on + // certificates. + * Certificate Signing + // Indicates that our root public key will be used to verify a signature on + // revocation + // information, such as CRL. + * CRL Sign + // Indicates that our root public key may be used as a digital signature to + // support security services that enable entity authentication and data + // origin authentication with integrity. + * Digital Signature + ``` + +* **intermediate certificate** + + ``` + * Validity (10 year window) + * Not Before: Now + // A 10 year window seems advisable until software and tools can be written + // for rotating the intermediates certificates without considerable agony + // on the part of the user. + * Not After: Now + 10 years + * Basic Constraints + // The intermediate certificate is a Certificate Authority, used to sign + // end-entity (service, process, job, etc.) certificates. + * CA: TRUE + // The path length constraint expresses the number of possible intermediate + // CA certificates in a path built from an end-entity certificate up to the + // CA certificate. An absent path length constraint means that there is no + // limitation to the number of intermediate certificates from end-entity to + // the CA certificate. There are no additional intermediary certificates in + // the path between the smallstep intermediate CA and end-entity certificates. + * pathlen: 0 + * Key Usage + // Indicates that a certificate will be used with a protocol that encrypts keys. + * Key Encipherment + // Indicates that our root public key will be used to verify a signature on + // certificates. + * Certificate Signing + // Indicates that this public key can be used to verify a signature on + // revocation information, such as CRL. + * CRL Sign + // Indicates that this public key may be used as a digital signature to + // support security services that enable entity authentication and data + // origin authentication with integrity. + * Digital Signature + * Extended Key Usage + // Certificate can be used as the server side certificate in the TLS protocol. + * TLS Web Server Authentication + // Certificate can be used as the client side certificate in the TLS protocol. + * TLS Web Client Authentication + ``` + +* **Leaf Certificate - End Entity Certificate** (certificates returned by the CA) + + ``` + * Validity (24 hour window) + * Not Before: Now + // The default is a 24hr window. This value is somewhat arbitrary, however, + // our goal is to have seamless end-entity certificate rotation (we are + // getting close). Rotating certificates frequently is good security hygiene + // because it gives bad actors very little time to form an attack and limits + // the usefulness of any single private key in the system. We will continue + // to work towards decreasing this window because we believe it significantly + // reduces probability and effectiveness of any attack. + * Not After: Now + 24 hours + * Key Usage + // Indicates that a certificate will be used with a protocol that encrypts keys. + * Key Encipherment + // Indicates that this public key may be used as a digital signature to + // support security services that enable entity authentication and data + // origin authentication with integrity. + * Digital Signature + * Extended Key Usage + // Certificate can be used as the server side certificate in the TLS protocol. + * TLS Web Server Authentication + // Certificate can be used as the client side certificate in the TLS protocol. + * TLS Web Client Authentication + ``` + +### Default TLS Configuration Options + + ``` + // The PCI Security Standards Council is requiring all payment processors + // and merchants to move to TLS 1.2 and above by June 30, 2018. By setting + // TLS 1.2 as the default for all tls protocol negotiation we encourage our + // users to adopt the same security conventions. + * MinVersion: TLS 1.2 + * MaxVersion: TLS 1.2 + + // https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#23-use-secure-cipher-suites + // The default 'ciphersuites' is a single cipher combination. For communication + // between services running step there is no need for cipher suite negotiation. + // The server can specify a single cipher suite which the client is already + // known to support. Reasons for selecting "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": + // - ECDHE key exchange algorithm has perfect forward secrecy + // - ECDSA has smaller keys and better performance (than RSA) + // - CHACHA20 with POLY1305 is the cipher mode used by google. + // - CHACHA20 is more performance than GCM and CBC. + // NOTE: The http2 spec requires the "TLS_ECDHE_(RSA|ECDSA)_WITH_AES_128_GCM_SHA256" + // ciphersuite be accepted by the server, therefore it makes our list of + // default ciphersuites until we build the functionality to modify our defaults + // based on http version. + * DefaultCipherSuites: [ + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + ] + // The following is a list of step approved cipher suites. Not all communication + // can be mediated with step TLS functionality. For those connections the list of + // server supported cipher suites must have more options - in case older clients + // do not support our favored cipher suite. Reasons for selecting these cipher + // suites can be found in the ssllabs article cited above. + * ApprovedCipherSuites: [ + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", + ] + // TLS renegotiation significantly complicates the state machine and has been + // the source of numerous, subtle security issues. Therefore, by default we + // disable it. + * Renegotation: Never +