github-pages-health-check 1.17.2 → 1.17.9

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: 41b89d75e93004b6de7694b363bcf15769ee02c8b03e7e6cea0eab99afa213cd
4
- data.tar.gz: 8c0ee563b5ca7c34bfcbbb61048b0e375e936ca8be0f8d527e72b1fa41917a50
3
+ metadata.gz: 4c5eb1174f9f171c28477d1971a3272da065cf3af53241759fd7e2f9f19fa513
4
+ data.tar.gz: 9a5b9221d8fc8dae3834f960203f8cfd0342e0796051165e3b79bb9a31c305a4
5
5
  SHA512:
6
- metadata.gz: 4e319123a847776a35923ce81d48d82e633a036166decf229bcd277437288f85c9333739af879584ea7ceb21d295a306b4004089e157da52721e725dd9eb1faf
7
- data.tar.gz: b2a091d7fdd15f89ca9d0ce22d9c6c8bfb6357a1c7f660ce8faa3ee8d5b8a0e3ea2f2299fab35dfc037c8ec369d6321bc2ff17c8923f18a2887754d1ab1769a7
6
+ metadata.gz: 8e5fe1e4172bb296dd1a3814914d2949fe4c4d50f7cb384dbfb0adad7d364f99913ae7c040d90bb362cf8bdbe37b7e7db01deace5773ce73c78d70879da23b07
7
+ data.tar.gz: ee584b59c168c47c194af89b9ed79c6911573acb277fd65fb4dbbaa4f227fce56779a5a88af5c676b537011daacf16ec6190f388f27ef47b37fb9f25fd3557b3
@@ -10,6 +10,7 @@ jobs:
10
10
  - 2.5
11
11
  - 2.6
12
12
  - 2.7
13
+ - 3.0
13
14
  steps:
14
15
  - uses: actions/checkout@master
15
16
  - name: script/cibuild-docker
data/.rubocop.yml CHANGED
@@ -52,7 +52,7 @@ Style/ClassAndModuleChildren:
52
52
  Enabled: false # module X<\n>module Y is just as good as module X::Y.
53
53
 
54
54
  Layout/LineLength:
55
- Max: 90
55
+ Max: 120
56
56
  Severity: warning
57
57
  Exclude:
58
58
  - github-pages-health-check.gemspec
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ group :development do
6
6
  gem "dotenv", "~> 2.7"
7
7
  gem "gem-release", "~> 2.1"
8
8
  gem "pry", "~> 0.10"
9
+ gem "pry-byebug"
9
10
  gem "rspec", "~> 3.0"
10
11
  gem "rubocop", "~> 0.52"
11
12
  gem "webmock", "~> 3.8"
