Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrated lets encrypt support #1921

Closed
wants to merge 2 commits into from
Closed

Integrated lets encrypt support #1921

wants to merge 2 commits into from

Conversation

tboerger
Copy link

No description provided.

@tboerger
Copy link
Author

Fails because of missing context dependency, but getting this:

# govendor add golang.org/x/net/context
Error: Package "github.com/drone/drone/vendor/golang.org/x/net/context" already in vendor.

It's pretty annoying to not being able to use govendor's full power because of all the unmanaged deps.

@tboerger
Copy link
Author

I have added the context package via the deps make task for now.


// define the server configuration
server := &http.Server{
Addr: c.String("server-addr"),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering, with let's encrypt, do we want to use https: as the address, and then start up a second server that listens for http: and auto-redirects to https?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe yes, however you prefer.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set Addr as ":https" for let's encrypt

@benschumacher
Copy link

Idle curiosity here, but why the (somewhat) moving target of https://golang.org/x/crypto/acme/autocert, versus https://github.com/xenolf/lego? I've used the latter as a CLI tool with some regularity, and particularly like that it offers many different options for DNS providers to do DNS-based validation.

Thanks!

@tboerger
Copy link
Author

The somewhat moving target compared to this from the Lego readme?

This is a work in progress. Please do NOT run this on a production server and please report any bugs you find!

@benschumacher
Copy link

Hah. Nice catch, though I still believe that supporting DNS-based validation is a killer feature.

From personal experience, I've used lego in production environments for more than a year.

@benschumacher
Copy link

Just to be explicit here: supporting DNS-based validations means I can use Let's Encrypt to generate usable certificates for services that aren't Internet accessible. This may not be an important use case to all organizations, but I think it is like to be a requirement for some.

@bradrydzewski
Copy link

@benschumacher the use case for DNS validation definitely makes sense for behind-the-firewall installations. @jmccann is this something you guys would be able to use? Is your DNS internal or external?

I wonder if the official Go library is planning to support this capability, and if anyone has requested the feature yet.

@tboerger
Copy link
Author

To being able to use the DNS challenge you must host your DNS setup on one of the supported providers.

@jmccann
Copy link

jmccann commented Feb 21, 2017

This isn't something we do currently AFAIK. Not sure where we host our DNS TBH.

While I'd like to use let's encrypt at some point I think a company solution would have to be thought out and implemented. I don't know if/when I'd try to tackle that. So I think for now this doesn't pertain to me.

However, 👍 to the PR from me because I want all the TLS hardening that comes with it. ;)

@bradrydzewski
Copy link

@benschumacher it looks like there is some code in place to handle DNS challenge records, but I'm not sure the level of completeness and if it can be integrated into this PR
https://godoc.org/golang.org/x/crypto/acme#Client.DNS01ChallengeRecord

any thoughts?

@@ -21,6 +21,7 @@ deps_backend:
go get -u github.com/elazarl/go-bindata-assetfs/...
go get -u github.com/drone/mq/...
go get -u github.com/tidwall/redlog
go get -u golang.org/x/net/context

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use context from the stdlib now that drone is using Go 1.8?


certManager := autocert.Manager{
Prompt: autocert.AcceptTOS,
Cache: autocert.DirCache(c.String("lets-encrypt-path")),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing HostPolicy? The user can set white list for the custom domains.

m := autocert.Manager{
    Prompt:     autocert.AcceptTOS,
    HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
    Cache:      autocert.DirCache("/var/www/.cache"),
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have any attribute for the domain

@bradrydzewski
Copy link

bradrydzewski commented Apr 6, 2017

Below is an example of how we could serve http and https simultaneously. It is also a bit more simple. It does not give the ability to configure ciphers but there is a CL to remove insecure ciphers in the next version of Go

var g errgroup.Group

g.Go(func() error {
  return http.ListenAndServe(":http", http.RedirectHandler("https://example.com", 303))
})
g.Go(func() error {
  return http.Serve(autocert.NewListener("example.com"), handler)
})

if err := g.Wait(); err != nil {
  log.Fatal(err)
}

In the Dockerfile we could add the following environment variable:

ENV XDG_CACHE_HOME /var/lib/drone

The acme library will then save to /var/lib/drone/golang-certs so that we don't have to worry about the user providing a cert cache location. When no cert location is specified the acme library will save to $HOME/.cache/golang-certs

@bradrydzewski
Copy link

bradrydzewski commented Apr 29, 2017

I added lets encrypt to another one of my projects based on the above code I posted. I ended up adding to drone as well. You can now visit http:https://beta.drone.io AND https://beta.drone.io. I appreciate the initial pr which inspired the final change. thanks @tboerger

Lets encrypt can be enabled with the following environment variable:

LETS_ENCRYPT=true

The dockerfile was updated to expose 8000, 80, and 443. If you are using lets encrypt you need to bind to the following ports on the the host machine:

--port=80:80
--port=443:443

The dockerfile includes the below environment variable which instructs drone to cache the certs in the same directory as the sqlite database. No configuration should be required for this.

ENV XDG_CACHE_HOME /var/lib/drone

Below is what the code looks like now, for those interested:

	// start the server with tls enabled
	if c.String("server-cert") != "" {
		return http.ListenAndServeTLS(
			c.String("server-addr"),
			c.String("server-cert"),
			c.String("server-key"),
			handler,
		)
	}

	// start the server without tls enabled
	if !c.Bool("lets-encrypt") {
		return http.ListenAndServe(
			c.String("server-addr"),
			handler,
		)
	}

	// start the server with lets encrypt enabled
	// listen on ports 443 and 80
	var g errgroup.Group
	g.Go(func() error {
		return http.ListenAndServe(":http", handler)
	})

	g.Go(func() error {
		address, err := url.Parse(c.String("server-host"))
		if err != nil {
			return err
		}
		return http.Serve(autocert.NewListener(address.Host), handler)
	})

	return g.Wait()

@tboerger tboerger deleted the feature/lets-encrypt branch September 12, 2017 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants