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.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +305 -0
  4. data/Rakefile +29 -0
  5. data/app/assets/config/apartment_acme_client_manifest.js +2 -0
  6. data/app/assets/javascripts/apartment_acme_client/application.js +13 -0
  7. data/app/assets/stylesheets/apartment_acme_client/application.css +15 -0
  8. data/app/controllers/apartment_acme_client/application_controller.rb +5 -0
  9. data/app/controllers/apartment_acme_client/verifications_controller.rb +5 -0
  10. data/app/helpers/apartment_acme_client/application_helper.rb +4 -0
  11. data/app/jobs/apartment_acme_client/application_job.rb +4 -0
  12. data/app/mailers/apartment_acme_client/application_mailer.rb +6 -0
  13. data/app/models/apartment_acme_client/application_record.rb +5 -0
  14. data/app/models/apartment_acme_client/verifier.rb +38 -0
  15. data/app/views/layouts/apartment_acme_client/application.html.erb +14 -0
  16. data/config/routes.rb +3 -0
  17. data/lib/apartment_acme_client.rb +61 -0
  18. data/lib/apartment_acme_client/acme_client/proxy.rb +14 -0
  19. data/lib/apartment_acme_client/acme_client/real_client.rb +56 -0
  20. data/lib/apartment_acme_client/certificate_storage/proxy.rb +15 -0
  21. data/lib/apartment_acme_client/certificate_storage/s3.rb +74 -0
  22. data/lib/apartment_acme_client/domain_checker.rb +21 -0
  23. data/lib/apartment_acme_client/encryption.rb +134 -0
  24. data/lib/apartment_acme_client/engine.rb +5 -0
  25. data/lib/apartment_acme_client/file_manipulation/proxy.rb +13 -0
  26. data/lib/apartment_acme_client/file_manipulation/real.rb +37 -0
  27. data/lib/apartment_acme_client/nginx_configuration/proxy.rb +13 -0
  28. data/lib/apartment_acme_client/nginx_configuration/real.rb +128 -0
  29. data/lib/apartment_acme_client/railtie.rb +8 -0
  30. data/lib/apartment_acme_client/renewal_service.rb +22 -0
  31. data/lib/apartment_acme_client/version.rb +3 -0
  32. data/lib/tasks/encryption.rake +21 -0
  33. metadata +208 -0
@@ -0,0 +1,13 @@
1
+ module ApartmentAcmeClient
2
+ module NginxConfiguration
3
+ class Proxy
4
+ def self.singleton
5
+ base_class.new
6
+ end
7
+
8
+ def self.base_class
9
+ ApartmentAcmeClient.nginx_configuration_class || NginxConfiguration::Real
10
+ end
11
+ end
12
+ end
13
+ end
@@ -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,8 @@
1
+ module ApartmentAcmeClient
2
+ class Railtie < Rails::Railtie
3
+ # rake_tasks do
4
+ # spec = Gem::Specification.find_by_name 'apartment_acme_client'
5
+ # load "#{spec.gem_dir}/lib/tasks/encryption.rake"
6
+ # end
7
+ end
8
+ 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,3 @@
1
+ module ApartmentAcmeClient
2
+ VERSION = '0.0.1'
3
+ 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: []