acmesmith 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.dockerignore +6 -0
- data/.github/workflows/build.yml +123 -0
- data/.gitignore +0 -1
- data/CHANGELOG.md +35 -0
- data/Dockerfile +29 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +73 -0
- data/LICENSE.txt +1 -1
- data/README.md +71 -93
- data/acmesmith.gemspec +1 -1
- data/config.sample.yml +41 -2
- data/docs/challenge_responders/route53.md +28 -0
- data/docs/examples/UpdateWindowsCertificate.ps1 +58 -0
- data/docs/post_issuing_hooks/acm.md +16 -0
- data/docs/post_issuing_hooks/shell.md +17 -0
- data/docs/storages/filesystem.md +11 -0
- data/docs/storages/s3.md +32 -0
- data/lib/acmesmith/account_key.rb +12 -1
- data/lib/acmesmith/authorization_service.rb +175 -0
- data/lib/acmesmith/certificate.rb +42 -11
- data/lib/acmesmith/challenge_responder_filter.rb +23 -0
- data/lib/acmesmith/challenge_responders/base.rb +11 -2
- data/lib/acmesmith/challenge_responders/pebble_challtestsrv_dns.rb +53 -0
- data/lib/acmesmith/challenge_responders/route53.rb +13 -2
- data/lib/acmesmith/client.rb +13 -131
- data/lib/acmesmith/config.rb +23 -2
- data/lib/acmesmith/ordering_service.rb +104 -0
- data/lib/acmesmith/storages/base.rb +15 -0
- data/lib/acmesmith/storages/s3.rb +3 -3
- data/lib/acmesmith/version.rb +1 -1
- metadata +19 -6
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'acmesmith/authorization_service'
|
2
|
+
require 'acmesmith/certificate'
|
3
|
+
|
4
|
+
module Acmesmith
|
5
|
+
class OrderingService
|
6
|
+
class NotCompleted < StandardError; end
|
7
|
+
|
8
|
+
# @param acme [Acme::Client] ACME client
|
9
|
+
# @param identifiers [Array<String>] Array of domain names for a ordering certificate. The first item will be a common name.
|
10
|
+
# @param challenge_responder_rules [Array<Acmesmith::Config::ChallengeResponderRule>] responders
|
11
|
+
# @param not_before [Time]
|
12
|
+
# @param not_after [Time]
|
13
|
+
def initialize(acme:, identifiers:, challenge_responder_rules:, not_before: nil, not_after: nil)
|
14
|
+
@acme = acme
|
15
|
+
@identifiers = identifiers
|
16
|
+
@challenge_responder_rules = challenge_responder_rules
|
17
|
+
@not_before = not_before
|
18
|
+
@not_after = not_after
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :acme, :identifiers, :challenge_responder_rules, :not_before, :not_after
|
22
|
+
|
23
|
+
def perform!
|
24
|
+
puts "=> Ordering a certificate for the following identifiers:"
|
25
|
+
puts
|
26
|
+
puts " * CN: #{common_name}"
|
27
|
+
sans.each do |san|
|
28
|
+
puts " * SAN: #{san}"
|
29
|
+
end
|
30
|
+
|
31
|
+
puts
|
32
|
+
puts "=> Placing an order"
|
33
|
+
@order = acme.new_order(identifiers: identifiers, not_before: not_before, not_after: not_after)
|
34
|
+
puts " * URL: #{order.url}"
|
35
|
+
|
36
|
+
ensure_authorization()
|
37
|
+
|
38
|
+
finalize_order()
|
39
|
+
wait_order_for_complete()
|
40
|
+
|
41
|
+
@certificate = Certificate.by_issuance(order.certificate, csr)
|
42
|
+
|
43
|
+
puts
|
44
|
+
puts "=> Certificate issued"
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def ensure_authorization
|
49
|
+
return if order.authorizations.empty? || order.status == 'ready'
|
50
|
+
puts "=> Looking for required domain authorizations"
|
51
|
+
puts
|
52
|
+
order.authorizations.map(&:domain).each do |domain|
|
53
|
+
puts " * #{domain}"
|
54
|
+
end
|
55
|
+
puts
|
56
|
+
|
57
|
+
AuthorizationService.new(challenge_responder_rules, order.authorizations).perform!
|
58
|
+
end
|
59
|
+
|
60
|
+
def finalize_order
|
61
|
+
puts
|
62
|
+
puts "=> Finalizing the order"
|
63
|
+
puts
|
64
|
+
puts csr.csr.to_pem
|
65
|
+
puts
|
66
|
+
|
67
|
+
print " * Requesting..."
|
68
|
+
order.finalize(csr: csr)
|
69
|
+
puts" [ ok ]"
|
70
|
+
end
|
71
|
+
|
72
|
+
def wait_order_for_complete
|
73
|
+
while %w(ready processing).include?(order.status)
|
74
|
+
order.reload()
|
75
|
+
puts " * Waiting for complete: status=#{order.status}"
|
76
|
+
sleep 2
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def certificate
|
81
|
+
@certificate or raise NotCompleted, "not completed yet"
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return Acme::Client::Resources::Order[]
|
85
|
+
def order
|
86
|
+
@order or raise "BUG: order not yet generated"
|
87
|
+
end
|
88
|
+
|
89
|
+
# @return [String]
|
90
|
+
def common_name
|
91
|
+
identifiers.first
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [Array<String>]
|
95
|
+
def sans
|
96
|
+
identifiers[1..-1]
|
97
|
+
end
|
98
|
+
|
99
|
+
# @return [Acme::Client::CertificateRequest]
|
100
|
+
def csr
|
101
|
+
@csr ||= Acme::Client::CertificateRequest.new(subject: { common_name: common_name }, names: sans)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -7,30 +7,45 @@ module Acmesmith
|
|
7
7
|
def initialize()
|
8
8
|
end
|
9
9
|
|
10
|
+
# @return [Acmesmith::AccountKey]
|
10
11
|
def get_account_key
|
11
12
|
raise NotImplementedError
|
12
13
|
end
|
13
14
|
|
15
|
+
# @param key [Acmesmith::AccountKey]
|
16
|
+
# @param passphrase [String, nil]
|
14
17
|
def put_account_key(key, passphrase = nil)
|
15
18
|
raise NotImplementedError
|
16
19
|
end
|
17
20
|
|
21
|
+
# @param cert [Acmesmith::Certificate]
|
22
|
+
# @param passphrase [String, nil]
|
23
|
+
# @param update_current [true, false]
|
18
24
|
def put_certificate(cert, passphrase = nil, update_current: true)
|
19
25
|
raise NotImplementedError
|
20
26
|
end
|
21
27
|
|
28
|
+
# @param common_name [String]
|
29
|
+
# @param version [String, nil]
|
30
|
+
# @return [Acmesmith::Certificate]
|
22
31
|
def get_certificate(common_name, version: 'current')
|
23
32
|
raise NotImplementedError
|
24
33
|
end
|
25
34
|
|
35
|
+
# @param common_name [String]
|
36
|
+
# @return [String] array of common_names
|
26
37
|
def list_certificates
|
27
38
|
raise NotImplementedError
|
28
39
|
end
|
29
40
|
|
41
|
+
# @param common_name [String]
|
42
|
+
# @return [String] array of versions
|
30
43
|
def list_certificate_versions(common_name)
|
31
44
|
raise NotImplementedError
|
32
45
|
end
|
33
46
|
|
47
|
+
# @param common_name [String]
|
48
|
+
# @return [String] current version
|
34
49
|
def get_current_certificate_version(common_name)
|
35
50
|
raise NotImplementedError
|
36
51
|
end
|
@@ -23,7 +23,7 @@ module Acmesmith
|
|
23
23
|
@kms_key_id_account = kms_key_id_account
|
24
24
|
@kms_key_id_certificate_key = kms_key_id_certificate_key
|
25
25
|
|
26
|
-
@s3 = Aws::S3::Client.new({region: region
|
26
|
+
@s3 = Aws::S3::Client.new({region: region}.tap do |opt|
|
27
27
|
opt[:credentials] = Aws::Credentials.new(aws_access_key['access_key_id'], aws_access_key['secret_access_key'], aws_access_key['session_token']) if aws_access_key
|
28
28
|
end)
|
29
29
|
end
|
@@ -85,10 +85,10 @@ module Acmesmith
|
|
85
85
|
put.call certificate_key(cert.common_name, cert.version), "#{h[:certificate].rstrip}\n", false
|
86
86
|
put.call chain_key(cert.common_name, cert.version), "#{h[:chain].rstrip}\n", false
|
87
87
|
put.call fullchain_key(cert.common_name, cert.version), "#{h[:fullchain].rstrip}\n", false
|
88
|
-
put.call private_key_key(cert.common_name, cert.version), "#{h[:private_key].rstrip}\n",
|
88
|
+
put.call private_key_key(cert.common_name, cert.version), "#{h[:private_key].rstrip}\n", use_kms
|
89
89
|
|
90
90
|
if generate_pkcs12?(cert)
|
91
|
-
put.call pkcs12_key(cert.common_name, cert.version), "#{cert.pkcs12(@pkcs12_passphrase).to_der}\n",
|
91
|
+
put.call pkcs12_key(cert.common_name, cert.version), "#{cert.pkcs12(@pkcs12_passphrase).to_der}\n", use_kms, 'application/x-pkcs12'
|
92
92
|
end
|
93
93
|
|
94
94
|
if update_current
|
data/lib/acmesmith/version.rb
CHANGED
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: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Sorah Fukumori
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acme-client
|
@@ -127,7 +127,7 @@ description: 'Acmesmith is an [ACME (Automatic Certificate Management Environmen
|
|
127
127
|
certificate and keys on cloud services (e.g. AWS S3) securely, then allow to deploy
|
128
128
|
issued certificates onto your servers smoothly. This works well on [Let''s encrypt](https://letsencrypt.org).
|
129
129
|
|
130
|
-
'
|
130
|
+
'
|
131
131
|
email:
|
132
132
|
- her@sorah.jp
|
133
133
|
executables:
|
@@ -135,28 +135,42 @@ executables:
|
|
135
135
|
extensions: []
|
136
136
|
extra_rdoc_files: []
|
137
137
|
files:
|
138
|
+
- ".dockerignore"
|
139
|
+
- ".github/workflows/build.yml"
|
138
140
|
- ".gitignore"
|
139
141
|
- ".rspec"
|
140
142
|
- ".travis.yml"
|
141
143
|
- CHANGELOG.md
|
144
|
+
- Dockerfile
|
142
145
|
- Gemfile
|
146
|
+
- Gemfile.lock
|
143
147
|
- LICENSE.txt
|
144
148
|
- README.md
|
145
149
|
- Rakefile
|
146
150
|
- acmesmith.gemspec
|
147
151
|
- bin/acmesmith
|
148
152
|
- config.sample.yml
|
153
|
+
- docs/challenge_responders/route53.md
|
154
|
+
- docs/examples/UpdateWindowsCertificate.ps1
|
155
|
+
- docs/post_issuing_hooks/acm.md
|
156
|
+
- docs/post_issuing_hooks/shell.md
|
157
|
+
- docs/storages/filesystem.md
|
158
|
+
- docs/storages/s3.md
|
149
159
|
- docs/vendor/aws.md
|
150
160
|
- lib/acmesmith.rb
|
151
161
|
- lib/acmesmith/account_key.rb
|
162
|
+
- lib/acmesmith/authorization_service.rb
|
152
163
|
- lib/acmesmith/certificate.rb
|
164
|
+
- lib/acmesmith/challenge_responder_filter.rb
|
153
165
|
- lib/acmesmith/challenge_responders.rb
|
154
166
|
- lib/acmesmith/challenge_responders/base.rb
|
155
167
|
- lib/acmesmith/challenge_responders/manual_dns.rb
|
168
|
+
- lib/acmesmith/challenge_responders/pebble_challtestsrv_dns.rb
|
156
169
|
- lib/acmesmith/challenge_responders/route53.rb
|
157
170
|
- lib/acmesmith/client.rb
|
158
171
|
- lib/acmesmith/command.rb
|
159
172
|
- lib/acmesmith/config.rb
|
173
|
+
- lib/acmesmith/ordering_service.rb
|
160
174
|
- lib/acmesmith/post_issueing_hooks.rb
|
161
175
|
- lib/acmesmith/post_issueing_hooks/base.rb
|
162
176
|
- lib/acmesmith/post_issuing_hooks.rb
|
@@ -191,8 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
205
|
- !ruby/object:Gem::Version
|
192
206
|
version: '0'
|
193
207
|
requirements: []
|
194
|
-
|
195
|
-
rubygems_version: 2.7.7
|
208
|
+
rubygems_version: 3.1.2
|
196
209
|
signing_key:
|
197
210
|
specification_version: 4
|
198
211
|
summary: ACME client (Let's encrypt client) to manage certificate in multi server
|