mirror of
https://github.com/neocities/neocities.git
synced 2025-04-25 01:32:36 +02:00
checkin of initial letsencrypt code
This commit is contained in:
parent
6a8aaacd20
commit
8473b99d56
11 changed files with 117 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -21,3 +21,6 @@ files/sslsites.zip
|
|||
public/banned_sites
|
||||
public/deleted_sites
|
||||
files/disposable_email_blacklist.conf
|
||||
files/letsencrypt.key
|
||||
files/tor.txt
|
||||
.bundle
|
||||
|
|
1
Gemfile
1
Gemfile
|
@ -39,6 +39,7 @@ gem 'simpleidn'
|
|||
gem 'gandi'
|
||||
gem 'hoe', '3.14.2', require: nil
|
||||
gem 'msgpack'
|
||||
gem 'acme-client'
|
||||
|
||||
platform :mri, :rbx do
|
||||
gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic
|
||||
|
|
16
Gemfile.lock
16
Gemfile.lock
|
@ -1,6 +1,9 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
acme-client (0.3.1)
|
||||
faraday (~> 0.9, >= 0.9.1)
|
||||
json-jwt (~> 1.2, >= 1.2.3)
|
||||
activesupport (4.2.6)
|
||||
i18n (~> 0.7)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
|
@ -14,6 +17,7 @@ GEM
|
|||
ansi (1.5.0)
|
||||
base32 (0.3.2)
|
||||
bcrypt (3.1.11)
|
||||
bindata (2.3.0)
|
||||
blankslate (3.1.3)
|
||||
builder (3.2.2)
|
||||
byebug (8.2.4)
|
||||
|
@ -58,6 +62,8 @@ GEM
|
|||
fabrication (2.15.0)
|
||||
faker (1.6.3)
|
||||
i18n (~> 0.5)
|
||||
faraday (0.9.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.10)
|
||||
ffi-compiler (0.1.3)
|
||||
ffi (>= 1.0.0)
|
||||
|
@ -82,6 +88,12 @@ GEM
|
|||
rack (~> 1.4)
|
||||
rest-client (~> 1.0)
|
||||
json (1.8.3)
|
||||
json-jwt (1.5.2)
|
||||
activesupport
|
||||
bindata
|
||||
multi_json (>= 1.3)
|
||||
securecompare
|
||||
url_safe_base64
|
||||
m (1.4.2)
|
||||
method_source (>= 0.6.7)
|
||||
rake (>= 0.9.2.2)
|
||||
|
@ -104,6 +116,7 @@ GEM
|
|||
mock_redis (0.16.1)
|
||||
msgpack (0.7.5)
|
||||
multi_json (1.11.2)
|
||||
multipart-post (2.0.0)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (3.1.1)
|
||||
|
@ -166,6 +179,7 @@ GEM
|
|||
scrypt (2.1.1)
|
||||
ffi-compiler (>= 0.0.2)
|
||||
rake
|
||||
securecompare (1.0.0)
|
||||
sequel (4.8.0)
|
||||
sequel_pg (1.6.16)
|
||||
pg (>= 0.8.0)
|
||||
|
@ -216,6 +230,7 @@ GEM
|
|||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.2)
|
||||
url_safe_base64 (0.2.2)
|
||||
uuidtools (2.1.5)
|
||||
webmock (1.24.2)
|
||||
addressable (>= 2.3.6)
|
||||
|
@ -233,6 +248,7 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
acme-client
|
||||
addressable
|
||||
ago
|
||||
base32
|
||||
|
|
|
@ -66,6 +66,7 @@ post '/settings/:username/profile' do
|
|||
redirect "/settings/#{@site.username}#profile"
|
||||
end
|
||||
|
||||
=begin
|
||||
post '/settings/:username/ssl' do
|
||||
require_login
|
||||
require_ownership_for_settings
|
||||
|
@ -167,6 +168,7 @@ post '/settings/:username/ssl' do
|
|||
flash[:success] = 'Updated SSL key/certificate.'
|
||||
redirect "/settings/#{@site.username}#custom_domain"
|
||||
end
|
||||
=end
|
||||
|
||||
post '/settings/:username/change_name' do
|
||||
require_login
|
||||
|
@ -241,6 +243,7 @@ post '/settings/:username/custom_domain' do
|
|||
|
||||
if @site.valid?
|
||||
@site.save_changes
|
||||
RequestSSLAuthWorker.perform_async @site.id
|
||||
flash[:success] = 'The domain has been successfully updated.'
|
||||
redirect "/settings/#{@site.username}#custom_domain"
|
||||
else
|
||||
|
|
|
@ -15,6 +15,8 @@ development:
|
|||
paypal_api_username: derp
|
||||
paypal_api_password: ing
|
||||
paypal_api_signature: tonz
|
||||
letsencrypt_key: ./tests/files/letsencrypt.key
|
||||
letsencrypt_endpoint: https://acme-staging.api.letsencrypt.org/
|
||||
test:
|
||||
database: 'postgres://neocities@localhost/neocities_test'
|
||||
database_pool: 1
|
||||
|
@ -31,3 +33,5 @@ test:
|
|||
paypal_api_username: derp
|
||||
paypal_api_password: ing
|
||||
paypal_api_signature: tonz
|
||||
letsencrypt_key: ./tests/files/letsencrypt.key
|
||||
letsencrypt_endpoint: https://acme-staging.api.letsencrypt.org/
|
|
@ -11,3 +11,5 @@ paypal_api_username: derp
|
|||
paypal_api_password: ing
|
||||
paypal_api_signature: tonz
|
||||
logs_path: "/tmp/neocitiestestlogs"
|
||||
letsencrypt_key: ./tests/files/letsencrypt.key
|
||||
letsencrypt_endpoint: https://acme-staging.api.letsencrypt.org/
|
|
@ -152,3 +152,10 @@ end
|
|||
gandi_opts = {}
|
||||
gandi_opts[:env] = :test unless ENV['RACK_ENV'] == 'production'
|
||||
$gandi = Gandi::Session.new $config['gandi_api_key'], gandi_opts
|
||||
|
||||
# Let's Encrypt
|
||||
|
||||
$letsencrypt = Acme::Client.new(
|
||||
private_key: OpenSSL::PKey::RSA.new(File.read($config['letsencrypt_key'])),
|
||||
endpoint: $config['letsencrypt_endpoint']
|
||||
)
|
|
@ -1330,6 +1330,28 @@ class Site < Sequel::Model
|
|||
sanitized.gsub(/(http|https):\/\//, '').gsub(/[^\w\s]/, '').downcase.split.uniq.select{|v| v.length < SiteFile::CLASSIFIER_WORD_LIMIT}.join(' ')
|
||||
end
|
||||
|
||||
def request_ssl_authorization
|
||||
auth = $letsencrypt.authorize domain: domain
|
||||
challenge = auth.http01
|
||||
FileUtils.mkdir_p File.join(base_files_path, File.dirname(challenge.filename))
|
||||
|
||||
File.write File.join(base_files_path, challenge.filename), challenge.file_content
|
||||
|
||||
challenge.request_verification
|
||||
|
||||
challenge
|
||||
end
|
||||
|
||||
# request_ssl_authorization must be run first!
|
||||
def obtain_ssl_certificate
|
||||
csr = Acme::Client::CertificateRequest.new names: [domain, "www.#{domain}"]
|
||||
certificate = $letsencrypt.new_certificate csr
|
||||
self.ssl_key = certificate.request.private_key.to_pem
|
||||
self.ssl_cert = certificate.fullchain_to_pem
|
||||
save_changes
|
||||
FileUtils.rm_rf File.join(base_files_path, '.well-known')
|
||||
end
|
||||
|
||||
# array of hashes: filename, tempfile, opts.
|
||||
def store_files(files, opts={})
|
||||
results = []
|
||||
|
|
27
tests/files/letsencrypt.key
Normal file
27
tests/files/letsencrypt.key
Normal file
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAwsY6rlj09XsfnxbzatQKEqjN9Kqynjp+o7jaHBaWMjRSOSqC
|
||||
xj0ThnxghxsXnUZEP+Wc/e38JQ15Ob8LRe5AnigP65ArvC3Fk9p19uV9JkX+gBtr
|
||||
LSzQqSD0As+4SQc8iE7zoAH8Oz2t1WXGOJnhw/D3DZBoEis4TBXctc9FMYYWtCSH
|
||||
2wfqUMTVUru6vOG9dv1w/7lQr4+YIHJGGai9p+XEqLGmkH/JkHwQ11XJZcBjKQtQ
|
||||
1jTfryzMtCGtdRBvF9Au2JCWz3zrVdh4Pz6pj8NTQ87izf97u3RvmnnZIT9RSPWF
|
||||
LVfkFSLNExguMqreWi8NzI79rfP08bMAhIcEFQIDAQABAoIBAEABJAdm9Bg2/Y0p
|
||||
3ZOdWjIHhqZ/8XJNhpAGjqXsRi75QovGjHLYXzIybQX4wSnNjV/x9ET9j34dj1iK
|
||||
jwnL4TAXuiOOnNCZufN8NoeLojSRi7BNUkrmDyuEyKqj18sntZyVVTmfbWOKQTV+
|
||||
3ER9TNM2u/iZG5nc2gMmrACSvAopktYvBYRPHAmCR8ZLkE6ZjPeOKcJbr6F5D9Ie
|
||||
X5+QKsoG0by7Gu8eHkOh0WtufeOM38OfSStDpPW5eu5JOFrtgEQPolaMi0Mw2h4D
|
||||
aaNLUQbmk1I9JMS17yVJFnTrrKTSeHFiC16rwKWJvG0S4DUfsyMW9u0oog4sYrAT
|
||||
5j0+oAECgYEA8ZD2QRbuZD52F6SPB6tV0LokUijKLLzUW1+d8R54sW7ATurCSspU
|
||||
J9CRSmyi9cfFn9ReP776dRBgtfYmf6IV5Ju6fH86+B2+WI/2YLqbMkpcAILnRF80
|
||||
IlfJK4mDy0ljxvubUNaEUcZj/bpINx5PwddU7Xl6POWuYxXzBn4TZNUCgYEAzmmH
|
||||
t+Qv9l+LxxaNDIdZYtWhkYUWGzupiLKWHjrnprqmFLODDCbfA95Y1jxK3tBxZ3Yp
|
||||
TRD9XJ/0+PrLK992OUDvlPxX4XSMZPMtsqLSAwlnAvUzzZQimhyhC8rx2eogbDSx
|
||||
Wf0pKqMRVJdk6zFEMKNx+Lcgvpv5rCWoIJ7twkECgYAJdFf/AivAZqVulXU3oqAQ
|
||||
NEjZolkPWTCihuKCnmOw5hnGvO9vx+11RXd6Rzg1kGUOtVwe+JWK4WI3nPOyySA8
|
||||
O1AYMU6YiWl6w9+rt4H9fOWO65Crn2JF+dOYzaAH485w6kYQ6uRw4ufk9VaAOcJ7
|
||||
XrcnODrtiTvDCwfg+CxAJQKBgFHlCNXrESR9ECYzSk8YPFy8SdhEp1qytzbnNCxW
|
||||
TqaWE2LPPkVJ/t24ECMf1MzGgtf7x7Mt9HgVdsp6JrYHeQ6KNwQzgmKPLUy4Nv9T
|
||||
HmPaDSbdRmpgRcJDbZoSMRa2j5qe5WbAzN5/yFZ5oq6140ow7v0xGyrFE7A7WJNo
|
||||
uwiBAoGAMyptWRsi0vFMXy/0b26whVj2LGFLRDS03bT3XhyQmCnp+f+03GHbuggM
|
||||
/IAf3RMj8oub1RrPoFqzd78n0CnZLwk+A6w8EMkKDFCY1sLESy7dVtPdS91deIxk
|
||||
H07fMxqzLYQO6XplcmqsD06PuTLmWYDjA9e8hSSMQo1n+rSw4ko=
|
||||
-----END RSA PRIVATE KEY-----
|
17
workers/create_ssl_cert_worker.rb
Normal file
17
workers/create_ssl_cert_worker.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
class CreateSSLCertWorker
|
||||
include Sidekiq::Worker
|
||||
sidekiq_options queue: :create_ssl_auth_worker, retry: 100, backtrace: true
|
||||
|
||||
sidekiq_retry_in do |count|
|
||||
180
|
||||
end
|
||||
|
||||
def perform(site_id, challenge)
|
||||
site = Site[site_id]
|
||||
|
||||
challenge = $letsencrypt.challenge_from_hash JSON.parse(challenge)
|
||||
if challenge.verify_status == 'valid'
|
||||
site.obtain_ssl_certificate
|
||||
end
|
||||
end
|
||||
end
|
15
workers/request_ssl_auth_worker.rb
Normal file
15
workers/request_ssl_auth_worker.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
class RequestSSLAuthWorker
|
||||
include Sidekiq::Worker
|
||||
sidekiq_options queue: :request_ssl_auth_worker, retry: 100, backtrace: true
|
||||
|
||||
sidekiq_retry_in do |count|
|
||||
180
|
||||
end
|
||||
|
||||
def perform(site_id)
|
||||
site = Site[site_id]
|
||||
challenge = site.request_ssl_authorization
|
||||
|
||||
CreateSSLCertWorker.perform_in 5.seconds, site_id, challenge.to_h.to_json
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue