apartment_acme_client 0.0.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +305 -0
- data/Rakefile +29 -0
- data/app/assets/config/apartment_acme_client_manifest.js +2 -0
- data/app/assets/javascripts/apartment_acme_client/application.js +13 -0
- data/app/assets/stylesheets/apartment_acme_client/application.css +15 -0
- data/app/controllers/apartment_acme_client/application_controller.rb +5 -0
- data/app/controllers/apartment_acme_client/verifications_controller.rb +5 -0
- data/app/helpers/apartment_acme_client/application_helper.rb +4 -0
- data/app/jobs/apartment_acme_client/application_job.rb +4 -0
- data/app/mailers/apartment_acme_client/application_mailer.rb +6 -0
- data/app/models/apartment_acme_client/application_record.rb +5 -0
- data/app/models/apartment_acme_client/verifier.rb +38 -0
- data/app/views/layouts/apartment_acme_client/application.html.erb +14 -0
- data/config/routes.rb +3 -0
- data/lib/apartment_acme_client.rb +61 -0
- data/lib/apartment_acme_client/acme_client/proxy.rb +14 -0
- data/lib/apartment_acme_client/acme_client/real_client.rb +56 -0
- data/lib/apartment_acme_client/certificate_storage/proxy.rb +15 -0
- data/lib/apartment_acme_client/certificate_storage/s3.rb +74 -0
- data/lib/apartment_acme_client/domain_checker.rb +21 -0
- data/lib/apartment_acme_client/encryption.rb +134 -0
- data/lib/apartment_acme_client/engine.rb +5 -0
- data/lib/apartment_acme_client/file_manipulation/proxy.rb +13 -0
- data/lib/apartment_acme_client/file_manipulation/real.rb +37 -0
- data/lib/apartment_acme_client/nginx_configuration/proxy.rb +13 -0
- data/lib/apartment_acme_client/nginx_configuration/real.rb +128 -0
- data/lib/apartment_acme_client/railtie.rb +8 -0
- data/lib/apartment_acme_client/renewal_service.rb +22 -0
- data/lib/apartment_acme_client/version.rb +3 -0
- data/lib/tasks/encryption.rake +21 -0
- metadata +208 -0
@@ -0,0 +1,128 @@
|
|
1
|
+
require "erb"
|
2
|
+
|
3
|
+
module ApartmentAcmeClient
|
4
|
+
module NginxConfiguration
|
5
|
+
class Real
|
6
|
+
# do we have a certificate on this server?
|
7
|
+
# We cannot start nginx when it is pointing at a non-existing certificate,
|
8
|
+
# so we need to check
|
9
|
+
def self.update_nginx(cert_exists:, base_domain:)
|
10
|
+
template = new(include_ssl: cert_exists, base_domain: base_domain).filled_template
|
11
|
+
|
12
|
+
tempfile = Tempfile.new('nginx_config')
|
13
|
+
raise "Path Error" unless template
|
14
|
+
|
15
|
+
begin
|
16
|
+
tempfile.write(template)
|
17
|
+
tempfile.flush
|
18
|
+
|
19
|
+
ApartmentAcmeClient::FileManipulation::Proxy.singleton.copy_file(tempfile.path.to_s, ApartmentAcmeClient.nginx_config_path)
|
20
|
+
ApartmentAcmeClient::FileManipulation::Proxy.singleton.restart_service("nginx")
|
21
|
+
ensure
|
22
|
+
tempfile.close
|
23
|
+
tempfile.unlink
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(options = {})
|
28
|
+
@options = default_options.merge(options)
|
29
|
+
end
|
30
|
+
|
31
|
+
def filled_template
|
32
|
+
return nil unless check_configuration
|
33
|
+
fill_template(read_template, @options)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def default_options
|
38
|
+
result = {}
|
39
|
+
result[:public_folder] = ApartmentAcmeClient.public_folder
|
40
|
+
result[:socket_path] = ApartmentAcmeClient.socket_path
|
41
|
+
result[:include_ssl] = false
|
42
|
+
result[:cert_prefix] = ApartmentAcmeClient::CertificateStorage::TEST_PREFIX if ApartmentAcmeClient.lets_encrypt_test_server_enabled
|
43
|
+
result[:certificate_storage_folder] = ApartmentAcmeClient.certificate_storage_folder
|
44
|
+
result
|
45
|
+
end
|
46
|
+
|
47
|
+
def check_configuration
|
48
|
+
unless File.exist?(@options[:public_folder])
|
49
|
+
puts "Webroot path #{@options[:public_folder]} Not found"
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
def read_template
|
57
|
+
default_template
|
58
|
+
end
|
59
|
+
|
60
|
+
def default_template
|
61
|
+
<<~THE_END
|
62
|
+
#
|
63
|
+
# A virtual host using mix of IP-, name-, and port-based configuration
|
64
|
+
#
|
65
|
+
|
66
|
+
upstream app {
|
67
|
+
# Path to Unicorn SOCK file, as defined previously
|
68
|
+
server unix:<%= options[:socket_path] %> fail_timeout=0;
|
69
|
+
}
|
70
|
+
|
71
|
+
server {
|
72
|
+
|
73
|
+
# FOR HTTP
|
74
|
+
listen 80;
|
75
|
+
|
76
|
+
gzip on;
|
77
|
+
|
78
|
+
# Application root, as defined previously
|
79
|
+
root <%= options[:public_folder] %>;
|
80
|
+
server_name <%= options[:base_domain] %> *.<%= options[:base_domain] %>;
|
81
|
+
|
82
|
+
try_files $uri/index.html $uri @app;
|
83
|
+
|
84
|
+
location @app {
|
85
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
86
|
+
proxy_set_header Host $http_host;
|
87
|
+
proxy_redirect off;
|
88
|
+
proxy_pass http://app;
|
89
|
+
}
|
90
|
+
|
91
|
+
error_page 500 502 503 504 /500.html;
|
92
|
+
client_max_body_size 4G;
|
93
|
+
keepalive_timeout 10;
|
94
|
+
|
95
|
+
# BELOW THIS LINE FOR HTTPS
|
96
|
+
<% if options[:include_ssl] %>
|
97
|
+
listen 443 default_server ssl;
|
98
|
+
|
99
|
+
# The following should be enabled once everything is SSL
|
100
|
+
# ssl on;
|
101
|
+
|
102
|
+
ssl_certificate <%= options[:certificate_storage_folder] %>/<%= options[:cert_prefix] %>cert.pem;
|
103
|
+
ssl_certificate_key <%= options[:certificate_storage_folder] %>/<%= options[:cert_prefix] %>privkey.pem;
|
104
|
+
|
105
|
+
ssl_stapling on;
|
106
|
+
ssl_stapling_verify on;
|
107
|
+
ssl_trusted_certificate <%= options[:certificate_storage_folder] %>/<%= options[:cert_prefix] %>fullchain.pem;
|
108
|
+
|
109
|
+
ssl_session_timeout 5m;
|
110
|
+
<% end %>
|
111
|
+
}
|
112
|
+
THE_END
|
113
|
+
end
|
114
|
+
|
115
|
+
def fill_template(template, options)
|
116
|
+
|
117
|
+
# scope defined for use in binding to ERB
|
118
|
+
def opts(options)
|
119
|
+
options
|
120
|
+
binding
|
121
|
+
end
|
122
|
+
# binds to current class
|
123
|
+
# uses 'options' in the template
|
124
|
+
ERB.new(template).result(opts(options))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ApartmentAcmeClient
|
2
|
+
class RenewalService
|
3
|
+
def self.run!
|
4
|
+
|
5
|
+
good_domains, rejected_domains = ApartmentAcmeClient::DomainChecker.new.accessible_domains
|
6
|
+
puts "All domains to be requested: #{good_domains}, invalid domains: #{rejected_domains}"
|
7
|
+
|
8
|
+
domains = ApartmentAcmeClient::Encryption.new.authorize_domains(good_domains)
|
9
|
+
puts "authorized-domains list: #{domains}"
|
10
|
+
|
11
|
+
common_name = ApartmentAcmeClient.common_name ? ApartmentAcmeClient.common_name : good_domains.first
|
12
|
+
certificate = ApartmentAcmeClient::Encryption.new.request_certificate(common_name: common_name, domains: domains)
|
13
|
+
|
14
|
+
ApartmentAcmeClient::CertificateStorage::Proxy.singleton.store_certificate(certificate)
|
15
|
+
|
16
|
+
puts "Restarting nginx with new certificate"
|
17
|
+
ApartmentAcmeClient::FileManipulation::Proxy.singleton.restart_service("nginx")
|
18
|
+
|
19
|
+
puts "done."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
namespace :encryption do
|
2
|
+
desc "Register a LetsEncrypt Client, create an open SSL key on S3 bucket"
|
3
|
+
task :create_crypto_client, [:email] => :environment do |_t, args|
|
4
|
+
ApartmentAcmeClient::Encryption.new.register_new(args[:email])
|
5
|
+
puts "done."
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Authorize all domains and request new certificate"
|
9
|
+
task renew_and_update_certificate: :environment do
|
10
|
+
ApartmentAcmeClient::RenewalService.run!
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Update the nginx_configuration"
|
14
|
+
task update_nginx_config: :environment do
|
15
|
+
puts "updating nginx configuration"
|
16
|
+
ssl_enabled = ApartmentAcmeClient::CertificateStorage::Proxy.singleton.cert_exists?
|
17
|
+
base_domain = ApartmentAcmeClient.common_name
|
18
|
+
ApartmentAcmeClient::NginxConfiguration::Proxy.base_class.update_nginx(cert_exists: ssl_enabled, base_domain: base_domain)
|
19
|
+
puts "done."
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apartment_acme_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robin Dunlop
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.1.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.2'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 4.1.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.2'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: acme-client
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.3.1
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.3.1
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: aws-sdk-s3
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: sqlite3
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: bundler
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.15'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.15'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rake
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '10.0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '10.0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rspec
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '3.0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '3.0'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rspec-rails
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: pry
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
description: Manage/renew Let's Encrypt SSL Certificates for sites which respond to
|
146
|
+
many different domains
|
147
|
+
email:
|
148
|
+
- robin@dunlopweb.com
|
149
|
+
executables: []
|
150
|
+
extensions: []
|
151
|
+
extra_rdoc_files: []
|
152
|
+
files:
|
153
|
+
- MIT-LICENSE
|
154
|
+
- README.md
|
155
|
+
- Rakefile
|
156
|
+
- app/assets/config/apartment_acme_client_manifest.js
|
157
|
+
- app/assets/javascripts/apartment_acme_client/application.js
|
158
|
+
- app/assets/stylesheets/apartment_acme_client/application.css
|
159
|
+
- app/controllers/apartment_acme_client/application_controller.rb
|
160
|
+
- app/controllers/apartment_acme_client/verifications_controller.rb
|
161
|
+
- app/helpers/apartment_acme_client/application_helper.rb
|
162
|
+
- app/jobs/apartment_acme_client/application_job.rb
|
163
|
+
- app/mailers/apartment_acme_client/application_mailer.rb
|
164
|
+
- app/models/apartment_acme_client/application_record.rb
|
165
|
+
- app/models/apartment_acme_client/verifier.rb
|
166
|
+
- app/views/layouts/apartment_acme_client/application.html.erb
|
167
|
+
- config/routes.rb
|
168
|
+
- lib/apartment_acme_client.rb
|
169
|
+
- lib/apartment_acme_client/acme_client/proxy.rb
|
170
|
+
- lib/apartment_acme_client/acme_client/real_client.rb
|
171
|
+
- lib/apartment_acme_client/certificate_storage/proxy.rb
|
172
|
+
- lib/apartment_acme_client/certificate_storage/s3.rb
|
173
|
+
- lib/apartment_acme_client/domain_checker.rb
|
174
|
+
- lib/apartment_acme_client/encryption.rb
|
175
|
+
- lib/apartment_acme_client/engine.rb
|
176
|
+
- lib/apartment_acme_client/file_manipulation/proxy.rb
|
177
|
+
- lib/apartment_acme_client/file_manipulation/real.rb
|
178
|
+
- lib/apartment_acme_client/nginx_configuration/proxy.rb
|
179
|
+
- lib/apartment_acme_client/nginx_configuration/real.rb
|
180
|
+
- lib/apartment_acme_client/railtie.rb
|
181
|
+
- lib/apartment_acme_client/renewal_service.rb
|
182
|
+
- lib/apartment_acme_client/version.rb
|
183
|
+
- lib/tasks/encryption.rake
|
184
|
+
homepage: https://github.com/rdunlop/apartment_acme_client
|
185
|
+
licenses:
|
186
|
+
- MIT
|
187
|
+
metadata: {}
|
188
|
+
post_install_message:
|
189
|
+
rdoc_options: []
|
190
|
+
require_paths:
|
191
|
+
- lib
|
192
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '0'
|
197
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
requirements: []
|
203
|
+
rubyforge_project:
|
204
|
+
rubygems_version: 2.6.13
|
205
|
+
signing_key:
|
206
|
+
specification_version: 4
|
207
|
+
summary: Let's Encrypt interface for Multi-tenancy applications (like Apartment)
|
208
|
+
test_files: []
|