go - istio 安全 grpc 网关的身份验证握手失败
问题描述
设置:
go
服务器和客户端通过 gRPC 通信- 使用 Istio 帮助进行身份验证/授权
- 能够与不安全的 HTTP 网关成功通信
- 现在,尝试设置一个安全的 HTTPS 网关,但它似乎不起作用。我在客户端收到此错误:
"transport: authentication handshake failed: EOF"
笔记:
- 我按照 istio文档设置了一个安全网关。
- 我没有域,但我在某处读到在 Istio 中设置安全网关时这不应该成为问题
- 部署在数字海洋中
证书/密钥生成
# Root certificate and private key
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=test/CN=test.com' -keyout certs/test.com.key -out certs/test.com.crt
# Certificate and private key for matchmaker service
openssl req -out certs/matchmaker.test.com.csr -newkey rsa:2048 -nodes -keyout certs/matchmaker.test.com.key -subj "/CN=matchmaker.test.com/O=matchmaker"
openssl x509 -req -days 365 -CA certs/test.com.crt -CAkey certs/test.com.key -set_serial 0 -in certs/matchmaker.test.com.csr -out certs/matchmaker.test.com.crt
Kubernetes 清单
创建秘密以包括媒人的证书和密钥:
kubectl create -n istio-system secret tls matchmaker-creds --key=path/to/matchmaker.test.com.key --cert=path/to/matchmaker.test.com.crt
Gateway、VirtualService 和 Service 清单:
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: grpc
protocol: GRPC
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: matchmaker-creds
hosts:
#- "*"
- matchmaker.test.com
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vservice
spec:
gateways:
- gateway
hosts:
#- "*"
- matchmaker.test.com
http:
- match:
- authority:
exact: "matchmaker"
route:
- destination:
host: matchmaker
port:
number: 5001
---
apiVersion: v1
kind: Service
metadata:
name: matchmaker
spec:
selector:
server: matchmaker
ports:
- name: https # Note: must be changed to grpc if we're connecting through port 80 in the gateway
port: 5001
服务器代码
服务器不需要包含任何 tls 设置,因为网关使用 TLS 终止,所以发送到matchmaker
服务的请求应该是未加密的,对吧?
const (
port = ":5001"
)
func main() {
matchmakerServer, err := matchmaker.Init()
if err != nil {
log.Fatal(err)
}
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
initializer := initializer.NewInitializer()
grpcServer := grpc.NewServer()
mmprotos.RegisterMatchmakerServer(grpcServer, matchmakerServer)
initprotos.RegisterInitializerServer(grpcServer, initializer)
// Register health check
healthService := healthcheck.NewHealthChecker()
grpc_health_v1.RegisterHealthServer(grpcServer, healthService)
version := os.Getenv("VERSION")
matchmakerServer.Logger.WithField("version", version).Infof("listening on %v", lis.Addr())
err = grpcServer.Serve(lis)
if err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
客户端代码
const (
address = "<ip-addr>:443"
token = "<jwt-token>"
)
func main() {
creds, err := credentials.NewClientTLSFromFile("path/to/test.com.crt", "")
if err != nil {
log.Fatal(err)
}
opts := []grpc.DialOption{
grpc.WithTransportCredentials(creds),
grpc.WithAuthority("matchmaker"),
//grpc.WithBlock(),
}
conn, err := grpc.Dial(address, opts...)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
client := initprotos.NewInitializerClient(conn)
md := metadata.Pairs(
"Authorization",
fmt.Sprintf("Bearer %v", token),
)
ctx := metadata.NewOutgoingContext(
context.TODO(),
md,
)
_, err = client.Connect(ctx, &initprotos.EmptyRequest{})
if err != nil {
log.Fatalf("connect method err: %v", err)
}
}
当请求发送到 istio 网关时,istio 代理日志不会显示任何有用的信息。
解决方案
推荐阅读
- ios - MapBox - detect zoomLevel changes
- ruby-on-rails - Rails Routes Redirect To Blog On Subdomain
- r - Set limits on loess line confidence interval shading in ggplot
- javascript - Uncaught SyntaxError: Unexpected reserved word on older android version
- sql-server-2016 - How to remove identity on primary key column in SQL Server 2016
- logic - 逻辑等价:证明 R OR P 蕴含 R OR Q 等价于 NOT R 蕴含(P 蕴含 Q)?
- c# - Serialize a list of objects inheriting from class A to xml, so the names of the elements in the xml are B,C,D
- python - 在 Maya 中,使用 Python 或 Mel,如何找到没有 UV 壳的对象
- security - WSO2:我的密钥库已添加到碳中,但在启动时未加载
- python - Python __doc__ documentation on instances