我在处理代码时遇到以下错误。
原因:io.grpc.StatusRuntimeException:不可用:ALPN 协商失败:无法找到兼容协议
通道管道:[SslHandler#0、ProtocolNegotiators$ClientTlsHandler#0、WriteBufferingAndExceptionHandler#0、DefaultChannelPipeline$TailContext#0]
/*
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.demo.certificate;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.logging.ConsoleHandler;
import org.slf4j.Logger;
import org.slf4j.event.Level;
// [START privateca_create_ca]
import com.google.api.core.ApiFuture;
import com.google.cloud.security.privateca.v1.CaPoolName;
import com.google.cloud.security.privateca.v1.CertificateAuthority;
import com.google.cloud.security.privateca.v1.CertificateAuthority.KeyVersionSpec;
import com.google.cloud.security.privateca.v1.CertificateAuthority.SignHashAlgorithm;
import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient;
import com.google.cloud.security.privateca.v1.CertificateConfig;
import com.google.cloud.security.privateca.v1.CertificateConfig.SubjectConfig;
import com.google.cloud.security.privateca.v1.CreateCertificateAuthorityRequest;
import com.google.cloud.security.privateca.v1.KeyUsage;
import com.google.cloud.security.privateca.v1.KeyUsage.KeyUsageOptions;
import com.google.cloud.security.privateca.v1.Subject;
import com.google.cloud.security.privateca.v1.X509Parameters;
import com.google.cloud.security.privateca.v1.X509Parameters.CaOptions;
import com.google.longrunning.Operation;
import com.google.protobuf.Duration;
public class CreateCertificateAuthority {
public static void main(String[] args)
throws InterruptedException, ExecutionException, IOException {
// TODO(developer): Replace these variables before running the sample.
// location: For a list of locations, see:
// https://cloud.google.com/certificate-authority-service/docs/locations
// poolId: Set it to the CA Pool under which the CA should be created.
// certificateAuthorityName: Unique name for the CA.
String project = "corp-esgda-dev";
String location = "us-east1";
String poolId = "test-pool";
String certificateAuthorityName = "myCA";
createCertificateAuthority(project, location, poolId, certificateAuthorityName);
}
// Create Certificate Authority which is the root CA in the given CA Pool.
public static void createCertificateAuthority(
String project, String location, String poolId, String certificateAuthorityName)
throws InterruptedException, ExecutionException, IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the `certificateAuthorityServiceClient.close()` method on the client to safely
// clean up any remaining background resources.
try (CertificateAuthorityServiceClient certificateAuthorityServiceClient =
CertificateAuthorityServiceClient.create()) {
System.setProperty("https.protocols", "TLSv1.2");
System.out.println(System.getProperties() );
String commonName = "dev";
String orgName = "qc";
int caDuration = 100000; // Validity of this CA in seconds.
// Set the type of Algorithm.
KeyVersionSpec keyVersionSpec =
KeyVersionSpec.newBuilder().setAlgorithm(SignHashAlgorithm.RSA_PKCS1_4096_SHA256).build();
// Set CA subject config.
SubjectConfig subjectConfig =
SubjectConfig.newBuilder()
.setSubject(
Subject.newBuilder().setCommonName(commonName).setOrganization(orgName).build())
.build();
// Set the key usage options for X.509 fields.
X509Parameters x509Parameters =
X509Parameters.newBuilder()
.setKeyUsage(
KeyUsage.newBuilder()
.setBaseKeyUsage(
KeyUsageOptions.newBuilder().setCrlSign(true).setCertSign(true).build())
.build())
.setCaOptions(CaOptions.newBuilder().setIsCa(true).build())
.build();
// Set certificate authority settings.
CertificateAuthority certificateAuthority =
CertificateAuthority.newBuilder()
// CertificateAuthority.Type.SELF_SIGNED denotes that this CA is a root CA.
.setType(CertificateAuthority.Type.SELF_SIGNED)
.setKeySpec(keyVersionSpec)
.setConfig(
CertificateConfig.newBuilder()
.setSubjectConfig(subjectConfig)
.setX509Config(x509Parameters)
.build())
// Set the CA validity duration.
.setLifetime(Duration.newBuilder().setSeconds(caDuration).build())
.build();
// Create the CertificateAuthorityRequest.
CreateCertificateAuthorityRequest certificateAuthorityRequest =
CreateCertificateAuthorityRequest.newBuilder()
.setParent(CaPoolName.of(project, location, poolId).toString())
.setCertificateAuthorityId(certificateAuthorityName)
.setCertificateAuthority(certificateAuthority)
.build();
// Create Certificate Authority.
ApiFuture<Operation> futureCall =
certificateAuthorityServiceClient
.createCertificateAuthorityCallable()
.futureCall(certificateAuthorityRequest);
System.out.println("futureCall:"+futureCall);
Operation response = futureCall.get();
if (response.hasError()) {
System.out.println("Error while creating CA !" + response.getError());
return;
}
System.out.println(
"Certificate Authority created successfully : " + certificateAuthorityName);
}
}
}
// [END privateca_create_ca]
Pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>certificate</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>certificate-demo</name>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>26.29.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-security-private-ca</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-monitoring</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-openjdk8-client</artifactId>
<version>9.4.44.v20210927</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version> <!-- Use the latest version available -->
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.70</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
该错误表明 ALPN 过程中建立 gRPC 连接时出现问题。 ALPN 用于协商用于连接的协议,例如 HTTP/2。如果客户端和服务器使用不同版本的 gRPC,或者服务器未配置为支持客户端尝试使用的协议,也可能会发生这种情况。
Alpn_协议 提供侦听器应公开的 ALPN 协议列表。 在实践中,这可能被设置为两个值之一。没有 该参数的默认值。如果为空,Envoy 将不会公开 ALPN。
“h2,http/1.1” 如果侦听器要支持 HTTP/2 和 HTTP/1.1。
“http/1.1” 如果侦听器仅支持 HTTP/1.1。
要解决您的问题,请尝试检查以下步骤。
根据 github 链接,问题可能是由于 man-in-the-middle 代理不支持 gRPC 所需的 http/2。当未在 中启用 http2 时,可能会发生这种情况配置.
如果您解决了代理问题,但 TLS 协商仍然遇到问题。您应确保客户端和服务器使用相同版本的 gRPC 库,并且将它们配置为使用相同的 TLS 协议。您还可以尝试在服务器上禁用 TLS,看看是否可以解决问题。
还要验证防火墙设置,因为它可能与您公司的防火墙阻止问题有关。
确保客户端和服务器使用兼容版本的 gRPC。
可能是您的服务器运行的企业环境不支持 ALPN 和 HTTP2。 gRPC 的故障排除中有更多信息。