From baaff358185edff03274fd0d890ebe29699abc68 Mon Sep 17 00:00:00 2001 From: max furman Date: Wed, 14 Nov 2018 01:06:34 -0800 Subject: [PATCH] fix grammar in examples/README.md --- examples/README.md | 180 +++++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 86 deletions(-) diff --git a/examples/README.md b/examples/README.md index 857d6591..36a1f530 100644 --- a/examples/README.md +++ b/examples/README.md @@ -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 `-/3-rand(/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 ``` -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