encryptbot 0.1.7 → 0.1.8

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
  SHA256:
3
- metadata.gz: 1c11220ad68f23896f0b736d977e06a569ca4552746d99793f59efda46bc88a6
4
- data.tar.gz: 0172a1b4a558e2ca2d59b48a99f79c543ad6ef7ad42758ff4bbccca4c72e71be
3
+ metadata.gz: 9e7e74780b62f252a70d355c14303aae026fecf987687b9029e363d1f956278a
4
+ data.tar.gz: 15c849942b0be5615dfcd12ba47b77d457a8b6a116ebe2f4ca8ca4cfb5612930
5
5
  SHA512:
6
- metadata.gz: cf7fd9ebd8e1710fbe9c1a56f1dc560b2d9603b53e9e0a403aedbd094dc37d8e69e415e4b3b58116f28e5a12dc0b0d2651fafd9a3b12ec4346ff8eceeb2598c1
7
- data.tar.gz: facab7606bf80df0bdf6ad391c68787bc3e030181cc984b67c50d039cb23ab8cbf406f5f3efaf09025263a872adf1bf7178eba3f8eb9af10a0542ce865117c9c
6
+ metadata.gz: b1c8059dcabce152577657c3125678e604caaebd5fd04d4b1b7b82f7be0ab38c274180facf8b7b0f442ed9a6afcd11378bedcb0bfb360daa1adacb23935032fc
7
+ data.tar.gz: 816ec380875e437679a8f82831ace056ea77d8dddd7c72e26ae255065db9e24b51ea9d4880a7e1101c33d9219dcf66f813d67714262621395554e4b46dc95bb8
data/Gemfile.lock CHANGED
@@ -1,12 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- encryptbot (0.1.7)
4
+ encryptbot (0.1.8)
5
5
  acme-client
6
6
  aws-sdk-route53
7
7
  faraday
8
8
  platform-api
9
- slack-notifier
10
9
 
11
10
  GEM
12
11
  remote: https://rubygems.org/
@@ -14,21 +13,24 @@ GEM
14
13
  acme-client (2.0.6)
15
14
  faraday (>= 0.17, < 2.0.0)
16
15
  aws-eventstream (1.0.3)
17
- aws-partitions (1.281.0)
18
- aws-sdk-core (3.90.1)
16
+ aws-partitions (1.292.0)
17
+ aws-sdk-core (3.92.0)
19
18
  aws-eventstream (~> 1.0, >= 1.0.2)
20
19
  aws-partitions (~> 1, >= 1.239.0)
21
20
  aws-sigv4 (~> 1.1)
22
21
  jmespath (~> 1.0)
23
- aws-sdk-route53 (1.30.0)
22
+ aws-sdk-route53 (1.32.0)
24
23
  aws-sdk-core (~> 3, >= 3.71.0)
25
24
  aws-sigv4 (~> 1.1)
26
25
  aws-sigv4 (1.1.1)
27
26
  aws-eventstream (~> 1.0, >= 1.0.2)
28
27
  erubis (2.7.0)
29
- excon (0.72.0)
30
- faraday (1.0.0)
28
+ excon (0.79.0)
29
+ faraday (1.3.0)
30
+ faraday-net_http (~> 1.0)
31
31
  multipart-post (>= 1.2, < 3)
32
+ ruby2_keywords
33
+ faraday-net_http (1.0.1)
32
34
  heroics (0.0.25)
33
35
  erubis (~> 2.0)
34
36
  excon
@@ -36,13 +38,13 @@ GEM
36
38
  multi_json (>= 1.9.2)
37
39
  jmespath (1.4.0)
38
40
  moneta (1.0.0)
39
- multi_json (1.14.1)
41
+ multi_json (1.15.0)
40
42
  multipart-post (2.1.1)
41
43
  platform-api (2.2.0)
42
44
  heroics (~> 0.0.25)
43
45
  moneta (~> 1.0.0)
44
46
  rake (13.0.1)
45
- slack-notifier (2.3.2)
47
+ ruby2_keywords (0.0.4)
46
48
 
47
49
  PLATFORMS
48
50
  ruby
data/README.md CHANGED
@@ -5,9 +5,8 @@ Encryptbot creates and renews your Let's Encrypt SSL certificate on Heroku allow
5
5
  The gem will:
6
6
 
7
7
  - Create Let's Encrypt
8
- - Add Let's Encrypt DNS Challenge TXT records to your DNS provider (Cloudflare and Dyn supported)
8
+ - Add Let's Encrypt DNS Challenge TXT records to DNS provider Route 53
9
9
  - Add certificate to your Heroku SNI endpoint
