sprinkle_dns 1.0.2 → 1.0.3

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: 5b3535eda69750742757aa7f7c7bcf14b811e2a596ef14efa626db61de75b69d
4
- data.tar.gz: 0f6e5928450f857ca7b304e1d0482c19e9112f6fa56c65d3716e0c14ec7a3638
3
+ metadata.gz: 95998c62520f5326402247fbc532e871436a3fa15ada7ada0b7129cd1d4ab051
4
+ data.tar.gz: '05139f95b6b5d8a7cdbe0bd97a0f17a85e40b32637c5e1c9098548fa7febce42'
5
5
  SHA512:
6
- metadata.gz: c613e559b39c52375aad712a395eeb894802dce620adfff24114664f6ecf1519f881e209e3be682a4472369e9d6218642390bcd64dda3f6a5f3f2a0189fce264
7
- data.tar.gz: d3297e82d02cba1b8a07d82323c3dbdf20988e5fa779edd7d4d3e02e90bda5773dd441bbc8c9b8b1f85458fc66598983d183e5af585c6341a683aa6c62eb8df9
6
+ metadata.gz: 985806eef794688c33d8de78a9755bf42f3d41e390fbf18e2afac7d7624b0ab228e7d8d8f13779ab3ff30bbaaf32929d4321e29be1bcec2d6e31ed63fc7308b5
7
+ data.tar.gz: 9221b6ec0d931d93ab30a0fa50389441ad7f4368f62d75d2c7dc8600580f109913aeb937e2e3bff1244b10cc1ba61732036d6ee28d3972683c55482d64f6d3b2
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.2
1
+ 2.6.6
data/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ N/A
9
+
10
+ ## [1.0.3] - 2023-05-26
11
+ ### Added
12
+ - Added an LetsEncrypt guide to the README, including the scripts to communicate with LetsEncrypt.
13
+ - Added support for CAA-records, https://blog.qualys.com/product-tech/2017/03/13/caa-mandated-by-cabrowser-forum
14
+
8
15
  ## [1.0.2] - 2019-05-11
9
16
  ### Fixed
10
17
  - Fixed issue with the non-interactive printer https://github.com/gfish/sprinkle_dns/commit/1e43591c46e056aab9711ccb37eaf91c904969cc
data/Gemfile.lock CHANGED
@@ -1,59 +1,58 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sprinkle_dns (1.0.1)
4
+ sprinkle_dns (1.0.2)
5
5
  aws-sdk-route53 (~> 1.21)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- addressable (2.6.0)
11
- public_suffix (>= 2.0.2, < 4.0)
12
- aws-eventstream (1.0.3)
13
- aws-partitions (1.160.0)
14
- aws-sdk-core (3.50.0)
15
- aws-eventstream (~> 1.0, >= 1.0.2)
16
- aws-partitions (~> 1.0)
10
+ addressable (2.7.0)
11
+ public_suffix (>= 2.0.2, < 5.0)
12
+ aws-eventstream (1.1.0)
13
+ aws-partitions (1.345.0)
14
+ aws-sdk-core (3.104.3)
15
+ aws-eventstream (~> 1, >= 1.0.2)
16
+ aws-partitions (~> 1, >= 1.239.0)
17
17
  aws-sigv4 (~> 1.1)
18
18
  jmespath (~> 1.0)
19
- aws-sdk-route53 (1.22.0)
20
- aws-sdk-core (~> 3, >= 3.48.2)
19
+ aws-sdk-route53 (1.40.0)
20
+ aws-sdk-core (~> 3, >= 3.99.0)
21
21
  aws-sigv4 (~> 1.1)
22
- aws-sigv4 (1.1.0)
23
- aws-eventstream (~> 1.0, >= 1.0.2)
24
- coderay (1.1.2)
22
+ aws-sigv4 (1.2.1)
23
+ aws-eventstream (~> 1, >= 1.0.2)
24
+ coderay (1.1.3)
25
25
  crack (0.4.3)
26
26
  safe_yaml (~> 1.0.0)
