From bfa13e5325a688a8ce2ecc7bb251a0d8606a0dae Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sat, 17 Sep 2016 10:02:51 -0700 Subject: [PATCH] Detect and remove dead custom domains --- migrations/092_domain_check.rb | 9 ++++++ views/templates/email/domain_fail.erb | 10 ++++++ workers/lets_encrypt_worker.rb | 46 ++++++++++++++++++++++----- 3 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 migrations/092_domain_check.rb create mode 100644 views/templates/email/domain_fail.erb diff --git a/migrations/092_domain_check.rb b/migrations/092_domain_check.rb new file mode 100644 index 00000000..06c6f91a --- /dev/null +++ b/migrations/092_domain_check.rb @@ -0,0 +1,9 @@ +Sequel.migration do + up { + DB.add_column :sites, :domain_fail_count, :integer, default: 0 + } + + down { + DB.drop_column :sites, :domain_fail_count + } +end diff --git a/views/templates/email/domain_fail.erb b/views/templates/email/domain_fail.erb new file mode 100644 index 00000000..ba0ae742 --- /dev/null +++ b/views/templates/email/domain_fail.erb @@ -0,0 +1,10 @@ +Hello <%= site.username %>, + +We have detected that your domain name <%= domain %> is no longer working with your Neocities web site, so we automatically removed it from the domain settings for your site. + +This does not mean your site has been deleted! It is still up and accessible at the following location: <%= site.uri %> + +If you believe your domain not working is a mistake, please check with your domain registrar and make sure the settings are correct for Neocities, and that your domain was properly renewed. + +Best, +The Neocities Team diff --git a/workers/lets_encrypt_worker.rb b/workers/lets_encrypt_worker.rb index b16fef5a..40d18ece 100644 --- a/workers/lets_encrypt_worker.rb +++ b/workers/lets_encrypt_worker.rb @@ -4,7 +4,7 @@ class LetsEncryptWorker class InvalidAuthError < StandardError; end class VerifyNotFoundWithDomain < StandardError; end include Sidekiq::Worker - sidekiq_options queue: :lets_encrypt_worker, retry: 5, backtrace: true + sidekiq_options queue: :lets_encrypt_worker, retry: 1, backtrace: true sidekiq_retry_in do |count| 1.hour.to_i @@ -50,8 +50,8 @@ class LetsEncryptWorker FileUtils.mkdir_p File.join(site.base_files_path, challenge_base_path) File.write File.join(testfile_fs_path, testfile_name), testfile_key rescue => e - puts "ERROR WRITING TO WELLKNOWN FILE, SKIPPING #{domain}: #{e.inspect}" - next + puts "ERROR WRITING TO WELLKNOWN FILE, FAILING ON THIS SITE: #{site.username} #{domain}: #{e.inspect}" + return end # Ensure that both domains work before sending request. Let's Encrypt has a low @@ -78,9 +78,11 @@ class LetsEncryptWorker begin auth = letsencrypt.authorize domain: domain challenge = auth.http01 - rescue Acme::Client::Error::Malformed - puts "international domains not supported yet, quitting" - return + rescue Acme::Client::Error => e + if e =~ /Internationalized domain names.+not yet supported/ + @international_domain = true + puts "This is an internationalized domain, and so is not yet supported." + end end begin @@ -88,7 +90,7 @@ class LetsEncryptWorker File.write File.join(site.base_files_path, challenge.filename), challenge.file_content rescue => e put "FAILED TO WRITE CHALLENGE: #{site.domain} #{challenge.filename}" - # A verification needs to be made anyways, otherwise 300 of them will jam up the system for a week + # A verification needs to be attempted anyways, otherwise 300 of them will jam up the system for a week end challenge.request_verification @@ -121,7 +123,35 @@ class LetsEncryptWorker end if verified_domains.empty? - puts "no verified domains, skipping" + if @international_domain + puts "still waiting on IDN support, ignoring failure for now" + clean_wellknown_turds site + return + end + + puts "no verified domains, skipping cert setup, reporting invalid domain" + + # This is a bit of an inappropriate shared responsibility, + # but since were here, it looks like the domain is dead, so let's + # try again a few times, but then pull the domain out of our system + # if it looks like it's gone completely. + + if site.domain_fail_count < 60 + site.domain_fail_count += 1 + site.save_changes validate: false + else + old_domain = site.domain + site.domain = nil + site.domain_fail_count = 0 + site.save validate: false + + site.send_email( + subject: "[Neocities] Your domain has stopped working", + body: Tilt.new('./views/templates/email/domain_fail.erb', pretty: true).render(self, site: site, domain: old_domain) + ) + end + + clean_wellknown_turds site return end