10
- - Send Slack notifications if the process fails.
11
10
 
12
11
  ## Installation
13
12
 
@@ -34,23 +33,12 @@ Add an initializer file to your rails application and all applicable config sett
34
33
  Encryptbot.configure do |config|
35
34
  config.heroku_app = "heroku_app_name"
36
35
  config.heroku_token = "heroku_api_token"
37
- config.cloudflare_api_key = "cloudflare_api_key"
38
- config.cloudflare_email = "cloudflare_account_email"
39
36
  config.acme_email = "letsencrypt_account_email"
40
- config.dyn_customer_name = "dyn_customer_name"
41
- config.dyn_username = "dyn_username"
42
- config.dyn_password = "dyn_password"
43
- config.slack_webhook = "slack_webhook_url"
44
- config.slack_bot_username = "name_for_slack_bot"
45
37
  config.route53_hosted_zone_id = "Z123456"
46
38
  config.route53_acme_record_name = "_acme-challenge.acme.domain.com"
47
39
  config.route53_access_key_id = "aws_api_key"
48
40
  config.route53_secret_access_key = "aws_api_secret"
49
- config.domains = [
50
- {domain: "*.domain1.com", service: "cloudflare"},
51
- {domain: "*.domain2.com", service: "dyn"},
52
- {domain: "domain3.com", service: "cloudflare"},
53
- ]
41
+ config.domains = ["*.domain1.com", "*.domain2.com"]
54
42
  end
