From a2d3733929b75c2dca493ee5199945d9ad239cb3 Mon Sep 17 00:00:00 2001 From: max furman Date: Mon, 26 Nov 2018 21:00:12 -0500 Subject: [PATCH] Add a simplified puppet example with snippets --- examples/README.md | 29 +++++++++++++ examples/puppet/ca.json.erb | 58 ++++++++++++++++++++++++++ examples/puppet/defaults.json.erb | 4 ++ examples/puppet/step.pp | 56 ++++++++++++++++++++++++++ examples/puppet/step_ca.pp | 67 +++++++++++++++++++++++++++++++ examples/puppet/tls_server.pp | 24 +++++++++++ 6 files changed, 238 insertions(+) create mode 100644 examples/puppet/ca.json.erb create mode 100644 examples/puppet/defaults.json.erb create mode 100644 examples/puppet/step.pp create mode 100644 examples/puppet/step_ca.pp create mode 100644 examples/puppet/tls_server.pp diff --git a/examples/README.md b/examples/README.md index 6afa645b..4e47f3f8 100644 --- a/examples/README.md +++ b/examples/README.md @@ -450,3 +450,32 @@ Removing docker_renewer_1 ... done Removing docker_ca_1 ... done Removing network docker_default ``` + +## Configuration Management Tools + +Configuration management tools such as Puppet, Chef, Ansible, Salt, etc. make +automation and deployment a whole lot easier and more manageable. Step CLI and +CA are built with automation in mind and are easy to configure using your +favorite tools + +# Puppet + +The following are snippets and files that users can add to their puppet +manifests to easily instrument services with TLS. + +** [step.pp](./puppet/step.pp) ** - Install `step` from source and configure the `step` user, group, +and home directory for use by the Step CLI and CA. +** [step_ca.pp](./puppet/step_ca.pp) ** - Install `step-ca` from source. Configure +certificates and secrets and run the Step CA. +** [tls_server.pp](./puppet/tls_server.pp) ** - This is your service, instrumented +with the Step CA SDK to request, receive, and renew TLS certificates. See +[the bootstrap-tls-server](./bootstrap-tls-server/server.go) for a +simple integration example. + +**Note:** This is a significantly oversimplified example that will not work standalone. +A complete Puppet configuration should use a service manager (like +[systemctl](https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units)) +and a secret store (like [Hiera](https://puppet.com/docs/puppet/6.0/hiera_intro.html)). +If you are interested in seeing a more complete example please let us know and we'll +make one available. + diff --git a/examples/puppet/ca.json.erb b/examples/puppet/ca.json.erb new file mode 100644 index 00000000..18ae7e5b --- /dev/null +++ b/examples/puppet/ca.json.erb @@ -0,0 +1,58 @@ +{ + "root": "/usr/local/lib/step/.step/secrets/root_ca.crt", + "crt": "/usr/local/lib/step/.step/secrets/intermediate_ca.crt", + "key": "/usr/local/lib/step/.step/secrets/intermediate_ca_key", + "password": "password", + "address": ":9000", + "dnsNames": [ + "localhost" + ], + "logger": { + "format": "text" + }, + "authority": { + "provisioners": [ + { + "name": "mariano@smallstep.com", + "type": "jwk", + "key": { + "use": "sig", + "kty": "EC", + "kid": "DmAtZt2EhmZr_iTJJ387fr4Md2NbzMXGdXQNW1UWPXk", + "crv": "P-256", + "alg": "ES256", + "x": "jXoO1j4CXxoTC32pNzkVC8l6k2LfP0k5ndhJZmcdVbk", + "y": "c3JDL4GTFxJWHa8EaHdMh4QgwMh64P2_AGWrD0ADXcI" + }, + "encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiOTFVWjdzRGw3RlNXcldfX1I1NUh3USJ9.FcWtrBDNgrkA33G9Ll9sXh1cPF-3jVXeYe1FLmSDc_Q2PmfLOPvJOA.0ZoN32ayaRWnufJb.WrkffMmDLWiq1-2kn-w7-kVBGW12gjNCBHNHB1hyEdED0rWH1YWpKd8FjoOACdJyLhSn4kAS3Lw5AH7fvO27A48zzvoxZU5EgSm5HG9IjkIH-LBJ-v79ShkpmPylchgjkFhxa5epD11OIK4rFmI7s-0BCjmJokLR_DZBhDMw2khGnsr_MEOfAz9UnqXaQ4MIy8eT52xUpx68gpWFlz2YP3EqiYyNEv0PpjMtyP5lO2i8-p8BqvuJdus9H3fO5Dg-1KVto1wuqh4BQ2JKTauv60QAnM_4sdxRHku3F_nV64SCrZfDvnN2ve21raFROtyXaqHZhN6lyoPxDncy8v4.biaOblEe0N-gMpJyFZ-3-A" + }, + { + "name": "mike@smallstep.com", + "type": "jwk", + "key": { + "use": "sig", + "kty": "EC", + "kid": "YYNxZ0rq0WsT2MlqLCWvgme3jszkmt99KjoGEJJwAKs", + "crv": "P-256", + "alg": "ES256", + "x": "LsI8nHBflc-mrCbRqhl8d3hSl5sYuSM1AbXBmRfznyg", + "y": "F99LoOvi7z-ZkumsgoHIhodP8q9brXe4bhF3szK-c_w" + }, + "encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiVERQS2dzcEItTUR4ZDJxTGo0VlpwdyJ9.2_j0cZgTm2eFkZ-hrtr1hBIvLxN0w3TZhbX0Jrrq7vBMaywhgFcGTA.mCasZCbZJ-JT7vjA.bW052WDKSf_ueEXq1dyxLq0n3qXWRO-LXr7OzBLdUKWKSBGQrzqS5KJWqdUCPoMIHTqpwYvm-iD6uFlcxKBYxnsAG_hoq_V3icvvwNQQSd_q7Thxr2_KtPIDJWNuX1t5qXp11hkgb-8d5HO93CmN7xNDG89pzSUepT6RYXOZ483mP5fre9qzkfnrjx3oPROCnf3SnIVUvqk7fwfXuniNsg3NrNqncHYUQNReiq3e9I1R60w0ZQTvIReY7-zfiq7iPgVqmu5I7XGgFK4iBv0L7UOEora65b4hRWeLxg5t7OCfUqrS9yxAk8FdjFb9sEfjopWViPRepB0dYPH8dVI.fb6-7XWqp0j6CR9Li0NI-Q", + "claims": { + "minTLSCertDuration": "60s", + "defaultTLSCertDuration": "120s" + } + } + ] + }, + "tls": { + "cipherSuites": [ + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" + ], + "minVersion": 1.2, + "maxVersion": 1.2, + "renegotiation": false + } +} diff --git a/examples/puppet/defaults.json.erb b/examples/puppet/defaults.json.erb new file mode 100644 index 00000000..3f330782 --- /dev/null +++ b/examples/puppet/defaults.json.erb @@ -0,0 +1,4 @@ +{ + "ca-url": "ca.smallstep.com:8080", + "root": "/usr/local/lib/step/.step/secrets/root_ca.crt" +} diff --git a/examples/puppet/step.pp b/examples/puppet/step.pp new file mode 100644 index 00000000..f37a7156 --- /dev/null +++ b/examples/puppet/step.pp @@ -0,0 +1,56 @@ +# smallstep package configuration +class step( + $version = false, +) { + if !$version { + fail("class ${name}: version cannot be empty") + } + + $pkg = "step_${version}_linux_amd64.tar.gz" + $download_url = "https://github.com/smallstep/cli/releases/download/v${version}/step_${version}_linux_amd64.tar.gz" + $step_exec = '/opt/smallstep/bin/step' + + exec { + 'download/update smallstep': + command => "/usr/bin/curl --fail -o /tmp/${pkg} ${download_url} && /bin/tar -xzvf /tmp/${pkg} -C /opt", + unless => "/usr/bin/which ${step_exec} && ${step_exec} version | grep ${version}", + user => 'step', + require => File['/opt/smallstep']; + } + + file { + '/opt/smallstep': + ensure => directory, + mode => '0755', + owner => 'step'; + '/usr/local/lib/step': + ensure => directory, + mode => '0755', + owner => 'step'; + '/usr/local/lib/step/.step': + ensure => directory, + mode => '0755', + owner => 'step'; + '/usr/local/lib/step/.step/secrets': + ensure => directory, + mode => '0644', + owner => 'step'; + '/usr/local/lib/step/.step/config': + ensure => directory, + mode => '0755', + owner => 'step'; + } + + group { 'step': + ensure => present, + gid => $::step_id, + } + + user { 'step': + ensure => present, + gid => 'puppet', + home => '/usr/local/lib/step', + managehome => false, + uid => $::step_id, + } +} diff --git a/examples/puppet/step_ca.pp b/examples/puppet/step_ca.pp new file mode 100644 index 00000000..45c7bdd0 --- /dev/null +++ b/examples/puppet/step_ca.pp @@ -0,0 +1,67 @@ +# step_ca package configuration +class step_ca( + $version = false, +) { + if !$version { + fail("class ${name}: version cannot be empty") + } + + $pkg = "step_${version}_linux_amd64.tar.gz" + $download_url = "https://github.com/smallstep/certificates/releases/download/v${version}/step-certificates_${version}_linux_amd64.tar.gz" + $step_ca_exec = '/opt/smallstep/bin/step-ca' + + exec { + 'download/update smallstep': + command => "/usr/bin/curl --fail -o /tmp/${pkg} ${download_url} && /bin/tar -xzvf /tmp/${pkg} -C /opt", + unless => "/usr/bin/which ${step_exec} && ${step_exec} version | grep ${version}", + user => 'step', + require => File['/opt/smallstep']; + } + + file { + '/usr/local/lib/step/.step': + ensure => directory, + mode => '0755', + owner => 'step'; + '/usr/local/lib/step/.step/secrets': + ensure => directory, + mode => '0644', + owner => 'step'; + '/usr/local/lib/step/.step/secrets/root_ca.crt': # Get this from Hiera. + ensure => file, + mode => '0644', + owner => 'step'; + '/usr/local/lib/step/.step/secrets/intermediate_ca.crt': # Get this from Hiera. + ensure => file, + mode => '0644', + owner => 'step'; + '/usr/local/lib/step/.step/secrets/intermediate_ca_key': # Get this from Hiera. + ensure => file, + mode => '0644', + owner => 'step'; + '/usr/local/lib/step/.step/secrets/intermediate_pass': # Get this from Hiera. + ensure => file, + mode => '0644', + owner => 'step'; + '/usr/local/lib/step/.step/config': + ensure => directory, + mode => '0755', + owner => 'step'; + '/usr/local/lib/step/.step/config/ca.json': # Fill from template in repo. + ensure => file, + content => template('ca.json.erb'), + mode => '0755', + owner => 'step'; + '/usr/local/lib/step/.step/config/ca.json': # Fill from template in repo. + ensure => file, + content => template('defaults.json.erb'), + mode => '0755', + owner => 'step'; + } + + service { $name: + ensure => running, + start => "${step_ca_exec} /usr/local/lib/step/.step/config/ca.json --password-file /usr/local/lib/step/.step/secrets/intermediate_pass", + provider => 'systemd', + } +} diff --git a/examples/puppet/tls_server.pp b/examples/puppet/tls_server.pp new file mode 100644 index 00000000..554171eb --- /dev/null +++ b/examples/puppet/tls_server.pp @@ -0,0 +1,24 @@ +# step package configuration +class tls_server( + $version = false, +) { + if !$version { + fail("class ${name}: version cannot be empty") + } + + file { + '/usr/local/lib/step/.step/secrets/provisioner_pupppet_pass': # Get this from Hiera. + ensure => file, + mode => '0644', + owner => 'step'; + } + + $step = "/opt/smallstep/bin/step" + $step_path = "/usr/local/lib/step/.step" + $secrets = "${step_path}/usr/local/lib/step/.step" + service { $name: + ensure => running, + start => "/usr/local/bin/tls_server --token $(${step} token foo.com --ca-url=ca.smallstep.com --root=${secrets}/root_ca.crt --password-file=${secrets}/intermediate_pass)", + provider => 'systemd', + } +}