【问题标题】:How to set up Let's Encrypt for a Go server application如何为 Go 服务器应用程序设置 Let's Encrypt
【发布时间】:2016-05-19 11:24:20
【问题描述】:

我有自己的域,其中包含用 Go 编写的 Web 服务。我使用的是内置的 Go 网络服务器,前面没有 Nginx 或 Apache。

我想开始通过 HTTPS 提供服务,但我意识到 Let's Encrypt 即将成为实现此目的的方式。

谁能分享配置在 Linux 服务器上运行的 Go 应用的整个设置过程?

【问题讨论】:

  • 使用caddyserver.com - 它为您执行此操作(为您的应用程序颁发证书和代理)。
  • 问题是什么:如何为 Go 网络服务器创建证书?如何配置 Go 网络服务器以使用证书/私钥?其他?
  • Go 自己的 crypto/tls 包能够从 PEM 格式的文件中加载证书(公钥和私钥)。 Let's Encrypt 提供的一个工具(现在它似乎被 EFF 推广)能够为您提供该 PEM 格式的文件。所以:1)阅读从 Let's Encrypt 获取证书的指南并这样做; 2) 获得该证书后,请阅读如何让crypto/tls 阅读并在您的服务器中实现该证书; 3)让您的服务器读取您的证书。你已经完成了。
  • 换句话说,除非您已经在服务器中实施配置旋钮来“配置”您的服务器,否则无法“配置”您的服务器。因为你很可能还没有,你可能会做一些事情,比如让他们解析一个特殊的命令行选项,指定证书的路径名,比如-cert
  • 相关信息:将所有http流量重定向到https。 stackoverflow.com/questions/37536006/…

标签: ssl go https ssl-certificate lets-encrypt


【解决方案1】:

这是使用我找到的 Go 和 Let's Encrypt 证书的 HTTPS 服务器的最小自动设置:

package main

import (
    "crypto/tls"
    "log"
    "net/http"

    "golang.org/x/crypto/acme/autocert"
)

func main() {
    certManager := autocert.Manager{
        Prompt:     autocert.AcceptTOS,
        HostPolicy: autocert.HostWhitelist("example.com"), //Your domain here
        Cache:      autocert.DirCache("certs"),            //Folder for storing certificates
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello world"))
    })

    server := &http.Server{
        Addr: ":https",
        TLSConfig: &tls.Config{
            GetCertificate: certManager.GetCertificate,
        },
    }

    go http.ListenAndServe(":http", certManager.HTTPHandler(nil))

    log.Fatal(server.ListenAndServeTLS("", "")) //Key and cert are coming from Let's Encrypt
}

有关自动证书包的更多信息:link

编辑:由于letsencrypt security issue 需要使http 可用,阅读更多here。作为此修复的奖励,我们现在有 http-->https 重定向。如果您已经收到证书,旧示例将继续工作,但它会因新站点而中断。

【讨论】:

  • 谢谢,这就是我要找的例子!但是根据文档必须小心:这个包是一个正在进行的工作,没有 API 稳定性承诺。
  • 非常感谢!这确实应该被选为正确答案。
  • 不,这是完整的包。如果您运行此代码,您将看到它创建了一个有效的证书。而且由于它可以创建它也可以更新。我运行它的服务器至少更新了一次证书。
  • 我收到这两个握手错误,但我无法弄清楚问题所在:“acme/autocert:缺少服务器名称”和“acme/autocert:主机未配置”。有人可以帮帮我吗?
  • @Pushan 你用的是什么版本的golang.org/x/crypto/acme/autocert?因为在 master 中似乎有这个功能:link
【解决方案2】:

我找到了一个非常简单的解决方案,使用 standalone 模式。


安装 CERTBOT 客户端(由 Let's Encrypt 推荐)

(go to the directory where you want to install the certbot client)
git clone https://github.com/certbot/certbot
cd certbot
./certbot-auto --help`


签发证书(第一次)

注意此操作通过端口 80 进行,因此如果您的 Go 应用程序侦听端口 80,则需要在运行此命令之前将其关闭(顺便说一下,运行速度非常快)

./certbot-auto certonly --standalone-supported-challenges http-01 -d www.yourdomain.com

在您的 GO 代码中添加 SSL 监听器

http.ListenAndServeTLS(":443", "/etc/letsencrypt/live/www.yourdomain.com/fullchain.pem", "/etc/letsencrypt/live/www.yourdomain.com/privkey.pem", nil)

完成!


更新证书(证书在 90 天后过期)

注意您可以手动运行此程序(您将在证书到期前几天收到一封电子邮件),或设置一个 crontab

如果您的 Go 应用不再监听 80 端口,您的 Go 应用可以在您执行以下命令时继续运行:
./certbot-auto renew --standalone

如果你的 Go 应用仍然监听 80 端口,你可以指定命令来停止和重启 Go 应用:
./certbot-auto renew --standalone --pre-hook "command to stop Go app" --post-hook "command to start Go app"

有关 Certbot 命令的完整文档: https://certbot.eff.org/docs/using.html

【讨论】:

  • 我也得到了这个工作,但使用了dns挑战方法,您可以将 TXT 记录添加到您的 dns。
  • 关于 cert 和 permkey 文件的权限问题怎么办?您不以 root 身份运行您的 golang 服务器/应用程序,但这些文件归 root 所有。
  • certbot更新时如何在不重启服务器的情况下重新加载pem文件?
【解决方案3】:

如果您可以使用 DNS 验证,那就是续订的方法。

为了使用证书,简单的做:

    c := &tls.Config{MinVersion: tls.VersionTLS12}
    s := &http.Server{Addr: ":443", Handler: Gzipler(nosurf.New(router), 1), TLSConfig: c}
    log.Fatal(s.ListenAndServeTLS(
        "/etc/letsencrypt/live/XXX/fullchain.pem", 
        "/etc/letsencrypt/live/XXX/privkey.pem"
    ))

这个包含 Gzip 和 CSRF 保护。你可以使用

Handler: router

没有那些额外的功能。

【讨论】:

    猜你喜欢
    • 2017-08-26
    • 2016-05-08
    • 2016-11-15
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多