capistrano-lets-encrypt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +101 -0
- data/Rakefile +2 -0
- data/capistrano-lets-encrypt.gemspec +24 -0
- data/lib/capistrano/lets-encrypt.rb +1 -0
- data/lib/capistrano/tasks/lets-encrypt.rake +190 -0
- data/lib/capistrano-lets-encrypt.rb +0 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f473171fd16aa1dce17e6fe5b6278a59b5170cba
|
4
|
+
data.tar.gz: af32bc3f5619c618c6ce81592aca906281d7cf82
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e303e3709d463323c185860a08c3507c14aeb99411674e3c860fa80706b945b1314cab424348278bcf8447ff619da8505fa1f743339459aa7534146f48e3b0f9
|
7
|
+
data.tar.gz: 61e95f90349114548fb6d73a9bb3ba35fc5a912809ec4f7fcd8cd5cbaafbebfb0cce2c2a44eb7f6268e1579a48be2d536c7cd3106c1523fac44e778ae92285a6
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2015 Platanus
|
2
|
+
MIT License
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# Capistrano::LetsEncrypt [![Gem Version](https://badge.fury.io/rb/capistrano-lets-encrypt.png)](http://badge.fury.io/rb/capistrano-lets-encrypt)
|
2
|
+
|
3
|
+
Let's encrypt support for Capistrano 3.x
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'capistrano-lets-encrypt', '~> 1.0'
|
10
|
+
gem 'capistrano'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install capistrano-lets-encrypt
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
Require in `Capfile` to use the default task:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require 'capistrano/lets-encrypt'
|
26
|
+
```
|
27
|
+
|
28
|
+
You will get the following tasks
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
cap delayed_job:start # Start delayed_job service
|
32
|
+
cap delayed_job:stop # Stop delayed_job service
|
33
|
+
cap delayed_job:restart # Restart delayed_job service
|
34
|
+
```
|
35
|
+
|
36
|
+
Configurable options (copy into deploy.rb), shown here with examples:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# Number of delayed_job workers
|
40
|
+
# default value: 1
|
41
|
+
set :delayed_job_workers, 2
|
42
|
+
|
43
|
+
# String to be prefixed to worker process names
|
44
|
+
# This feature allows a prefix name to be placed in front of the process.
|
45
|
+
# For example: reports/delayed_job.0 instead of just delayed_job.0
|
46
|
+
set :delayed_job_prefix, :reports
|
47
|
+
|
48
|
+
# Delayed_job queue or queues
|
49
|
+
# Set the --queue or --queues option to work from a particular queue.
|
50
|
+
# default value: nil
|
51
|
+
set :delayed_job_queues, ['mailer','tracking']
|
52
|
+
|
53
|
+
# Specify different pools
|
54
|
+
# You can use this option multiple times to start different numbers of workers for different queues.
|
55
|
+
# default value: nil
|
56
|
+
set :delayed_job_pools, {
|
57
|
+
:mailer => 2,
|
58
|
+
:tracking => 1,
|
59
|
+
:* => 2
|
60
|
+
}
|
61
|
+
|
62
|
+
# Set the roles where the delayed_job process should be started
|
63
|
+
# default value: :app
|
64
|
+
set :delayed_job_roles, [:app, :background]
|
65
|
+
|
66
|
+
# Set the location of the delayed_job executable
|
67
|
+
# Can be relative to the release_path or absolute
|
68
|
+
# default value 'bin'
|
69
|
+
set :delayed_job_bin_path, 'script' # for rails 3.x
|
70
|
+
|
71
|
+
### Set the location of the delayed_job logfile
|
72
|
+
set :delayed_log_dir, 'path_to_logfile'
|
73
|
+
```
|
74
|
+
|
75
|
+
It also adds the following hook
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
after 'deploy:published', 'restart' do
|
79
|
+
invoke 'delayed_job:restart'
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
90
|
+
|
91
|
+
## Credits
|
92
|
+
|
93
|
+
Thank you [contributors](https://github.com/platanus/guides/graphs/contributors)!
|
94
|
+
|
95
|
+
<img src="http://platan.us/gravatar_with_text.png" alt="Platanus" width="250"/>
|
96
|
+
|
97
|
+
capistrano-lets-encrypt is maintained by [platanus](http://platan.us).
|
98
|
+
|
99
|
+
## License
|
100
|
+
|
101
|
+
Guides is © 2014 platanus, spa. It is free software and may be redistributed under the terms specified in the LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "capistrano-lets-encrypt"
|
7
|
+
spec.version = "0.1.0"
|
8
|
+
spec.authors = ["Juan Ignacio Donoso"]
|
9
|
+
spec.email = ["juan.ignacio@platan.us"]
|
10
|
+
spec.summary = %q{Adds support for let's encrypt to Capistrano 3.x}
|
11
|
+
spec.description = %q{Adds support for let's encrypt to Capistrano 3.x}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency 'capistrano', '>= 3.0.0'
|
21
|
+
spec.add_dependency 'letsencrypt-cli', '>= 0.1.4'
|
22
|
+
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path('../tasks/lets-encrypt.rake', __FILE__)
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'letsencrypt/cli/acme_wrapper'
|
3
|
+
|
4
|
+
namespace :lets_encrypt do
|
5
|
+
|
6
|
+
desc 'Register Let\' Encrypt account with email'
|
7
|
+
task :register do
|
8
|
+
email = fetch(:lets_encrypt_email)
|
9
|
+
if email.nil? || email == ""
|
10
|
+
wrapper.log "no E-Mail specified!", :fatal
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
if !email[/.*@.*/]
|
14
|
+
wrapper.log "not an email", :fatal
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
registration = client.register(contact: "mailto:" + email)
|
18
|
+
registration.agree_terms
|
19
|
+
wrapper.log "Account created, Terms accepted"
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Check if the certificate are valid'
|
23
|
+
task :check_certificate do
|
24
|
+
on roles(fetch(:lets_encrypt_roles)) do
|
25
|
+
check_certificate
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Authorize the domain using the ACME challenge'
|
30
|
+
task :authorize do
|
31
|
+
on roles(fetch(:lets_encrypt_roles), select: :primary) do
|
32
|
+
unless check_certificate
|
33
|
+
domains.each do |domain|
|
34
|
+
authorize(domain)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "create certificate and private key pair for domains. The first domain is the main CN domain"
|
41
|
+
task :cert do
|
42
|
+
cert(domains)
|
43
|
+
on roles(fetch(:lets_encrypt_roles)) do
|
44
|
+
domains.each do |domain|
|
45
|
+
upload_certs domain
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# On server methods
|
51
|
+
|
52
|
+
def check_certificate
|
53
|
+
if test("[ -f #{certificate_path} ]")
|
54
|
+
temp_path = "/tmp/#{primary_domain}.cert.pem"
|
55
|
+
download! certificate_path, temp_path
|
56
|
+
wrapper.check_certificate(temp_path)
|
57
|
+
else
|
58
|
+
wrapper.log "No certificate found"
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def authorize(domain)
|
64
|
+
wrapper.log "Authorizing #{domain.blue}."
|
65
|
+
authorization = client.authorize(domain: domain)
|
66
|
+
|
67
|
+
challenge = authorization.http01
|
68
|
+
challenge_public_path = fetch(:lets_encrypt_challenge_public_path)
|
69
|
+
challenge_path = File.join(challenge_public_path, File.dirname(challenge.filename))
|
70
|
+
challenge_file_path = File.join(challenge_public_path, challenge.filename)
|
71
|
+
execute :mkdir, '-pv', challenge_path
|
72
|
+
|
73
|
+
wrapper.log "Writing challenge to #{challenge_file_path}", :debug
|
74
|
+
|
75
|
+
execute :echo, "\"#{challenge.file_content}\" > #{challenge_file_path}"
|
76
|
+
|
77
|
+
challenge.request_verification
|
78
|
+
|
79
|
+
5.times do
|
80
|
+
wrapper.log "Checking verification...", :debug
|
81
|
+
sleep 1
|
82
|
+
break if challenge.verify_status != 'pending'
|
83
|
+
end
|
84
|
+
if challenge.verify_status == 'valid'
|
85
|
+
wrapper.log "Authorization successful for #{domain.green}"
|
86
|
+
execute :rm, '-f', challenge_file_path
|
87
|
+
true
|
88
|
+
else
|
89
|
+
wrapper.log "Authorization error for #{domain.red}", :error
|
90
|
+
wrapper.log challenge.error['detail']
|
91
|
+
false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def cert(domains)
|
96
|
+
domains.each do |domain|
|
97
|
+
FileUtils.mkdir_p(local_out_path(domain))
|
98
|
+
end
|
99
|
+
wrapper.cert(domains)
|
100
|
+
end
|
101
|
+
|
102
|
+
def upload_certs(domain)
|
103
|
+
execute :mkdir, '-pv', "#{fetch(:lets_encrypt_output_path)}/#{domain}"
|
104
|
+
upload! local_private_key_path, private_key_path
|
105
|
+
upload! local_fullchain_path, fullchain_path
|
106
|
+
upload! local_certificate_path, certificate_path
|
107
|
+
upload! local_chain_path, chain_path
|
108
|
+
end
|
109
|
+
|
110
|
+
# Helpers
|
111
|
+
def certificate_path(domain = primary_domain)
|
112
|
+
File.join(fetch(:lets_encrypt_output_path), domain, "cert.pem")
|
113
|
+
end
|
114
|
+
|
115
|
+
def chain_path(domain = primary_domain)
|
116
|
+
File.join(fetch(:lets_encrypt_output_path), domain, "chain.pem")
|
117
|
+
end
|
118
|
+
|
119
|
+
def fullchain_path(domain = primary_domain)
|
120
|
+
File.join(fetch(:lets_encrypt_output_path), domain, "fullchain.pem")
|
121
|
+
end
|
122
|
+
|
123
|
+
def private_key_path(domain = primary_domain)
|
124
|
+
File.join(fetch(:lets_encrypt_output_path), domain, "key.pem")
|
125
|
+
end
|
126
|
+
|
127
|
+
def local_certificate_path(domain = primary_domain)
|
128
|
+
File.join(local_out_path(domain), "cert.pem")
|
129
|
+
end
|
130
|
+
|
131
|
+
def local_chain_path(domain = primary_domain)
|
132
|
+
File.join(local_out_path(domain), "chain.pem")
|
133
|
+
end
|
134
|
+
|
135
|
+
def local_fullchain_path(domain = primary_domain)
|
136
|
+
File.join(local_out_path(domain), "fullchain.pem")
|
137
|
+
end
|
138
|
+
|
139
|
+
def local_private_key_path(domain = primary_domain)
|
140
|
+
File.join(local_out_path(domain), "key.pem")
|
141
|
+
end
|
142
|
+
|
143
|
+
def local_out_path(domain = primary_domain)
|
144
|
+
File.join(File.expand_path(fetch(:lets_encrypt_local_output_path)), domain)
|
145
|
+
end
|
146
|
+
|
147
|
+
def domains
|
148
|
+
fetch(:lets_encrypt_domains).split(" ")
|
149
|
+
end
|
150
|
+
|
151
|
+
def primary_domain
|
152
|
+
domains.first
|
153
|
+
end
|
154
|
+
|
155
|
+
def wrapper
|
156
|
+
@wrapper ||= AcmeWrapper.new(options)
|
157
|
+
end
|
158
|
+
|
159
|
+
def options
|
160
|
+
@options ||= {
|
161
|
+
account_key: fetch(:lets_encrypt_account_key),
|
162
|
+
test: fetch(:lets_encrypt_test),
|
163
|
+
log_level: "info",
|
164
|
+
color: true,
|
165
|
+
days_valid: fetch(:lets_encrypt_days_valid),
|
166
|
+
private_key_path: local_private_key_path,
|
167
|
+
fullchain_path: local_fullchain_path,
|
168
|
+
certificate_path: local_certificate_path,
|
169
|
+
chain_path: local_chain_path,
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
173
|
+
def client
|
174
|
+
@client ||= wrapper.client
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
namespace :load do
|
179
|
+
task :defaults do
|
180
|
+
set :lets_encrypt_roles, -> { :web }
|
181
|
+
set :lets_encrypt_test, -> { false }
|
182
|
+
set :lets_encrypt_email, -> { nil }
|
183
|
+
set :lets_encrypt_domains, -> { nil }
|
184
|
+
set :lets_encrypt_challenge_public_path, -> { "#{release_path}/public" }
|
185
|
+
set :lets_encrypt_output_path, -> { "#{shared_path}/ssl/certs" }
|
186
|
+
set :lets_encrypt_account_key, -> { "#{fetch(:lets_encrypt_email)}.account_key.pem" }
|
187
|
+
set :lets_encrypt_days_valid, -> { 30 }
|
188
|
+
set :lets_encrypt_local_output_path, -> { "~/certs" }
|
189
|
+
end
|
190
|
+
end
|
File without changes
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano-lets-encrypt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Juan Ignacio Donoso
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capistrano
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: letsencrypt-cli
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.4
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
description: Adds support for let's encrypt to Capistrano 3.x
|
56
|
+
email:
|
57
|
+
- juan.ignacio@platan.us
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- capistrano-lets-encrypt.gemspec
|
68
|
+
- lib/capistrano-lets-encrypt.rb
|
69
|
+
- lib/capistrano/lets-encrypt.rb
|
70
|
+
- lib/capistrano/tasks/lets-encrypt.rake
|
71
|
+
homepage: ''
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.4.8
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Adds support for let's encrypt to Capistrano 3.x
|
95
|
+
test_files: []
|
96
|
+
has_rdoc:
|