acmesmith 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4360b52e2ad9bae70d23e26155063d46e7590fbd
4
- data.tar.gz: 88e3f90208ec52d8e3509272d5bab71ee666472e
3
+ metadata.gz: f4eabbcb2bb88783d1b487344b1022f921968f2f
4
+ data.tar.gz: 2a664ea8940194eb01f951ebdddc3dd3cf81ec65
5
5
  SHA512:
6
- metadata.gz: 54a4e48a88bbc94b5972dc531c5a79be4824a9146834cd7b92aa376a74f877b4143aed3221dda9f7c150495eab168044090ad3cc01ee4b9a2e4fe3ace43c1ea9
7
- data.tar.gz: a43f52ebfe0b87a44f8fea7440506b8a46e930fd12fb6b8299f1316ad694cf5319b8e6cca8b14a493e8bb532a51c5281f8be5a25aa65f64e0acfa0e7d8a751b3
6
+ metadata.gz: 95858bf33cf374a349ec1ee5c45c5be68ee914294801a603151fcbe76b943a7c59918795cbfbee99b09597058c4b648240d6e66eec6ab8e0648c232eff66d054
7
+ data.tar.gz: dba846aad843896b668640663b0c67e15f5de36a706dbada70dfab566ef5883821828803f3bfc6bcc79f9440366ce20dad760ff2ebfa6e15d8f2b57007c489a9
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Acmesmith: An effective ACME client to operate on multiple servers environment with the cloud
1
+ # Acmesmith: A simple, effective ACME client to use with many servers and a cloud
2
2
 
