autosign 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +2 -0
- data/Gemfile.lock +3 -1
- data/README.md +90 -0
- data/autosign.gemspec +1 -0
- data/features/autosign.feature +17 -12
- data/lib/autosign/config.rb +37 -23
- data/lib/autosign/decoder.rb +1 -1
- data/lib/autosign/token.rb +2 -2
- data/lib/autosign/validator.rb +4 -0
- data/lib/autosign/validators/jwt.rb +1 -1
- data/lib/autosign/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YTQ1YWExMWZhOTA2OGYzN2NmODBjOGRhNjAxY2NkMTdhZDQ4ZTliNQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDNlZmY2YjcxMDY0ODZjMDM0ZDFkNzNhNGI5Zjk0NDMxZDgxMTc3Yw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NTlkZDVhZDY3OWE5Mzk4YmQyMjVjYzg0OTI1Y2U3ZDU3ZjJkYjYzOTIzZDQz
|
10
|
+
Mzg2NjI0MGVkNDA2ZTcwMTk3MjNhODIyZjU0NzMxNGU0MDIyY2VmMDkyOWI3
|
11
|
+
MDI4OTE2OTg5NWMwYTM2NjdkMTYyN2JlZGRmZDY1YjY4NjY3ZDk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YWI5ZTQzNzljNGU3NWUzMjJmMmU2ZTM1OTlkNWEwZjhjNzBjYTI5MWExZmIx
|
14
|
+
NWUxNjg0N2ZjMTE2ZTIxNTM5ZDBlNGQxOTkxYjZlMWVhYjQ2YjcyOGFlNjBj
|
15
|
+
MThhYmY2MmVjYWE0ZmNkMDJiMDM2ZTlkNzQxNTYyNzcxYmE3M2U=
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
autosign (0.0.
|
4
|
+
autosign (0.0.8)
|
5
5
|
deep_merge (~> 1)
|
6
6
|
gli (~> 2)
|
7
7
|
iniparse (~> 1)
|
@@ -9,6 +9,7 @@ PATH
|
|
9
9
|
jwt (~> 1)
|
10
10
|
logging (~> 2)
|
11
11
|
require_all (~> 1)
|
12
|
+
safe_yaml (~> 1)
|
12
13
|
yard (~> 0.8)
|
13
14
|
|
14
15
|
GEM
|
@@ -91,6 +92,7 @@ GEM
|
|
91
92
|
diff-lcs (>= 1.2.0, < 2.0)
|
92
93
|
rspec-support (~> 3.3.0)
|
93
94
|
rspec-support (3.3.0)
|
95
|
+
safe_yaml (1.0.4)
|
94
96
|
simplecov (0.10.0)
|
95
97
|
docile (~> 1.1.0)
|
96
98
|
json (~> 1.8)
|
data/README.md
CHANGED
@@ -6,3 +6,93 @@ Tooling to make puppet autosigning easy, secure, and extensible
|
|
6
6
|
### Introduction
|
7
7
|
|
8
8
|
This tool provides a CLI for performing puppet policy-based autosigning using JWT tokens. Read more at https://danieldreier.github.io/autosign.
|
9
|
+
|
10
|
+
### Quick Start: How to Generate Tokens
|
11
|
+
|
12
|
+
##### 1. Install Gem on Puppet Master
|
13
|
+
```shell
|
14
|
+
gem install autosign
|
15
|
+
```
|
16
|
+
|
17
|
+
##### 2. Generate default configuration
|
18
|
+
|
19
|
+
```shell
|
20
|
+
autosign config setup
|
21
|
+
```
|
22
|
+
|
23
|
+
##### 3. Generate your first autosign token on the puppet master
|
24
|
+
```shell
|
25
|
+
autosign generate foo.example.com
|
26
|
+
```
|
27
|
+
|
28
|
+
The output will look something like
|
29
|
+
```
|
30
|
+
Autosign token for: foo.example.com, valid until: 2015-07-16 16:25:50 -0700
|
31
|
+
To use the token, put the following in ${puppet_confdir}/csr_attributes.yaml prior to running puppet agent for the first time:
|
32
|
+
|
33
|
+
custom_attributes:
|
34
|
+
challengePassword: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJkYXRhIjoie1wiY2VydG5hbWVcIjpcImZvby5leGFtcGxlLmNvbVwiLFwicmVxdWVzdGVyXCI6XCJEYW5pZWxzLU1hY0Jvb2stUHJvLTIubG9jYWxcIixcInJldXNhYmxlXCI6ZmFsc2UsXCJ2YWxpZGZvclwiOjcyMDAsXCJ1dWlkXCI6XCJkM2YyNzI0OC1jZDFmLTRhZmItYjI0MC02ZjBjMDU4NWJiZDNcIn0iLCJleHAiOiIxNDM3MDg5MTUwIn0.lC-EzWaV2dL81aLL7P-9mGwNbiOQDJWcoYjuSHVOqmaLtc7Wis5OZvHFOLln2Fn9qv98oSTnZsIkjmFpbI5dvA"
|
35
|
+
```
|
36
|
+
|
37
|
+
The resulting output can be copied to `/etc/puppet/csr_attributes.yaml` on an agent machine prior to running puppet for the first time to add the token to the CSR as the `challengePassword` OID. (just copy-paste from one terminal to another to copy the text)
|
38
|
+
|
39
|
+
### Quick Start: Puppet Master Configuration
|
40
|
+
|
41
|
+
Run through the previous quick start steps to get the gem installed, then configure puppet to use the `autosign-validator` executable as the policy autosign command:
|
42
|
+
|
43
|
+
##### 1. Prerequisities
|
44
|
+
Note that these settings will be slightly different if you're running Puppet Enterprise, because you'll need to use the `pe-puppet` user instead of `puppet`.
|
45
|
+
|
46
|
+
```shell
|
47
|
+
mkdir /var/autosign
|
48
|
+
chown puppet:puppet /var/autosign
|
49
|
+
chmod 750 /var/autosign
|
50
|
+
touch /var/log/autosign.log
|
51
|
+
chown puppet:puppet /var/log/autosign.log
|
52
|
+
```
|
53
|
+
|
54
|
+
|
55
|
+
##### 2. Configure master
|
56
|
+
```shell
|
57
|
+
puppet config set autosign $(which autosign-validator) --section master
|
58
|
+
```
|
59
|
+
|
60
|
+
Your master is now configured to autosign using the autosign gem.
|
61
|
+
|
62
|
+
|
63
|
+
##### 3. Using Legacy Autosign Scripts
|
64
|
+
|
65
|
+
If you already had an autosign script you want to continue using, add a setting to your `autosign.conf` like:
|
66
|
+
|
67
|
+
```yaml
|
68
|
+
multiplexer:
|
69
|
+
external_policy_executable: "/path/to/autosign/executable"
|
70
|
+
```
|
71
|
+
|
72
|
+
The master will validate the certificate if either the token validator or the external validator succeeds.
|
73
|
+
|
74
|
+
If the autosign script was just validating simple strings, you can use the `password_list` validator instead. For example, to configure the master to sign any CSR that includes the challenge passwords of "hunter2" or "CPE1704TKS" you would add:
|
75
|
+
|
76
|
+
```ini
|
77
|
+
password_list:
|
78
|
+
password: "hunter2"
|
79
|
+
password: "CPE1704TKS"
|
80
|
+
```
|
81
|
+
|
82
|
+
Note that this is a relatively insecure way to do certificate autosigning. Using one-time tokens via the `autosign generate` command is more secure. This functionality is provided to grandfather in existing use cases to ease the transition.
|
83
|
+
|
84
|
+
|
85
|
+
### Troubleshooting
|
86
|
+
If you're having problems, try the following:
|
87
|
+
|
88
|
+
- Set `loglevel: "debug"` in `/etc/autosign.conf`
|
89
|
+
- Check the `journalfile`, in `/var/autosign/autosign.journal` by default, to see if the one-time token's UUID has already been recorded. It's just YAML, so you can either delete it or remove the offending entry if you actually want to re-use a token.
|
90
|
+
- you can manually trigger the autosigning script with something like `cat the_csr.csr | autosign-validator certname.example.com`
|
91
|
+
- If you run the puppet master foregrounded, you'll see quite a bit of autosign script output if autosign loglevel is set to debug.
|
92
|
+
|
93
|
+
|
94
|
+
### Further Reading
|
95
|
+
|
96
|
+
- [https://danieldreier.github.io/autosign](https://danieldreier.github.io/autosign) has background on why this exists.
|
97
|
+
- Automatically generated code documentation in YARDOC format is [available on rubydoc.info](http://rubydoc.info/github/danieldreier/autosign).
|
98
|
+
- Look at the [puppet-autosign](https://travis-ci.org/danieldreier/puppet-autosign) puppet module to automate setup of this tool, and for a puppet function to generate tokens inside of Puppet, for example when provisioning systems in AWS.
|
data/autosign.gemspec
CHANGED
data/features/autosign.feature
CHANGED
@@ -8,9 +8,10 @@ Feature: Generate autosign key
|
|
8
8
|
And a hostname of "foo.example.com"
|
9
9
|
And a file named "autosign.conf" with:
|
10
10
|
"""
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
---
|
12
|
+
jwt_token:
|
13
|
+
validity: '7200'
|
14
|
+
secret: 'secret'
|
14
15
|
"""
|
15
16
|
When I run `chmod 600 autosign.conf`
|
16
17
|
And I run `autosign --config autosign.conf generate foo.example.com`
|
@@ -23,9 +24,10 @@ Feature: Generate autosign key
|
|
23
24
|
And a hostname of "foo.example.com"
|
24
25
|
And a file named "autosign.conf" with:
|
25
26
|
"""
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
---
|
28
|
+
jwt_token:
|
29
|
+
validity: '7200'
|
30
|
+
secret: 'secret'
|
29
31
|
"""
|
30
32
|
When I run `chmod 600 autosign.conf`
|
31
33
|
When I run `autosign --config autosign.conf generate foo.example.com --reusable`
|
@@ -38,8 +40,9 @@ Feature: Generate autosign key
|
|
38
40
|
And a hostname of "foo.example.com"
|
39
41
|
And a file named "autosign.conf" with:
|
40
42
|
"""
|
41
|
-
|
42
|
-
|
43
|
+
---
|
44
|
+
jwt_token:
|
45
|
+
secret: 'secret'
|
43
46
|
"""
|
44
47
|
When I run `chmod 600 autosign.conf`
|
45
48
|
When I run `autosign --config autosign.conf validate --certname "foo.example.com" "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJkYXRhIjoie1wiY2VydG5hbWVcIjpcImZvby5leGFtcGxlLmNvbVwiLFwicmVxdWVzdGVyXCI6XCJEYW5pZWxzLU1hY0Jvb2stUHJvLTIubG9jYWxcIixcInJldXNhYmxlXCI6ZmFsc2UsXCJ2YWxpZGZvclwiOjI5OTk5OTk5OSxcInV1aWRcIjpcIjlkYTA0Yzc4LWQ5NjUtNDk2OC04MWNjLWVhM2RjZDllZjVjMFwifSIsImV4cCI6IjE3MzY0NjYxMzAifQ.PJwY8rIunVyWi_lw0ypFclME0jx3Vd9xJIQSyhN3VUmul3V8u4Tp9XwDgoAu9DVV0-WEG2Tfxs6F8R6Fn71Ndg"`
|
@@ -51,8 +54,9 @@ Feature: Generate autosign key
|
|
51
54
|
And a hostname of "foo.example.com"
|
52
55
|
And a file named "autosign.conf" with:
|
53
56
|
"""
|
54
|
-
|
55
|
-
|
57
|
+
---
|
58
|
+
jwt_token:
|
59
|
+
secret: 'secret'
|
56
60
|
"""
|
57
61
|
When I run `chmod 600 autosign.conf`
|
58
62
|
When I run `autosign --config autosign.conf validate --certname "foo.example.com" "invalid_token"`
|
@@ -63,8 +67,9 @@ Feature: Generate autosign key
|
|
63
67
|
And a hostname of "foo.example.com"
|
64
68
|
And a file named "autosign.conf" with:
|
65
69
|
"""
|
66
|
-
|
67
|
-
|
70
|
+
---
|
71
|
+
jwt_token:
|
72
|
+
secret: 'secret'
|
68
73
|
"""
|
69
74
|
When I run `chmod 600 autosign.conf`
|
70
75
|
When I run `autosign --config autosign.conf validate --certname "foo.example.com" "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJkYXRhIjoie1wiY2VydG5hbWVcIjpcImZvby5leGFtcGxlLmNvbVwiLFwicmVxdWVzdGVyXCI6XCJEYW5pZWxzLU1hY0Jvb2stUHJvLTIubG9jYWxcIixcInJldXNhYmxlXCI6ZmFsc2UsXCJ2YWxpZGZvclwiOjEsXCJ1dWlkXCI6XCJlNjI1Y2I1Ny02NzY5LTQwMzQtODNiZS0zNzkxNmQ5YmMxMDRcIn0iLCJleHAiOiIxNDM2NDY2MzAyIn0.UXEDEbRqEWx5SdSpQjfowU56JubY5Yz2QN6cckby2es-g2P_n2lyAS6AwFeliBXyCDyVUelIT3g1QP4TdB9EEA"`
|
data/lib/autosign/config.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
require 'iniparse'
|
2
1
|
require 'rbconfig'
|
3
2
|
require 'securerandom'
|
4
3
|
require 'deep_merge'
|
4
|
+
require 'yaml'
|
5
|
+
require 'safe_yaml'
|
5
6
|
|
6
7
|
module Autosign
|
7
8
|
# Exceptions namespace for Autosign class
|
@@ -38,7 +39,7 @@ module Autosign
|
|
38
39
|
# set up logging
|
39
40
|
@log = Logging.logger['Autosign::Config']
|
40
41
|
@log.debug "initializing Autosign::Config"
|
41
|
-
|
42
|
+
SafeYAML::OPTIONS[:default_mode] = :safe
|
42
43
|
# validate parameter
|
43
44
|
raise 'settings is not a hash' unless settings_param.is_a?(Hash)
|
44
45
|
|
@@ -101,7 +102,8 @@ module Autosign
|
|
101
102
|
if File.file?(file)
|
102
103
|
@log.debug "Reading config file from: " + file
|
103
104
|
config_file = File.read(file)
|
104
|
-
parsed_config_file =
|
105
|
+
parsed_config_file = YAML.safe_load(config_file)
|
106
|
+
#parsed_config_file = IniParse.parse(config_file).to_hash
|
105
107
|
@log.debug "configuration read from config file: " + parsed_config_file.to_s
|
106
108
|
return parsed_config_file if parsed_config_file.is_a?(Hash)
|
107
109
|
else
|
@@ -161,27 +163,39 @@ module Autosign
|
|
161
163
|
end
|
162
164
|
)
|
163
165
|
|
164
|
-
config =
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
166
|
+
config = {
|
167
|
+
'general' => {
|
168
|
+
'loglevel' => 'warn',
|
169
|
+
'logfile' => os_defaults['logpath']
|
170
|
+
},
|
171
|
+
'jwt_token' => {
|
172
|
+
'secret' => SecureRandom.base64(20),
|
173
|
+
'validity' => '7200',
|
174
|
+
'journalfile' => os_defaults['journalfile']
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
# config = IniParse.gen do |doc|
|
179
|
+
# doc.section("general") do |general|
|
180
|
+
# general.option("loglevel", "warn")
|
181
|
+
# general.option("logfile", os_defaults['logpath'])
|
182
|
+
# end
|
183
|
+
# doc.section("jwt_token") do |jwt_token|
|
184
|
+
# jwt_token.option("secret", SecureRandom.base64(15))
|
185
|
+
# jwt_token.option("validity", 7200)
|
186
|
+
# jwt_token.option("journalfile", os_defaults['journalfile'])
|
187
|
+
# end
|
188
|
+
# doc.section("multiplexer") do |jwt_token|
|
189
|
+
# jwt_token.option(";external_policy_executable", '/usr/local/bin/some_autosign_executable')
|
190
|
+
# jwt_token.option(";external_policy_executable", '/usr/local/bin/another_autosign_executable')
|
191
|
+
# end
|
192
|
+
# doc.section("password_list") do |jwt_token|
|
193
|
+
# jwt_token.option(";password", 'static_autosign_password_here')
|
194
|
+
# jwt_token.option(";password", 'another_static_autosign_password')
|
195
|
+
# end
|
196
|
+
# end.to_ini
|
183
197
|
raise Autosign::Exceptions::Error, "file #{os_defaults['confpath']} already exists, aborting" if File.file?(os_defaults['confpath'])
|
184
|
-
return os_defaults['confpath'] if File.write(os_defaults['confpath'], config)
|
198
|
+
return os_defaults['confpath'] if File.write(os_defaults['confpath'], config.to_yaml)
|
185
199
|
end
|
186
200
|
end
|
187
201
|
end
|
data/lib/autosign/decoder.rb
CHANGED
@@ -23,7 +23,7 @@ module Autosign
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# extract challenge password
|
26
|
-
challenge_password = csr.attributes.select { |a| a.oid == 'challengePassword' }.first.value.value.first.value
|
26
|
+
challenge_password = csr.attributes.select { |a| a.oid == 'challengePassword' }.first.value.value.first.value.to_s
|
27
27
|
|
28
28
|
# extract common name
|
29
29
|
common_name = /^\/CN=(\S*)$/.match(csr.subject.to_s)[1]
|
data/lib/autosign/token.rb
CHANGED
@@ -106,7 +106,7 @@ module Autosign
|
|
106
106
|
|
107
107
|
# check if the token is reusable or a one-time use token
|
108
108
|
# @return [True, False] return true if the token can be used multiple times, false if the token can only be used once
|
109
|
-
def reusable
|
109
|
+
def reusable?
|
110
110
|
!!@reusable
|
111
111
|
end
|
112
112
|
|
@@ -116,7 +116,7 @@ module Autosign
|
|
116
116
|
{
|
117
117
|
"certname" => certname,
|
118
118
|
"requester" => requester,
|
119
|
-
"reusable" => reusable
|
119
|
+
"reusable" => reusable?,
|
120
120
|
"validfor" => validfor,
|
121
121
|
"uuid" => uuid
|
122
122
|
}
|
data/lib/autosign/validator.rb
CHANGED
@@ -132,6 +132,10 @@ module Autosign
|
|
132
132
|
true
|
133
133
|
end
|
134
134
|
|
135
|
+
# Find other classes that inherit from this class.
|
136
|
+
# Used to discover autosign validators. There is probably no reason to use
|
137
|
+
# this directly.
|
138
|
+
# @return [Array] of classes inheriting from Autosign::Validator
|
135
139
|
def self.descendants
|
136
140
|
ObjectSpace.each_object(Class).select { |klass| klass < self }
|
137
141
|
end
|
data/lib/autosign/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autosign
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Your Name Here
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -220,6 +220,20 @@ dependencies:
|
|
220
220
|
- - ~>
|
221
221
|
- !ruby/object:Gem::Version
|
222
222
|
version: '0.8'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: safe_yaml
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ~>
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '1'
|
230
|
+
type: :runtime
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ~>
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '1'
|
223
237
|
description:
|
224
238
|
email: your@email.address.com
|
225
239
|
executables:
|