data/README.md CHANGED
@@ -81,3 +81,40 @@ check = GitHubPages::HealthCheck::Site.new "github/pages-health-check", access_t
81
81
  ```
82
82
 
83
83
  You can also set `OCTOKIT_ACCESS_TOKEN` as an environmental variable, or via a `.env` file in your working directory.
84
+
85
+ ### Command Line
86
+
87
+ ```
88
+ ./script/check pages.github.com
89
+
90
+ host: pages.github.com
91
+ uri: https://pages.github.com/
92
+ nameservers: :default
93
+ dns_resolves?: true
94
+ proxied?: false
95
+ cloudflare_ip?: false
96
+ fastly_ip?: false
97
+ old_ip_address?: false
98
+ a_record?: false
99
+ cname_record?: true
100
+ mx_records_present?: false
101
+ valid_domain?: true
102
+ apex_domain?: false
103
+ should_be_a_record?: false
104
+ cname_to_github_user_domain?: true
105
+ cname_to_pages_dot_github_dot_com?: false
106
+ cname_to_fastly?: false
107
+ pointed_to_github_pages_ip?: false
108
+ non_github_pages_ip_present?: false
109
+ pages_domain?: true
110
+ served_by_pages?: true
111
+ valid?: true
112
+ reason:
113
+ https?: true
114
+ enforces_https?: true
115
+ https_error:
116
+ https_eligible?: true
117
+ caa_error:
118
+ dns_zone_soa?: false
119
+ dns_zone_ns?: false
120
+ ```
@@ -9,7 +9,14 @@
9
9
  197.234.240.0/22
10
10
  198.41.128.0/17
11
11
  162.158.0.0/15
12
- 172.64.0.0/13
13
- 131.0.72.0/22
14
12
  104.16.0.0/13
15
13
  104.24.0.0/14
14
+ 172.64.0.0/13
15
+ 131.0.72.0/22
16
+ 2400:cb00::/32
17
+ 2606:4700::/32
18
+ 2803:f800::/32
19
+ 2405:b500::/32
20
+ 2405:8100::/32
21
+ 2a06:98c0::/29
22
+ 2c0f:f248::/32
@@ -4,7 +4,7 @@
4
4
  103.245.222.0/23
5
5
  103.245.224.0/24
6
6
  104.156.80.0/20
7
- 146.75.0.0/16
7
+ 146.75.0.0/17
8
8
  151.101.0.0/16
9
9
  157.52.64.0/18
10
10
  167.82.0.0/17
@@ -14,4 +14,6 @@
14
14
  172.111.64.0/18
15
15
  185.31.16.0/22
16
16
  199.27.72.0/21
17
- 199.232.0.0/16
17
+ 199.232.0.0/16
18
+ 2a04:4e40::/32
19
+ 2a04:4e42::/32
@@ -19,6 +19,6 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency("addressable", "~> 2.3")
20
20
  s.add_dependency("dnsruby", "~> 1.60")
21
21
  s.add_dependency("octokit", "~> 4.0")
22
- s.add_dependency("public_suffix", ">= 2.0.2", "< 5.0")
22
+ s.add_dependency("public_suffix", ">= 3.0", "< 5.0")
23
23
  s.add_dependency("typhoeus", "~> 1.3")
24
24
  end
@@ -77,15 +77,25 @@ module GitHubPages
77
77
  185.199.111.153
78
78
  ).freeze
79
79
 
80
+ CURRENT_IPV6_ADDRESSES = %w(
81
+ 2606:50c0:8000::153
82
+ 2606:50c0:8001::153
83
+ 2606:50c0:8002::153
84
+ 2606:50c0:8003::153
85
+ ).freeze
86
+
87
+ CURRENT_IP_ADDRESSES_ALL =
88
+ (CURRENT_IP_ADDRESSES + CURRENT_IPV6_ADDRESSES).freeze
89
+
80
90
  HASH_METHODS = %i[
81
91
  host uri nameservers dns_resolves? proxied? cloudflare_ip?
82
- fastly_ip? old_ip_address? a_record? cname_record?
83
- mx_records_present? valid_domain? apex_domain? should_be_a_record?
84
- cname_to_github_user_domain? cname_to_pages_dot_github_dot_com?
85
- cname_to_fastly? pointed_to_github_pages_ip?
86
- non_github_pages_ip_present? pages_domain?
92
+ fastly_ip? old_ip_address? a_record? aaaa_record? a_record_present? aaaa_record_present?
93
+ cname_record? mx_records_present? valid_domain? apex_domain?
94
+ should_be_a_record? cname_to_github_user_domain?
95
+ cname_to_pages_dot_github_dot_com? cname_to_fastly?
96
+ pointed_to_github_pages_ip? non_github_pages_ip_present? pages_domain?
87
97
  served_by_pages? valid? reason valid_domain? https?
88
- enforces_https? https_error https_eligible? caa_error
98
+ enforces_https? https_error https_eligible? caa_error dns_zone_soa? dns_zone_ns?
89
99
  ].freeze
90
100
 
91
101
  def self.redundant(host)
@@ -128,14 +138,13 @@ module GitHubPages
128
138
  def invalid_aaaa_record?
129
139
  return @invalid_aaaa_record if defined? @invalid_aaaa_record
130
140
 
131
- @invalid_aaaa_record = (valid_domain? && should_be_a_record? &&
132
- aaaa_record_present?)
141
+ @invalid_aaaa_record = (valid_domain? && aaaa_record_present? && !should_be_a_record?)
133
142
  end
134
143
 
135
144
  def invalid_a_record?
136
145
  return @invalid_a_record if defined? @invalid_a_record
137
146
 
138
- @invalid_a_record = (valid_domain? && a_record? && !should_be_a_record?)
147
+ @invalid_a_record = (valid_domain? && a_record_present? && !should_be_a_record?)
139
148
  end
140
149
 
141
150
  def invalid_cname?
@@ -164,7 +173,10 @@ module GitHubPages
164
173
  # Is this domain an apex domain, meaning a CNAME would be innapropriate
165
174
  def apex_domain?
166
175
  return @apex_domain if defined?(@apex_domain)
167
- return unless valid_domain?
176
+
177
+ return false unless valid_domain?
178
+
179
+ return true if dns_zone_soa? && dns_zone_ns?
168
180
 
169
181
  # PublicSuffix.domain pulls out the apex-level domain name.
170
182
  # E.g. PublicSuffix.domain("techblog.netflix.com") # => "netflix.com"
@@ -177,6 +189,30 @@ module GitHubPages
177
189
  :ignore_private => true) == unicode_host
178
190
  end
179
191
 
192
+ #
193
+ # Does the domain have an associated SOA record?
194
+ #
195
+ def dns_zone_soa?
196
+ return @soa_records if defined?(@soa_records)
197
+ return false unless dns?
198
+
199
+ @soa_records = dns.any? do |answer|
200
+ answer.type == Dnsruby::Types::SOA && answer.name.to_s == host
201
+ end
202
+ end
203
+
204
+ #
205
+ # Does the domain have assoicated NS records?
206
+ #
207
+ def dns_zone_ns?
208
+ return @ns_records if defined?(@ns_records)
209
+ return false unless dns?
210
+
211
+ @ns_records = dns.any? do |answer|
212
+ answer.type == Dnsruby::Types::NS && answer.name.to_s == host
213
+ end
214
+ end
215
+
180
216
  # Should the domain use an A record?
181
217
  def should_be_a_record?
182
218
  !pages_io_domain? && (apex_domain? || mx_records_present?)
@@ -186,20 +222,20 @@ module GitHubPages
186
222
  !should_be_a_record?
187
223
  end
188
224
 
189
- # Is the domain's first response an A record to a valid GitHub Pages IP?
225
+ # Is the domain's first response an A or AAAA record to a valid GitHub Pages IP?
190
226
  def pointed_to_github_pages_ip?
191
- a_record? && CURRENT_IP_ADDRESSES.include?(dns.first.address.to_s)
227
+ return false unless address_record?
228
+
229
+ CURRENT_IP_ADDRESSES_ALL.include?(dns.first.address.to_s.downcase)
192
230
  end
193
231
 
194
- # Are any of the domain's A records pointing elsewhere?
232
+ # Are any of the domain's A or AAAA records pointing elsewhere?
195
233
  def non_github_pages_ip_present?
196
234
  return unless dns?
197
235
 
198
- a_records = dns.select { |answer| answer.type == Dnsruby::Types::A }
199
-
200
- a_records.any? { |answer| !github_pages_ip?(answer.address.to_s) }
201
-
202
- false
236
+ dns
237
+ .select { |a| Dnsruby::Types::A == a.type || Dnsruby::Types::AAAA == a.type }
238
+ .any? { |a| !github_pages_ip?(a.address.to_s) }
203
239
  end
204
240
 
205
241
  # Is the domain's first response a CNAME to a pages domain?
@@ -278,7 +314,9 @@ module GitHubPages
278
314
  Dnsruby::Types::A,
279
315
  Dnsruby::Types::AAAA,
280
316
  Dnsruby::Types::CNAME,
281
- Dnsruby::Types::MX
317
+ Dnsruby::Types::MX,
318
+ Dnsruby::Types::NS,
319
+ Dnsruby::Types::SOA
282
320
  ].freeze
283
321
 
284
322
  # Returns an array of DNS answers
@@ -316,15 +354,32 @@ module GitHubPages
316
354
 
317
355
  # Is this domain's first response an A record?
318
356
  def a_record?
357
+ return @is_a_record if defined?(@is_a_record)
319
358
  return unless dns?
320
359
 
321
- dns.first.type == Dnsruby::Types::A
360
+ @is_a_record = Dnsruby::Types::A == dns.first.type
322
361
  end
323
362
 
363
+ # Is this domain's first response an AAAA record?
364
+ def aaaa_record?
365
+ return @is_aaaa_record if defined?(@is_aaaa_record)
366
+ return unless dns?
367
+
368
+ @is_aaaa_record = Dnsruby::Types::AAAA == dns.first.type
369
+ end
370
+
371
+ # Does this domain has an A record setup (not necessarily as the first record)?
372
+ def a_record_present?
373
+ return unless dns?
374
+
375
+ dns.any? { |answer| answer.type == Dnsruby::Types::A && answer.name.to_s == host }
376
+ end
377
+
378
+ # Does this domain has an AAAA record setup (not necessarily as the first record)?
324
379
  def aaaa_record_present?
325
380
  return unless dns?
326
381
 
327
- dns.any? { |answer| answer.type == Dnsruby::Types::AAAA }
382
+ dns.any? { |answer| answer.type == Dnsruby::Types::AAAA && answer.name.to_s == host }
328
383
  end
329
384
 
330
385
  # Is this domain's first response a CNAME record?
@@ -339,6 +394,8 @@ module GitHubPages
339
394
  # The domain to which this domain's CNAME resolves
340
395
  # Returns nil if the domain is not a CNAME
341
396
  def cname
397
+ return unless dns?
398
+
342
399
  cnames = dns.take_while { |answer| answer.type == Dnsruby::Types::CNAME }
343
400
  return if cnames.empty?
344
401
 
@@ -392,8 +449,6 @@ module GitHubPages
392
449
  def https_eligible?
393
450
  # Can't have any IP's which aren't GitHub's present.
394
451
  return false if non_github_pages_ip_present?
395
- # Can't have any AAAA records present
396
- return false if aaaa_record_present?
397
452
  # Must be a CNAME or point to our IPs.
398
453
 
399
454
  # Only check the one domain if a CNAME. Don't check the parent domain.
@@ -405,13 +460,17 @@ module GitHubPages
405
460
 
406
461
  # Any errors querying CAA records
407
462
  def caa_error
408
- return nil unless caa.errored?
463
+ return nil unless caa&.errored?
409
464
 
410
465
  caa.error.class.name
411
466
  end
412
467
 
413
468
  private
414
469
 
470
+ def address_record?
471
+ a_record? || aaaa_record?
472
+ end
473
+
415
474
  def caa
416
475
  @caa ||= GitHubPages::HealthCheck::CAA.new(
417
476
  :host => cname&.host || host,
@@ -486,10 +545,12 @@ module GitHubPages
486
545
  def cdn_ip?(cdn)
487
546
  return unless dns?
488
547
 
489
- a_records = dns.select { |answer| answer.type == Dnsruby::Types::A }
490
- return false if !a_records || a_records.empty?
548
+ address_records = dns.select do |answer|
549
+ Dnsruby::Types::A == answer.type || Dnsruby::Types::AAAA == answer.type
550
+ end
551
+ return false if !address_records || address_records.empty?
491
552
 
492
- a_records.all? do |answer|
553
+ address_records.all? do |answer|
493
554
  cdn.controls_ip?(answer.address)
494
555
  end
495
556
  end
@@ -499,7 +560,7 @@ module GitHubPages
499
560
  end
500
561
 
501
562
  def github_pages_ip?(ip_addr)
502
- CURRENT_IP_ADDRESSES.include?(ip_addr)
563
+ CURRENT_IP_ADDRESSES_ALL.include?(ip_addr&.to_s&.downcase)
503
564
  end
504
565
  end
505
566
  end
@@ -8,9 +8,9 @@ module GitHubPages
8
8
 
9
9
  def message
10
10
  <<-MSG
11
- Your site's DNS settings are using a custom subdomain, #{domain.host},
12
- that's set up with an AAAA record. GitHub Pages currently does not support
13
- IPv6.
11
+ Your site's DNS settings are using a custom subdomain, #{domain.host},
12
+ that's set up as an AAAA record. We recommend you change this to a CNAME
13
+ record pointing at #{username}.github.io.
14
14
  MSG
15
15
  end
16
16
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GitHubPages
4
4
  module HealthCheck
5
- VERSION = "1.17.2"
5
+ VERSION = "1.17.9"
6
6
  end
7
7
  end
data/script/check CHANGED
@@ -3,6 +3,8 @@
3
3
  #
4
4
  # Usage: script/check [DOMAIN]
5
5
 
6
+ require "rubygems"
7
+ require "bundler/setup"
6
8
  require_relative "../lib/github-pages-health-check"
7
9
 
8
10
  if ARGV.count != 1
@@ -8,15 +8,43 @@ require "open-uri"
8
8
  require "json"
9
9
 
10
10
  SOURCES = {
11
- :cloudflare => "https://www.cloudflare.com/ips-v4",
12
- :fastly => "https://api.fastly.com/public-ip-list"
11
+ :cloudflare => ["https://www.cloudflare.com/ips-v4", "https://www.cloudflare.com/ips-v6"],
12
+ :fastly => ["https://api.fastly.com/public-ip-list"]
13
13
  }.freeze
14
14
 
15
- SOURCES.each do |source, url|
15
+ def parse_fastly(data)
16
+ json_data = JSON.parse(data)
17
+ (json_data["addresses"] + json_data["ipv6_addresses"]).join("\n")
18
+ end
19
+
20
+ def parse_cloudflare(data)
21
+ data
22
+ end
23
+
24
+ def fetch_ips_from_cdn(urls)
25
+ urls.map do |url|
26
+ puts "Fetching #{url}..."
27
+ URI.parse(url).open.read
28
+ end.join("\n")
29
+ end
30
+
31
+ def update_cdn_file(source, data)
16
32
  file = "config/#{source}-ips.txt"
17
- puts "Fetching #{url}..."
18
- data = open(url).read
19
- data = JSON.parse(data)["addresses"].join("\n") if source == :fastly
20
33
  File.write(file, data)
34
+ puts "Writing contents to #{file} and staging changes."
21
35
  `git add --verbose #{file}`
