letsencrypt_heroku 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fd350843a8264fbb86c567c3da1050d577ad6bff
4
+ data.tar.gz: 4a09bf20e63e78b20718ca4647441ce9a1df8d77
5
+ SHA512:
6
+ metadata.gz: b8ab3351b3b0055270feb47c668c0622211b42ad0f68af19463a90c7993b67f72c6b6adf8220cc0b02b94083fd2218ee110b2eaad13d83ae13129ad2705084db
7
+ data.tar.gz: 77a13396a80b2a4a78e3477effa4f99b5197ddebb4f04b65bd2ad2c277e8773b73845f575378e38c56c37d1f223725ba2ded003c4d09e812c9190e669da59629
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in letsencrypt_heroku.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # LetsencryptHeroku
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/letsencrypt_heroku`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ ## Installation
6
+
7
+ Add these lines to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'letsencrypt_rack'
11
+ gem 'letsencrypt_heroku', require: false
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ You'll need a `config/letsencrypt_heroku.yml`
19
+
20
+ - contact: contact@foobar.dev
21
+ domains: foobar.dev www.foobar.dev
22
+ herokuapp: foobar
23
+
24
+ And finally execute
25
+
26
+ $ letsencrypt_heroku
27
+
28
+ ## Contributing
29
+
30
+ Bug reports and pull requests are welcome on GitHub at https://github.com/xijo/letsencrypt_heroku.
31
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
6
+
7
+ desc 'Open an irb session preloaded with this library'
8
+ task :console do
9
+ sh 'irb -rubygems -I lib -r letsencrypt_heroku.rb'
10
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "letsencrypt_heroku"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'letsencrypt_heroku'
5
+
6
+ LetsencryptHeroku::CLI.run
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'letsencrypt_heroku/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'letsencrypt_heroku'
8
+ spec.version = LetsencryptHeroku::VERSION
9
+ spec.authors = ['Johannes Opper']
10
+ spec.email = ['johannes.opper@gmail.com']
11
+
12
+ spec.summary = %q{Setup SSL for heroku with letsencrypt}
13
+ spec.description = %q{Setup SSL for heroku with letsencrypt}
14
+ spec.homepage = 'https://github.com/xijo/letsencrypt_heroku'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "rainbow"
22
+ spec.add_dependency "acme-client"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.12"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ end
@@ -0,0 +1,21 @@
1
+ require 'rainbow'
2
+ require 'yaml'
3
+ require 'acme-client'
4
+ require 'openssl'
5
+ require 'letsencrypt_heroku/version'
6
+ require 'letsencrypt_heroku/setup'
7
+
8
+ module LetsencryptHeroku
9
+ class CLI
10
+ CONFIG_FILE = 'config/letsencrypt_heroku.yml'
11
+
12
+ def self.run
13
+ if File.exist?(CONFIG_FILE)
14
+ configs = Array(YAML.load(File.read(CONFIG_FILE))).map { |c| OpenStruct.new(c) }
15
+ configs.each { |config| Setup.new(config).perform }
16
+ else
17
+ puts Rainbow("Missing config: #{CONFIG_FILE}").red
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,92 @@
1
+ module LetsencryptHeroku
2
+ class Setup
3
+ class SetupError < StandardError ; end
4
+
5
+ PRODUCTION = 'https://acme-v01.api.letsencrypt.org/'
6
+ STAGING = 'https://acme-staging.api.letsencrypt.org/'
7
+
8
+ attr_accessor :config
9
+
10
+ def initialize(config)
11
+ @config = config
12
+ @config.endpoint ||= PRODUCTION
13
+ @config.domains = config.domains.split
14
+ end
15
+
16
+ def perform
17
+ run_task "preflight" do
18
+ # heroku labs:enable http-sni
19
+ # heroku plugins:install heroku-certs
20
+
21
+ # check that ssl endpoint is on
22
+ # check heroku is there
23
+ # check that certs are there
24
+ end
25
+
26
+ run_task 'register with letsencrypt server' do
27
+ @private_key = OpenSSL::PKey::RSA.new(4096)
28
+ @client = Acme::Client.new(private_key: @private_key, endpoint: config.endpoint)
29
+ @client.register(contact: "mailto:#{config.contact}").agree_terms or fail_task
30
+ end
31
+
32
+ config.domains.each do |domain|
33
+ run_task "authorize #{domain}" do
34
+ @challenge = @client.authorize(domain: domain).http01
35
+
36
+ command = "heroku config:set LETSENCRYPT_RESPONSE=#{@challenge.file_content} &> /dev/null"
37
+ `#{command}`
38
+ $?.success? or fail_task
39
+
40
+ test_response(domain: domain, challenge: @challenge)
41
+
42
+ @challenge.request_verification
43
+ sleep(1) while 'pending' == @challenge.verify_status
44
+ @challenge.verify_status == 'valid' or fail_task
45
+ end
46
+ end
47
+
48
+ # if has cert: update cert, else add cert
49
+
50
+ run_task "update certificates" do
51
+ csr = Acme::Client::CertificateRequest.new(names: config.domains)
52
+ certificate = @client.new_certificate(csr)
53
+ File.write('privkey.pem', certificate.request.private_key.to_pem)
54
+ File.write('fullchain.pem', certificate.fullchain_to_pem)
55
+
56
+ command = "heroku _certs:update fullchain.pem privkey.pem --confirm #{config.herokuapp}"
57
+ `#{command}`
58
+ $?.success? or fail_task
59
+
60
+ FileUtils.rm %w(privkey.pem fullchain.pem)
61
+ end
62
+ rescue SetupError
63
+ end
64
+
65
+ def test_response(domain:, challenge:)
66
+ url = "http://#{domain}/#{challenge.filename}"
67
+ fail_count = 0
68
+ while fail_count < 30
69
+ answer = `curl -sL #{url}`
70
+ if answer != challenge.file_content
71
+ fail_count += 1
72
+ sleep(1)
73
+ else
74
+ return
75
+ end
76
+ end
77
+ fail_task
78
+ end
79
+
80
+ def run_task(name)
81
+ @_current_task = name
82
+ print Rainbow(" #{@_current_task}").yellow
83
+ yield
84
+ puts Rainbow("\r ✔ #{@_current_task}").green
85
+ end
86
+
87
+ def fail_task(reason = nil)
88
+ puts Rainbow("\r ✘ #{@_current_task}").red
89
+ raise SetupError, reason
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,3 @@
1
+ module LetsencryptHeroku
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: letsencrypt_heroku
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Johannes Opper
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rainbow
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: acme-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ description: Setup SSL for heroku with letsencrypt
84
+ email:
85
+ - johannes.opper@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".ruby-version"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - README.md
96
+ - Rakefile
97
+ - bin/console
98
+ - bin/letsencrypt_heroku
99
+ - bin/setup
100
+ - letsencrypt_heroku.gemspec
101
+ - lib/letsencrypt_heroku.rb
102
+ - lib/letsencrypt_heroku/setup.rb
103
+ - lib/letsencrypt_heroku/version.rb
104
+ homepage: https://github.com/xijo/letsencrypt_heroku
105
+ licenses: []
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.6.4
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Setup SSL for heroku with letsencrypt
127
+ test_files: []
128
+ has_rdoc: