substrakt / letsencrypt-heroku Goto Github PK
View Code? Open in Web Editor NEWMake any Heroku application secure in just a couple of minutes.
Home Page: https://substrakt.com/heroku-ssl-me-weve-come-a-long-way/
License: MIT License
Make any Heroku application secure in just a couple of minutes.
Home Page: https://substrakt.com/heroku-ssl-me-weve-come-a-long-way/
License: MIT License
Hey, thanks for your work on this. I’m happy that the moment of free and easy SSL is approaching.
It seems like my installation isn’t working properly, as it never progresses beyond the Deploying certificate to Heroku
stage. I’ve looked at the data in Redis but don’t see anything helpful there. I can see that CloudFlare has some ACME-related TXT
records, which seems like a good sign.
When I run heroku _certs:info
it says there are no certificates, which I think wouldn’t be the case if the process succeeded?
Let me know if I can provide any debugging information.
Also, I have a side question about something in the documentation:
It doesn't currently add the CNAME records to CloudFlare once the SSL certificate has been generated.
Would the CNAME
just be an alias for applicationname.herokuapp.com
?
https://github.com/heroku/platform-api
Now SSL support is no longer in beta we should update to use heroku's gem. This will provide a cleaner interface, give better error messages and should be more stable.
Could investigate the idea of wrapping the API in some sort of JS application for those less keen on using an API directly.
I'm getting this error message from the API call:
{
"status": "error",
"message": "Invalid zone."
}
I'm copying the Zone ID directly from the "domain summary" section on Cloudflare. The Cloudflare API also returns the same Zone ID.
Is there something else that would be causing this error?
Hey. I am super excited about this project - it has the potential to make my life a lot easier, I'm more than willing / eager to contribute.
I've found an issue, for me this line always returns the staging
endpoint regardless of if @debug
is set to 0
or 1
.
https://github.com/substrakt/letsencrypt-heroku/blob/master/lib/certificate_generation.rb#L124
I verified it in IRB using ruby 1.9 and 2.2 by simply:
irb(main):001:0> @debug = 0
=> 0
irb(main):002:0> @debug ? 'https://acme-staging.api.letsencrypt.org/' : 'https://acme-v01.api.letsencrypt.org/'
=> "https://acme-staging.api.letsencrypt.org/"
irb(main):003:0> @debug = 1
=> 1
irb(main):004:0> @debug ? 'https://acme-staging.api.letsencrypt.org/' : 'https://acme-v01.api.letsencrypt.org/'
=> "https://acme-staging.api.letsencrypt.org/"
Whats up with that?
Says '/domains' instead of '/domain'. Had to search through code to find it.
Thanks for setting this up. Really excited to get this up and running. I'm running into some snags following your instructions and was hoping you could clarify a bit.
auth_token is the value of ENV['AUTH_TOKEN']
- Perhaps clarify that is is set on the new project that one sets up during the setup process. I (foolishly) thought it meant I needed to add this to the project I wanted to add SSL to.http://chuckpad-social-letsencrypt.herokuapps.com/certificate_generation/new/chuckpad.io?subdomains=www&debug=0&app_name=chuckpad-social&auth_token={AUTH_TOKEN_REMOVED}
Thank you!
We've got need (internally at least) to use DigitalOcean DNS as a provider for some clients.
Investigate implementing an adapter model for the DNS verification to use DigitalOcean (and potentially other DNS providers too.)
We can use sidekiq to schedule in renewals.
What should I specify in subdomains
query parameter, if the domain I'd like to get a certificate for is domain.tld
, without any www.
etc.?
The initial beta api needs a total rewrite to address some of the issues raised. This would make up a major 2.0 release.
While reloading generation status page i stumbled upon this error:
2016-08-16T14:02:09.261023+00:00 app[web.1]: 2016-08-16 14:02:09 - Redis::CommandError - ERR max number of clients reached:
2016-08-16T14:02:09.261032+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:121:in `call'
2016-08-16T14:02:09.261033+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:102:in `block in connect'
2016-08-16T14:02:09.261033+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:293:in `with_reconnect'
2016-08-16T14:02:09.261034+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:100:in `connect'
2016-08-16T14:02:09.261034+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:364:in `ensure_connected'
2016-08-16T14:02:09.261035+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:221:in `block in process'
2016-08-16T14:02:09.261035+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:306:in `logging'
2016-08-16T14:02:09.261036+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:220:in `process'
2016-08-16T14:02:09.261037+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis/client.rb:120:in `call'
2016-08-16T14:02:09.261037+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis.rb:862:in `block in get'
2016-08-16T14:02:09.261038+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis.rb:58:in `block in synchronize'
2016-08-16T14:02:09.261038+00:00 app[web.1]: /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
2016-08-16T14:02:09.261039+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis.rb:58:in `synchronize'
2016-08-16T14:02:09.261039+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/redis-3.3.1/lib/redis.rb:861:in `get'
2016-08-16T14:02:09.261040+00:00 app[web.1]: /app/app.rb:22:in `block in <top (required)>'
2016-08-16T14:02:09.261041+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1611:in `call'
2016-08-16T14:02:09.261041+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1611:in `block in compile!'
2016-08-16T14:02:09.261042+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:975:in `block (3 levels) in route!'
2016-08-16T14:02:09.261043+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:994:in `route_eval'
2016-08-16T14:02:09.261043+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:975:in `block (2 levels) in route!'
2016-08-16T14:02:09.261044+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1015:in `block in process_route'
2016-08-16T14:02:09.261045+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1013:in `catch'
2016-08-16T14:02:09.261045+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1013:in `process_route'
2016-08-16T14:02:09.261046+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:973:in `block in route!'
2016-08-16T14:02:09.261046+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:972:in `each'
2016-08-16T14:02:09.261047+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:972:in `route!'
2016-08-16T14:02:09.261048+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1085:in `block in dispatch!'
2016-08-16T14:02:09.261048+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in `block in invoke'
2016-08-16T14:02:09.261049+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in `catch'
2016-08-16T14:02:09.261049+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in `invoke'
2016-08-16T14:02:09.261050+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1082:in `dispatch!'
2016-08-16T14:02:09.261050+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:907:in `block in call!'
2016-08-16T14:02:09.261051+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in `block in invoke'
2016-08-16T14:02:09.261052+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in `catch'
2016-08-16T14:02:09.261052+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in `invoke'
2016-08-16T14:02:09.261053+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:907:in `call!'
2016-08-16T14:02:09.261054+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:895:in `call'
2016-08-16T14:02:09.261054+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in `call'
2016-08-16T14:02:09.261055+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in `call'
2016-08-16T14:02:09.261056+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in `call'
2016-08-16T14:02:09.261056+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
2016-08-16T14:02:09.261057+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
2016-08-16T14:02:09.261058+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in `call'
2016-08-16T14:02:09.261058+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/logger.rb:15:in `call'
2016-08-16T14:02:09.261063+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/commonlogger.rb:33:in `call'
2016-08-16T14:02:09.261064+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:219:in `call'
2016-08-16T14:02:09.261064+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:212:in `call'
2016-08-16T14:02:09.261065+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/head.rb:13:in `call'
2016-08-16T14:02:09.261066+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/methodoverride.rb:22:in `call'
2016-08-16T14:02:09.261066+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:182:in `call'
2016-08-16T14:02:09.261067+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:2013:in `call'
2016-08-16T14:02:09.261068+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1487:in `block in call'
2016-08-16T14:02:09.261068+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1787:in `synchronize'
2016-08-16T14:02:09.261069+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1487:in `call'
2016-08-16T14:02:09.261070+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.6.0/lib/puma/configuration.rb:225:in `call'
2016-08-16T14:02:09.261070+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.6.0/lib/puma/server.rb:578:in `handle_request'
2016-08-16T14:02:09.261071+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.6.0/lib/puma/server.rb:415:in `process_client'
2016-08-16T14:02:09.261071+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.6.0/lib/puma/server.rb:275:in `block in run'
2016-08-16T14:02:09.261072+00:00 app[web.1]: /app/vendor/bundle/ruby/2.3.0/gems/puma-3.6.0/lib/puma/thread_pool.rb:116:in `block in spawn_thread'
in case you want 1 cert, with lots of sub-domains, running on multiple heroku apps in your org (micro services?)
Not having tests is a massive failure on my part. Add tests and add the repo to Travis.
worker.rb
is a massive single point of failure. The code needs refactoring in to something a bit more friendly.
I'm having an issue where I am getting a response with message Not authenticated
when trying to view the status_path.
It looks like I am getting a 403 because my AUTH_TOKEN is incorrect but i've pulled it straight form the heroku configs and have double checked that it's matching.
I get to the status page that shows status_path without any issues but when I check on the status I get Not authenticated
This is the request i'm submitting.
https://herokuappname.herokuapp.com/certificate_generation/new/aaaa.com?subdomains=www,api&debug=0&app_name=aaaa-backend-loadbalancer&auth_token=XXXXXXX
I'm not quite sure why cloudfare is a requirement for this project to work
API endpoint to get the status of certificate provisioning
I've tried inputting both the "ID" and "Token" generated by the oauth command but they don't work.
Creating OAuth Authorization... done
Client:
ID: [my id]
Description: letsencrypt-heroku
Scope: global
Token: [my token]
They don't work with the above link
Is this software using secure communication (https://devcenter.heroku.com/articles/securing-heroku-redis) such as stunnel to communicate with redis? If not, what are the implications of a possible attack?
For some reason the certificate is nil (From what I understand it, not a Ruby expert).
Do you guys have any idea what might be going wrong? We're using Heroku Teams and the app is owned by the team, not sure if you guys have tried that combo before but if not that might be related.
2016-11-09T15:35:56.068386+00:00 app[worker.1]: 4 TID-otktdy67s WARN: NoMethodError: undefined method `fullchain_to_pem' for nil:NilClass
2016-11-09T15:35:56.068425+00:00 app[worker.1]: 4 TID-otktdy67s WARN: /app/lib/certificate_generation.rb:92:in `deploy_certificate'
2016-11-09T15:35:56.068427+00:00 app[worker.1]: /app/lib/certificate_generation.rb:72:in `provision!'
2016-11-09T15:35:56.068428+00:00 app[worker.1]: /app/workers/worker.rb:11:in `perform'
2016-11-09T15:35:56.068428+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/processor.rb:152:in `execute_job'
2016-11-09T15:35:56.068429+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/processor.rb:134:in `block (2 levels) in process'
2016-11-09T15:35:56.068430+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/middleware/chain.rb:128:in `block in invoke'
2016-11-09T15:35:56.068431+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/middleware/server/retry_jobs.rb:74:in `call'
2016-11-09T15:35:56.068431+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/middleware/chain.rb:130:in `block in invoke'
2016-11-09T15:35:56.068432+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/middleware/server/logging.rb:11:in `block in call'
2016-11-09T15:35:56.068433+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/logging.rb:32:in `with_context'
2016-11-09T15:35:56.068433+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/middleware/server/logging.rb:7:in `call'
2016-11-09T15:35:56.068434+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/middleware/chain.rb:130:in `block in invoke'
2016-11-09T15:35:56.068435+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/middleware/chain.rb:133:in `invoke'
2016-11-09T15:35:56.068435+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/processor.rb:129:in `block in process'
2016-11-09T15:35:56.068436+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/processor.rb:168:in `stats'
2016-11-09T15:35:56.068436+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/processor.rb:128:in `process'
2016-11-09T15:35:56.068437+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/processor.rb:80:in `process_one'
2016-11-09T15:35:56.068438+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/processor.rb:68:in `run'
2016-11-09T15:35:56.068438+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/util.rb:17:in `watchdog'
2016-11-09T15:35:56.068439+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.3.0/gems/sidekiq-4.1.4/lib/sidekiq/util.rb:25:in `block in safe_thread'
I misspelled my heroku app name and it appeared to "succeed"
Hello,
As the README states, "Heroku has started giving out free SSL options", I'm not sure if that's correct.
2017-01-01T12:46:14.004441+00:00 app[worker.1]: ---> Provisioning Heroku application with new certificate
2017-01-01T12:46:14.099025+00:00 app[worker.1]: ---> Uploading new certificate
2017-01-01T12:46:14.205924+00:00 app[worker.1]: ----> Error: {"id":"invalid_params","message":"You need to be running on either Hobby or Professional dynos to be able to use SNI SSL."}
Here is the log from my letsencrypt-heroku
when I tried to run it for my app.
Hi,
I came upon this and was looking forward to installing this. I started the Heroku deploy wizard from the button on the README page, but when I specified the app (in this case "blackops-staging", I got a response saying that the "application is not available".
I'm assuming that this is because I am a collaborator on this app and not an owner. If this is correct, it might be good to specify that one needs to be an owner.
According to the Collaborator Permissions, the only items that a collaborator should not be able to do are:
Considering that this is a free solution, I am not clear on whether doing this deploy requires ownership, or whether there are other reasons why the automatic deploy didn't work.
Thanks in advance.
Here's a JSON from the state endpoint:
{
"token": "e...a",
"status": null,
"error": null,
"domain": null,
"subdomains": [],
"message": null
}
What does that mean?
I just deployed letsencrypt-test, but according to #14 it sounds like I should be doing YOURNAME-certificate-management, or similar.
Perhaps the README could include that?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.