27
- diff-lcs (1.3)
28
- docile (1.3.1)
29
- hashdiff (0.3.9)
30
- jmespath (1.4.0)
31
- json (2.2.0)
32
- method_source (0.9.2)
33
- pry (0.12.2)
34
- coderay (~> 1.1.0)
35
- method_source (~> 0.9.0)
36
- public_suffix (3.0.3)
37
- rake (12.3.2)
38
- rspec (3.8.0)
39
- rspec-core (~> 3.8.0)
40
- rspec-expectations (~> 3.8.0)
41
- rspec-mocks (~> 3.8.0)
42
- rspec-core (3.8.0)
43
- rspec-support (~> 3.8.0)
44
- rspec-expectations (3.8.3)
27
+ diff-lcs (1.4.4)
28
+ docile (1.3.2)
29
+ hashdiff (1.0.1)
30
+ jmespath (1.6.1)
31
+ method_source (1.0.0)
32
+ pry (0.14.2)
33
+ coderay (~> 1.1)
34
+ method_source (~> 1.0)
35
+ public_suffix (4.0.5)
36
+ rake (12.3.3)
37
+ rexml (3.2.5)
38
+ rspec (3.9.0)
39
+ rspec-core (~> 3.9.0)
40
+ rspec-expectations (~> 3.9.0)
41
+ rspec-mocks (~> 3.9.0)
42
+ rspec-core (3.9.2)
43
+ rspec-support (~> 3.9.3)
44
+ rspec-expectations (3.9.2)
45
45
  diff-lcs (>= 1.2.0, < 2.0)
46
- rspec-support (~> 3.8.0)
47
- rspec-mocks (3.8.0)
46
+ rspec-support (~> 3.9.0)
47
+ rspec-mocks (3.9.1)
48
48
  diff-lcs (>= 1.2.0, < 2.0)
49
- rspec-support (~> 3.8.0)
50
- rspec-support (3.8.0)
49
+ rspec-support (~> 3.9.0)
50
+ rspec-support (3.9.3)
51
51
  safe_yaml (1.0.5)
52
- simplecov (0.16.1)
52
+ simplecov (0.18.5)
53
53
  docile (~> 1.1)
54
- json (>= 1.8, < 3)
55
- simplecov-html (~> 0.10.0)
56
- simplecov-html (0.10.2)
54
+ simplecov-html (~> 0.11)
55
+ simplecov-html (0.12.3)
57
56
  vcr (3.0.3)
58
57
  webmock (2.3.2)
59
58
  addressable (>= 2.3.6)
@@ -64,8 +63,9 @@ PLATFORMS
64
63
  ruby
65
64
 
66
65
  DEPENDENCIES
67
- pry (~> 0.12)
66
+ pry (~> 0.14.2)
68
67
  rake (~> 12.3)
68
+ rexml (~> 3.2)
69
69
  rspec (~> 3.8)
70
70
  simplecov (~> 0.16)
71
71
  sprinkle_dns!
@@ -73,4 +73,4 @@ DEPENDENCIES
73
73
  webmock (~> 2.3)
74
74
 
75
75
  BUNDLED WITH
