-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 702b162
Showing
28 changed files
with
1,230 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/.bundle/ | ||
/.yardoc | ||
/Gemfile.lock | ||
/_yardoc/ | ||
/coverage/ | ||
/doc/ | ||
/pkg/ | ||
/spec/reports/ | ||
/tmp/ | ||
config.yml | ||
config.dev.yml | ||
/storage/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
--format documentation | ||
--color |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
language: ruby | ||
rvm: | ||
- 2.4.0 | ||
before_install: gem install bundler -v 1.10.6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
source 'https://rubygems.org' | ||
|
||
# Specify your gem's dependencies in acmesmith.gemspec | ||
gemspec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2016 sorah (Shota Fukumori) | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
# Acmesmith: An effective ACME client to operate on multiple servers environment with the cloud | ||
|
||
Acmesmith is an [ACME (Automatic Certificate Management Environment)](https://github.com/ietf-wg-acme/acme) client that works perfect on environment with multiple servers. This client saves certificate and keys on cloud services (e.g. AWS S3) securely, then allow to deploy issued certificates onto your servers smoothly. This works well on [Let's encrypt](https://letsencrypt.org). | ||
|
||
This tool is written in Ruby, but this saves certificates in simple scheme, so you can fetch certificate by your own simple scripts. | ||
|
||
## Installation | ||
|
||
Add this line to your application's Gemfile: | ||
|
||
```ruby | ||
gem 'acmesmith' | ||
``` | ||
|
||
And then execute: | ||
|
||
$ bundle | ||
|
||
Or install it yourself as: | ||
|
||
$ gem install acmesmith | ||
|
||
## Usage | ||
|
||
``` | ||
$ acmesmith register CONTACT # Create account key (contact e.g. mailto:xxx@example.org) | ||
``` | ||
|
||
``` | ||
$ acmesmith authorize DOMAIN # Get authz for DOMAIN. | ||
$ acmesmith request COMMON_NAME [SAN] # request certificate for CN +COMMON_NAME+ with SANs +SAN+ | ||
``` | ||
|
||
``` | ||
$ acmesmith list [COMMON_NAME] # list certificates or its versions | ||
$ acmesmith current COMMON_NAME # show current version for certificate | ||
$ acmesmith show-certificate COMMON_NAME # show certificate | ||
$ acmesmith show-private-key COMMON_NAME # show private key | ||
``` | ||
|
||
## Configuration | ||
|
||
See [config.sample.yml](./config.sample.yml) to start. | ||
|
||
``` yaml | ||
endpoint: https://acme-staging.api.letsencrypt.org/ | ||
# endpoint: https://acme-v01.api.letsencrypt.org/ # productilon | ||
|
||
storage: | ||
# configure where to store keys and certificates; described later | ||
challenge_responders: | ||
# configure how to respond ACME challenges; described later | ||
|
||
account_key_passphrase: password | ||
certificate_key_passphrase: secret | ||
``` | ||
### Storage | ||
#### S3 | ||
``` | ||
storage: | ||
type: s3 | ||
region: | ||
bucket: | ||
# prefix: | ||
# aws_access_key: # aws credentials (optional); If omit, default configuration of aws-sdk use will be used. | ||
# access_key_id: | ||
# secret_access_key: | ||
# session_token: | ||
# use_kms: true | ||
# kms_key_id: # KMS key id (optional); if omit, default AWS managed key for S3 will be used | ||
# kms_key_id_account: # KMS key id for account key (optional); This overrides kms_key_id | ||
# kms_key_id_certificate_key: # KMS key id for private keys for certificates (optional); This oveerides kms_key_id | ||
``` | ||
|
||
This saves certificates and keys in the following S3 keys: | ||
|
||
- `{prefix}/account.pem`: Account private key in pem | ||
- `{prefix}/certs/{common_name}/current`: text file contains current version name | ||
- `{prefix}/certs/{common_name}/{version}/cert.pem`: certificate in pem | ||
- `{prefix}/certs/{common_name}/{version}/key.pem`: private key in pem | ||
- `{prefix}/certs/{common_name}/{version}/chain.pem`: CA chain in pem | ||
- `{prefix}/certs/{common_name}/{version}/fullchain.pem`: certificate + CA chain in pem. This is suitable for some server softwares like nginx. | ||
|
||
#### Filesystem | ||
|
||
This is not recommended. If you're planning to use this, make sure backing up the keys. | ||
|
||
``` | ||
storage: | ||
type: filesystem | ||
path: /path/to/directory/to/store/keys | ||
``` | ||
|
||
### Challenge Responders | ||
|
||
Challenge responders responds to ACME challenges to prove domain ownership to CA. | ||
|
||
#### Route53 | ||
|
||
Route53 responder supports `dns-01` challenge type. This assumes domain NS are managed under Route53 hosted zone. | ||
|
||
``` | ||
challenge_responders: | ||
- route53: | ||
# aws_access_key: # aws credentials (optional); If omit, default configuration of aws-sdk use will be used. | ||
# access_key_id: | ||
# secret_access_key: | ||
# session_token: | ||
# hosted_zone_map: # hosted zone map (optional); This is to specify exactly one hosted zone to use. This will be required when there are multiple hosted zone with same domain name. Usually | ||
# "example.org.": "/hostedzone/DEADBEEF" | ||
``` | ||
|
||
## Vendor dependent notes | ||
|
||
### AWS | ||
|
||
#### IAM policy | ||
|
||
##### All access (S3 + Route53 setup) | ||
|
||
``` json | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Effect": "Allow", | ||
"Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"], | ||
"Resource": ["arn:aws:s3:::{BUCKET-NAME}", "arn:aws:s3:::{BUCKET-NAME}/*"] | ||
}, | ||
{ | ||
"Effect": "Allow", | ||
"Action": "route53:ListHostedZones", | ||
"Resource": "*" | ||
} | ||
{ | ||
"Effect": "Allow", | ||
"Action": "route53:ChangeResourceRecordSets", | ||
"Resource": ["arn:aws:route53:::hostedzone/*"] | ||
} | ||
{ | ||
"Effect": "Allow", | ||
"Action": "route53:GetChange", | ||
"Resource": "*" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Note: You can limit allowed hosted zone by modifying `Resource` of `route53:ChangeResourceRecordSets` | ||
|
||
##### Only fetching certificates | ||
|
||
``` json | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Effect": "Allow", | ||
"Action": ["s3:GetObject"], | ||
"Resource": ["arn:aws:s3:::{BUCKET-NAME}/certs/*"] | ||
}, | ||
{ | ||
"Effect": "Allow", | ||
"Action": ["s3:ListBucket"], | ||
"Resource": ["arn:aws:s3:::{BUCKET-NAME}"], | ||
"Condition": { | ||
"StringEquals": { | ||
"s3:delimiter": "/" | ||
}, | ||
"StringLike": { | ||
"s3:prefix": "certs/*", | ||
} | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
#### AWS KMS key policy for customer managed keys | ||
|
||
If you're going to use `aws_kms_id` option to use customer managed keys instead of AWS managed default KMS key for Amazon S3, use the following policy as base: | ||
|
||
Be sure to replace `{S3-REGION}` and `{YOUR-AWS-ACCOUNT-ID}` before applying it. | ||
|
||
``` json | ||
{ | ||
"Version": "2012-10-17", | ||
"Id": "kms-acmesmith-s3-policy", | ||
"Statement": [ | ||
{ | ||
"Effect": "Allow", | ||
"Principal": { | ||
"AWS": "*" | ||
}, | ||
"Action": [ | ||
"kms:Encrypt", | ||
"kms:Decrypt", | ||
"kms:ReEncrypt*", | ||
"kms:GenerateDataKey*", | ||
"kms:DescribeKey" | ||
], | ||
"Resource": "*", | ||
"Condition": { | ||
"StringEquals": { | ||
"kms:ViaService": "s3.{S3-REGION}.amazonaws.com", | ||
"kms:CallerAccount": "{YOUR-AWS-ACCOUNT-ID}" | ||
} | ||
} | ||
}, | ||
{ | ||
"Effect": "Allow", | ||
"Principal": { | ||
"AWS": "arn:aws:iam::{YOUR-AWS-ACCOUNT-ID}:root" | ||
}, | ||
"Action": [ | ||
"kms:Describe*", | ||
"kms:Get*", | ||
"kms:List*", | ||
"kms:Put*" | ||
], | ||
"Resource": "*" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
## Development | ||
|
||
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. | ||
|
||
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). | ||
|
||
### Todos | ||
|
||
- Tests | ||
- Support post actions (notifying servers, deploying to somewhere, etc...) | ||
- Automated renewal command (request new certificates for existing certificates that expires soon) | ||
|
||
## Contributing | ||
|
||
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/acmesmith. | ||
|
||
|
||
## License | ||
|
||
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
require "bundler/gem_tasks" | ||
require "rspec/core/rake_task" | ||
|
||
RSpec::Core::RakeTask.new(:spec) | ||
|
||
task :default => :spec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# coding: utf-8 | ||
lib = File.expand_path('../lib', __FILE__) | ||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | ||
require 'acmesmith/version' | ||
|
||
Gem::Specification.new do |spec| | ||
spec.name = "acmesmith" | ||
spec.version = Acmesmith::VERSION | ||
spec.authors = ["sorah (Shota Fukumori)"] | ||
spec.email = ["her@sorah.jp"] | ||
|
||
spec.summary = %q{ACME client to manage certificate in multi server environment with cloud services (e.g. AWS)} | ||
spec.homepage = "https://github.com/sorah/acmesmith" | ||
spec.license = "MIT" | ||
|
||
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } | ||
spec.bindir = "bin" | ||
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } | ||
spec.require_paths = ["lib"] | ||
|
||
spec.add_dependency "acme-client" | ||
spec.add_dependency "aws-sdk" | ||
spec.add_dependency "thor" | ||
|
||
spec.add_development_dependency "bundler", "~> 1.10" | ||
spec.add_development_dependency "rake", "~> 10.0" | ||
spec.add_development_dependency "rspec" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/usr/bin/env ruby | ||
require 'acmesmith/command' | ||
|
||
Acmesmith::Command.start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
endpoint: https://acme-staging.api.letsencrypt.org/ | ||
# endpoint: https://acme-v01.api.letsencrypt.org/ | ||
storage: | ||
type: s3 | ||
region: 'ap-northeast-1' | ||
bucket: '...' | ||
# prefix: '...' | ||
# kms_key_id: 'arn:aws:kms:...' | ||
|
||
# storage: | ||
# type: filesystem | ||
# path: ./storage | ||
|
||
challenge_responders: | ||
- route53: {} | ||
|
||
account_key_passphrase: password | ||
certificate_key_passphrase: secret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
require "acmesmith/version" | ||
|
||
module Acmesmith | ||
# Your code goes here... | ||
end |
Oops, something went wrong.