- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个 gRPC 客户端和服务器,都使用 ssl 证书进行保护。如果中间没有代理,这些工作很好。作为测试,当我故意创建有缺陷的证书时,它失败了。稍后将在本文中证明这不是证书问题。
gRPC 服务器代码:
// Creates a new gRPC server
// Create the TLS credentials
creds, err := credentials.NewServerTLSFromFile("configs/cert/servercert.pem", "configs/cert/serverkey.pem")
if err != nil {
log.Fatalf("could not load TLS keys: %s", err)
}
// Create an array of gRPC options with the credentials
opts := []grpc.ServerOption{grpc.Creds(creds)}
// create a gRPC server object
s := grpc.NewServer(opts...)
gRPC 客户端代码:
// Create the client TLS credentials
creds, err := credentials.NewClientTLSFromFile("configs/cert/servercert.pem", "")
if err != nil {
log.Fatalf("could not load tls cert: %s", err)
}
conn, err := grpc.Dial(grpcUri, grpc.WithTransportCredentials(creds))
if err != nil {
log.Fatalf("Unable to connect: %v", err)
}
现在我正在尝试使用转发代理(我已经测试过并且在正常的 HTTP api 请求上工作正常)。然而,它在通过代理的 gRPC 请求上总是失败。
我正在使用 cuttle内部使用 goproxy使用以下设置。请注意,InsecureSkipVerify
bool 值已尝试 true
和 false
。根据我对 SSL 的(有限)理解,这需要为 false
,因为它将在线检查证书,并且这些证书是自签名的,因此自然会失败。但是,我再次尝试了 true
和 false
// Config proxy.
proxy := goproxy.NewProxyHttpServer()
proxy.Tr = &http.Transport{
// Config TLS cert verification.
TLSClientConfig: &tls.Config{InsecureSkipVerify: !cfg.TLSVerify},
Proxy: http.ProxyFromEnvironment,
}
在 gRPC 客户端和服务器之间运行代理会导致以下错误:
transport: authentication handshake failed: x509: certificate signed by unknown authority (possibly because of "x509: invalid signature: parent certificate cannot sign this kind of certificate" while trying to verify candidate authority certificate "test server"
这表明这是一个证书问题,但是,如前所述和测试,gRPC 在没有代理的情况下也能完美运行。
另请注意:我不想在代理后面运行 gRPC,但由于开发环境而被迫这样做。 gRPC 服务器和代理在同一台 docker 机器上运行。具有相同的 IP 地址会导致以下配置,这只会相互抵消(相信我,我无论如何都试过了)。
ENV http_proxy 192.168.99.100:3128
ENV https_proxy 192.168.99.100:3128
ENV no_proxy 192.168.99.100 # <- this would be the gRPC server IP, which is the same as the proxy. resulting in nothing being run through a proxy.
拆分在 docker 中寻址的 ip 可以解决这个问题,但是,我什么也学不到,也想解决这个问题。我试过像回答 here 这样的配置然而,要设置不同的 Docker 内部 IP,IP 将保持为空(仅设置网络)并且访问新 IP 将超时。
最佳答案
背景:
TLS 连接的每一端都需要预先安排的信任。大多数客户端在连接到远程主机时使用系统信任链(GeoTrust、DigiCert CA 的受信任证书都列在那里并允许您安全地访问像 https://facebook.com、https://google.com 等网站)
go
,在使用 TLS 时,在联系服务器时将默认使用系统信任链。在开发自定义解决方案时,很可能您的应用程序服务器的公共(public)证书不在此系统信任链中。所以你有两个选择:
InsecureSkipVerify: true
禁用信任(DON'T 这样做!)您的应用程序服务器很可能有一个自签名证书,所以它是 easy获取此的公共(public)证书部分。您还可以使用 openssl 等工具查看服务器的公共(public)证书- 使用链接的解决方案,您不仅可以为自己的开发服务器获取公共(public)证书,还可以为任何其他远程服务获取公共(public)证书 - 只需提供主机名和端口即可。
所以只是总结一下你的情况。你有:
Client <- TLS -> Server
但是想要:
Client <-TLS-> Proxy <-TLS-> Server
因此您的客户端现在不再信任服务器,而是只需要信任代理 - 因为它只直接与代理对话。代理很可能有一个自签名证书(见上文关于如何提取信任证书)。完成后,更新您的 go
代码以使用此自定义信任文件,如下所示:
// Get the SystemCertPool, continue with an empty pool on error
rootCAs, err := x509.SystemCertPool() // <- probably not needed, if we're only ever talking to this single proxy
if err != nil || rootCAs == nil {
rootCAs = x509.NewCertPool()
}
// Read in the custom trust file
certs, err := ioutil.ReadFile(localTrustFile)
if err != nil {
log.Fatalf("Failed to append %q to RootCAs: %v", localTrustFile, err)
}
// Append our cert to the system pool
if ok := rootCAs.AppendCertsFromPEM(certs); !ok {
log.Fatalf("failed to append custom cert")
}
tlsConfig := &tls.Config{
RootCAs: rootCAs,
}
代理也需要信任服务器 - 所以如果服务器的证书不在系统信任链中,那么它需要像上面类似的 tls.Config 设置。
关于docker - goproxy 背后的 gPRC 返回证书错误,在没有代理的情况下工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56870402/
我在Windows 10中使用一些简单的Powershell代码遇到了这个奇怪的问题,我认为这可能是我做错了,但我不是Powershell的天才。 我有这个: $ix = [System.Net.Dn
var urlsearch = "http://192.168.10.113:8080/collective-intellegence/StoreClicks?userid=" + userId +
我有一个非常奇怪的问题,过去两天一直让我抓狂。 我有一个我试图控制的串行设备(LS 100 光度计)。使用设置了正确参数的终端(白蚁),我可以发送命令(“MES”),然后是定界符(CR LF),然后我
我目前正试图让无需注册的 COM 使用 Excel 作为客户端,使用 .NET dll 作为服务器。目前,我只是试图让概念验证工作,但遇到了麻烦。 显然,当我使用 Excel 时,我不能简单地使用与可
我开发了简单的 REST API - https://github.com/pavelpetrcz/MandaysFigu - 我的问题是在本地主机上,WildFly 16 服务器的应用程序运行正常。
我遇到了奇怪的情况 - 从 Django shell 创建一些 Mongoengine 对象是成功的,但是从 Django View 创建相同的对象看起来成功,但 MongoDB 中没有出现任何数据。
我是 flask 的新手,只编写了一个相当简单的网络应用程序——没有数据库,只是一个航类搜索 API 的前端。一切正常,但为了提高我的技能,我正在尝试使用应用程序工厂和蓝图重构我的代码。让它与 pus
我的谷歌分析 JavaScript 事件在开发者控制台中运行得很好。 但是当从外部 js 文件包含在页面上时,它们根本不起作用。由于某种原因。 例如; 下面的内容将在包含在控制台中时运行。但当包含在单
这是一本名为“Node.js 8 the Right Way”的书中的任务。你可以在下面看到它: 这是我的解决方案: 'use strict'; const zmq = require('zeromq
我正在阅读文本行,并创建其独特单词的列表(在将它们小写之后)。我可以使它与 flatMap 一起工作,但不能使它与 map 的“子”流一起工作。 flatMap 看起来更简洁和“更好”,但为什么 di
我正在编写一些 PowerShell 脚本来进行一些构建自动化。我发现 here echo $? 根据前面的语句返回真或假。我刚刚发现 echo 是 Write-Output 的别名。 写主机 $?
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我将一个工作 View Controller 类从另一个项目复制到一个新项目中。我无法在新项目中加载 View 。在旧项目中我使用了presentModalViewController。在新版本中,我
我对 javascript 很陌生,所以很难看出我哪里出错了。由于某种原因,我的功能无法正常工作。任何帮助,将不胜感激。我尝试在外部 js 文件、头部/主体中使用它们,但似乎没有任何效果。错误要么出在
我正在尝试学习Flutter中的复选框。 问题是,当我想在Scaffold(body :)中使用复选框时,它正在工作。但我想在不同的地方使用它,例如ListView中的项目。 return Cente
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我有一个组合框,其中包含一个项目,比如“a”。我想调用该组合框的 Action 监听器,仅在手动选择项目“a”完成时才调用。我也尝试过 ItemStateChanged,但它的工作原理与 Action
你能看一下照片吗?现在,一步前我执行了 this.interrupt()。您可以看到 this.isInterrupted() 为 false。我仔细观察——“这个”没有改变。它具有相同的 ID (1
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我正在尝试在我的网站上设置一个联系表单,当有人点击发送时,就会运行一个作业,并在该作业中向所有管理员用户发送通知。不过,我在失败的工作表中不断收到此错误: Illuminate\Database\El
我是一名优秀的程序员,十分优秀!