Remove deprecated docs directory
@ -1,740 +0,0 @@
|
||||
# Getting Started
|
||||
|
||||
Demonstrates setting up your own public key infrastructure (PKI) and certificate authority (CA) using `step ca`
|
||||
and getting certificates using the `step` command line tool and SDK.
|
||||
|
||||
Check out [Getting started with docker](docker.md) to run [step certificates](https://github.com/smallstep/certificates)
|
||||
using docker.
|
||||
|
||||
![Animated terminal showing step ca init in practice](https://smallstep.com/images/blog/2018-12-04-unfurl.gif)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* [Step CA](#installation-guide)
|
||||
|
||||
## Terminology
|
||||
|
||||
### PKI - Public Key Infrastructure
|
||||
|
||||
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
|
||||
|
||||
Provisioners are people or code that are registered with the CA and authorized
|
||||
to issue "provisioning tokens". Provisioning tokens are single use tokens that
|
||||
can be used to authenticate with the CA and get a certificate.
|
||||
|
||||
See [provisioners.md](provisioners.md) for more information on the supported
|
||||
provisioners and its options.
|
||||
|
||||
## Initializing PKI and configuring the Certificate Authority
|
||||
|
||||
To initialize a PKI and configure the Step Certificate Authority run:
|
||||
|
||||
> **NOTE**: `step ca init` only initialize an x509 CA. If you
|
||||
> would like to initialize an SSH CA as well, add the `--ssh` flag.
|
||||
|
||||
```
|
||||
step ca init [--ssh]
|
||||
```
|
||||
|
||||
You'll be asked for a name for your PKI. This name will appear in your CA
|
||||
certificates. It doesn't really matter what you choose. The name of your
|
||||
organization or your project will suffice.
|
||||
|
||||
If you run:
|
||||
|
||||
```
|
||||
tree $(step path)
|
||||
```
|
||||
|
||||
You should see:
|
||||
|
||||
```
|
||||
.
|
||||
├── certs
|
||||
│ ├── intermediate_ca.crt
|
||||
│ ├── root_ca.crt
|
||||
│ ├── ssh_host_key.pub (--ssh only)
|
||||
│ └── ssh_user_key.pub (--ssh only)
|
||||
├── config
|
||||
│ ├── ca.json
|
||||
│ └── defaults.json
|
||||
└── secrets
|
||||
├── intermediate_ca_key
|
||||
├── root_ca_key
|
||||
├── ssh_host_key (--ssh only)
|
||||
└── ssh_user_key (--ssh only)
|
||||
```
|
||||
|
||||
The files created include:
|
||||
|
||||
* `root_ca.crt` and `root_ca_key`: the root certificate and private key for
|
||||
your PKI.
|
||||
|
||||
* `intermediate_ca.crt` and `intermediate_ca_key`: the intermediate certificate
|
||||
and private key that will be used to sign leaf certificates.
|
||||
|
||||
* `ssh_host_key.pub` and `ssh_host_key` (`--ssh` only): the SSH host pub/priv key
|
||||
pair that will be used to sign new host SSH certificates.
|
||||
|
||||
* `ssh_user_key.pub` and `ssh_user_key` (`--ssh` only): the SSH user pub/priv key
|
||||
pair that will be used to sign new user SSH certificates.
|
||||
|
||||
* `ca.json`: the configuration file necessary for running the Step CA.
|
||||
|
||||
* `defaults.json`: file containing default parameters for the `step` CA cli
|
||||
interface. You can override these values with the appropriate flags or
|
||||
environment variables.
|
||||
|
||||
All of the files ending in `_key` are password protected using the password
|
||||
you chose during PKI initialization. We advise you to change these passwords
|
||||
(using the `step crypto change-pass` utility) if you plan to run your CA in a
|
||||
non-development environment.
|
||||
|
||||
## What's Inside `ca.json`?
|
||||
|
||||
`ca.json` is responsible for configuring communication, authorization, and
|
||||
default new certificate values for the Step CA. Below is a short list of
|
||||
definitions and descriptions of available configuration attributes.
|
||||
|
||||
* `root`: location of the root certificate on the filesystem. The root certificate
|
||||
is used to mutually authenticate all api clients of the CA.
|
||||
|
||||
* `crt`: location of the intermediate certificate on the filesystem. The
|
||||
intermediate certificate is returned alongside each new certificate,
|
||||
allowing the client to complete the certificate chain.
|
||||
|
||||
* `key`: location of the intermediate private key on the filesystem. The
|
||||
intermediate key signs all new certificates generated by the CA.
|
||||
|
||||
* `password`: optionally store the password for decrypting the intermediate private
|
||||
key (this should be the same password you chose during PKI initialization). If
|
||||
the value is not stored in configuration then you will be prompted for it when
|
||||
starting the CA.
|
||||
|
||||
* `address`: e.g. `127.0.0.1:8080` - address and port on which the CA will bind
|
||||
and respond to requests.
|
||||
|
||||
* `dnsNames`: comma separated list of DNS Name(s) for the CA.
|
||||
|
||||
* `logger`: the default logging format for the CA is `text`. The other option
|
||||
is `json`.
|
||||
|
||||
* `db`: data persistence layer. See [database documentation](./database.md) for more
|
||||
info.
|
||||
* `type`: `badger`, `bbolt`, `mysql`, etc.
|
||||
* `dataSource`: string that can be interpreted differently depending on the
|
||||
type of the database. Usually a path to where the data is stored. See the
|
||||
[database configuration docs](./database.md#configuration) for more info.
|
||||
* `database`: name of the database. Used for backends that may have multiple
|
||||
databases. e.g. MySQL
|
||||
* `valueDir`: directory to store the value log in (Badger specific).
|
||||
|
||||
* `crl`: Certificate Revocation List settings:
|
||||
* `enable`: enables CRL generation (`true` to generate, `false` to disable)
|
||||
* `generateOnRevoke`: a revoke will generate a new CRL if the crl is enabled.
|
||||
* `cacheDuration`: the duration until next update of the CRL, defaults to 24h.
|
||||
* `renewPeriod`: the time between CRL regeneration. If not set ~2/3 of the
|
||||
cacheDuration will be used.
|
||||
|
||||
* `tls`: settings for negotiating communication with the CA; includes acceptable
|
||||
ciphersuites, min/max TLS version, etc.
|
||||
|
||||
* `authority`: controls the request authorization and signature processes.
|
||||
|
||||
- `template`: default ASN1DN values for new certificates.
|
||||
|
||||
- `claims`: default validation for requested attributes in the certificate request.
|
||||
Can be overriden by similar claims objects defined by individual provisioners.
|
||||
|
||||
* `minTLSCertDuration`: do not allow certificates with a duration less
|
||||
than this value.
|
||||
|
||||
* `maxTLSCertDuration`: do not allow certificates with a duration greater
|
||||
than this value.
|
||||
|
||||
* `defaultTLSCertDuration`: if no certificate validity period is specified,
|
||||
use this value.
|
||||
|
||||
* `disableIssuedAtCheck`: disable a check verifying that provisioning
|
||||
tokens must be issued after the CA has booted. This is one prevention
|
||||
against token reuse. The default value is `false`. Do not change this
|
||||
unless you know what you are doing.
|
||||
|
||||
SSH CA properties
|
||||
|
||||
* `minUserSSHDuration`: do not allow certificates with a duration less
|
||||
than this value.
|
||||
|
||||
* `maxUserSSHDuration`: do not allow certificates with a duration
|
||||
greater than this value.
|
||||
|
||||
* `defaultUserSSHDuration`: if no certificate validity period is specified,
|
||||
use this value.
|
||||
|
||||
* `minHostSSHDuration`: do not allow certificates with a duration less
|
||||
than this value.
|
||||
|
||||
* `maxHostSSHDuration`: do not allow certificates with a duration
|
||||
greater than this value.
|
||||
|
||||
* `defaultHostSSHDuration`: if no certificate validity period is specified,
|
||||
use this value.
|
||||
|
||||
* `enableSSHCA`: enable all provisioners to generate SSH Certificates.
|
||||
The deault value is `false`. You can enable this option per provisioner
|
||||
by setting it to `true` in the provisioner claims.
|
||||
|
||||
- `provisioners`: list of provisioners.
|
||||
See the [provisioners documentation](./provisioners.md). Each provisioner
|
||||
has an optional `claims` attribute that can override any attribute defined
|
||||
at the level above in the `authority.claims`.
|
||||
|
||||
`step ca init` will generate one provisioner. New provisioners can be added by
|
||||
running `step ca provisioner add`.
|
||||
|
||||
## Running the CA
|
||||
|
||||
To start the CA run:
|
||||
|
||||
```
|
||||
export STEPPATH=$(step path)
|
||||
step-ca $STEPPATH/config/ca.json
|
||||
```
|
||||
|
||||
### Systemctl
|
||||
|
||||
Consider adding a service user that will only be used by `systemctl` to manage
|
||||
the service.
|
||||
|
||||
```
|
||||
$ useradd step
|
||||
$ passwd -l step
|
||||
```
|
||||
|
||||
Use the following example as a base for your `systemctl` service file:
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=step-ca
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
|
||||
User=step
|
||||
Group=step
|
||||
ExecStart=/bin/sh -c '/bin/step-ca /home/step/.step/config/ca.json --password-file=/home/step/.step/pwd >> /var/log/step-ca/output.log 2>&1'
|
||||
Type=simple
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
The following are a few example commands you can use to check the status,
|
||||
enable on restart, and start your `systemctl` service.
|
||||
|
||||
```
|
||||
# Check the current status of the `step-ca` service
|
||||
$ systemctl status step-ca
|
||||
# Configure the `step-ca` process to startup on reboot automatically
|
||||
$ systemctl enable step-ca
|
||||
# Start the `step-ca` service.
|
||||
$ systemctl start step-ca
|
||||
```
|
||||
|
||||
## Configure Your Environment
|
||||
|
||||
**Note**: Configuring your environment is only necessary for remote servers
|
||||
(not the server on which the `step ca init` command was originally run).
|
||||
|
||||
Many of the cli utilities under `step ca [sub-command]` interface directly with
|
||||
a running instance of the Step CA. The CA exposes an HTTP API and clients are
|
||||
required to connect using HTTP over TLS (aka HTTPS). As part of bootstraping
|
||||
the Step CA, a certificate was generated using the root of trust that was
|
||||
created when you initilialized your PKI. In order to properly validate this
|
||||
certificate clients need access to the public root of trust, aka the public root
|
||||
certificate. If you are using the `step cli` on the same host where you
|
||||
initialized your PKI (the `root_ca.crt` is stored on disk locally), then you can
|
||||
continue to [setting up your environment](#setup-env),
|
||||
otherwise we will show you how to easily download your root certificate in the
|
||||
following step.
|
||||
|
||||
#### Download the Root Certificate
|
||||
|
||||
The next few steps are a guide for downloading the root certificate of your PKI
|
||||
from a running instance of the CA. First we'll define two servers:
|
||||
|
||||
* **remote server**: This is the server where the Step CA is running. This may
|
||||
also be the server where you initialized your PKI, but for security reasons
|
||||
you may have done that offline.
|
||||
|
||||
* **local server**: This is the server that wants access to the `step ca [sub-command]`
|
||||
|
||||
* **ca-url**: This is the url at which the CA is listening for requests. This
|
||||
should be a combination of the DNS name and port entered during PKI initialization.
|
||||
In the examples below we will use `https://ca.smallstep.com:8080`.
|
||||
|
||||
1. Get the Fingerprint.
|
||||
|
||||
From the **remote server**:
|
||||
|
||||
```
|
||||
$ FP=$(step certificate fingerprint $(step path)/certs/root_ca.crt)
|
||||
```
|
||||
|
||||
2. Bootstrap your environment.
|
||||
|
||||
From the **local server**:
|
||||
|
||||
```
|
||||
$ step ca bootstrap --fingerprint $FP --ca-url "https://ca.smallstep.com:8080"
|
||||
$ cat $(step path)/config/defaults.json
|
||||
```
|
||||
|
||||
3. Test.
|
||||
|
||||
```
|
||||
$ step ca health
|
||||
```
|
||||
|
||||
<a name="setup-env"></a>
|
||||
#### Setting up Environment Defaults
|
||||
|
||||
This is optional, but we recommend you populate a `defaults.json` file with a
|
||||
few variables that will make your command line experience much more pleasant.
|
||||
|
||||
You can do this manually or with the step command `step ca bootstrap`:
|
||||
|
||||
```
|
||||
$ step ca bootstrap \
|
||||
--ca-url https://ca.smallstep.com:8080 \
|
||||
--fingerprint 0d7d3834cf187726cf331c40a31aa7ef6b29ba4df601416c9788f6ee01058cf3
|
||||
# Let's see what we got...
|
||||
$ cat $STEPPATH/config/defaults.json
|
||||
{
|
||||
"ca-url": "https://ca.smallstep.com:8080",
|
||||
"fingerprint": "628cfc85090ca65bb246d224f1217445be155cfc6167db4ed8f1b0e3de1447c5",
|
||||
"root": "/Users/<you>/src/github.com/smallstep/step/.step/certs/root_ca.crt"
|
||||
}
|
||||
# Test it out
|
||||
$ step ca health
|
||||
```
|
||||
|
||||
* **ca-url** is the DNS name and port that you used when initializing the CA.
|
||||
|
||||
* **root** is the path to the root certificate on the file system.
|
||||
|
||||
* **fingerprint** is the root certificate fingerprint (SHA256).
|
||||
|
||||
You can always override these values with command-line flags or environment
|
||||
variables.
|
||||
|
||||
To manage the CA provisioners you can also add the property **ca-config** with
|
||||
the path to the CA configuration file, with that property you won't need to add
|
||||
it in commands like `step ca provisioners [add|remove]`.
|
||||
**Note**: to manage provisioners you must be on the host on which the CA is
|
||||
running. You need direct access to the `ca.json` file.
|
||||
|
||||
### Hot 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 automate 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.
|
||||
|
||||
### Let's issue a certificate!
|
||||
|
||||
There are two steps to issuing a certificate at the command line:
|
||||
|
||||
1. Generate a provisioning token using your provisioning credentials.
|
||||
2. Generate a CSR and exchange it, along with the provisioning token, for a certificate.
|
||||
|
||||
If you would like to generate a certificate from the command line, the Step CLI
|
||||
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
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
$ TOKEN=$(step ca token foo.example.com \
|
||||
--kid 4vn46fbZT68Uxfs9LBwHkTvrjEvxQqx-W8nnE-qDjts \
|
||||
--ca-url https://ca.example.com \
|
||||
--root /path/to/root_ca.crt --password-file /path/to/provisioner/password)
|
||||
|
||||
$ step ca certificate "foo.example.com" foo.crt foo.key --token "$TOKEN"
|
||||
```
|
||||
|
||||
You can take a closer look at the contents of the certificate using `step certificate inspect`:
|
||||
|
||||
```
|
||||
$ step certificate inspect foo.crt
|
||||
```
|
||||
|
||||
### List|Add|Remove Provisioners
|
||||
|
||||
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.
|
||||
|
||||
**Why should I be using multiple provisioners?**
|
||||
|
||||
* 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.
|
||||
|
||||
Let's begin by listing the existing provisioners:
|
||||
|
||||
```
|
||||
$ bin/step ca provisioner list
|
||||
```
|
||||
|
||||
Now let's add a provisioner for Jim.
|
||||
|
||||
```
|
||||
$ bin/step ca provisioner add jim@smallstep.com --create
|
||||
```
|
||||
|
||||
**NOTE**: This change will not affect the Step CA until a `reload` is forced by
|
||||
sending a SIGHUP signal to the process.
|
||||
|
||||
List the provisioners again and you will see that nothing has changed.
|
||||
|
||||
```
|
||||
$ 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 you are using `--password-file`.
|
||||
|
||||
```
|
||||
$ ps aux | grep step-ca # to get the PID
|
||||
$ kill -1 <pid>
|
||||
```
|
||||
|
||||
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 <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.
|
||||
|
||||
## Use Custom Claims for Provisioners to Control Certificate Validity etc
|
||||
|
||||
It's possible to configure provisioners on the CA to issue certs using
|
||||
properties specific to their target environments. Most commonly different
|
||||
validity periods and disabling renewals for certs. Here's how:
|
||||
|
||||
```bash
|
||||
$ step ca init
|
||||
# complete the init steps
|
||||
$ step ca provisioner add --create dev@smallstep.com
|
||||
# lets create a provisioner for dev certs
|
||||
Please enter a password to encrypt the provisioner private key? password
|
||||
# add claims inside a provisioner element in ~/.step/config/ca.json
|
||||
~/.step/config/ca.json
|
||||
[...]
|
||||
"authority": {
|
||||
"provisioners": [
|
||||
{
|
||||
"name": "you@smallstep.com",
|
||||
"type": "jwk",
|
||||
"key": {
|
||||
"use": "sig",
|
||||
"kty": "EC",
|
||||
"kid": "Kg43gSukHnl8f5NztLPDxqpz_9TNUILnMrIMIa70jOU",
|
||||
"crv": "P-256",
|
||||
"alg": "ES256",
|
||||
"x": "So0JVWFFXo-6GmDwq6WWZZk-AFZt5GKTx5PzdLhdsrQ",
|
||||
"y": "kVz8pCl2Qx9fZmJZhXGrHpufwNDTp7oHwi8Zaj7rhiQ"
|
||||
},
|
||||
"encryptedKey": "...",
|
||||
+ "claims": {
|
||||
+ "minTLSCertDuration": "5s",
|
||||
+ "maxTLSCertDuration": "12h",
|
||||
+ "defaultTLSCertDuration": "2h",
|
||||
+ "disableRenewal": true
|
||||
+ }
|
||||
}
|
||||
]
|
||||
},
|
||||
[...]
|
||||
|
||||
## launch CA...
|
||||
$ step-ca $(step path)/config/ca.json
|
||||
Please enter the password to decrypt ~/.step/secrets/intermediate_ca_key: password
|
||||
2019/02/21 12:09:51 Serving HTTPS on :9443 ...
|
||||
```
|
||||
|
||||
See the [`provisioner doc`][1] for details on all available provisioner claims.
|
||||
The durations are strings which are a sequence of decimal numbers, each with
|
||||
optional fraction and a unit suffix, such as "300ms" or "2h45m". Valid time
|
||||
units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
Now certs issued by the `dev@smallstep.com` provisioner will be valid for two
|
||||
hours and deny renewals. Command line flags allow validity extension up to 12h,
|
||||
please see [`step ca certificate`][2]'s docs for details.
|
||||
|
||||
[1]: ./provisioners.md
|
||||
[2]: https://smallstep.com/docs/cli/ca/certificate/
|
||||
|
||||
```bash
|
||||
# grab a cert, will also work with 'step ca token' flow
|
||||
$ step ca certificate localhost site.crt site.key
|
||||
Use the arrow keys to navigate: ↓ ↑ → ←
|
||||
What provisioner key do you want to use?
|
||||
IY7gYg_cDKmXtcs1sbhdBDDb9K9YvLO5aHzArjaayso (sebastian@smallstep.com)
|
||||
▸ uBYWYDCpeJu_IYzMGPZ1LJJTdlaiJQfdpkOVewbjy-8 (dev@smallstep.com)
|
||||
|
||||
✔ Please enter the password to decrypt the provisioner key: password
|
||||
✔ CA: https://ca.smallstep.com:9443/1.0/sign
|
||||
✔ Certificate: site.crt
|
||||
✔ Private Key: site.key
|
||||
|
||||
$ step certificate inspect site.crt --format json | jq .validity
|
||||
{
|
||||
"start": "2019-02-21T20:19:06Z",
|
||||
"end": "2019-02-21T22:19:06Z",
|
||||
"length": 7200
|
||||
}
|
||||
|
||||
# renewals will be denied for certs issued by this provisioner
|
||||
$ step ca renew site.crt site.key
|
||||
error renewing certificate: Unauthorized
|
||||
```
|
||||
|
||||
## Use Oauth OIDC to obtain personal certificates
|
||||
|
||||
To authenticate users with the CA you can leverage services that expose OAuth
|
||||
OpenID Connect identity providers. One of the most common providers, and the
|
||||
one we'll use in this example, is G-Suite.
|
||||
|
||||
Navigate to the Google APIs developer console and pick a suitable project from the
|
||||
top navbar's dropdown.
|
||||
|
||||
![Google Dev Console](./images/oidc1.png)
|
||||
|
||||
In the masthead navigation click **Credentials** (key symbol) and then "OAuth
|
||||
consent screen" from the subnav. Fill out naming details, all mandatory fields,
|
||||
and decide if your app is of type **Public** or **Internal**. Internal
|
||||
will make sure the access scope is bound to your G-Suite organization.
|
||||
**Public** will let anybody with a Google Account log in, incl.
|
||||
`gmail.com` accounts.
|
||||
|
||||
Move back to **Credentials** on the subnav and choose "OAuth client ID" from the
|
||||
**Create credentials** dropdown. Since OIDC will be used from the `step CLI` pick **Other**
|
||||
from the available options and pick a name (e.g. **Step CLI**).
|
||||
|
||||
![Create credential](./images/oidc2.png)
|
||||
|
||||
On successful completion, a confirmation modal with both `clientID` and
|
||||
`clientSecret` will be presented. Please note that the `clientSecret` will
|
||||
allow applications access to the configured OAuth consent screen. However, it
|
||||
will not allow direct authentication of users without their own MfA credentials
|
||||
per account.
|
||||
|
||||
![OIDC credentials](./images/oidc3.png)
|
||||
|
||||
Now using `clientID` and `clientSecret` run the following command to add
|
||||
G-Suite as a provisioner to `step certificates`. Please see [`step ca
|
||||
provisioner add`](https://smallstep.com/docs/cli/ca/provisioner/add/)'s docs
|
||||
for all available configuration options and descriptions.
|
||||
|
||||
```bash
|
||||
$ step ca provisioner add Google --type oidc --ca-config $(step path)/config/ca.json \
|
||||
--client-id 972437157139-ssiqna0g4ibuhafl3pkrrcb52tbroekt.apps.googleusercontent.com \
|
||||
--client-secret RjEk-GwKBvdsFAICiJhn_RiF \
|
||||
--configuration-endpoint https://accounts.google.com/.well-known/openid-configuration \
|
||||
--domain yourdomain.com --domain gmail.com
|
||||
```
|
||||
|
||||
Start up the online CA or send a HUP signal if it's already running to reload
|
||||
the configuration and pick up the new provisioner. Now users should be able to
|
||||
obtain certificates using the familiar `step ca certificate` flow:
|
||||
|
||||
```bash
|
||||
$ step ca certificate sebastian@smallstep.com personal.crt personal.key
|
||||
Use the arrow keys to navigate: ↓ ↑ → ←
|
||||
What provisioner key do you want to use?
|
||||
fYDoiQdYueq_LAXx2kqA4N_Yjf_eybe-wari7Js5iXI (admin)
|
||||
▸ 972437157139-ssiqna0g4ibuhafl3pkrrcb52tbroekt.apps.googleusercontent.com (Google)
|
||||
✔ Key ID: 972437157139-ssiqna0g4ibuhafl3pkrrcb52tbroekt.apps.googleusercontent.com (Google)
|
||||
✔ CA: https://localhost
|
||||
✔ Certificate: personal.crt
|
||||
✔ Private Key: personal.key
|
||||
|
||||
$ step certificate inspect --short personal.crt ⏎
|
||||
X.509v3 TLS Certificate (ECDSA P-256) [Serial: 6169...4235]
|
||||
Subject: 106202051347258973689
|
||||
sebastian@smallstep.com
|
||||
Issuer: Local CA Intermediate CA
|
||||
Provisioner: Google [ID: 9724....com]
|
||||
Valid from: 2019-03-26T20:36:28Z
|
||||
to: 2019-03-27T20:36:28Z
|
||||
```
|
||||
|
||||
Now it's easy for anybody in the G-Suite organization to obtain valid personal
|
||||
certificates!
|
||||
|
||||
## Notes on Securing the Step CA and your PKI.
|
||||
|
||||
In this section we recommend a few best practices when it comes to
|
||||
running, deploying, and managing your own online CA and PKI. Security is a moving
|
||||
target and we expect out recommendations to change and evolve as well.
|
||||
|
||||
### Initializing your PKI
|
||||
|
||||
When you initialize your PKI two private keys are generated; one intermediate
|
||||
private key and one root private key. It is very important that these private keys
|
||||
are kept secret. The root private key should be moved around as little as possible,
|
||||
preferably not all - meaning it never leaves the server on which it was created.
|
||||
|
||||
### Passwords
|
||||
|
||||
When you initialize your PKI (`step ca init`) the root and intermediate
|
||||
private keys will be encrypted with the same password. We recommend that you
|
||||
change the password with which the intermediate is encrypted at your earliest
|
||||
convenience.
|
||||
|
||||
```
|
||||
$ step crypto change-pass $STEPPATH/secrets/intermediate_ca_key
|
||||
```
|
||||
|
||||
Once you've changed the intermediate private key password you should never have
|
||||
to use the root private key password again.
|
||||
|
||||
We encourage users to always use a password manager to generate random passwords
|
||||
or let Step CLI generate passwords for you.
|
||||
|
||||
The next important matter is how your passwords are stored. We recommend using a
|
||||
[password manager](https://en.wikipedia.org/wiki/List_of_password_managers).
|
||||
There are many to choose from and the choice will depend on the risk & security
|
||||
profile of your organization.
|
||||
|
||||
In addition to using a password manager to store all passwords (private key,
|
||||
provisioner, etc.) we recommend using a threshold cryptography algorithm like
|
||||
[Shamir's Secret Sharing](https://en.wikipedia.org/wiki/Shamir's_Secret_Sharing)
|
||||
to divide the root private key password across a handful of trusted parties.
|
||||
|
||||
### Provisioners
|
||||
|
||||
When you initialize your PKI (`step ca init`) a default provisioner will be created
|
||||
and it's private key will be encrypted using the same password used to encrypt
|
||||
the root private key. Before deploying the Step CA you should remove this
|
||||
provisioner and add new ones that are encrypted with new, secure, random passwords.
|
||||
See the section on [managing provisioners](#listaddremove-provisioners).
|
||||
|
||||
### Deploying
|
||||
|
||||
* Refrain from entering passwords for private keys or provisioners on the command line.
|
||||
Use the `--password-file` flag whenever possible.
|
||||
* Run the Step CA as a new user and make sure that the config files, private keys,
|
||||
and passwords used by the CA are stored in such a way that only this new user
|
||||
has permissions to read and write them.
|
||||
* Use short lived certificates. Our default validity period for new certificates
|
||||
is 24 hours. You can configure this value in the `ca.json` file. Shorter is
|
||||
better - less time to form an attack.
|
||||
* Short lived certificates are **not** a replacement for CRL and OCSP. CRL and OCSP
|
||||
are features that we plan to implement, but are not yet available. In the mean
|
||||
time short lived certificates are a decent alternative.
|
||||
* Keep your hosts secure by enforcing AuthN and AuthZ for every connection. SSH
|
||||
access is a big one.
|
||||
|
||||
<a name="step-ca-ha"></a>
|
||||
## Notes on Running Step CA as a Highly Available Service
|
||||
|
||||
**CAUTION**: `step-ca` is built to scale horizontally. However, the creators
|
||||
and maintainers do not regularly test in an HA environment using mulitple
|
||||
instances. You may run into issues we did not plan for. If this happens, please
|
||||
[open an issue][3].
|
||||
|
||||
### Considerations
|
||||
|
||||
A few things to consider / implement when running multiple instances of `step-ca`:
|
||||
|
||||
* Use `MySQL` DB: The default `Badger` DB cannot be read / written by more than one
|
||||
process simultaneously. The only supported DB that can support multiple instances
|
||||
is `MySQL`. See the [database documentation][4] for guidance on configuring `MySQL`.
|
||||
* The ACME server has known concurrency limitations when using the same account to
|
||||
manage multiple orders. The recommended temporary workaround is to generate
|
||||
an ephemeral account keypair for each new ACME order, or to ensure that ACME
|
||||
orders owned by the same account are managed serially. The issue tracking
|
||||
this limitation can be found [here](https://github.com/smallstep/certificates/issues/341).
|
||||
|
||||
* Synchronize `ca.json` across instances: `step-ca` reads all of it's
|
||||
configuration (and all of the provisioner configuration) from the `ca.json` file
|
||||
specified on the command line. If the `ca.json` of one instance is modified
|
||||
(either manually or using a command like `step ca provisioner (add | remove)`)
|
||||
the other instances will not pick up on this change until the `ca.json` is
|
||||
copied over to the correct location for each instance and the instance itself
|
||||
is `SIGHUP`'ed (or restarted). It's recommended to use a configuration management
|
||||
(ansible, chef, salt, puppet, etc.) tool to synchronize `ca.json` across instances.
|
||||
|
||||
[3]: https://github.com/smallstep/certificates/issues
|
||||
[4]: ./database.md
|
@ -1,41 +0,0 @@
|
||||
# Step Certificates Documentation
|
||||
|
||||
## Note: Much of [our documentation has moved](https://smallstep.com/docs)
|
||||
|
||||
Index of Documentation and Tutorials for using and deploying the `step certificates`.
|
||||
|
||||
[![GitHub release](https://img.shields.io/github/release/smallstep/certificates.svg)](https://github.com/smallstep/certificates/releases)
|
||||
[![CA Image](https://images.microbadger.com/badges/image/smallstep/step-ca.svg)](https://microbadger.com/images/smallstep/step-ca)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/smallstep/certificates)](https://goreportcard.com/report/github.com/smallstep/certificates)
|
||||
[![Build Status](https://travis-ci.com/smallstep/certificates.svg?branch=master)](https://travis-ci.com/smallstep/certificates)
|
||||
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
|
||||
[![CLA assistant](https://cla-assistant.io/readme/badge/smallstep/certificates)](https://cla-assistant.io/smallstep/certificates)
|
||||
|
||||
[![GitHub stars](https://img.shields.io/github/stars/smallstep/certificates.svg?style=social)](https://github.com/smallstep/certificates/stargazers)
|
||||
[![Twitter followers](https://img.shields.io/twitter/follow/smallsteplabs.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=smallsteplabs)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* **General Info**
|
||||
* [Website](https://smallstep.com)
|
||||
* [Installation Guide](https://smallstep.com/docs/step-ca/installation)
|
||||
* [Getting Started](https://smallstep.com/docs/step-ca/getting-started): in depth guide on getting started
|
||||
with `step-ca`, including all configuration options.
|
||||
* [Contributor's Guide](./CONTRIBUTING.md)
|
||||
* [Sane Defaults](https://smallstep.com/docs/step-ca/certificate-authority-server-production#sane-cryptographic-defaults): default algorithms and attributes used
|
||||
in cryptographic primitives and why they were selected.
|
||||
* [Frequently Asked Questions](./questions.md)
|
||||
* Check out our [Blog](https://smallstep.com/blog/). We post quality
|
||||
educational content as well as periodic updates on new releases.
|
||||
* **API**: Guides to using the API via the `step` CLI.
|
||||
* [Revoking Certificates](https://smallstep.com/docs/step-ca/revocation)
|
||||
* [Persistence Layer](https://smallstep.com/docs/step-ca/configuration#databases): description and guide to using `step certificates`'
|
||||
persistence layer for storing certificate management metadata.
|
||||
* **Tutorials**: Guides for deploying and getting started with `step` in various environments.
|
||||
* [Docker](./docker.md)
|
||||
* [Kubernetes](../autocert/README.md)
|
||||
|
||||
## Further Reading
|
||||
|
||||
* [Use TLS Everywhere](https://smallstep.com/blog/use-tls.html)
|
||||
* [Everything you should know about certificates and PKI but are too afraid to ask](https://smallstep.com/blog/everything-pki.html)
|
@ -1,217 +0,0 @@
|
||||
# Registration Authorities
|
||||
|
||||
This document describes how to use an external registration authority (RA), aka
|
||||
certificate authority service (CAS) to sign X.509 certificates requests.
|
||||
|
||||
A CAS is a system that implements an API to sign certificate requests, the
|
||||
difference between CAS and KMS is that the latter can sign any data, while CAS
|
||||
is intended to sign only X.509 certificates.
|
||||
|
||||
`step-ca` defines an interface that can be implemented to support other
|
||||
registration authorities, currently only CloudCAS and the default SoftCAS are
|
||||
implemented.
|
||||
|
||||
The `CertificateAuthorityService` is defined in the package
|
||||
`github.com/smallstep/certificates/cas/apiv1` and it is:
|
||||
|
||||
```go
|
||||
type CertificateAuthorityService interface {
|
||||
CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error)
|
||||
RenewCertificate(req *RenewCertificateRequest) (*RenewCertificateResponse, error)
|
||||
RevokeCertificate(req *RevokeCertificateRequest) (*RevokeCertificateResponse, error)
|
||||
}
|
||||
```
|
||||
|
||||
The same package defines another interface that is used to get the root
|
||||
certificates from the CAS:
|
||||
|
||||
```go
|
||||
type CertificateAuthorityGetter interface {
|
||||
GetCertificateAuthority(req *GetCertificateAuthorityRequest) (*GetCertificateAuthorityResponse, error)
|
||||
}
|
||||
```
|
||||
|
||||
## SoftCAS
|
||||
|
||||
SoftCAS is the default implementation supported by `step-ca`. No special
|
||||
configurations are required to enable it.
|
||||
|
||||
SoftCAS generally uses certificates and keys in the filesystem, but a KMS can
|
||||
also be used instead of a key file for signing certificates. See [KMS](kms.md)
|
||||
for more information.
|
||||
|
||||
## CloudCAS
|
||||
|
||||
CloudCAS is the implementation of the `CertificateAuthorityService` and
|
||||
`CertificateAuthorityGetter` interfaces using [Google's Certificate Authority
|
||||
Service](https://cloud.google.com/certificate-authority-service/).
|
||||
|
||||
Before enabling CloudCAS in `step-ca` you do some steps in Google Cloud Console
|
||||
or using `gcloud` CLI:
|
||||
|
||||
1. Create or define a project to use. Let's say the name is `smallstep-cas-test`.
|
||||
2. Create the KMS keyring and keys for root and intermediate certificates:
|
||||
|
||||
```sh
|
||||
# Create key ring
|
||||
gcloud kms keyrings create kr1 --location us-west1
|
||||
# Create key for Root certificate
|
||||
gcloud kms keys create k1 \
|
||||
--location us-west1 \
|
||||
--keyring kr1 \
|
||||
--purpose asymmetric-signing \
|
||||
--default-algorithm ec-sign-p256-sha256 \
|
||||
--protection-level software
|
||||
# Create key for Intermediate certicate
|
||||
gcloud kms keys create k2 \
|
||||
--location us-west1 \
|
||||
--keyring kr1 \
|
||||
--purpose asymmetric-signing \
|
||||
--default-algorithm ec-sign-p256-sha256 \
|
||||
--protection-level software
|
||||
|
||||
# Put the resource name for version 1 of the new KMS keys into a shell variable.
|
||||
# This will be used in the other instructions below.
|
||||
KMS_ROOT_KEY_VERSION=$(gcloud kms keys versions describe 1 --key k1 --keyring kr1 --location us-west1 --format "value(name)")
|
||||
KMS_INTERMEDIATE_KEY_VERSION=$(gcloud kms keys versions describe 1 --key k2 --keyring kr1 --location us-west1 --format "value(name)")
|
||||
```
|
||||
|
||||
3. Enable the CA service API. You can do it on the console or running:
|
||||
|
||||
```sh
|
||||
gcloud services enable privateca.googleapis.com
|
||||
```
|
||||
|
||||
4. Configure IAM. Create a service account using Google Console or running:
|
||||
|
||||
```sh
|
||||
# Create service account
|
||||
gcloud iam service-accounts create step-ca-sa \
|
||||
--project smallstep-cas-test \
|
||||
--description "Step-CA Service Account" \
|
||||
--display-name "Step-CA Service Account"
|
||||
# Add permissions to use the privateca API
|
||||
gcloud projects add-iam-policy-binding smallstep-cas-test \
|
||||
--member=serviceAccount:step-ca-sa@smallstep-cas-test.iam.gserviceaccount.com \
|
||||
--role=roles/privateca.caManager
|
||||
gcloud projects add-iam-policy-binding smallstep-cas-test \
|
||||
--member=serviceAccount:step-ca-sa@smallstep-cas-test.iam.gserviceaccount.com \
|
||||
--role=roles/privateca.certificateRequester
|
||||
# Download the credentials.file
|
||||
gcloud iam service-accounts keys create credentials.json \
|
||||
--iam-account step-ca-sa@smallstep-cas-test.iam.gserviceaccount.com
|
||||
```
|
||||
|
||||
5. Create a Root CA. You can do this on the console or running:
|
||||
|
||||
```sh
|
||||
gcloud beta privateca roots create prod-root-ca \
|
||||
--location us-west1 \
|
||||
--kms-key-version "$KMS_ROOT_KEY_VERSION" \
|
||||
--subject "CN=Example Root CA, O=Example LLC" \
|
||||
--max-chain-length 2
|
||||
```
|
||||
|
||||
6. Create an Intermediate CA. You can do this on the console or running:
|
||||
|
||||
```sh
|
||||
gcloud beta privateca subordinates create prod-intermediate-ca \
|
||||
--location us-west1 \
|
||||
--issuer prod-root-ca \
|
||||
--issuer-location us-west1 \
|
||||
--kms-key-version "$KMS_INTERMEDIATE_KEY_VERSION" \
|
||||
--subject "CN=Example Intermediate CA, O=Example LLC" \
|
||||
--reusable-config "subordinate-server-tls-pathlen-0"
|
||||
```
|
||||
|
||||
Now it's time to enable it in `step-ca` by adding some new files in the
|
||||
`"authority"` section of the `ca.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"authority": {
|
||||
"type": "cloudCAS",
|
||||
"credentialsFile": "/path/to/credentials.json",
|
||||
"certificateAuthority": "projects/<name>/locations/<loc>/certificateAuthorities/<ca-name>",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* **type** defines the name of the CAS to use, _cloudCAS_ must be used to enable it.
|
||||
* **credentialsFile** defines the path to a Google Cloud credential file with
|
||||
access to Google's Certificate AuthorityService. We created this file before
|
||||
in step 4. Instead of setting this property, the environment variable
|
||||
`GOOGLE_APPLICATION_CREDENTIALS` can be pointed to the file to use. Or if the
|
||||
`step-ca` is running in Google Cloud, the default service account in the
|
||||
machine can also be used.
|
||||
* **certificateAuthority** defines the Google Cloud resource to the intermediate
|
||||
(or subordinated) certificate to use. We created this resource in step 6.
|
||||
|
||||
As we said before, the CloudCAS implementation in `step-ca` also defines the
|
||||
interface `CertificateAuthorityGetter`, this allows `step-ca` to automatically
|
||||
download the root certificate from Cloud CAS. In the `ca.json` now you don't
|
||||
need to configure `"root"`, and because the intermediate is in Google Cloud,
|
||||
`"crt"` and `"key"` are no needed. A full `ca.json` can look like:
|
||||
|
||||
```json
|
||||
{
|
||||
"address": ":443",
|
||||
"dnsNames": ["ca.example.com"],
|
||||
"logger": {"format": "text"},
|
||||
"db": {
|
||||
"type": "badger",
|
||||
"dataSource": "/home/jane/.step/db",
|
||||
},
|
||||
"authority": {
|
||||
"type": "cloudCAS",
|
||||
"credentialsFile": "/home/jane/.step/credentials.json",
|
||||
"certificateAuthority": "projects/smallstep-cas-test/locations/us-west1/certificateAuthorities/prod-intermediate-ca",
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "JWK",
|
||||
"name": "jane@example.com",
|
||||
"key": {
|
||||
"use": "sig",
|
||||
"kty": "EC",
|
||||
"kid": "ehFT9BkVOY5k_eIiMax0ZxVZCe2hlDVkMwZ2Y78av4s",
|
||||
"crv": "P-256",
|
||||
"alg": "ES256",
|
||||
"x": "GtEftN0_ED1lNc2SEUJDXV9EMi7JY-kqINPIEQJIkjM",
|
||||
"y": "8HYFdNe1MbWcbclF-hU1L80SCmMcZQI6vZfTOXfPOjg"
|
||||
},
|
||||
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiSjBSWnY5UFZrM3JKRUJkem5RbExzZyJ9.Fiwvo-RIKU5G6v5udeCT1nlX87ElxrocP2FcgNs3AqEz5OH9H4suew.NmzUJR_9xv8ynQC8.dqOveA_G5kn5lxjxnEZoJCystnJMVYLkZ_8CVzfJQhYchbZfNk_-FKdIuQxeWWBzvmomsILFNtLOIUoqSt30qk83lFyGQWN8Ke2bK5DhuwojF7RI_UqkMyiKP0F28Z4ZFhfQP5D2ZT_stoFaMlU8eak0-T8MOiBIfdAJTWM9x2DN-68mtUBuL5z5eU8bqsxELnjGauD_GHTdnduOosmYsw8vp_PmffTTwqUzDFH1RhkeSmRFRZntAizZMGYkxLamquHI3Jvuqiv4eeJ3yLqh3Ppyo_mVQKnxM7P9TyTxcvLkb2dB3K-cItl1fpsz92cy8euKsKG8n5-hKFRyPfY.j7jBN7nUwatoSsIZuNIwHA"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tls": {
|
||||
"cipherSuites": [
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
|
||||
],
|
||||
"minVersion": 1.2,
|
||||
"maxVersion": 1.3,
|
||||
"renegotiation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The we only need to run `step-ca` as usual, but this time, the CA will print the
|
||||
root fingerprint too:
|
||||
|
||||
```sh
|
||||
$ step-ca /home/jane/.step/config/ca.json
|
||||
2020/09/22 13:17:15 Using root fingerprint '3ef16343cf0952eedbe2b843066bb798fa7a7bceb16aa285e8b0399f661b28b7'
|
||||
2020/09/22 13:17:15 Serving HTTPS on :9000 ...
|
||||
```
|
||||
|
||||
We will need to bootstrap once our environment using the printed fingerprint:
|
||||
|
||||
```sh
|
||||
step ca bootstrap --ca-url https://ca.example.com --fingerprint 3ef16343cf0952eedbe2b843066bb798fa7a7bceb16aa285e8b0399f661b28b7
|
||||
```
|
||||
|
||||
And now we can sign sign a certificate as always:
|
||||
|
||||
```sh
|
||||
step ca certificate test.example.com test.crt test.key
|
||||
```
|
@ -1,106 +0,0 @@
|
||||
# Step Certificates Database
|
||||
|
||||
`step certificates` uses a simple key-value interface over popular database
|
||||
implementations to store persistent certificate management meta-data.
|
||||
|
||||
Our recommended default database implementation is
|
||||
[nosql-Badger](https://github.com/smallstep/nosql/badger) - a NoSQL interface
|
||||
over the popular [Badger](https://github.com/dgraph-io/badger) database.
|
||||
|
||||
## What will the database store?
|
||||
|
||||
As a first pass, the database layer will store every certificate (along with
|
||||
metadata surrounding the provisioning of the certificate) and revocation data
|
||||
that will be used to enforce passive revocation.
|
||||
|
||||
## Implementations
|
||||
|
||||
Current implementations include Badger (default), BoltDB, and MysQL.
|
||||
|
||||
- [ ] Memory
|
||||
- [x] No database
|
||||
- [x] [BoltDB](https://github.com/etcd-io/bbolt) -- etcd fork.
|
||||
- [x] [Badger](https://github.com/dgraph-io/badger)
|
||||
- [x] [MySQL/MariaDB](https://github.com/go-sql-driver/mysql)
|
||||
- [ ] PostgreSQL
|
||||
- [ ] Cassandra
|
||||
|
||||
Let us know which integration you would like to see next by opening an issue or PR.
|
||||
|
||||
## Configuration
|
||||
|
||||
Configuring `step certificates` to use a database is as simple as adding a
|
||||
top-level `db` stanza to `$(step path)/config/ca.json`. Below are a few examples for supported databases:
|
||||
|
||||
### Badger
|
||||
|
||||
```
|
||||
{
|
||||
...
|
||||
"db": {
|
||||
"type": "badger",
|
||||
"dataSource": "./.step/db",
|
||||
"valueDir": "./.step/valuedb"
|
||||
"badgerFileLoadingMode": "MemoryMap"
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
#### Options for `db`:
|
||||
|
||||
* `type`
|
||||
* `badger` - currently refers to Badger V1. However, as Badger V1 is deprecated,
|
||||
this will refer to Badger V2 starting with a the next major version release.
|
||||
* `badgerV1` - explicitly select Badger V1.
|
||||
* `badgerV2` - explicitly select Badger V2. Anyone looking to use Badger V2
|
||||
will need to set it explicitly until it becomes the default.
|
||||
* `dataSource` - path, database directory.
|
||||
* `valueDir` [optional] - path, value directory, only if different from `dataSource`.
|
||||
* `badgerFileLoadingMode` [optional] - can be set to `FileIO` (instead of the default
|
||||
`MemoryMap`) to avoid memory-mapping log files. This can be
|
||||
useful in environments with low RAM. Make sure to use `badgerV2` as the
|
||||
database `type` if using this option.
|
||||
* `MemoryMap` - default.
|
||||
* `FileIO` - This can be useful in environments with low RAM.
|
||||
|
||||
### BoltDB
|
||||
|
||||
```
|
||||
{
|
||||
...
|
||||
"db": {
|
||||
"type": "bbolt",
|
||||
"dataSource": "./stepdb"
|
||||
},
|
||||
...
|
||||
},
|
||||
```
|
||||
|
||||
### MySQL
|
||||
|
||||
```
|
||||
{
|
||||
...
|
||||
"db": {
|
||||
"type": "mysql",
|
||||
"dataSource": "user:password@tcp(127.0.0.1:3306)/",
|
||||
"database": "myDatabaseName"
|
||||
},
|
||||
...
|
||||
},
|
||||
```
|
||||
|
||||
## Schema
|
||||
|
||||
As the interface is a key-value store, the schema is very simple. We support
|
||||
`tables`, `keys`, and `values`. An entry in the database is a `[]byte value`
|
||||
that is indexed by `[]byte table` and `[]byte key`.
|
||||
|
||||
## Data Backup
|
||||
|
||||
Backing up your data is important, and it's good hygiene. We chose
|
||||
[Badger](https://github.com/dgraph-io/badger) as our default file based data
|
||||
storage backend because it has mature tooling for running common database
|
||||
tasks. See the [documentation](https://github.com/dgraph-io/badger#database-backup)
|
||||
for a guide on backing up your data.
|
@ -1,227 +0,0 @@
|
||||
# Default Algorithms and Attributes for Tokens, Keys, Certificates, etc.
|
||||
|
||||
The `step` ecosystem aims to be a "easy to use and hard to misuse" suite of PKI
|
||||
tools. This means we need to select sane defaults for the myriad
|
||||
configuration options that exist when using cryptographic primitives and higher
|
||||
order abstractions (e.g. JWTs).
|
||||
|
||||
Below we document significant configuration options that we have selected as
|
||||
defaults. These selections will change and evolve over time; security and
|
||||
cryptography are constantly changing in response to real world pressures. We
|
||||
intend for this document be an accurate representation of current best practices
|
||||
in the industry, and to have these practices codified as defaults in the `step
|
||||
certificates` code base. If you have questions, suggestions, or comments about
|
||||
any of these decisions please let us know by opening an issue on this repo,
|
||||
reaching out through [GitHub Discussions](https://github.com/smallstep/certificates/discussions).
|
||||
|
||||
## Tokens
|
||||
|
||||
We use JWTs (JSON Web Tokens) to prove authenticity and identity within the
|
||||
Step ecosystem. JWTs have received negative attention because they are easy to
|
||||
misuse and misconfigure. We agree! But lots of things are easy to misuse. We also
|
||||
believe that when configured well JWTs are a great way to sign and encode data.
|
||||
Our JWT's are, by default, short-lived (5 minute lifespan) and one time use
|
||||
during the lifetime of the Step CA. We use a 1 minute clock drift leeway
|
||||
because that was the recommended default in the reputable JWT package that we
|
||||
chose. If using Step JWTs or your own JWTs in your code be sure to verify and
|
||||
validate every single standard attribute of the JWT. JWTs, like all
|
||||
cryptographic tools, are useless without proper attention to configuration and
|
||||
guidelines.
|
||||
|
||||
## 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
|
||||
|
||||
We've chosen the AES encryption algorithm (aka Rijndael) for writing private
|
||||
keys to disk 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
|
||||
|
||||
* **Not After**: Now + 10 years
|
||||
|
||||
A 10 year window seems advisable until software and tools can be written
|
||||
for rotating the root certificate.
|
||||
|
||||
* **Basic Constraints**
|
||||
* **CA**: TRUE
|
||||
|
||||
The root certificate is a Certificate Authority, it will be used to sign
|
||||
other Certificates.
|
||||
|
||||
* **pathlen**: 1
|
||||
|
||||
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.
|
||||
|
||||
* **Key Usage** describes how the certificate can be used.
|
||||
* **Certificate Sign**
|
||||
|
||||
Indicates that our root public key will be used to verify a signature on
|
||||
certificates.
|
||||
|
||||
* **CRL Sign**
|
||||
|
||||
Indicates that our root public key will be used to verify a signature on
|
||||
revocation information, such as CRL.
|
||||
|
||||
### Intermediate Certificate
|
||||
|
||||
* Validity (10 year window)
|
||||
* **Not Before**: Now
|
||||
* **Not After**: Now + 10 years
|
||||
|
||||
A 10 year window seems advisable until software and tools can be written
|
||||
for rotating the root certificate.
|
||||
|
||||
* **Basic Constraints**
|
||||
* **CA**: TRUE
|
||||
|
||||
The intermediate certificate is a Certificate Authority, used to sign
|
||||
end-entity (service, process, job, etc.) certificates.
|
||||
* **pathlen**: 0
|
||||
|
||||
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.
|
||||
|
||||
* **Key Usage**
|
||||
* **Certificate Signing**
|
||||
|
||||
Indicates that our the intermediate private key can be used to sign
|
||||
certificate requests.
|
||||
|
||||
* **CRL Sign**
|
||||
|
||||
Indicates that this public key can be used to verify a signature on
|
||||
revocation information, such as CRL.
|
||||
|
||||
### Leaf Certificate - End Entity Certificate (certificates returned by the CA)
|
||||
|
||||
* Validity (24 hour window)
|
||||
* **Not Before**: Now
|
||||
* **Not After**: Now + 24 hours
|
||||
|
||||
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.
|
||||
|
||||
* **Key Usage**
|
||||
* **Key Encipherment**
|
||||
|
||||
Indicates that a certificate will be used with a protocol that encrypts keys.
|
||||
|
||||
* **Digital Signature**
|
||||
|
||||
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.
|
||||
|
||||
* **Extended Key Usage**
|
||||
* **TLS Web Server Authentication**
|
||||
|
||||
Certificate can be used as the server side certificate in the TLS protocol.
|
||||
|
||||
* **TLS Web Client Authentication**
|
||||
|
||||
Certificate can be used as the client side certificate in the TLS protocol.
|
||||
|
||||
## Default TLS Configuration Options
|
||||
|
||||
* **Min TLS Version**: TLS 1.2
|
||||
* **Max TLS Version**: TLS 1.2
|
||||
|
||||
The PCI Security Standards Council required 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.
|
||||
|
||||
* **Default Cipher Suites**:
|
||||
|
||||
```
|
||||
[
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
]
|
||||
```
|
||||
|
||||
The default 'ciphersuites' are a list of two cipher combinations. 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's performance is better than GCM and CBC.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
* **Approved Cipher Suites**:
|
||||
|
||||
```
|
||||
[
|
||||
"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",
|
||||
]
|
||||
```
|
||||
|
||||
Above 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 following
|
||||
[ssllabs article](https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#23-use-secure-cipher-suites).
|
||||
|
||||
* **Renegotation**: Never
|
||||
|
||||
TLS renegotiation significantly complicates the state machine and has been
|
||||
the source of numerous, subtle security issues. Therefore, by default we
|
||||
disable it.
|
@ -1,186 +0,0 @@
|
||||
# Getting started with Docker
|
||||
|
||||
## NOTE: This guide is deprecated. Please see [smallstep/step-ca](https://hub.docker.com/r/smallstep/step-ca) on Docker Hub for instructions.
|
||||
|
||||
This guide shows how to set up [step certificates](https://github.com/smallstep/certificates) using docker.
|
||||
|
||||
For short, we will use **step-ca** to refer to [step certificates](https://github.com/smallstep/certificates).
|
||||
|
||||
## Requirements
|
||||
|
||||
1. To follow this guide you will need to [install step
|
||||
cli](https://github.com/smallstep/cli#installation-guide).
|
||||
|
||||
2. Get the docker image.
|
||||
|
||||
Get the latest version of **step-ca** from the [step-ca docker
|
||||
hub](https://hub.docker.com/r/smallstep/step-ca):
|
||||
|
||||
```sh
|
||||
$ docker pull smallstep/step-ca
|
||||
```
|
||||
|
||||
3. Create the required volumes.
|
||||
|
||||
We need to create a volume in docker where we will store our PKI as well as
|
||||
the step-ca configuration file.
|
||||
|
||||
```sh
|
||||
$ docker volume create step
|
||||
```
|
||||
|
||||
4. Initialize the PKI.
|
||||
|
||||
The simple way to do this is to run an interactive terminal:
|
||||
|
||||
```sh
|
||||
$ docker run -it -v step:/home/step smallstep/step-ca sh
|
||||
|
||||
~ $ step ca init
|
||||
✔ What would you like to name your new PKI? (e.g. Smallstep): Smallstep
|
||||
✔ What DNS names or IP addresses would you like to add to your new CA? (e.g. ca.smallstep.com[,1.1.1.1,etc.]): localhost
|
||||
✔ What address will your new CA listen at? (e.g. :443): :9000
|
||||
✔ What would you like to name the first provisioner for your new CA? (e.g. you@smallstep.com): admin
|
||||
✔ What do you want your password to be? [leave empty and we'll generate one]: <your password here>
|
||||
|
||||
Generating root certificate...
|
||||
all done!
|
||||
|
||||
Generating intermediate certificate...
|
||||
all done!
|
||||
|
||||
✔ Root certificate: /home/step/certs/root_ca.crt
|
||||
✔ Root private key: /home/step/secrets/root_ca_key
|
||||
✔ Root fingerprint: f9e45ae9ec5d42d702ce39fd9f3125372ce54d0b29a5ff3016b31d9b887a61a4
|
||||
✔ Intermediate certificate: /home/step/certs/intermediate_ca.crt
|
||||
✔ Intermediate private key: /home/step/secrets/intermediate_ca_key
|
||||
✔ Default configuration: /home/step/config/defaults.json
|
||||
✔ Certificate Authority configuration: /home/step/config/ca.json
|
||||
|
||||
Your PKI is ready to go. To generate certificates for individual services see 'step help ca'.
|
||||
```
|
||||
|
||||
5. Place the PKI root password in a known location.
|
||||
|
||||
Our image is expecting the password to be placed in `/home/step/secrets/password`
|
||||
you can simply go in to the terminal again and write that file:
|
||||
|
||||
```sh
|
||||
$ docker run -it -v step:/home/step smallstep/step-ca sh
|
||||
~ $ echo <your password here> > /home/step/secrets/password
|
||||
```
|
||||
|
||||
At this time everything is ready to run step-ca!
|
||||
|
||||
## Running step certificates
|
||||
|
||||
Now that we have configured our environment we are ready to run step-ca.
|
||||
|
||||
Expose the server address locally and run the step-ca with:
|
||||
```sh
|
||||
$ docker run -d -p 127.0.0.1:9000:9000 -v step:/home/step smallstep/step-ca
|
||||
```
|
||||
|
||||
Let's verify that the service is running with curl:
|
||||
```sh
|
||||
$ curl https://localhost:9000/health
|
||||
curl: (60) SSL certificate problem: unable to get local issuer certificate
|
||||
More details here: https://curl.haxx.se/docs/sslcerts.html
|
||||
|
||||
curl performs SSL certificate verification by default, using a "bundle"
|
||||
of Certificate Authority (CA) public keys (CA certs). If the default
|
||||
bundle file isn't adequate, you can specify an alternate file
|
||||
using the --cacert option.
|
||||
If this HTTPS server uses a certificate signed by a CA represented in
|
||||
the bundle, the certificate verification probably failed due to a
|
||||
problem with the certificate (it might be expired, or the name might
|
||||
not match the domain name in the URL).
|
||||
If you'd like to turn off curl's verification of the certificate, use
|
||||
the -k (or --insecure) option.
|
||||
HTTPS-proxy has similar options --proxy-cacert and --proxy-insecure.
|
||||
```
|
||||
|
||||
It's working but curl complains because the certificate is not signed by an
|
||||
accepted certificate authority.
|
||||
|
||||
### Notes for running on a Raspberry Pi
|
||||
|
||||
When you run step-ca on a Raspberry Pi, you might get the following error in
|
||||
your continaer logs:
|
||||
|
||||
```sh
|
||||
step-ca | badger 2021/05/08 20:13:12 INFO: All 0 tables opened in 0s
|
||||
step-ca | Error opening database of Type badger with source /home/step/db: error opening Badger database: Mmap value log file. Path=/home/step/db/000000.vlog. Error=cannot allocate memory
|
||||
```
|
||||
|
||||
To fix it, adjust the `db` configuration in the file `config/ca.json`.
|
||||
Change the value of `badgerFileLoadingMode` from `""` to `"FileIO"`.
|
||||
|
||||
```sh
|
||||
docker run -it -v step:/home/step smallstep/step-ca sh
|
||||
|
||||
~ $ vi config/ca.json
|
||||
```
|
||||
|
||||
You will end up with this:
|
||||
|
||||
```json
|
||||
"db": {
|
||||
"type": "badger",
|
||||
"dataSource": "/root/.step/db",
|
||||
"badgerFileLoadingMode": "FileIO"
|
||||
},
|
||||
```
|
||||
|
||||
## Dev environment bootstrap
|
||||
|
||||
To initialize the development environment we need to grab the Root fingerprint
|
||||
from the [Initializing the PKI](#initializing-the-pki) step earlier. In the
|
||||
case of this example:
|
||||
`f9e45ae9ec5d42d702ce39fd9f3125372ce54d0b29a5ff3016b31d9b887a61a4`. With the
|
||||
fingerprint we can bootstrap our dev environment.
|
||||
|
||||
```sh
|
||||
$ step ca bootstrap --ca-url https://localhost:9000 --fingerprint f9e45ae9ec5d42d702ce39fd9f3125372ce54d0b29a5ff3016b31d9b887a61a4 --install
|
||||
The root certificate has been saved in ~/.step/certs/root_ca.crt.
|
||||
Your configuration has been saved in ~/.step/config/defaults.json.
|
||||
Installing the root certificate in the system truststore... done.
|
||||
```
|
||||
|
||||
Now [step cli](https://github.com/smallstep/cli) is configured to use step-ca
|
||||
and our new root certificate is trusted by our local environment.
|
||||
```sh
|
||||
$ curl https://localhost:9000/health
|
||||
{"status":"ok"}
|
||||
```
|
||||
|
||||
And we are able to run web services configured with TLS (and mTLS):
|
||||
```sh
|
||||
~ $ step ca certificate localhost localhost.crt localhost.key
|
||||
✔ Key ID: aTPGWP0qbuQdflR5VxtNouDIOXyNMH1H9KAZKP-UcHo (admin)
|
||||
✔ Please enter the password to decrypt the provisioner key:
|
||||
✔ CA: https://localhost:9000/1.0/sign
|
||||
✔ Certificate: localhost.crt
|
||||
✔ Private Key: localhost.key
|
||||
~ $ step ca root root_ca.crt
|
||||
The root certificate has been saved in root_ca.crt.
|
||||
~ $ python <<EOF
|
||||
import BaseHTTPServer, ssl
|
||||
class H(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
self.send_response(200); self.send_header('content-type', 'text/html; charset=utf-8'); self.end_headers()
|
||||
self.wfile.write(b'\n\xf0\x9f\x91\x8b Hello! Welcome to TLS \xf0\x9f\x94\x92\xe2\x9c\x85\n\n')
|
||||
httpd = BaseHTTPServer.HTTPServer(('', 8443), H)
|
||||
httpd.socket = ssl.wrap_socket (httpd.socket, server_side=True, keyfile="localhost.key", certfile="localhost.crt", ca_certs="root_ca.crt")
|
||||
httpd.serve_forever()
|
||||
EOF
|
||||
```
|
||||
|
||||
Test from another terminal:
|
||||
```sh
|
||||
$ curl https://localhost:8443
|
||||
|
||||
👋 Hello! Welcome to TLS 🔒✅
|
||||
```
|
||||
|
||||
Or visit `https://localhost:8443` from your browser.
|
Before Width: | Height: | Size: 572 KiB |
Before Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 6.2 MiB |
Before Width: | Height: | Size: 9.5 MiB |
@ -1,237 +0,0 @@
|
||||
# Key Management Services
|
||||
|
||||
This document describes how to use a key management service or KMS to store the
|
||||
private keys and sign certificates.
|
||||
|
||||
Support for multiple KMS are planned, but currently the only Google's Cloud KMS,
|
||||
and Amazon's AWS KMS are supported. A still experimental version for YubiKeys is
|
||||
also available if you compile [step-ca](https://github.com/smallstep/certificates)
|
||||
yourself.
|
||||
|
||||
## Google's Cloud KMS
|
||||
|
||||
[Cloud KMS](https://cloud.google.com/kms) is the Google's cloud-hosted KMS that
|
||||
allows you to store the cryptographic keys, and sign certificates using their
|
||||
infrastructure. Cloud KMS supports two different protection levels, SOFTWARE and
|
||||
HSM.
|
||||
|
||||
To configure Cloud KMS in your CA you need add the `"kms"` property to you
|
||||
`ca.json`, and replace the property`"key"` with the Cloud KMS key name of your
|
||||
intermediate key:
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"key": "projects/<project-id>/locations/global/keyRings/<ring-id>/cryptoKeys/<key-id>/cryptoKeyVersions/<version-number>",
|
||||
...
|
||||
"kms": {
|
||||
"type": "cloudkms",
|
||||
"credentialsFile": "path/to/credentials.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In a similar way, for SSH certificate, the SSH keys must be Cloud KMS names:
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"ssh": {
|
||||
"hostKey": "projects/<project-id>/locations/global/keyRings/<ring-id>/cryptoKeys/<key-id>/cryptoKeyVersions/<version-number>",
|
||||
"userKey": "projects/<project-id>/locations/global/keyRings/<ring-id>/cryptoKeys/<key-id>/cryptoKeyVersions/<version-number>"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Currently [step](https://github.com/smallstep/cli) does not provide an automatic
|
||||
way to initialize the public key infrastructure (PKI) using Cloud KMS, but an
|
||||
experimental tool named `step-cloudkms-init` is available for this use case. At
|
||||
some point this tool will be integrated into `step` and it will be deleted.
|
||||
|
||||
To use `step-cloudkms-init` just enable Cloud KMS in your project and run:
|
||||
|
||||
```sh
|
||||
$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
|
||||
$ step-cloudkms-init --project your-project-id --ssh
|
||||
Creating PKI ...
|
||||
✔ Root Key: projects/your-project-id/locations/global/keyRings/pki/cryptoKeys/root/cryptoKeyVersions/1
|
||||
✔ Root Certificate: root_ca.crt
|
||||
✔ Intermediate Key: projects/your-project-id/locations/global/keyRings/pki/cryptoKeys/intermediate/cryptoKeyVersions/1
|
||||
✔ Intermediate Certificate: intermediate_ca.crt
|
||||
|
||||
Creating SSH Keys ...
|
||||
✔ SSH User Public Key: ssh_user_ca_key.pub
|
||||
✔ SSH User Private Key: projects/your-project-id/locations/global/keyRings/pki/cryptoKeys/ssh-user-key/cryptoKeyVersions/1
|
||||
✔ SSH Host Public Key: ssh_host_ca_key.pub
|
||||
✔ SSH Host Private Key: projects/your-project-id/locations/global/keyRings/pki/cryptoKeys/ssh-host-key/cryptoKeyVersions/1
|
||||
```
|
||||
|
||||
See `step-cloudkms-init --help` for more options.
|
||||
|
||||
## AWS KMS
|
||||
|
||||
[AWS KMS](https://docs.aws.amazon.com/kms/index.html) is the Amazon's managed
|
||||
encryption and key management service. It creates and store the cryptographic
|
||||
keys, and use their infrastructure for signing operations. Amazon KMS operations
|
||||
are always backed by hardware security modules (HSMs).
|
||||
|
||||
To configure AWS KMS in your CA you need add the `"kms"` property to you
|
||||
`ca.json`, and replace the property`"key"` with the AWS KMS key name of your
|
||||
intermediate key:
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"key": "awskms:key-id=f879f239-feb6-4596-9ed2-b1606277c7fe",
|
||||
...
|
||||
"kms": {
|
||||
"type": "awskms",
|
||||
"region": "us-east-1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By default it uses the credentials in `~/.aws/credentials`, but this can be
|
||||
overridden using the `credentialsFile` option, `region` and `profile` can also
|
||||
be configured as options. These can also be configured using environment
|
||||
variables as described by their [session
|
||||
docs](https://docs.aws.amazon.com/sdk-for-go/api/aws/session/).
|
||||
|
||||
To configure SSH certificate signing we do something similar, and replace the
|
||||
ssh keys with the ones in the KMS:
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"ssh": {
|
||||
"hostKey": "awskms:key-id=d48e502a-09bc-4bf7-9af8-ae1bccedc931",
|
||||
"userKey": "awskms:key-id=cf28e942-1e10-4a08-b84c-5359af1b5f12"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The keys can also be just the Amazon's Key ID or the ARN, but using the format
|
||||
based on the [RFC7512](https://tools.ietf.org/html/rfc7512) will allow more
|
||||
flexibility for future releases of `step`.
|
||||
|
||||
Currently [step](https://github.com/smallstep/cli) does not provide an automatic
|
||||
way to initialize the public key infrastructure (PKI) using AWS KMS, but an
|
||||
experimental tool named `step-awskms-init` is available for this use case. At
|
||||
some point this tool will be integrated into `step` and it will be deleted.
|
||||
|
||||
To use `step-awskms-init` make sure to have to have your [environment
|
||||
configured](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)
|
||||
running `aws configure` and then just run:
|
||||
|
||||
```sh
|
||||
$ bin/step-awskms-init --ssh --region us-east-1
|
||||
Creating PKI ...
|
||||
✔ Root Key: awskms:key-id=f53fb767-4029-40ff-b650-0dd35fb661df
|
||||
✔ Root Certificate: root_ca.crt
|
||||
✔ Intermediate Key: awskms:key-id=f879f239-feb6-4596-9ed2-b1606277c7fe
|
||||
✔ Intermediate Certificate: intermediate_ca.crt
|
||||
|
||||
Creating SSH Keys ...
|
||||
✔ SSH User Public Key: ssh_user_ca_key.pub
|
||||
✔ SSH User Private Key: awskms:key-id=cf28e942-1e10-4a08-b84c-5359af1b5f12
|
||||
✔ SSH Host Public Key: ssh_host_ca_key.pub
|
||||
✔ SSH Host Private Key: awskms:key-id=cf28e942-1e10-4a08-b84c-5359af1b5f12
|
||||
```
|
||||
|
||||
The `--region` parameter is only required if your aws configuration does not
|
||||
define a region. See `step-awskms-init --help` for more options.
|
||||
|
||||
## YubiKey
|
||||
|
||||
And incomplete and experimental support for [YubiKeys](https://www.yubico.com)
|
||||
is also available. Support for YubiKeys is not enabled by default and only TLS
|
||||
signing can be configured.
|
||||
|
||||
The YubiKey implementation requires cgo, and our build system does not produce
|
||||
binaries with it. To enable YubiKey download the source code and run:
|
||||
|
||||
```sh
|
||||
make build GOFLAGS=""
|
||||
```
|
||||
|
||||
The implementation uses [piv-go](https://github.com/go-piv/piv-go), and it
|
||||
requires PCSC support, this is available by default on macOS and Windows
|
||||
operating systems, but on Linux piv-go requires PCSC lite.
|
||||
|
||||
To install on Debian-based distributions, run:
|
||||
|
||||
```sh
|
||||
sudo apt-get install libpcsclite-dev
|
||||
```
|
||||
|
||||
On Fedora:
|
||||
|
||||
```sh
|
||||
sudo yum install pcsc-lite-devel
|
||||
```
|
||||
|
||||
On CentOS:
|
||||
|
||||
```sh
|
||||
sudo yum install 'dnf-command(config-manager)'
|
||||
sudo yum config-manager --set-enabled PowerTools
|
||||
sudo yum install pcsc-lite-devel
|
||||
```
|
||||
|
||||
The initialization of the public key infrastructure (PKI) for YubiKeys, is not
|
||||
currently integrated into [step](https://github.com/smallstep/cli), but an
|
||||
experimental tool named `step-yubikey-init` is available for this use case. At
|
||||
some point this tool will be integrated into `step` and it will be deleted.
|
||||
|
||||
To configure your YubiKey just run:
|
||||
|
||||
```sh
|
||||
$ bin/step-yubikey-init
|
||||
What is the YubiKey PIN?:
|
||||
Creating PKI ...
|
||||
✔ Root Key: yubikey:slot-id=9a
|
||||
✔ Root Certificate: root_ca.crt
|
||||
✔ Intermediate Key: yubikey:slot-id=9c
|
||||
✔ Intermediate Certificate: intermediate_ca.crt
|
||||
```
|
||||
|
||||
See `step-yubikey-init --help` for more options.
|
||||
|
||||
Finally to enable it in the ca.json, point the `root` and `crt` to the generated
|
||||
certificates, set the `key` with the yubikey URI generated in the previous step
|
||||
and configure the `kms` property with the `type` and your `pin` in it.
|
||||
|
||||
```json
|
||||
{
|
||||
"root": "/path/to/root_ca.crt",
|
||||
"crt": "/path/to/intermediate_ca.crt",
|
||||
"key": "yubikey:slot-id=9c",
|
||||
"kms": {
|
||||
"type": "yubikey",
|
||||
"pin": "123456"
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## SSHAgentKMS
|
||||
|
||||
SSHAgentKMS is a KMS that wrapps a ssh-agent which has access to the keys to
|
||||
sign ssh certificates. This was primarly written to be able to use gpg-agent
|
||||
to provide the keys stored in a YubiKeys openpgp interface.
|
||||
|
||||
```json
|
||||
{
|
||||
"kms": {
|
||||
"type": "sshagentkms"
|
||||
},
|
||||
"ssh": {
|
||||
"hostKey": "sshagentkms:cardno:000123456789",
|
||||
"userKey": "sshagentkms:cardno:000123456789",
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
This KMS requires that "root", "crt" and "key" are stored in plain files as for
|
||||
SoftKMS.
|
@ -1,211 +0,0 @@
|
||||
# Revocation
|
||||
|
||||
**Active Revocation**: A certificate is no longer valid from the moment it has
|
||||
been actively revoked. Clients are required to check against centralized
|
||||
sources of certificate validity information (e.g. by using CRLs (Certificate
|
||||
Revocation Lists) or OCSP (Online Certificate Status Protocol)) to
|
||||
verify that certificates have not been revoked. Active Revocation requires
|
||||
clients to take an active role in certificate validation for the benefit of
|
||||
real time revocation.
|
||||
|
||||
**Passive Revocation**: A certificate that has been passively revoked can no
|
||||
longer be renewed. It will still be valid for the remainder of it's validity period,
|
||||
but cannot be prolonged. The benefit of passive revocation is that clients
|
||||
can verify certificates in a simple, decentralized manner without relying on
|
||||
centralized 3rd parties. Passive revocation works best with short
|
||||
certificate lifetimes.
|
||||
|
||||
`step certificates` currently only supports passive revocation. Active revocation
|
||||
is on our roadmap.
|
||||
|
||||
Run `step help ca revoke` from the command line for full documentation, list of
|
||||
command line flags, and examples.
|
||||
|
||||
## How It Works
|
||||
|
||||
Certificates can be created and revoked through the `step cli`. Let's walk
|
||||
through an example.
|
||||
|
||||
### Requirements
|
||||
|
||||
* `step` (>=v0.10.0) ([install instructions](../README.md#installation-guide))
|
||||
|
||||
### Let's Get To It
|
||||
|
||||
1. Bootstrap your PKI.
|
||||
|
||||
> If you've already done this before and you have a `$STEPPATH` with certs,
|
||||
> secrets, and configuration files then you can move on to step 2.
|
||||
|
||||
Run `step ca init`.
|
||||
|
||||
<pre><code>
|
||||
<b>$ step ca init --name "Local CA" --provisioner admin --dns localhost --address ":443"</b>
|
||||
</code></pre>
|
||||
|
||||
Move on to step 3.
|
||||
|
||||
2. Configure a persistence layer in your `ca.json`.
|
||||
|
||||
> If you did step 1 with `step` v0.10.0 or greater then your db will
|
||||
> have been configured in the previous step.
|
||||
|
||||
Get your full step path by running `echo $(step path)`. Now edit
|
||||
your `ca.json` by adding the following stanza as a top-level attribute:
|
||||
> Your `ca.json` should be in `$(step path)/config/ca.json`.
|
||||
|
||||
```
|
||||
...
|
||||
"db": {
|
||||
"type": "badger",
|
||||
"dataSource": "<full step path>/db"
|
||||
},
|
||||
...
|
||||
```
|
||||
|
||||
Check out our [database documentation](./database.md) to see all available
|
||||
database backends and adapters.
|
||||
|
||||
3. Run the CA
|
||||
|
||||
<pre><code>
|
||||
<b>$ step-ca $(step path)/config/ca.json</b>
|
||||
</code></pre>
|
||||
|
||||
4. Create a certificate for localhost
|
||||
|
||||
<pre><code>
|
||||
<b>$ step ca certificate localhost localhost.crt localhost.key</b>
|
||||
✔ Key ID: n2kqNhicCCqVxJidspCQrjXWBtGwsa9zk3eBObrViy8 (sebastian@smallstep.com)
|
||||
✔ Please enter the password to decrypt the provisioner key:
|
||||
✔ CA: https://ca.smallstep.com
|
||||
✔ Certificate: localhost.crt
|
||||
✔ Private Key: localhost.key
|
||||
|
||||
<b>$ step certificate inspect --short localhost.crt</b>
|
||||
X.509v3 TLS Certificate (ECDSA P-256) [Serial: 2400...2409]
|
||||
Subject: localhost
|
||||
Issuer: Smallstep Intermediate CA
|
||||
Provisioner: sebastian@smallstep.com [ID: n2kq...Viy8]
|
||||
Valid from: 2019-04-23T22:55:54Z
|
||||
to: 2019-04-24T22:55:54Z
|
||||
</code></pre>
|
||||
|
||||
5. Renew the certificate (just to prove we can!)
|
||||
|
||||
<pre><code>
|
||||
<b>$ step ca renew localhost.crt localhost.key</b>
|
||||
✔ Would you like to overwrite localhost.crt [y/n]: y
|
||||
Your certificate has been saved in localhost.crt.
|
||||
|
||||
# Make sure the from timestamp is "newer"
|
||||
<b>$ step certificate inspect --short localhost.crt</b>
|
||||
X.509v3 TLS Certificate (ECDSA P-256) [Serial: 5963...8406]
|
||||
Subject: localhost
|
||||
Issuer: Smallstep Intermediate CA
|
||||
Provisioner: sebastian@smallstep.com [ID: n2kq...Viy8]
|
||||
Valid from: 2019-04-23T22:57:50Z
|
||||
to: 2019-04-24T22:57:50Z
|
||||
</pre></code>
|
||||
|
||||
6. Now let's revoke the certificate
|
||||
|
||||
<pre><code>
|
||||
<b>$ step certificate inspect --format=json localhost.crt | jq .serial_number</b>
|
||||
"59636004850364466675608080466579278406"
|
||||
# the serial number is unique
|
||||
|
||||
<b>$ step ca revoke 59636004850364466675608080466579278406</b>
|
||||
✔ Key ID: n2kqNhicCCqVxJidspCQrjXWBtGwsa9zk3eBObrViy8 (sebastian@smallstep.com)
|
||||
✔ Please enter the password to decrypt the provisioner key:
|
||||
✔ CA: https://ca.smallstep.com
|
||||
Certificate with Serial Number 59636004850364466675608080466579278406 has been revoked.
|
||||
</pre></code>
|
||||
|
||||
7. Awesome! But did it work?
|
||||
|
||||
<pre><code>
|
||||
<b>$ step ca renew localhost.crt localhost.key</b>
|
||||
error renewing certificate: Unauthorized
|
||||
|
||||
# log trace from CA:
|
||||
[...]
|
||||
WARN[0569] duration="82.782µs" duration-ns=82782
|
||||
error="renew: certificate has been revoked"
|
||||
fields.time="2019-04-23T16:03:01-07:00" method=POST
|
||||
name=ca path=/renew protocol=HTTP/1.1 referer=
|
||||
remote-address=127.0.0.1 request-id=bivpj9a3q563rpjheh5g
|
||||
size=40 status=401 user-agent=Go-http-client/1.1 user-id=
|
||||
[...]
|
||||
</pre></code>
|
||||
|
||||
8. Other ways to revoke a Certificate
|
||||
|
||||
Use the certificate and key. This method does not require a provisioner
|
||||
because it uses the certificate and key to authenticate the request.
|
||||
|
||||
<pre><code>
|
||||
<b>$ step ca revoke --cert localhost.crt --key localhost.key</b>
|
||||
Certificate with Serial Number 59636004850364466675608080466579278406 has been revoked.
|
||||
</pre></code>
|
||||
|
||||
Or, revoke a certificate in two steps by first creating a revocation token and
|
||||
then exchanging that token in a revocation request.
|
||||
|
||||
<pre><code>
|
||||
<b>$ TOKEN=$(step ca token --revoke 59636004850364466675608080466579278406)</b>
|
||||
✔ Key ID: n2kqNhicCCqVxJidspCQrjXWBtGwsa9zk3eBObrViy8 (sebastian@smallstep.com)
|
||||
✔ Please enter the password to decrypt the provisioner key:
|
||||
|
||||
<b>$ echo $TOKEN | step crypto jwt inspect --insecure</b>
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"kid": "uxEunU9UhUo96lRvKgpEtRevkzbN5Yq88AFFtb1nSGg",
|
||||
"typ": "JWT"
|
||||
},
|
||||
"payload": {
|
||||
"aud": "https://localhost:443/1.0/revoke",
|
||||
"exp": 1556395590,
|
||||
"iat": 1556395290,
|
||||
"iss": "sebastian@smallstep.com",
|
||||
"jti": "1f222fc1a22530b7bcd2a40d7308c566c8e49f90413bc350e07bfabc8002b79b",
|
||||
"nbf": 1556395290,
|
||||
"sha": "fef4c75a050e1f3a31175ca4f4fdb711cbef1efcd374fcae4700596604eb8e5a",
|
||||
"sub": "59636004850364466675608080466579278406"
|
||||
},
|
||||
"signature": "M1wX0ea3VXwS5rIim0TgtcCXHDtvP1GWD15cJSvVkrHNO6XMYl6m3ZmnWdwMi976msv-n2GTG3h6dJ3j2ImdfQ"
|
||||
}
|
||||
|
||||
<b>$ step ca revoke --token $TOKEN 59636004850364466675608080466579278406</b>
|
||||
Certificate with Serial Number 59636004850364466675608080466579278406 has been revoked.
|
||||
</pre></code>
|
||||
|
||||
Or, revoke a certificate in offline mode:
|
||||
|
||||
<pre><code>
|
||||
<b>$ step ca revoke --offline 59636004850364466675608080466579278406</b>
|
||||
Certificate with Serial Number 59636004850364466675608080466579278406 has been revoked.
|
||||
|
||||
<b>$ step ca revoke --offline --cert localhost.crt --key localhost.key</b>
|
||||
Certificate with Serial Number 59636004850364466675608080466579278406 has been revoked.
|
||||
</pre></code>
|
||||
|
||||
> NOTE: you can only revoke a certificate once. Any repeated attempts to revoke
|
||||
> the same serial number will fail.
|
||||
|
||||
Run `step help ca revoke` from the command line for full documentation, list of
|
||||
command line flags, and examples.
|
||||
|
||||
## What's next?
|
||||
|
||||
[Use TLS Everywhere](https://smallstep.com/blog/use-tls.html) and let us know
|
||||
what you think of our tools. Get in touch over
|
||||
[Twitter](twitter.com/smallsteplabs) or through our
|
||||
[GitHub Discussions](https://github.com/smallstep/certificates/discussions) to find answers to frequently asked questions.
|
||||
[Discord](https://bit.ly/step-discord) to chat with us in real time.
|
||||
|
||||
## Further Reading
|
||||
|
||||
* [Use TLS Everywhere](https://smallstep.com/blog/use-tls.html)
|
||||
* [Everything you should know about certificates and PKI but are too afraid to ask](https://smallstep.com/blog/everything-pki.html)
|