From e8a66d85a70e7cdefe99fa260bd4149e640078b1 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Fri, 2 Nov 2018 18:55:13 -0700 Subject: [PATCH] Add examples using the bootstrap methods. --- examples/README.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++ examples/client.go | 39 ++++++++++++++++++++++++++ examples/server.go | 35 ++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 examples/README.md create mode 100644 examples/client.go create mode 100644 examples/server.go diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..90a5162b --- /dev/null +++ b/examples/README.md @@ -0,0 +1,68 @@ +# Example + +# Client & Server requests + +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. + +The examples directory already contains a sample pki configuration with the +password `password` hardcoded, but you can create your own using `step ca init`. + +First we will start the certificate authority: +``` +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 +provisioner password: +``` +certificates $ export STEPPATH=examples/pki +certificates $ export STEP_CA_URL=https://localhost:9000 +certificates $ go run examples/server.go $(step ca new-token localhost)) +✔ Key ID: DmAtZt2EhmZr_iTJJ387fr4Md2NbzMXGdXQNW1UWPXk (mariano@smallstep.com) +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: +``` +certificates $ curl https://localhost:8443 +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. +``` + +But if we use the root certificate it will properly work: +``` +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 +detected a TLS client configuration. + +But if we the client with the certificate name Mike we'll see: +``` +certificates $ export STEPPATH=examples/pki +certificates $ export STEP_CA_URL=https://localhost:9000 +certificates $ go run examples/client.go $(step ca new-token Mike) +✔ Key ID: DmAtZt2EhmZr_iTJJ387fr4Md2NbzMXGdXQNW1UWPXk (mariano@smallstep.com) +Please enter the password to decrypt the provisioner key: +Server responded: Hello Mike at 2018-11-03 01:52:52.678215 +0000 UTC!!! +Server responded: Hello Mike at 2018-11-03 01:52:53.681563 +0000 UTC!!! +Server responded: Hello Mike at 2018-11-03 01:52:54.682787 +0000 UTC!!! +... +``` \ No newline at end of file diff --git a/examples/client.go b/examples/client.go new file mode 100644 index 00000000..869484bd --- /dev/null +++ b/examples/client.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + "time" + + "github.com/smallstep/certificates/ca" +) + +func main() { + if len(os.Args) != 2 { + fmt.Fprintf(os.Stderr, "Usage: %s \n", os.Args[0]) + os.Exit(1) + } + + token := os.Args[1] + + client, err := ca.BootstrapClient(token) + if err != nil { + panic(err) + } + + for { + resp, err := client.Get("https://localhost:8443") + if err != nil { + panic(err) + } + b, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + panic(err) + } + + fmt.Printf("Server responded: %s\n", b) + time.Sleep(1 * time.Second) + } +} diff --git a/examples/server.go b/examples/server.go new file mode 100644 index 00000000..c48ca776 --- /dev/null +++ b/examples/server.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "net/http" + "os" + "time" + + "github.com/smallstep/certificates/ca" +) + +func main() { + if len(os.Args) != 2 { + fmt.Fprintf(os.Stderr, "Usage: %s \n", os.Args[0]) + os.Exit(1) + } + + token := os.Args[1] + + srv, err := ca.BootstrapServer(":8443", token, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + name := "nobody" + if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 { + name = r.TLS.PeerCertificates[0].Subject.CommonName + } + w.Write([]byte(fmt.Sprintf("Hello %s at %s!!!", name, time.Now().UTC()))) + })) + if err != nil { + panic(err) + } + + fmt.Println("Listening on :8443 ...") + if err := srv.ListenAndServeTLS("", ""); err != nil { + panic(err) + } +}