rails-letsencrypt 0.10.1 → 0.11.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/README.md +14 -4
- data/app/controllers/lets_encrypt/verifications_controller.rb +2 -1
- data/app/jobs/lets_encrypt/renew_certificates_job.rb +1 -0
- data/app/models/concerns/lets_encrypt/certificate_issuable.rb +5 -3
- data/app/models/concerns/lets_encrypt/certificate_verifiable.rb +3 -3
- data/app/models/lets_encrypt/certificate.rb +5 -3
- data/lib/generators/lets_encrypt/install_generator.rb +1 -1
- data/lib/generators/lets_encrypt/register_generator.rb +3 -5
- data/lib/letsencrypt/logger_proxy.rb +2 -2
- data/lib/letsencrypt/redis.rb +2 -0
- data/lib/letsencrypt/version.rb +1 -1
- data/lib/letsencrypt.rb +5 -4
- data/lib/tasks/letsencrypt_tasks.rake +1 -1
- metadata +53 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1831382c1a2c8970e928bb47c8760bdf4e58b11c6d0944465cf781be3d91f8c5
|
4
|
+
data.tar.gz: 77a91de46a8a4b0b1b8f49789b1eb390bafb1245347f30a6598f0176398da64d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb4e008a900c46946cbe3a2077deb110c13115c0ba1b64246e376d63f54b3913f81bda6fec525ad031c78be67e6bfb58a47d25153ea3b5695a6a19f1ee52fb22
|
7
|
+
data.tar.gz: 34740983c6aa421bf5bf7bdc703ddfc77ff5b4ceba1277ef3c9568d11dca3049a278e0d5204d4b34049d8d35d216bd7a6a05d19506ff257328dff9276359ea72
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
# LetsEncrypt [](https://badge.fury.io/rb/rails-letsencrypt) [](https://badge.fury.io/rb/rails-letsencrypt) [](https://codeclimate.com/github/elct9620/rails-letsencrypt)
|
2
2
|
|
3
3
|
Provide manageable Let's Encrypt Certificate for Rails.
|
4
4
|
|
5
5
|
## Requirement
|
6
6
|
|
7
|
-
* Rails
|
8
|
-
* Ruby 2.
|
7
|
+
* Rails 6.1+
|
8
|
+
* Ruby 2.7+
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -22,7 +22,7 @@ rails generate lets_encrypt:install
|
|
22
22
|
rake db:migrate
|
23
23
|
```
|
24
24
|
|
25
|
-
Setup private key for Let's Encrypt API
|
25
|
+
Setup private key for Let's Encrypt API, and create an account at letsencrypt.org associated with that key
|
26
26
|
|
27
27
|
```bash
|
28
28
|
rails generate lets_encrypt:register
|
@@ -140,6 +140,16 @@ If you are using Sidekiq or others, you can enqueue renew task daily.
|
|
140
140
|
LetsEncrypt::RenewCertificatesJob.perform_later
|
141
141
|
```
|
142
142
|
|
143
|
+
### Subscribe
|
144
|
+
|
145
|
+
When the certificate is trying to issue a new one, you can subscribe it for logging or error handling.
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
ActiveSupport::Notifications.subscribe('letsencrypt.issue') do |name, start, finish, id, payload|
|
149
|
+
Rails.logger.info("Certificate for #{payload[:domain]} is issued")
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
143
153
|
### ngx_mruby
|
144
154
|
|
145
155
|
The setup is following this [Article](http://hb.matsumoto-r.jp/entry/2017/03/23/173236)
|
@@ -7,7 +7,8 @@ module LetsEncrypt
|
|
7
7
|
class VerificationsController < ApplicationController
|
8
8
|
def show
|
9
9
|
return render_verification_string if certificate.present?
|
10
|
-
|
10
|
+
|
11
|
+
render plain: 'Verification not found', status: :not_found
|
11
12
|
end
|
12
13
|
|
13
14
|
protected
|
@@ -9,9 +9,7 @@ module LetsEncrypt
|
|
9
9
|
def issue
|
10
10
|
logger.info "Getting certificate for #{domain}"
|
11
11
|
create_certificate
|
12
|
-
# rubocop:disable Metrics/LineLength
|
13
12
|
logger.info "Certificate issued for #{domain} (expires on #{expires_at}, will renew after #{renew_after})"
|
14
|
-
# rubocop:enable Metrics/LineLength
|
15
13
|
true
|
16
14
|
end
|
17
15
|
|
@@ -30,12 +28,16 @@ module LetsEncrypt
|
|
30
28
|
order.finalize(csr: csr)
|
31
29
|
sleep 1 while order.status == 'processing'
|
32
30
|
fullchain = order.certificate.split("\n\n")
|
31
|
+
assign_new_certificate(fullchain)
|
32
|
+
save!
|
33
|
+
end
|
34
|
+
|
35
|
+
def assign_new_certificate(fullchain)
|
33
36
|
cert = OpenSSL::X509::Certificate.new(fullchain.shift)
|
34
37
|
self.certificate = cert.to_pem
|
35
38
|
self.intermediaries = fullchain.join("\n\n")
|
36
39
|
self.expires_at = cert.not_after
|
37
40
|
self.renew_after = (expires_at - 1.month) + rand(10).days
|
38
|
-
save!
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
@@ -52,16 +52,16 @@ module LetsEncrypt
|
|
52
52
|
true
|
53
53
|
end
|
54
54
|
|
55
|
-
def retry_on_verify_error(
|
55
|
+
def retry_on_verify_error(error)
|
56
56
|
@retries ||= 0
|
57
|
-
if
|
57
|
+
if error.is_a?(Acme::Client::Error::BadNonce) && @retries < 5
|
58
58
|
@retries += 1
|
59
59
|
logger.info "#{domain}: Bad nounce encountered. Retrying (#{@retries} of 5 attempts)"
|
60
60
|
sleep 1
|
61
61
|
verify
|
62
62
|
else
|
63
63
|
logger.info "#{domain}: Error: #{e.class} (#{e.message})"
|
64
|
-
|
64
|
+
false
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
@@ -22,7 +22,7 @@ module LetsEncrypt
|
|
22
22
|
# index_letsencrypt_certificates_on_domain (domain)
|
23
23
|
# index_letsencrypt_certificates_on_renew_after (renew_after)
|
24
24
|
#
|
25
|
-
class Certificate <
|
25
|
+
class Certificate < ApplicationRecord
|
26
26
|
include CertificateVerifiable
|
27
27
|
include CertificateIssuable
|
28
28
|
|
@@ -33,8 +33,8 @@ module LetsEncrypt
|
|
33
33
|
scope :expired, -> { where('expires_at <= ?', Time.zone.now) }
|
34
34
|
|
35
35
|
before_create -> { self.key = OpenSSL::PKey::RSA.new(4096).to_s }
|
36
|
-
after_save -> { save_to_redis }, if: -> { LetsEncrypt.config.use_redis? && active? }
|
37
36
|
after_destroy -> { delete_from_redis }, if: -> { LetsEncrypt.config.use_redis? && active? }
|
37
|
+
after_save -> { save_to_redis }, if: -> { LetsEncrypt.config.use_redis? && active? }
|
38
38
|
|
39
39
|
# Returns false if certificate is not issued.
|
40
40
|
#
|
@@ -51,7 +51,9 @@ module LetsEncrypt
|
|
51
51
|
|
52
52
|
# Returns true if success get a new certificate
|
53
53
|
def get
|
54
|
-
|
54
|
+
ActiveSupport::Notifications.instrument('letsencrypt.issue', domain: domain) do
|
55
|
+
verify && issue
|
56
|
+
end
|
55
57
|
end
|
56
58
|
|
57
59
|
alias renew get
|
@@ -10,7 +10,7 @@ module LetsEncrypt
|
|
10
10
|
class InstallGenerator < ::Rails::Generators::Base
|
11
11
|
include ::Rails::Generators::Migration
|
12
12
|
|
13
|
-
source_root File.expand_path('
|
13
|
+
source_root File.expand_path('templates', __dir__)
|
14
14
|
|
15
15
|
def self.next_migration_number(path)
|
16
16
|
ActiveRecord::Generators::Base.next_migration_number(path)
|
@@ -26,26 +26,24 @@ module LetsEncrypt
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def generate_key
|
29
|
-
# rubocop:disable Metrics/LineLength
|
30
29
|
key_path = ask("Where you to save private key [#{LetsEncrypt.private_key_path}]:", path: true)
|
31
|
-
# rubocop:enable Metrics/LineLength
|
32
30
|
key_path = LetsEncrypt.private_key_path if key_path.blank?
|
33
31
|
|
34
32
|
return unless file_collision(key_path)
|
35
|
-
|
33
|
+
|
34
|
+
FileUtils.rm_f(key_path)
|
36
35
|
LetsEncrypt.config.use_env_key = false
|
37
36
|
LetsEncrypt.config.private_key_path = key_path
|
38
37
|
|
39
38
|
LetsEncrypt.load_private_key
|
40
39
|
|
41
|
-
# rubocop:disable Metrics/LineLength
|
42
40
|
say "Your privated key is saved in #{key_path}, make sure setup configure for your rails.", :yellow
|
43
|
-
# rubocop:enable Metrics/LineLength
|
44
41
|
end
|
45
42
|
|
46
43
|
def register_email
|
47
44
|
email = ask('What email you want to register:')
|
48
45
|
return say('Email is inavlid!', :red) if email.blank?
|
46
|
+
|
49
47
|
LetsEncrypt.register(email)
|
50
48
|
say 'Register successed, don\'t forget backup your private key', :green
|
51
49
|
end
|
@@ -15,10 +15,10 @@ module LetsEncrypt
|
|
15
15
|
@tags = @tags.uniq
|
16
16
|
end
|
17
17
|
|
18
|
-
def tag(logger)
|
18
|
+
def tag(logger, &block)
|
19
19
|
if logger.respond_to?(:tagged)
|
20
20
|
current_tags = tags - logger.formatter.current_tags
|
21
|
-
logger.tagged(*current_tags)
|
21
|
+
logger.tagged(*current_tags, &block)
|
22
22
|
else
|
23
23
|
yield
|
24
24
|
end
|
data/lib/letsencrypt/redis.rb
CHANGED
@@ -11,6 +11,7 @@ module LetsEncrypt
|
|
11
11
|
# Save certificate into redis.
|
12
12
|
def save(cert)
|
13
13
|
return unless cert.key.present? && cert.bundle.present?
|
14
|
+
|
14
15
|
LetsEncrypt.logger.info "Save #{cert.domain}'s certificate (bundle) to redis"
|
15
16
|
connection.set "#{cert.domain}.key", cert.key
|
16
17
|
connection.set "#{cert.domain}.crt", cert.bundle
|
@@ -19,6 +20,7 @@ module LetsEncrypt
|
|
19
20
|
# Delete certificate from redis.
|
20
21
|
def delete(cert)
|
21
22
|
return unless cert.key.present? && cert.certificate.present?
|
23
|
+
|
22
24
|
LetsEncrypt.logger.info "Delete #{cert.domain}'s certificate from redis"
|
23
25
|
connection.del "#{cert.domain}.key"
|
24
26
|
connection.del "#{cert.domain}.crt"
|
data/lib/letsencrypt/version.rb
CHANGED
data/lib/letsencrypt.rb
CHANGED
@@ -32,14 +32,15 @@ module LetsEncrypt
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def load_private_key
|
35
|
-
return ENV
|
35
|
+
return ENV.fetch('LETSENCRYPT_PRIVATE_KEY', nil) if config.use_env_key
|
36
36
|
return File.open(private_key_path) if File.exist?(private_key_path)
|
37
|
+
|
37
38
|
generate_private_key
|
38
39
|
end
|
39
40
|
|
40
41
|
# Get current using Let's Encrypt endpoint
|
41
42
|
def directory
|
42
|
-
@
|
43
|
+
@directory ||= config.use_staging? ? ENDPOINT_STAGING : ENDPOINT
|
43
44
|
end
|
44
45
|
|
45
46
|
# Register a Let's Encrypt account
|
@@ -56,12 +57,12 @@ module LetsEncrypt
|
|
56
57
|
end
|
57
58
|
|
58
59
|
def private_key_path
|
59
|
-
config.private_key_path || Rails.root.join('config
|
60
|
+
config.private_key_path || Rails.root.join('config/letsencrypt.key')
|
60
61
|
end
|
61
62
|
|
62
63
|
def generate_private_key
|
63
64
|
key = OpenSSL::PKey::RSA.new(4096)
|
64
|
-
File.
|
65
|
+
File.write(private_key_path, key.to_s)
|
65
66
|
logger.info "Created new private key for Let's Encrypt"
|
66
67
|
key
|
67
68
|
end
|
metadata
CHANGED
@@ -1,121 +1,135 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-letsencrypt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 蒼時弦也
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: acme-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: actionmailer
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - ">="
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
33
|
+
version: '6.1'
|
20
34
|
type: :runtime
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
38
|
- - ">="
|
25
39
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
40
|
+
version: '6.1'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
42
|
+
name: actionpack
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- - "
|
45
|
+
- - ">="
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
47
|
+
version: '6.1'
|
34
48
|
type: :runtime
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- - "
|
52
|
+
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
54
|
+
version: '6.1'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
56
|
+
name: actionview
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
61
|
+
version: '6.1'
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '6.1'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
70
|
+
name: activemodel
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - ">="
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
type: :
|
75
|
+
version: '6.1'
|
76
|
+
type: :runtime
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
82
|
+
version: '6.1'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: activerecord
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
76
|
-
type: :
|
89
|
+
version: '6.1'
|
90
|
+
type: :runtime
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
96
|
+
version: '6.1'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: activesupport
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- - "
|
101
|
+
- - ">="
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
90
|
-
type: :
|
103
|
+
version: '6.1'
|
104
|
+
type: :runtime
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- - "
|
108
|
+
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
110
|
+
version: '6.1'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: railties
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- - "
|
115
|
+
- - ">="
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
104
|
-
type: :
|
117
|
+
version: '6.1'
|
118
|
+
type: :runtime
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
|
-
- - "
|
122
|
+
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
124
|
+
version: '6.1'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: redis
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
|
-
type: :
|
132
|
+
type: :runtime
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
@@ -155,7 +169,8 @@ files:
|
|
155
169
|
homepage: https://github.com/elct9620/rails-letsencrypt
|
156
170
|
licenses:
|
157
171
|
- MIT
|
158
|
-
metadata:
|
172
|
+
metadata:
|
173
|
+
rubygems_mfa_required: 'true'
|
159
174
|
post_install_message:
|
160
175
|
rdoc_options: []
|
161
176
|
require_paths:
|
@@ -164,14 +179,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
179
|
requirements:
|
165
180
|
- - ">="
|
166
181
|
- !ruby/object:Gem::Version
|
167
|
-
version:
|
182
|
+
version: 2.7.0
|
168
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
184
|
requirements:
|
170
185
|
- - ">="
|
171
186
|
- !ruby/object:Gem::Version
|
172
187
|
version: '0'
|
173
188
|
requirements: []
|
174
|
-
rubygems_version: 3.
|
189
|
+
rubygems_version: 3.4.10
|
175
190
|
signing_key:
|
176
191
|
specification_version: 4
|
177
192
|
summary: The Let's Encrypt certificate manager for rails
|