3
3
  Acmesmith is an [ACME (Automatic Certificate Management Environment)](https://github.com/ietf-wg-acme/acme) client that works perfect on environment with multiple servers. This client saves certificate and keys on cloud services (e.g. AWS S3) securely, then allow to deploy issued certificates onto your servers smoothly. This works well on [Let's encrypt](https://letsencrypt.org).
4
4
 
5
- This tool is written in Ruby, but this saves certificates in simple scheme, so you can fetch certificate by your own simple scripts.
5
+ This tool is written in Ruby, but Acmesmith saves certificates in simple scheme, so you can fetch certificate by your own simple scripts.
6
6
 
7
7
  ## Features
8
8
 
@@ -13,6 +13,9 @@ This tool is written in Ruby, but this saves certificates in simple scheme, so y
13
13
  - Currently AWS S3 is supported
14
14
  - Challenge response
15
15
  - Currently `dns-01` with AWS Route 53 is supported
16
+ - Pluggable modules, you can use 3rd party one or write:
17
+ - Storages for other than AWS S3
18
+ - Challenge reponses for other than AWS Route53 or dns-01 challenges, like for Openstack DNSaaS.
16
19
 
17
20
  ### Planned
18
21
 
@@ -54,6 +57,7 @@ $ acmesmith show-certificate COMMON_NAME # show certificate
54
57
  $ acmesmith show-private-key COMMON_NAME # show private key
55
58
  $ acmesmith save-certificate COMMON_NAME --output=PATH # Save certificate to a file
56
59
  $ acmesmith save-private-key COMMON_NAME --output=PATH # Save private key to a file
60
+ $ acmesmith save-pkcs12 COMMON_NAME --output=PATH # Save certificate and private key to a PKCS12 file
57
61
  ```
58
62
 
59
63
  ```
@@ -137,114 +141,15 @@ challenge_responders:
137
141
  # "example.org.": "/hostedzone/DEADBEEF"
138
142
  ```
139
143
 
140
- ## Vendor dependent notes
144
+ ## 3rd party Plugins
141
145
 
142
- ### AWS
143
-
144
- #### IAM policy
145
-
146
- ##### All access (S3 + Route53 setup)
147
-
148
- ``` json
149
- {
150
- "Version": "2012-10-17",
151
- "Statement": [
152
- {
153
- "Effect": "Allow",
154
- "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
155
- "Resource": ["arn:aws:s3:::{BUCKET-NAME}", "arn:aws:s3:::{BUCKET-NAME}/*"]
156
- },
157
- {
158
- "Effect": "Allow",
159
- "Action": ["route53:ListHostedZones", "route53:GetChange"],
160
- "Resource": "*"
161
- },
162
- {
163
- "Effect": "Allow",
164
- "Action": "route53:ChangeResourceRecordSets",
165
- "Resource": ["arn:aws:route53:::hostedzone/*"]
166
- }
167
- ]
168
- }
169
- ```
146
+ ### Challenge responders
170
147
 
171
- Note: You can limit allowed hosted zone by modifying `Resource` of `route53:ChangeResourceRecordSets`
172
-
173
- ##### Only fetching certificates
174
-
175
- ``` json
176
- {
177
- "Version": "2012-10-17",
178
- "Statement": [
179
- {
180
- "Effect": "Allow",
181
- "Action": ["s3:GetObject"],
182
- "Resource": ["arn:aws:s3:::{BUCKET-NAME}/certs/*"]
183
- },
184
- {
185
- "Effect": "Allow",
186
- "Action": ["s3:ListBucket"],
187
- "Resource": ["arn:aws:s3:::{BUCKET-NAME}"],
188
- "Condition": {
189
- "StringEquals": {
190
- "s3:delimiter": "/"
191
- },
192
- "StringLike": {
193
- "s3:prefix": "certs/*",
194
- }
195
- }
196
- }
197
- ]
198
- }
199
- ```
148
+ - [hanazuki/acmesmith-designate](https://github.com/hanazuki/acmesmith-designate) `dns-01` challenge responder with OpenStack-based DNSaaS (Designate v1 API), e.g. for ConoHa.
200
149
 
201
- #### AWS KMS key policy for customer managed keys
202
-
203
- If you're going to use `aws_kms_id` option to use customer managed keys instead of AWS managed default KMS key for Amazon S3, use the following policy as base:
204
-
205
- Be sure to replace `{S3-REGION}` and `{YOUR-AWS-ACCOUNT-ID}` before applying it.
206
-
207
- ``` json
208
- {
209
- "Version": "2012-10-17",
210
- "Id": "kms-acmesmith-s3-policy",
211
- "Statement": [
212
- {
213
- "Effect": "Allow",
214
- "Principal": {
215
- "AWS": "*"
216
- },
217
- "Action": [
218
- "kms:Encrypt",
219
- "kms:Decrypt",
220
- "kms:ReEncrypt*",
221
- "kms:GenerateDataKey*",
222
- "kms:DescribeKey"
223
- ],
224
- "Resource": "*",
225
- "Condition": {
226
- "StringEquals": {
227
- "kms:ViaService": "s3.{S3-REGION}.amazonaws.com",
228
- "kms:CallerAccount": "{YOUR-AWS-ACCOUNT-ID}"
229
- }
230
- }
231
- },
232
- {
233
- "Effect": "Allow",
234
- "Principal": {
235
- "AWS": "arn:aws:iam::{YOUR-AWS-ACCOUNT-ID}:root"
236
- },
237
- "Action": [
238
- "kms:Describe*",
239
- "kms:Get*",
240
- "kms:List*",
241
- "kms:Put*"
242
- ],
243
- "Resource": "*"
244
- }
245
- ]
246
- }
247
- ```
150
+ ## Vendor dependent notes
151
+
152
+ - [./docs/vendor/aws.md](./docs/vendor/aws.md): IAM and KMS key policies, and some tips
248
153
 
249
154
  ## Development
250
155
 
@@ -0,0 +1,106 @@
1
+ #### IAM policy
2
+
3
+ ##### All access (S3 + Route53 setup)
4
+
5
+ ``` json
6
+ {
7
+ "Version": "2012-10-17",
8
+ "Statement": [
9
+ {
10
+ "Effect": "Allow",
11
+ "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
12
+ "Resource": ["arn:aws:s3:::{BUCKET-NAME}", "arn:aws:s3:::{BUCKET-NAME}/*"]
13
+ },
14
+ {
15
+ "Effect": "Allow",
16
+ "Action": ["route53:ListHostedZones", "route53:GetChange"],
17
+ "Resource": "*"
18
+ },
19
+ {
20
+ "Effect": "Allow",
21
+ "Action": "route53:ChangeResourceRecordSets",
22
+ "Resource": ["arn:aws:route53:::hostedzone/*"]
23
+ }
24
+ ]
25
+ }
26
+ ```
27
+
28
+ Note: You can limit allowed hosted zone by modifying `Resource` of `route53:ChangeResourceRecordSets`
29
+
30
+ ##### Only fetching certificates
31
+
32
+ ``` json
33
+ {
34
+ "Version": "2012-10-17",
35
+ "Statement": [
36
+ {
37
+ "Effect": "Allow",
38
+ "Action": ["s3:GetObject"],
39
+ "Resource": ["arn:aws:s3:::{BUCKET-NAME}/certs/*"]
40
+ },
41
+ {
42
+ "Effect": "Allow",
43
+ "Action": ["s3:ListBucket"],
44
+ "Resource": ["arn:aws:s3:::{BUCKET-NAME}"],
45
+ "Condition": {
46
+ "StringEquals": {
47
+ "s3:delimiter": "/"
48
+ },
49
+ "StringLike": {
50
+ "s3:prefix": "certs/*"
51
+ }
52
+ }
53
+ }
54
+ ]
55
+ }
56
+ ```
57
+
58
+ #### AWS KMS key policy for customer managed keys
59
+
60
+ If you're going to use `aws_kms_id` option to use customer managed keys instead of AWS managed default KMS key for Amazon S3, use the following policy as base:
61
+
62
+ Be sure to replace `{S3-REGION}` and `{YOUR-AWS-ACCOUNT-ID}` before applying it.
63
+
64
+ ``` json
65
+ {
66
+ "Version": "2012-10-17",
67
+ "Id": "kms-acmesmith-s3-policy",
68
+ "Statement": [
69
+ {
70
+ "Effect": "Allow",
71
+ "Principal": {
72
+ "AWS": "*"
73
+ },
74
+ "Action": [
75
+ "kms:Encrypt",
76
+ "kms:Decrypt",
77
+ "kms:ReEncrypt*",
78
+ "kms:GenerateDataKey*",
79
+ "kms:DescribeKey"
80
+ ],
81
+ "Resource": "*",
82
+ "Condition": {
83
+ "StringEquals": {
84
+ "kms:ViaService": "s3.{S3-REGION}.amazonaws.com",
85
+ "kms:CallerAccount": "{YOUR-AWS-ACCOUNT-ID}"
86
+ }
87
+ }
88
+ },
89
+ {
90
+ "Effect": "Allow",
91
+ "Principal": {
92
+ "AWS": "arn:aws:iam::{YOUR-AWS-ACCOUNT-ID}:root"
93
+ },
94
+ "Action": [
95
+ "kms:Describe*",
96
+ "kms:Get*",
97
+ "kms:List*",
98
+ "kms:Put*"
99
+ ],
100
+ "Resource": "*"
101
+ }
102
+ ]
103
+ }
104
+ ```
105
+
106
+
@@ -34,17 +34,23 @@ module Acmesmith
34
34
 
35
35
  responder.respond(domain, challenge)
36
36
 
37
- puts "=> Requesting verification..."
38
- challenge.request_verification
39
- loop do
40
- status = challenge.verify_status
41
- puts " * verify_status: #{status}"
42
- break if status == 'valid'
43
- sleep 3
37
+ begin
38
+ puts "=> Requesting verification..."
39
+ challenge.request_verification
40
+ loop do
41
+ status = challenge.verify_status
42
+ puts " * verify_status: #{status}"
43
+ break if status == 'valid'
44
+ if status == "invalid"
45
+ err = challenge.error
46
+ puts "#{err["type"]}: #{err["detail"]}"
47
+ end
48
+ sleep 3
49
+ end
50
+ puts "=> Done"
51
+ ensure
52
+ responder.cleanup(domain, challenge)
44
53
  end
45
-
46
- responder.cleanup(domain, challenge)
47
- puts "=> Done"
48
54
  end
49
55
 
50
56
  desc "request COMMON_NAME [SAN]", "request certificate for CN +COMMON_NAME+ with SANs +SAN+"
@@ -126,6 +132,28 @@ module Acmesmith
126
132
  end
127
133
  end
128
134
 
135
+ desc 'save-pkcs12 COMMON_NAME', 'Save ceriticate and private key to .p12 file'
136
+ method_option :version, type: :string, default: 'current'
137
+ method_option :output, type: :string, required: true, banner: 'PATH', desc: 'Path to output file'
138
+ method_option :mode, type: :string, default: '0600', desc: 'Mode (permission) of the output file on create'
139
+ def save_pkcs12(common_name)
140
+ cert = storage.get_certificate(common_name, version: options[:version])
141
+ cert.key_passphrase = certificate_key_passphrase if certificate_key_passphrase
142
+
143
+ print 'Passphrase: '
144
+ passphrase = $stdin.noecho { $stdin.gets }.chomp
145
+ print "\nPassphrase (confirm): "
146
+ passphrase2 = $stdin.noecho { $stdin.gets }.chomp
147
+ puts
148
+
149
+ raise ArgumentError, "Passphrase doesn't match" if passphrase != passphrase2
150
+
151
+ p12 = OpenSSL::PKCS12.create(passphrase, cert.common_name, cert.private_key, cert.certificate)
152
+ File.open(options[:output], 'w', options[:mode].to_i(8)) do |f|
153
+ f.puts p12.to_der
154
+ end
155
+ end
156
+
129
157
  desc "autorenew", "request renewal of certificates which expires soon"
130
158
  method_option :days, aliases: %w(-d), default: 7, desc: 'specify threshold in days to select certificates to renew'
131
159
  def autorenew
@@ -1,3 +1,3 @@
1
1
  module Acmesmith
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acmesmith
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sorah (Shota Fukumori)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-24 00:00:00.000000000 Z
11
+ date: 2016-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acme-client
@@ -117,6 +117,7 @@ files:
117
117
  - acmesmith.gemspec
118
118
  - bin/acmesmith
119
119
  - config.sample.yml
120
+ - docs/vendor/aws.md
120
121
  - lib/acmesmith.rb
121
122
  - lib/acmesmith/account_key.rb
122
123
  - lib/acmesmith/certificate.rb
@@ -153,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
154
  version: '0'
154
155
  requirements: []
155
156
  rubyforge_project:
156
- rubygems_version: 2.5.2
157
+ rubygems_version: 2.6.4
157
158
  signing_key:
158
159
  specification_version: 4
159
160
  summary: ACME client (Let's encrypt client) to manage certificate in multi server