22
36
  end
37
+
38
+ def parse_cdn_response(source, ips)
39
+ send("parse_#{source}", ips)
40
+ end
41
+
42
+ def update_cdn_ips(source, urls)
43
+ ips = fetch_ips_from_cdn(urls)
44
+ data = parse_cdn_response(source, ips)
45
+ update_cdn_file(source, data)
46
+ end
47
+
48
+ SOURCES.each do |source, urls|
49
+ update_cdn_ips(source, urls)
50
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github-pages-health-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.17.2
4
+ version: 1.17.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-21 00:00:00.000000000 Z
11
+ date: 2021-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 2.0.2
61
+ version: '3.0'
62
62
  - - "<"
63
63
  - !ruby/object:Gem::Version
64
64
  version: '5.0'
@@ -68,7 +68,7 @@ dependencies:
68
68
  requirements:
69
69
  - - ">="
70
70
  - !ruby/object:Gem::Version
71
- version: 2.0.2
71
+ version: '3.0'
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '5.0'
@@ -99,7 +99,6 @@ files:
99
99
  - ".rspec"
100
100
  - ".rubocop.yml"
101
101
  - ".ruby-version"
102
- - ".travis.yml"
103
102
  - Dockerfile
104
103
  - Gemfile
105
104
  - LICENSE.md
@@ -161,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
160
  - !ruby/object:Gem::Version
162
161
  version: '0'
163
162
  requirements: []
164
- rubygems_version: 3.1.2
163
+ rubygems_version: 3.2.9
165
164
  signing_key:
166
165
  specification_version: 4
167
166
  summary: Checks your GitHub Pages site for commons DNS configuration issues
data/.travis.yml DELETED
@@ -1,16 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.5
4
- - 2.6
5
- - 2.7
6
-
7
- before_install:
8
- - gem update --system
9
-
10
- script: "script/cibuild"
11
-
12
- notifications:
13
- email: false
14
-
15
- cache: bundler
16
- sudo: false