更新经过多次调试后,我发现了
Get "https://acme-v02.api.letsencrypt.org/directory": x509: certificate signed by unknown authority和怀疑(!?)这是最近加密根证书过期的结果。
我接受这样的观点:“这个包正在进行中,没有API稳定性的保证。”但是,如果它不再起作用(而且更有可能发生问题),那么也许可以将回购标记为龙来了。
代码产生了一个acme_account+key (EC PRIVATE KEY),但没有一个证书要求我让autocert披露(日志)它的魔力,以了解我的错误所在。
代码本质上是repo的Manager示例,其中包含来自此回答的输入。我假设GetCertificate阻塞了ACME流的完成。
代码:
package main
import (
"crypto/tls"
"flag"
"fmt"
"log"
"net"
"net/http"
"golang.org/x/crypto/acme/autocert"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
)
const (
email string = "my@email.com"
var (
host = flag.String("host", "foo.example.org", "Fully-qualified domain name")
port = flag.Uint("port", 443, "gRPC service port")
path = flag.String("path", "", "Folder location for certificate")
)
func main() {
flag.Parse()
if *host == "" {
log.Fatal("Flag --host is required")
}
log.Printf("Host: %s", *host)
log.Printf("Port: %d", *port)
if *path == "" {
log.Fatal("Flag --path is required")
}
log.Printf("Path: %s", *path)
addr := fmt.Sprintf(":%d", *port)
lis, err := net.Listen("tcp", addr)
if err != nil {
log.Fatalf("failed to listen: %s", err)
}
m := &autocert.Manager{
Cache: autocert.DirCache(*path),
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(*host),
Email: email,
}
go func() {
log.Println("Starting HTTP server w/ autocert handler")
if err := http.ListenAndServe(":http", m.HTTPHandler(nil)); err != nil {
log.Fatalf("HTTP failure\n%s", err)
}
}()
tlsConfig := &tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
cert, err := m.GetCertificate(hello)
if err != nil {
log.Fatalf("GetCertificate\n%s", err)
}
return cert, err
},
}
opts := grpc.Creds(credentials.NewTLS(tlsConfig))
server := grpc.NewServer(opts)
healthcheck := health.NewServer()
healthpb.RegisterHealthServer(server, healthcheck)
log.Println("Starting gRPC server")
if err := server.Serve(lis); err != nil {
log.Fatalf("gRPC failure\n%s", err)
}
}我将部署到一个()容器VM中,等效的docker命令是:
docker run \
--name=autocert \
--detach \
--net=host \
--volume=/tmp/certs:/certs \
${IMAGE} \
--host=${HOST} \
--port=${PORT} \
--path=/certs和集装箱日志:
2021/11/25 17:30:00 Host: [HOST]
2021/11/25 17:30:00 Port: 443
2021/11/25 17:30:00 Path: /certs
2021/11/25 17:30:00 Starting gRPC server
2021/11/25 17:30:00 Starting HTTP server主机的/tmp/certs目录接收acme_account+key (我很难找到谷歌解释过),但怀疑(!?)是域验证的初始阶段。它包含一个私钥(BEGIN EC PRIVATE KEY)。
即使在服务器运行了一段时间之后,也不会有更多的文件被保存。
我没有收到电子邮件,让我们加密在配置的电子邮件地址。
不幸的是,虽然使用起来很容易,但autocert生成的日志很少,我一直无法确定是否能够记录正在(希望)发生的ACME流。
由于为GetCertificate添加了匿名函数,所以不再创建acme_account+key (我删除了前一个文件以检查是否重新创建了它),因此我无法从它收集任何日志记录--,但从未调用。这要么是因为我的匿名函数不正确,要么是因为我超过了针对ACME端点的请求。删除函数并恢复到m.GetCertificate并不会导致acme_account+key的重新创建,所以我感到很困惑。
autocert Manager类型记录了我没有设置的*acme.Client字段。该评论描述“如果Client.Key为零,将生成一个新的ECDSAP-256密钥”,这也许是我正在经历的,但它并没有解释我应该做些什么。应该将此值设置为acme_account+key的内容吗?:
我试着解码私钥,创建一个
crypto.Signer并把它传递到&acme.Client{Key: key}中,但是没有明显的区别。
// Client is used to perform low-level operations, such as account registration
// and requesting new certificates.
//
// If Client is nil, a zero-value acme.Client is used with DefaultACMEDirectory
// as the directory endpoint.
// If the Client.Key is nil, a new ECDSA P-256 key is generated and,
// if Cache is not nil, stored in cache.
//
// Mutating the field after the first call of GetCertificate method will have no effect.
Client *acme.Client显然,我用得不对。我没有从“让我们加密”中接收到证书,因此我无法从端点获得证书,也无法调用gRPC端点:
openssl s_client -showcerts -connect ${HOST}:${PORT}
grpcurl \
-proto health.proto \
${HOST}:${PORT} \
grpc.health.v1.Health/Check
Failed to dial target host "${HOST}:${PORT}": remote error: tls: internal error如能提供指导,将不胜感激。
发布于 2021-11-26 21:32:20
♂️
呃:-(
我开始使用SCRATCH,没有复制CA证书
一旦容器获得了CA证书,一切都几乎完美无缺。
我仍然在尝试使用:
tlsConfig := &tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
GetCertificate: m.GetCertificate
}和am使用m.TLSConfig()
因此,autocert的工作就像对待(尽管很难调试自己造成的错误)。
https://stackoverflow.com/questions/70115693
复制相似问题