76
- 1.17.2
76
+ 2.4.10
data/README.md CHANGED
@@ -181,3 +181,120 @@ For a more "locked down" policy you can use this (remember to update the `resour
181
181
  ]
182
182
  }
183
183
  ```
184
+
185
+ # Obtain certificates with LetsEncrypt
186
+
187
+ Not everyone is aware of it, but LetsEncrypt allows for a DNS-challenge, this means that if you want to have a certificate for `billetto.com` you can ask certbot to use the DNS-challenge, and run a script:
188
+
189
+ ```bash
190
+ certbot --preferred-challenges dns --manual-auth-hook "bash run_my_dns_script.sh"
191
+ ```
192
+
193
+ The script `run_my_dns_script.sh` will then recieve two ENV-variables, one for `CERTBOT_DOMAIN` which in our example is `billetto.com` and `CERTBOT_VALIDATION` which is a value that needs to be set in the DNS, so in order to prove to LetsEncrypt that we manage the domain we have to set the following:
194
+
195
+ ```
196
+ TXT _acme-challenge.ENV['CERTBOT_DOMAIN'] ENV['CERTBOT_VALIDATION']
197
+ ```
198
+
199
+ Instead of a bash-script, we can use Ruby and SprinkleDNS like so:
200
+
201
+ ```ruby
202
+ #!/usr/bin/env ruby
203
+ require 'sprinkle_dns'
204
+ require_relative '../includes/access_keys'
205
+
206
+ raise 'ENV-variable CERTBOT_DOMAIN is not supplied' if ENV['CERTBOT_DOMAIN'].nil?
207
+ raise 'ENV-variable CERTBOT_VALIDATION is not supplied' if ENV['CERTBOT_VALIDATION'].nil?
208
+
209
+ c = SprinkleDNS::Route53Client.new(ACCESS_KEY_ID, SECRET_ACCESS_KEY)
210
+ s = SprinkleDNS::Client.new(c, interactive_progress: false, diff: false, force: true, delete: false, create_hosted_zones: false)
211
+ s.entry('TXT', "_acme-challenge.#{ENV['CERTBOT_DOMAIN']}", %Q{"#{ENV['CERTBOT_VALIDATION']}"}, 60)
212
+ s.sprinkle!
213
+ ```
214
+
215
+ Save it as `dns_auth.rb`, and remember to chmod it: `chmod +x dns_auth.rb`.
216
+
217
+ Now you can start on the main script `ssl_certbot.rb`:
218
+
219
+ ```ruby
220
+ #!/usr/bin/env ruby
221
+ require 'open3'
222
+ require 'fileutils'
223
+
224
+ EMAIL = 'domains@billetto.com'
225
+ MAIN_DOMAIN = 'billetto.com'
226
+ DOMAINS = ['billetto.dk', 'billetto.co.uk', 'billetto.com']
227
+
228
+ def run_command(command)
229
+ puts("+: #{command}")
230
+
231
+ Open3.popen2e(command) do |stdin, stdout_stderr, wait_thread|
232
+ Thread.new do
233
+ stdout_stderr.each {|l| puts l }
234
+ end
235
+ wait_thread.value
236
+ end
237
+ end
238
+
239
+ def print_guide
240
+ puts "Congratulations, you have a new certificate!"
241
+ puts "----------------------------------------------------------------"
242
+ puts "CERTIFICATE: #{Dir.pwd}/config/live/billetto.com/cert.pem"
243
+ puts "KEY: #{Dir.pwd}/config/live/billetto.com/privkey.pem"
244
+ puts "CHAIN: #{Dir.pwd}/config/live/billetto.com/chain.pem"
245
+ end
246
+
247
+ letsencrypt_dirs = ['config', 'work', 'logs']
248
+ previous_letsencrypt_run = letsencrypt_dirs.all?{|dir| Dir.exist?(dir)}
249
+
250
+ case ARGV[0]
251
+ when 'create'
252
+ certbot_commands = []
253
+ certbot_commands << "certbot certonly"
254
+ certbot_commands << "--manual --manual-public-ip-logging-ok --agree-tos"
255
+ certbot_commands << "--email #{EMAIL} --update-registration --no-eff-email"
256
+ certbot_commands << "--non-interactive --preferred-challenges dns"
257
+ certbot_commands << "--manual-auth-hook \"bundle exec #{Dir.pwd}/dns_auth.rb\""
258
+ certbot_commands << "--config-dir config --work-dir work --logs-dir logs"
259
+ certbot_commands << "--cert-name #{MAIN_DOMAIN}"
260
+ DOMAINS.each do |domain|
261
+ certbot_commands << "-d #{domain} -d www.#{domain}"
262
+ end
263
+ certbot_commands = certbot_commands.join(" ")
264
+
265
+ letsencrypt_dirs.select{|dirname| Dir.exists?(dirname)}.map{|dirname| FileUtils.remove_dir(dirname)}
266
+ run_command("mkdir -p #{letsencrypt_dirs.join(' ')}")
267
+ stdout, stdeerr, status = run_command(certbot_commands)
268
+
269
+ print_guide
270
+ when 'renew'
271
+ if previous_letsencrypt_run
272
+ certbot_commands = []
273
+ certbot_commands << "certbot renew"
274
+ certbot_commands << "--manual --manual-public-ip-logging-ok --agree-tos"
275
+ certbot_commands << "--email #{EMAIL} --update-registration --no-eff-email"
276
+ certbot_commands << "--non-interactive --preferred-challenges dns"
277
+ certbot_commands << "--manual-auth-hook \"bundle exec #{Dir.pwd}/dns_auth.rb\""
278
+ certbot_commands << "--config-dir config --work-dir work --logs-dir logs"
279
+ certbot_commands << "--cert-name #{MAIN_DOMAIN}"
280
+ certbot_commands = certbot_commands.join(" ")
281
+ stdout, stdeerr, status = run_command(certbot_commands)
282
+
283
+ print_guide
284
+ else
285
+ puts "It seems like there are no files from a previous LetsEncrypt run, exiting!"
286
+ exit 1
287
+ end
288
+ else
289
+ puts "Usage:"
290
+ puts "bundle exec ruby ssl_certbot.rb COMMAND"
291
+ puts
292
+ puts "Commands:"
293
+ puts "create - Request a new certificate from LetsEncrypt, should only be used on the first run, or if you have modified the list of domains."
294
+ puts "renew - Renew an already created certificate"
295
+ end
296
+ ```
297
+
298
+ You can update the variables in top of the script, and then you can run `bundle exec ruby ssl_certbot.rb create`, and everytime you need to renew the certificate you can run `bundle exec ruby ssl_certbot.rb renew`.
299
+
300
+ You will need to run the `create` if your list of domains have changed.
@@ -83,7 +83,7 @@ module SprinkleDNS
83
83
  private
84
84
 
85
85
  def valid_record_types
86
- ['SOA','A','TXT','NS','CNAME','MX','NAPTR','PTR','SRV','SPF','AAAA']
86
+ ['SOA','A','TXT','NS','CNAME','MX','NAPTR','PTR','SRV','SPF','AAAA', 'CAA']
87
87
  end
88
88
 
89
89
  end
@@ -90,7 +90,7 @@ module SprinkleDNS
90
90
  private
91
91
 
92
92
  def valid_record_types
93
- ['SOA','A','TXT','NS','CNAME','MX','NAPTR','PTR','SRV','SPF','AAAA']
93
+ ['SOA','A','TXT','NS','CNAME','MX','NAPTR','PTR','SRV','SPF','AAAA', 'CAA']
94
94
  end
95
95
 
96
96
  end
@@ -9,8 +9,6 @@ module SprinkleDNS
9
9
  end
10
10
 
11
11
  def fetch_hosted_zones(filter: [])
12
- hosted_zones = []
13
-
14
12
  if filter.empty?
15
13
  return []
16
14
  end
@@ -1,3 +1,3 @@
1
1
  module SprinkleDNS
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -24,6 +24,7 @@ require 'simplecov'
24
24
  SimpleCov.start
25
25
 
26
26
  require 'vcr'
27
+ require 'pry'
27
28
 
28
29
  require './spec/support/entry_helpers'
29
30
 
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe "CAA-records" do
4
+ it 'should allow for CAA records' do
5
+ hz = SprinkleDNS::HostedZone.new('colourful.com.')
6
+ e1 = SprinkleDNS::HostedZoneEntry.new('A', 'colourful.com.', Array.wrap('80.80.80.80'), 3600, hz.name)
7
+ e1.persisted!
8
+ hz.resource_record_sets << e1
9
+
10
+ client = SprinkleDNS::MockClient.new([hz])
11
+ sdns = SprinkleDNS::Client.new(client, dry_run: false, delete: true, force: true)
12
+
13
+ sdns.entry('A', 'colourful.com', '80.80.80.80', 3600)
14
+ sdns.entry('CAA', 'colourful.com', '0 issue "letsencrypt.org"', 3600)
15
+
16
+ existing_hosted_zones, _ = sdns.sprinkle!
17
+
18
+ shz = client.fetch_hosted_zones(filter: [hz.name]).first
19
+
20
+ rrs = shz.resource_record_sets.select{|rrs| rrs.type == 'CAA' && rrs.name == 'colourful.com.'}.first
21
+ expect(rrs.ttl).to eq 3600
22
+ expect(rrs.value).to eq ['0 issue "letsencrypt.org"']
23
+ end
24
+ end
@@ -269,7 +269,7 @@ RSpec.describe SprinkleDNS::Client do
269
269
 
270
270
  context 'record validation' do
271
271
  it 'should only allow valid string records' do
272
- valid_records = ['SOA','A','TXT','NS','CNAME','MX','NAPTR','PTR','SRV','SPF','AAAA']
272
+ valid_records = ['SOA','A','TXT','NS','CNAME','MX','NAPTR','PTR','SRV','SPF','AAAA', 'CAA']
273
273
 
274
274
  valid_records.each do |record_type|
275
275
  r53c = SprinkleDNS::Route53Client.new('1','2')
@@ -280,7 +280,7 @@ RSpec.describe SprinkleDNS::Client do
280
280
  end
281
281
 
282
282
  it 'should not allow symbols for records' do
283
- invalid_records = [:SOA, :A, :TXT, :NS, :CNAME, :MX, :NAPTR, :PTR, :SRV, :SPF, :AAAA]
283
+ invalid_records = [:SOA, :A, :TXT, :NS, :CNAME, :MX, :NAPTR, :PTR, :SRV, :SPF, :AAAA, :CAA]
284
284
 
285
285
  invalid_records.each do |record_type|
286
286
  r53c = SprinkleDNS::Route53Client.new('1','2')
data/sprinkle_dns.gemspec CHANGED
@@ -22,8 +22,9 @@ Gem::Specification.new do |gem|
22
22
 
23
23
  gem.add_development_dependency "rspec", '~> 3.8'
24
24
  gem.add_development_dependency "simplecov", '~> 0.16'
25
- gem.add_development_dependency "pry", '~> 0.12'
25
+ gem.add_development_dependency "pry", '~> 0.14.2'
26
26
  gem.add_development_dependency "rake", '~> 12.3'
27
27
  gem.add_development_dependency "vcr", '~> 3.0'
28
28
  gem.add_development_dependency "webmock", '~> 2.3'
29
+ gem.add_development_dependency "rexml", '~> 3.2'
29
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sprinkle_dns
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kasper Grubbe
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-10 00:00:00.000000000 Z
11
+ date: 2023-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-route53
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.12'
61
+ version: 0.14.2
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.12'
68
+ version: 0.14.2
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '2.3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rexml
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.2'
111
125
  description: Make handling DNS easier by using simple Ruby constructs
112
126
  email:
113
127
  - kaspergrubbe@gmail.com
@@ -152,6 +166,7 @@ files:
152
166
  - readme_files/force_false.png
153
167
  - spec/spec_helper.rb
154
168
  - spec/support/entry_helpers.rb
169
+ - spec/unit/caa_record.rb
155
170
  - spec/unit/cli_hosted_zone_diff_spec.rb
156
171
  - spec/unit/hosted_zone_domain_spec.rb
157
172
  - spec/unit/hosted_zone_spec.rb
@@ -164,7 +179,7 @@ licenses:
164
179
  - MIT
165
180
  - GPL-2.0
166
181
  metadata: {}
167
- post_install_message:
182
+ post_install_message:
168
183
  rdoc_options: []
169
184
  require_paths:
170
185
  - lib
@@ -179,13 +194,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
194
  - !ruby/object:Gem::Version
180
195
  version: '0'
181
196
  requirements: []
182
- rubygems_version: 3.0.3
183
- signing_key:
197
+ rubygems_version: 3.4.10
198
+ signing_key:
184
199
  specification_version: 4
185
200
  summary: Make handling DNS easier
186
201
  test_files:
187
202
  - spec/spec_helper.rb
188
203
  - spec/support/entry_helpers.rb
204
+ - spec/unit/caa_record.rb
189
205
  - spec/unit/cli_hosted_zone_diff_spec.rb
190
206
  - spec/unit/hosted_zone_domain_spec.rb
191
207
  - spec/unit/hosted_zone_spec.rb