55
43
  ```
56
44
 
data/encryptbot.gemspec CHANGED
@@ -24,7 +24,6 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "acme-client"
25
25
  spec.add_dependency "platform-api"
26
26
  spec.add_dependency "faraday"
27
- spec.add_dependency "slack-notifier"
28
27
  spec.add_dependency "aws-sdk-route53"
29
28
  spec.add_development_dependency "bundler", "~> 1.16"
30
29
  spec.add_development_dependency "rake", ">= 12.3.3"
data/lib/encryptbot.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  require "encryptbot/configuration"
2
2
  require "encryptbot/cert"
3
3
  require "encryptbot/version"
4
- require "encryptbot/services/cloudflare"
5
- require "encryptbot/services/dyn"
6
4
  require "encryptbot/services/route53"
7
5
 
8
6
  if defined?(Rails)
@@ -2,17 +2,15 @@ require "platform-api"
2
2
  require "acme-client"
3
3
  require "encryptbot/heroku"
4
4
  require "encryptbot/exceptions"
5
- require "encryptbot/slacker"
6
5
  require "resolv"
7
6
 
8
7
  module Encryptbot
9
8
  class Cert
10
9
 
11
- attr_reader :domain_list, :domain_names, :account_email, :test_mode
10
+ attr_reader :domains, :account_email, :test_mode
12
11
 
13
12
  def initialize
14
- @domain_list = Encryptbot.configuration.domains
15
- @domain_names = @domain_list.map{|d| d[:domain] }
13
+ @domains = Encryptbot.configuration.domains
16
14
  @account_email = Encryptbot.configuration.acme_email
17
15
  @test_mode = Encryptbot.configuration.test_mode
18
16
  end
@@ -35,27 +33,22 @@ module Encryptbot
35
33
  )
36
34
 
37
35
  # create order
38
- order = client.new_order(identifiers: @domain_names)
36
+ order = client.new_order(identifiers: @domains)
39
37
 
38
+ puts "Start Authorization"
40
39
  # authorization of domains
41
40
  order.authorizations.each do |authorization|
42
41
  dns_challenge = authorization.dns
43
42
  domain = authorization.domain
43
+ puts "Start Authorization of #{domain}"
44
44
  dns_entry = {
45
45
  name: dns_challenge.record_name,
46
46
  type: dns_challenge.record_type,
47
47
  content: dns_challenge.record_content
48
48
  }
49
- case @domain_list.detect{|t| t[:domain].gsub("*.", "") == domain }[:service]
50
- when "route53"
51
- Encryptbot::Services::Route53.new(domain, dns_entry).add_challenge
52
- when "cloudflare"
53
- Encryptbot::Services::Cloudflare.new(domain, dns_entry).add_challenge
54
- when "dyn"
55
- Encryptbot::Services::Dyn.new(domain, dns_entry).add_challenge
56
- else
57
- raise Encryptbot::Error::UnknownServiceError, "#{domain} service unknown"
58
- end
49
+
50
+ Encryptbot::Services::Route53.new(domain, dns_entry).add_challenge
51
+
59
52
  # check if the DNS service has updated
60
53
  sleep(8)
61
54
 
@@ -73,6 +66,7 @@ module Encryptbot
73
66
  sleep(2)
74
67
  dns_challenge.reload
75
68
  end
69
+ puts "Completed authorization of #{domain}. Status: #{dns_challenge.status}"
76
70
 
77
71
  end # end auth loop
78
72
 
@@ -81,14 +75,17 @@ module Encryptbot
81
75
  end
82
76
 
83
77
  # Generate certificate
78
+ puts "Generate Certificate"
84
79
  csr = Acme::Client::CertificateRequest.new(names: @domain_names)
85
80
  order.finalize(csr: csr)
86
81
  sleep(1) while order.status == "processing"
87
82
 
88
83
  # add certificate to heroku
84
+ puts "Adding Certificate to heroku"
89
85
  certificate = order.certificate
90
86
  private_key = csr.private_key.to_pem
91
87
  Encryptbot::Heroku.new.add_certificate(order.certificate, private_key)
88
+ puts "Completed"
92
89
  end
93
90
 
94
91
  # Check if TXT value has been set correctly
@@ -104,4 +101,4 @@ module Encryptbot
104
101
 
105
102
  end
106
103
 
107
- end
104
+ end
@@ -1,36 +1,25 @@
1
1
  module Encryptbot
2
2
  class Configuration
3
3
  attr_accessor :heroku_app, :heroku_token,
4
- :cloudflare_api_key, :cloudflare_email,
5
- :dyn_customer_name, :dyn_username, :dyn_password,
6
4
  :route53_hosted_zone_id, :route53_acme_record_name,
7
5
  :route53_access_key_id, :route53_secret_access_key,
8
- :acme_email, :domains, :test_mode,
9
- :slack_webhook, :slack_bot_username
6
+ :acme_email, :domains, :test_mode
10
7
 
11
8
  def initialize
12
9
  @heroku_app = nil
13
10
  @heroku_token = nil
14
- @cloudflare_api_key = nil
15
- @cloudflare_email = nil
16
- @dyn_customer_name = nil
17
- @dyn_username = nil
18
- @dyn_password = nil
19
11
  @route53_hosted_zone_id = nil
20
12
  @route53_acme_record_name = nil
21
13
  @route53_access_key_id = nil
22
14
  @route53_secret_access_key = nil
23
15
  @acme_email = nil
24
- @slack_webhook = nil
25
- @slack_bot_username = "encryptbot"
26
16
  @test_mode = false # use lets encrypt staging
27
- @domains = [] #[{domain: "*.domain.com", service: "cloudflare"}, {domain: "*.domain.com", service: "dyn"}]
17
+ @domains = [] #["*.domain1.com","*.domain2.com"]
28
18
  end
29
19
 
30
20
  def valid?
31
- heroku_app && heroku_token && acme_email && domains.any? &&
32
- (cloudflare_api_key || dyn_customer_name || route53_access_key_id)
21
+ heroku_app && heroku_token && acme_email && domains.any? && route53_access_key_id
33
22
  end
34
23
 
35
24
  end
36
- end
25
+ end
@@ -1,12 +1,9 @@
1
- require "encryptbot/slacker"
2
-
3
1
  module Encryptbot
4
2
  module Error
5
3
 
6
4
  class EncryptbotError < StandardError
7
5
 
8
6
  def initialize(msg = "")
9
- Encryptbot::Slacker.post_message("Unable to autorenew SSL certificate. #{self.class.name} #{msg}")
10
7
  super(msg)
11
8
  end
12
9
 
@@ -27,4 +24,4 @@ module Encryptbot
27
24
  # Exception raised as order was failed - this happens when the DNS Challenge failed
28
25
  class InvalidOrderError < EncryptbotError; end
29
26
  end
30
- end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Encryptbot
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: encryptbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - danlewis
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-08 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acme-client
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: slack-notifier
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: aws-sdk-route53
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -131,17 +117,14 @@ files:
131
117
  - lib/encryptbot/exceptions.rb
132
118
  - lib/encryptbot/heroku.rb
133
119
  - lib/encryptbot/railtie.rb
134
- - lib/encryptbot/services/cloudflare.rb
135
- - lib/encryptbot/services/dyn.rb
136
120
  - lib/encryptbot/services/route53.rb
137
- - lib/encryptbot/slacker.rb
138
121
  - lib/encryptbot/version.rb
139
122
  - lib/tasks/encryptbot.rake
140
123
  homepage: https://github.com/danlewis/encryptbot
141
124
  licenses:
142
125
  - MIT
143
126
  metadata: {}
144
- post_install_message:
127
+ post_install_message:
145
128
  rdoc_options: []
146
129
  require_paths:
147
130
  - lib
@@ -157,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
140
  version: '0'
158
141
  requirements: []
159
142
  rubygems_version: 3.0.3
160
- signing_key:
143
+ signing_key:
161
144
  specification_version: 4
162
145
  summary: Manage Let's Encrypt wildcard certificates on Heroku
163
146
  test_files: []
@@ -1,111 +0,0 @@
1
- # a=Encryptbot::Services::Cloudflare.new("*.domain.com", {type: "TXT", name: "_acme-challenge.adventist.place", content: "test-3"});a.add_challenge
2
- require "faraday"
3
- require "json"
4
-
5
- module Encryptbot
6
- module Services
7
- class Cloudflare
8
-
9
- attr_accessor :domain, :api_key, :api_email, :zone_id, :dns_entry, :dns_record_id, :dns_record
10
-
11
- def initialize(domain, dns_entry)
12
- @domain = domain.to_s.gsub("*.", "") # cleanup wildcard by removing *. infront
13
- @api_key = Encryptbot.configuration.cloudflare_api_key
14
- @api_email = Encryptbot.configuration.cloudflare_email
15
- @dns_entry = dns_entry # {content: "txt-record-content", type: "TXT", name: "_acme-challenge.domain.com"}
16
- @dns_record = "#{dns_entry[:name]}.#{@domain}"
17
- end
18
-
19
- def add_challenge
20
- begin
21
- get_zone_id
22
- setup_dns_record
23
- rescue => e
24
- raise Encryptbot::Error::CloudflareDNSError, e
25
- end
26
- end
27
-
28
- def get_zone_id
29
- response = get("/zones?name=#{@domain}")
30
- if response["result"].any?
31
- @zone_id = response["result"].first["id"]
32
- end
33
- end
34
-
35
- def setup_dns_record
36
- find_dns_record
37
- return false if @zone_id.nil?
38
-
39
- if @dns_record_id
40
- update_dns_record
41
- else
42
- add_dns_record
43
- end
44
- end
45
-
46
- def find_dns_record
47
- response = get("/zones/#{@zone_id}/dns_records?name=#{@dns_record}&type=#{@dns_entry[:type]}")
48
- if response["result"].any?
49
- @dns_record_id = response["result"].first["id"]
50
- end
51
- end
52
-
53
- def add_dns_record
54
- response = post("/zones/#{@zone_id}/dns_records", {
55
- type: @dns_entry[:type],
56
- name: @dns_record,
57
- content: @dns_entry[:content],
58
- ttl: 120
59
- })
60
- response["success"]
61
- end
62
-
63
- def update_dns_record
64
- response = put("/zones/#{@zone_id}/dns_records/#{@dns_record_id}", {
65
- type: @dns_entry[:type],
66
- name: @dns_record,
67
- content: @dns_entry[:content],
68
- ttl: 120
69
- })
70
- response["success"]
71
- end
72
-
73
- private
74
-
75
- def post(endpoint_path, payload)
76
- response = connection.post "https://api.cloudflare.com/client/v4#{endpoint_path}", payload.to_json
77
- format_response(response)
78
- end
79
-
80
- def put(endpoint_path, payload)
81
- response = connection.put "https://api.cloudflare.com/client/v4#{endpoint_path}", payload.to_json
82
- format_response(response)
83
- end
84
-
85
- def get(endpoint_path)
86
- response = connection.get "https://api.cloudflare.com/client/v4#{endpoint_path}"
87
- format_response(response)
88
- end
89
-
90
- def connection
91
- @connection ||= begin
92
- headers = {
93
- "X-Auth-Key" => @api_key,
94
- "X-Auth-Email" => @api_email,
95
- "Content-Type" => "application/json"
96
- }
97
- Faraday.new(url: "https://api.cloudflare.com", headers: headers)
98
- end
99
- end
100
-
101
- def format_response(response)
102
- if response.success?
103
- JSON.parse(response.body)
104
- else
105
- nil
106
- end
107
- end
108
-
109
- end
110
- end
111
- end
@@ -1,145 +0,0 @@
1
- # a=Encryptbot::Services::Dyn.new("*.domain.com", {type: "TXT", name: "_acme-challenge", content: "test-3"});a.add_challenge
2
- require "faraday"
3
- require "json"
4
-
5
- module Encryptbot
6
- module Services
7
- class Dyn
8
-
9
- attr_accessor :domain, :dns_entry, :full_domain_name, :api_token, :customer_name, :username, :password
10
-
11
- def initialize(domain, dns_entry)
12
- @domain = domain.to_s.gsub("*.", "") # cleanup wildcard by removing *. infront
13
- @dns_entry = dns_entry # {content: "txt-record-content", type: "TXT", name: "_acme-challenge.domain.com"}
14
- @full_domain_name = "#{dns_entry[:name]}.#{@domain}"
15
- @api_token = nil
16
- @customer_name = Encryptbot.configuration.dyn_customer_name
17
- @username = Encryptbot.configuration.dyn_username
18
- @password = Encryptbot.configuration.dyn_password
19
- end
20
-
21
- # sign in
22
- # check for txt record, update if already exists, otherwise create new one
23
- # publish changes
24
- # sign out
25
- def add_challenge
26
- begin
27
- sign_in
28
- success = setup_dns_record
29
- sign_out
30
- success
31
- rescue => e
32
- raise Encryptbot::Error::DynDNSError, e
33
- end
34
-
35
- end
36
-
37
- def sign_in
38
- response = post("/REST/Session/", {
39
- customer_name: customer_name,
40
- user_name: username,
41
- password: password
42
- })
43
- if response && response["status"] == "success"
44
- @api_token = response["data"]["token"]
45
- end
46
- if @api_token.nil?
47
- raise Encryptbot::Error::DynDNSError, "Unable to get Dyn API Token"
48
- end
49
- end
50
-
51
- def sign_out
52
- response = delete("/REST/Session/")
53
- end
54
-
55
- def setup_dns_record
56
- txt_endpoint = find_dns_record
57
-
58
- if txt_endpoint
59
- update_dns_record(txt_endpoint)
60
- else
61
- add_dns_record
62
- end
63
- end
64
-
65
- def find_dns_record
66
- response = get("/REST/TXTRecord/#{domain}/#{full_domain_name}/")
67
- if response && response["status"] == "success"
68
- return response["data"][0]
69
- end
70
- nil
71
- end
72
-
73
- def add_dns_record
74
- response = post("/REST/TXTRecord/#{domain}/#{full_domain_name}/", {
75
- rdata: {
76
- txtdata: dns_entry[:content]
77
- },
78
- ttl: "30"
79
- })
80
- if response && response["status"] == "success"
81
- return publish_changes
82
- end
83
- false
84
- end
85
-
86
- def update_dns_record(txt_endpoint)
87
- response = put(txt_endpoint, {
88
- rdata: {
89
- txtdata: dns_entry[:content]
90
- },
91
- ttl: "30"
92
- })
93
- if response && response["status"] == "success"
94
- return publish_changes
95
- end
96
- false
97
- end
98
-
99
- def publish_changes
100
- response = put("/REST/Zone/#{domain}/", {publish: true})
101
- response && response["status"] == "success"
102
- end
103
-
104
- private
105
-
106
- def post(endpoint_path, payload)
107
- response = connection.post "https://api2.dynect.net#{endpoint_path}", payload.to_json
108
- format_response(response)
109
- end
110
-
111
- def put(endpoint_path, payload)
112
- response = connection.put "https://api2.dynect.net#{endpoint_path}", payload.to_json
113
- format_response(response)
114
- end
115
-
116
- def delete(endpoint_path)
117
- response = connection.delete "https://api2.dynect.net#{endpoint_path}"
118
- format_response(response)
119
- end
120
-
121
- def get(endpoint_path)
122
- response = connection.get "https://api2.dynect.net#{endpoint_path}"
123
- format_response(response)
124
- end
125
-
126
- # Api token if set for requests after sign in completed
127
- def connection
128
- headers = {
129
- "Auth-Token" => api_token.to_s,
130
- "Content-Type" => "application/json"
131
- }
132
- Faraday.new(url: "https://api2.dynect.net", headers: headers)
133
- end
134
-
135
- def format_response(response)
136
- if response.success?
137
- JSON.parse(response.body)
138
- else
139
- nil
140
- end
141
- end
142
-
143
- end
144
- end
145
- end
@@ -1,16 +0,0 @@
1
- require "slack-notifier"
2
-
3
- module Encryptbot
4
- class Slacker
5
-
6
- def self.post_message(message)
7
- unless Encryptbot.configuration.slack_webhook.nil?
8
- notifier.ping message
9
- end
10
- end
11
-
12
- def self.notifier
13
- @notifier ||= Slack::Notifier.new Encryptbot.configuration.slack_webhook, username: Encryptbot.configuration.slack_bot_username
14
- end
15
- end
16
- end