forked from TrueCloudLab/certificates
fix grammar in examples/README.md
This commit is contained in:
parent
b94a87708a
commit
baaff35818
1 changed files with 94 additions and 86 deletions
|
@ -2,12 +2,11 @@
|
|||
|
||||
## Basic client usage
|
||||
|
||||
The basic-client example shows the use of the most of the functioanlity of the
|
||||
`ca.Client`, those methods works as an SDK for integrating other services with
|
||||
the Certificate Authority (CA).
|
||||
The basic-client example shows the functionality of the `ca.Client` type. The
|
||||
methods work as an SDK for integrating services with the Certificate Authority (CA).
|
||||
|
||||
In [basic-client/client.go](/examples/basic-client/client.go) we first can see
|
||||
the initialization of the client:
|
||||
In [basic-client/client.go](/examples/basic-client/client.go) we see
|
||||
the initialization of a client:
|
||||
|
||||
```go
|
||||
client, err := ca.NewClient("https://localhost:9000", ca.WithRootSHA256("84a033e84196f73bd593fad7a63e509e57fd982f02084359c4e8c5c864efc27d"))
|
||||
|
@ -15,80 +14,79 @@ client, err := ca.NewClient("https://localhost:9000", ca.WithRootSHA256("84a033e
|
|||
|
||||
The previous code uses the CA address and the root certificate fingerprint.
|
||||
The CA url will be present in the token, and the root fingerprint can be present
|
||||
too if the `--root root_ca.crt` option is use in the creation of the token. If
|
||||
this is the case is simpler to rely in the token and use just:
|
||||
too if the `--root root_ca.crt` option is used in the creation of the token. If
|
||||
the token does contain the root fingerprint then it is simpler to use:
|
||||
|
||||
```go
|
||||
client, err := ca.Bootstrap(token)
|
||||
```
|
||||
|
||||
After the initialization there're examples of all the client methods, they are
|
||||
just a convenient way to use the CA API endpoints. The first method `Health`
|
||||
returns the status of the CA server, on the first implementation if the server
|
||||
is up it will return just ok.
|
||||
After the initialization there are examples of all the client methods. These
|
||||
methods are a convenient way to use the CA API. The first method, `Health`,
|
||||
returns the status of the CA server. If the server is up it will return
|
||||
`{"status":"ok"}`.
|
||||
|
||||
```go
|
||||
health, err := client.Health()
|
||||
// Health is a struct created from the JSON response {"status": "ok"}
|
||||
```
|
||||
|
||||
The next method `Root` is used to get and verify the root certificate. We will
|
||||
pass a finger print, it will download the root certificate from the CA and it
|
||||
will make sure that the fingerprint matches. This method uses an insecure HTTP
|
||||
The next method `Root` is used to get and verify the root certificate. We
|
||||
pass a fingerprint and it downloads the root certificate from the CA and
|
||||
verifies that the fingerprint matches. This method uses an insecure HTTP
|
||||
client as it might be used in the initialization of the client, but the response
|
||||
is considered secure because we have compared against the given digest.
|
||||
is considered secure because we have compared against the expected digest.
|
||||
|
||||
```go
|
||||
root, err := client.Root("84a033e84196f73bd593fad7a63e509e57fd982f02084359c4e8c5c864efc27d")
|
||||
```
|
||||
|
||||
After Root we have the most important method `Sign`, this is used to sign a
|
||||
Certificate Signing Request that we provide. To secure this request we use
|
||||
the one-time-token. You can build your own certificate request and add it in
|
||||
the `*api.SignRequest`, but the ca package contains a method that will create a
|
||||
secure random key, and create the CSR based on the information in the token.
|
||||
Next we have the most important method; `Sign`. `Sign` will authorize and sign a
|
||||
CSR (Certificate Signing Request) that we provide. To authorize this request we use
|
||||
a provisioning token issued by an authorized provisioner.
|
||||
You can build your own certificate request and add it in
|
||||
the `*api.SignRequest`, but our CA SDK contains a method that will generate a
|
||||
secure random key and create a CSR - combining the key with the information
|
||||
provided in the provisioning token.
|
||||
|
||||
```go
|
||||
// Create a CSR from token and return the sign request, the private key and an
|
||||
// Create a CSR from a token and return the SignRequest, the private key, and an
|
||||
// error if something failed.
|
||||
req, pk, err := ca.CreateSignRequest(token)
|
||||
if err != nil { ... }
|
||||
|
||||
// Do the sign request and return the signed certificate
|
||||
// Do the Sign request and return the signed certificate.
|
||||
sign, err := client.Sign(req)
|
||||
if err != nil { ... }
|
||||
```
|
||||
|
||||
To renew the certificate we can use the `Renew` method, the certificate renewal
|
||||
relies on a mTLS connection with a previous certificate, so we will need to pass
|
||||
a transport with the previous certificate.
|
||||
Next is the `Renew` method which is used to (you guessed it!) renew certificates.
|
||||
Certificate renewal relies on a mTLS connection with using an existing certificate.
|
||||
So, as input we will need to pass a transport with the current certificate.
|
||||
|
||||
```go
|
||||
// Get a cancelable context to stop the renewal goroutines and timers.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
// Create a transport from with the sign response and the private key.
|
||||
// Create a transport with the sign response and the private key.
|
||||
tr, err := client.Transport(ctx, sign, pk)
|
||||
if err != nil { ... }
|
||||
// Renew the certificate and get the new ones.
|
||||
// The return type are equivalent to ones in the Sign method.
|
||||
// Renew the certificate. The return type is equivalent to the Sign method.
|
||||
renew, err := client.Renew(tr)
|
||||
if err != nil { ... }
|
||||
```
|
||||
|
||||
All the previous methods map with one endpoint in the CA API, but the API
|
||||
provides a couple more that are used for creating the tokens. For those we have
|
||||
a couple of methods, one that returns a list of provisioners and one that
|
||||
returns the encrypted key of one provisioner.
|
||||
The following methods are for inpsecting Provisioners.
|
||||
One method that returns a list of provisioners or a the encrypted key of one provisioner.
|
||||
|
||||
```go
|
||||
// Without options it will return the first 20 provisioners
|
||||
// Without options it will return the first 20 provisioners.
|
||||
provisioners, err := client.Provisioners()
|
||||
// We can also set a limit up to 100
|
||||
// We can also set a limit up to 100.
|
||||
provisioners, err := client.Provisioners(ca.WithProvisionerLimit(100))
|
||||
// With a pagination cursor
|
||||
// With a pagination cursor.
|
||||
provisioners, err := client.Provisioners(ca.WithProvisionerCursor("1f18c1ecffe54770e9107ce7b39b39735"))
|
||||
// Or combining both
|
||||
// Or combine both.
|
||||
provisioners, err := client.Provisioners(
|
||||
ca.WithProvisionerCursor("1f18c1ecffe54770e9107ce7b39b39735"),
|
||||
ca.WithProvisionerLimit(100),
|
||||
|
@ -99,21 +97,21 @@ provisioners, err := client.Provisioners(
|
|||
key, err := client.ProvisionerKey("DmAtZt2EhmZr_iTJJ387fr4Md2NbzMXGdXQNW1UWPXk")
|
||||
```
|
||||
|
||||
The example shows also the use of some helper methods used to get configured
|
||||
tls.Config objects that can be injected in servers and clients. These methods,
|
||||
are also configured to auto-renew the certificate once two thirds of the
|
||||
duration of the certificate has passed, approximately.
|
||||
The following example shows how to create a
|
||||
tls.Config object that can be injected into servers and clients. By default these
|
||||
methods will spin off Go routines that auto-renew a certificate once (approximately)
|
||||
two thirds of the duration of the certificate has passed.
|
||||
|
||||
```go
|
||||
// Get a cancelable context to stop the renewal goroutines and timers.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
// Get tls.Config for a server
|
||||
// Get tls.Config for a server.
|
||||
tlsConfig, err := client.GetServerTLSConfig(ctx, sign, pk)
|
||||
// Get tls.Config for a client
|
||||
// Get tls.Config for a client.
|
||||
tlsConfig, err := client.GetClientTLSConfig(ctx, sign, pk)
|
||||
// Get an http.Transport for a client, this can be used as a http.RoundTripper
|
||||
// in an http.Client
|
||||
// Get an http.Transport for a client; this can be used as a http.RoundTripper
|
||||
// in an http.Client.
|
||||
tr, err := client.Transport(ctx, sign, pk)
|
||||
```
|
||||
|
||||
|
@ -124,7 +122,7 @@ certificates $ bin/step-ca examples/pki/config/ca.json
|
|||
2018/11/02 18:29:25 Serving HTTPS on :9000 ...
|
||||
```
|
||||
|
||||
And just run the client.go with a new token:
|
||||
Then run client.go with a new token:
|
||||
```sh
|
||||
certificates $ export STEPPATH=examples/pki
|
||||
certificates $ export STEP_CA_URL=https://localhost:9000
|
||||
|
@ -133,17 +131,15 @@ certificates $ go run examples/basic-client/client.go $(step ca token client.sma
|
|||
|
||||
## Bootstrap Client & Server
|
||||
|
||||
On this example we are going to see the Certificate Authority running, as well
|
||||
as a simple Server using TLS and a simple client doing TLS requests to the
|
||||
server.
|
||||
In this example we are going run the CA alongside a simple Server using TLS and
|
||||
a simple client making TLS requests to the server.
|
||||
|
||||
The examples directory already contains a sample pki configuration with the
|
||||
password `password` hardcoded, but you can create your own using `step ca init`.
|
||||
|
||||
These examples show the use of other helper methods, they are simple ways to
|
||||
These examples show the use of some other helper methods - simple ways to
|
||||
create TLS configured http.Server and http.Client objects. The methods are
|
||||
`BootstrapServer`, `BootstrapServerWithMTLS` and `BootstrapClient` and they are
|
||||
used like:
|
||||
`BootstrapServer`, `BootstrapServerWithMTLS` and `BootstrapClient`.
|
||||
|
||||
```go
|
||||
// Get a cancelable context to stop the renewal goroutines and timers.
|
||||
|
@ -187,17 +183,20 @@ if err != nil {
|
|||
resp, err := client.Get("https://localhost:8443")
|
||||
```
|
||||
|
||||
We will demonstrate the mTLS configuration if a different example, for this one
|
||||
we will only verify it if provided.
|
||||
We will demonstrate the mTLS configuration in a different example. In this
|
||||
examplefor we will configure the server to only verify client certificates
|
||||
if they are provided.
|
||||
|
||||
To being with let's start the Step CA:
|
||||
|
||||
To run the example first we will start the certificate authority:
|
||||
```sh
|
||||
certificates $ bin/step-ca examples/pki/config/ca.json
|
||||
2018/11/02 18:29:25 Serving HTTPS on :9000 ...
|
||||
```
|
||||
|
||||
We will start the server and we will type `password` when step asks for the
|
||||
Next we will start the bootstrap-server and enter `password` prompted for the
|
||||
provisioner password:
|
||||
|
||||
```sh
|
||||
certificates $ export STEPPATH=examples/pki
|
||||
certificates $ export STEP_CA_URL=https://localhost:9000
|
||||
|
@ -207,7 +206,8 @@ Please enter the password to decrypt the provisioner key:
|
|||
Listening on :8443 ...
|
||||
```
|
||||
|
||||
We try that using cURL with the system certificates it will return an error:
|
||||
Let's try to cURL our new bootstrap server with the system certificates bundle
|
||||
as our root. It should fail.
|
||||
```
|
||||
certificates $ curl https://localhost:8443
|
||||
curl: (60) SSL certificate problem: unable to get local issuer certificate
|
||||
|
@ -226,16 +226,19 @@ If you'd like to turn off curl's verification of the certificate, use
|
|||
HTTPS-proxy has similar options --proxy-cacert and --proxy-insecure.
|
||||
```
|
||||
|
||||
But if we use the root certificate it will properly work:
|
||||
Now lets use the root certificate generated for the Step PKI. It should work.
|
||||
|
||||
```sh
|
||||
certificates $ curl --cacert examples/pki/secrets/root_ca.crt https://localhost:8443
|
||||
Hello nobody at 2018-11-03 01:49:25.66912 +0000 UTC!!!
|
||||
```
|
||||
|
||||
Notice that in the response we see `nobody`, this is because the server didn't
|
||||
Notice that in the response we see `nobody`. This is because the server did not
|
||||
detected a TLS client configuration.
|
||||
|
||||
But if we the client with the certificate name Mike we'll see:
|
||||
But if we create a client with it's own certificate (generated by the Step CA),
|
||||
we should see the Common Name of the client certificate:
|
||||
|
||||
```sh
|
||||
certificates $ export STEPPATH=examples/pki
|
||||
certificates $ export STEP_CA_URL=https://localhost:9000
|
||||
|
@ -250,17 +253,19 @@ Server responded: Hello Mike at 2018-11-03 01:52:54.682787 +0000 UTC!!!
|
|||
|
||||
## Bootstrap mTLS Client & Server
|
||||
|
||||
This example demonstrates a stricter configuration of the bootstrap server, this
|
||||
one always requires a valid client certificate.
|
||||
This example demonstrates a stricter configuration of the bootstrap-server. Here
|
||||
we configure the server to require mTLS (mutual TLS) with a valid client certificate.
|
||||
|
||||
As always, we begin by starting the CA:
|
||||
|
||||
As always, to run this example will require the Certificate Authority running:
|
||||
```sh
|
||||
certificates $ bin/step-ca examples/pki/config/ca.json
|
||||
2018/11/02 18:29:25 Serving HTTPS on :9000 ...
|
||||
```
|
||||
|
||||
We will start the mTLS server and we will type `password` when step asks for the
|
||||
Next we start the mTLS server and we enter `password` when prompted for the
|
||||
provisioner password:
|
||||
|
||||
```sh
|
||||
certificates $ export STEPPATH=examples/pki
|
||||
certificates $ export STEP_CA_URL=https://localhost:9000
|
||||
|
@ -270,13 +275,17 @@ Please enter the password to decrypt the provisioner key:
|
|||
Listening on :8443 ...
|
||||
```
|
||||
|
||||
For mTLS, curl and curl with the root certificate will fail:
|
||||
Now that the server is configured to require mTLS cURL-ing should fail even
|
||||
if we use the correct root certificate bundle.
|
||||
|
||||
```sh
|
||||
certificates $ curl --cacert examples/pki/secrets/root_ca.crt https://localhost:8443
|
||||
curl: (35) error:1401E412:SSL routines:CONNECT_CR_FINISHED:sslv3 alert bad certificate
|
||||
```
|
||||
|
||||
But if we the client with the certificate name Mike we'll see:
|
||||
However, if we use our client (which requests a certificate from the Step CA
|
||||
when it starts):
|
||||
|
||||
```sh
|
||||
certificates $ export STEPPATH=examples/pki
|
||||
certificates $ export STEP_CA_URL=https://localhost:9000
|
||||
|
@ -291,11 +300,11 @@ Server responded: Hello Mike at 2018-11-07 21:54:02.141578 +0000 UTC!!!
|
|||
|
||||
## Certificate rotation
|
||||
|
||||
We can use the bootstrap-server to demonstrate the certificate rotation. We've
|
||||
added second provisioner to to the ca with the name of `mike@smallstep.com`,
|
||||
this provisioner is configured with a default certificate duration of 2 minutes.
|
||||
If we run the server, and inspect the used certificate, we can verify how it
|
||||
rotates after approximately two thirds of the duration has passed.
|
||||
We can use the bootstrap-server to demonstrate certificate rotation. We've
|
||||
added a second provisioner, named `mike@smallstep.com`, to the CA configuration.
|
||||
This provisioner is has a default certificate duration of 2 minutes.
|
||||
Let's run the server, and inspect the certificate. We can should be able to
|
||||
see the certificate rotate once approximately 2/3rds of it's lifespan has passed.
|
||||
|
||||
```sh
|
||||
certificates $ export STEPPATH=examples/pki
|
||||
|
@ -306,9 +315,9 @@ Please enter the password to decrypt the provisioner key:
|
|||
Listening on :8443 ...
|
||||
```
|
||||
|
||||
In this specific case, the the rotation will happen after 74-80 seconds have
|
||||
passed, the exact formula is 120-120/3-rand(120/20), where rand will return a
|
||||
number between 0 and 6.
|
||||
In this case, the certificate will rotate after 74-80 seconds.
|
||||
The exact formula is `<duration>-<duration>/3-rand(<duration>/20)` (`duration=120`
|
||||
in our example).
|
||||
|
||||
We can use the following command to check the certificate expiration and to make
|
||||
sure the certificate changes after 74-80 seconds.
|
||||
|
@ -319,21 +328,21 @@ certificates $ step certificate inspect --insecure https://localhost:8443
|
|||
|
||||
## NGINX with Step CA certificates
|
||||
|
||||
The example under the `docker` directory shows how to combine the Smallstep CA
|
||||
with NGINX to server pages or proxy services using certificates created by the
|
||||
step-ca.
|
||||
The example under the `docker` directory shows how to combine the Step CA
|
||||
with NGINX to serve or proxy services using certificates created by the
|
||||
Step CA.
|
||||
|
||||
This example creates 3 different docker images:
|
||||
|
||||
* nginx-test: docker image with NGINX and a script using inotify-tools to watch
|
||||
for changes in the certificate to reload NGINX.
|
||||
* step-ca-test: docker image with the Smallstep CA
|
||||
* step-renewer-test: docker images with the step cli tool, it creates the
|
||||
certificate and has a cron that renews the certificate. Right now the cron
|
||||
runs every minute for testing purposes.
|
||||
* step-ca-test: docker image with the Step CA
|
||||
* step-renewer-test: docker image with the step cli tool - it creates the
|
||||
certificate and sets a cron that renews the certificate (the cron
|
||||
runs every minute for testing purposes).
|
||||
|
||||
To run this test you need to have docker daemon running. With docker running
|
||||
swith to the `examples/docker directory` and just run `make`
|
||||
To run this test you need to have the docker daemon running. With docker running
|
||||
swith to the `examples/docker directory` and run `make`:
|
||||
|
||||
```
|
||||
certificates $ cd examples/docker/
|
||||
|
@ -370,7 +379,7 @@ make sure the cert is right we need to add the following entry to `/etc/hosts`:
|
|||
127.0.0.1 nginx
|
||||
```
|
||||
|
||||
Now we can use curl to check:
|
||||
Now we can use cURL to verify:
|
||||
|
||||
```sh
|
||||
docker $ curl --cacert ca/pki/secrets/root_ca.crt https://nginx:4443/
|
||||
|
@ -401,8 +410,7 @@ Commercial support is available at
|
|||
</html>
|
||||
```
|
||||
|
||||
Now you can use `make inspect` to inspect the certificate to see how the
|
||||
certificate gets updated every minute:
|
||||
We can use `make inspect` to witness the certificate being rotated every minute.
|
||||
|
||||
```sh
|
||||
docker $ make inspect | head
|
||||
|
@ -429,7 +437,7 @@ Certificate:
|
|||
Not After : Nov 11 02:14:00 2018 UTC
|
||||
```
|
||||
|
||||
Finally, to remove the containers and volumes you can use `make down`:
|
||||
Finally, to cleanup the containers and volumes created in this demo use `make down`:
|
||||
|
||||
```sh
|
||||
docker $ make down
|
||||
|
|
Loading…
Reference in a new issue