未验证 提交 d8d28a0b 编写于 作者: wu-sheng's avatar wu-sheng 提交者: GitHub

Support TLS of gRPC between agent and server. (#968)

* Finish the prototype of TLS of gRPC between agent and server.

* Fix for rat check.

* Update GRPCChannelManager.java

* Update AgentModuleGRPCProvider.java

* Upgrade netty version (#971)

* Make sure end user can't start gRPC server with and without SSL in the same port.
上级 0e60d40d
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
package org.apache.skywalking.apm.collector.agent.grpc.provider; package org.apache.skywalking.apm.collector.agent.grpc.provider;
import java.io.File;
import java.util.Properties; import java.util.Properties;
import org.apache.skywalking.apm.collector.agent.grpc.define.AgentGRPCModule; import org.apache.skywalking.apm.collector.agent.grpc.define.AgentGRPCModule;
import org.apache.skywalking.apm.collector.agent.grpc.provider.handler.ApplicationRegisterServiceHandler; import org.apache.skywalking.apm.collector.agent.grpc.provider.handler.ApplicationRegisterServiceHandler;
import org.apache.skywalking.apm.collector.agent.grpc.provider.handler.InstanceDiscoveryServiceHandler; import org.apache.skywalking.apm.collector.agent.grpc.provider.handler.InstanceDiscoveryServiceHandler;
...@@ -41,6 +43,7 @@ import org.apache.skywalking.apm.collector.grpc.manager.service.GRPCManagerServi ...@@ -41,6 +43,7 @@ import org.apache.skywalking.apm.collector.grpc.manager.service.GRPCManagerServi
import org.apache.skywalking.apm.collector.naming.NamingModule; import org.apache.skywalking.apm.collector.naming.NamingModule;
import org.apache.skywalking.apm.collector.naming.service.NamingHandlerRegisterService; import org.apache.skywalking.apm.collector.naming.service.NamingHandlerRegisterService;
import org.apache.skywalking.apm.collector.server.Server; import org.apache.skywalking.apm.collector.server.Server;
import org.eclipse.jetty.util.StringUtil;
/** /**
* @author peng-yongsheng * @author peng-yongsheng
...@@ -50,22 +53,44 @@ public class AgentModuleGRPCProvider extends ModuleProvider { ...@@ -50,22 +53,44 @@ public class AgentModuleGRPCProvider extends ModuleProvider {
public static final String NAME = "gRPC"; public static final String NAME = "gRPC";
private static final String HOST = "host"; private static final String HOST = "host";
private static final String PORT = "port"; private static final String PORT = "port";
private static final String SSL_CERT_CHAIN_FILEPATH = "ssl_cert_chain_file";
private static final String SSL_PRIVATE_KEY_FILE = "ssl_private_key_file";
@Override public String name() { @Override
public String name() {
return NAME; return NAME;
} }
@Override public Class<? extends Module> module() { @Override
public Class<? extends Module> module() {
return AgentGRPCModule.class; return AgentGRPCModule.class;
} }
@Override public void prepare(Properties config) throws ServiceNotProvidedException { @Override
public void prepare(Properties config) throws ServiceNotProvidedException {
} }
@Override public void start(Properties config) throws ServiceNotProvidedException { @Override
public void start(Properties config) throws ServiceNotProvidedException {
String host = config.getProperty(HOST); String host = config.getProperty(HOST);
Integer port = (Integer)config.get(PORT); Integer port = (Integer) config.get(PORT);
String sslCertChainFilePath = config.getProperty(SSL_CERT_CHAIN_FILEPATH);
String sslPrivateKeyFilePath = config.getProperty(SSL_PRIVATE_KEY_FILE);
File sslCertChainFile = null;
File sslPrivateKeyFile = null;
if (StringUtil.isNotBlank(sslCertChainFilePath)) {
sslCertChainFile = new File(sslCertChainFilePath);
if (!(sslCertChainFile.exists() && sslCertChainFile.isFile())) {
sslCertChainFile = null;
}
}
if (StringUtil.isNotBlank(sslPrivateKeyFilePath)) {
sslPrivateKeyFile = new File(sslPrivateKeyFilePath);
if (!(sslPrivateKeyFile.exists() && sslPrivateKeyFile.isFile())) {
sslPrivateKeyFile = null;
}
}
ModuleRegisterService moduleRegisterService = getManager().find(ClusterModule.NAME).getService(ModuleRegisterService.class); ModuleRegisterService moduleRegisterService = getManager().find(ClusterModule.NAME).getService(ModuleRegisterService.class);
moduleRegisterService.register(AgentGRPCModule.NAME, this.name(), new AgentModuleGRPCRegistration(host, port)); moduleRegisterService.register(AgentGRPCModule.NAME, this.name(), new AgentModuleGRPCRegistration(host, port));
...@@ -78,17 +103,24 @@ public class AgentModuleGRPCProvider extends ModuleProvider { ...@@ -78,17 +103,24 @@ public class AgentModuleGRPCProvider extends ModuleProvider {
namingHandlerRegisterService.register(new AgentGRPCNamingHandler(namingListener)); namingHandlerRegisterService.register(new AgentGRPCNamingHandler(namingListener));
GRPCManagerService managerService = getManager().find(GRPCManagerModule.NAME).getService(GRPCManagerService.class); GRPCManagerService managerService = getManager().find(GRPCManagerModule.NAME).getService(GRPCManagerService.class);
Server gRPCServer = managerService.createIfAbsent(host, port); Server gRPCServer;
if (sslCertChainFile != null && sslPrivateKeyFile != null) {
gRPCServer = managerService.createIfAbsent(host, port, sslCertChainFile, sslPrivateKeyFile);
} else {
gRPCServer = managerService.createIfAbsent(host, port);
}
addHandlers(gRPCServer); addHandlers(gRPCServer);
} }
@Override public void notifyAfterCompleted() throws ServiceNotProvidedException { @Override
public void notifyAfterCompleted() throws ServiceNotProvidedException {
} }
@Override public String[] requiredModules() { @Override
return new String[] {ClusterModule.NAME, NamingModule.NAME, GRPCManagerModule.NAME, AnalysisSegmentParserModule.NAME, AnalysisMetricModule.NAME}; public String[] requiredModules() {
return new String[]{ClusterModule.NAME, NamingModule.NAME, GRPCManagerModule.NAME, AnalysisSegmentParserModule.NAME, AnalysisMetricModule.NAME};
} }
private void addHandlers(Server gRPCServer) { private void addHandlers(Server gRPCServer) {
......
...@@ -15,6 +15,9 @@ agent_gRPC: ...@@ -15,6 +15,9 @@ agent_gRPC:
gRPC: gRPC:
host: localhost host: localhost
port: 11800 port: 11800
#Set these two setting to open ssl
#ssl_cert_chain_file: $path
#ssl_private_key_file: $path
agent_jetty: agent_jetty:
jetty: jetty:
host: localhost host: localhost
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
package org.apache.skywalking.apm.collector.server; package org.apache.skywalking.apm.collector.server;
/** /**
* @author peng-yongsheng * @author peng-yongsheng, wusheng
*/ */
public interface Server { public interface Server {
...@@ -33,4 +33,8 @@ public interface Server { ...@@ -33,4 +33,8 @@ public interface Server {
void start() throws ServerException; void start() throws ServerException;
void addHandler(ServerHandler handler); void addHandler(ServerHandler handler);
boolean isSSLOpen();
boolean isStatusEqual(Server target);
} }
...@@ -19,17 +19,23 @@ ...@@ -19,17 +19,23 @@
package org.apache.skywalking.apm.collector.server.grpc; package org.apache.skywalking.apm.collector.server.grpc;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyServerBuilder; import io.grpc.netty.NettyServerBuilder;
import java.io.IOException; import io.netty.handler.ssl.SslContextBuilder;
import java.net.InetSocketAddress; import io.netty.handler.ssl.SslProvider;
import org.apache.skywalking.apm.collector.server.Server; import org.apache.skywalking.apm.collector.server.Server;
import org.apache.skywalking.apm.collector.server.ServerException; import org.apache.skywalking.apm.collector.server.ServerException;
import org.apache.skywalking.apm.collector.server.ServerHandler; import org.apache.skywalking.apm.collector.server.ServerHandler;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Objects;
/** /**
* @author peng-yongsheng * @author peng-yongsheng, wusheng
*/ */
public class GRPCServer implements Server { public class GRPCServer implements Server {
...@@ -39,28 +45,57 @@ public class GRPCServer implements Server { ...@@ -39,28 +45,57 @@ public class GRPCServer implements Server {
private final int port; private final int port;
private io.grpc.Server server; private io.grpc.Server server;
private NettyServerBuilder nettyServerBuilder; private NettyServerBuilder nettyServerBuilder;
private SslContextBuilder sslContextBuilder;
private File certChainFile;
private File privateKeyFile;
public GRPCServer(String host, int port) { public GRPCServer(String host, int port) {
this.host = host; this.host = host;
this.port = port; this.port = port;
} }
@Override public String hostPort() { /**
* Require for `server.crt` and `server.pem` for open ssl at server side.
*
* @param host
* @param port
* @param certChainFile `server.crt` file
* @param privateKeyFile `server.pem` file
*/
public GRPCServer(String host, int port, File certChainFile, File privateKeyFile) {
this.host = host;
this.port = port;
this.certChainFile = certChainFile;
this.privateKeyFile = privateKeyFile;
this.sslContextBuilder = SslContextBuilder.forServer(certChainFile,
privateKeyFile);
}
@Override
public String hostPort() {
return host + ":" + port; return host + ":" + port;
} }
@Override public String serverClassify() { @Override
public String serverClassify() {
return "Google-RPC"; return "Google-RPC";
} }
@Override public void initialize() throws ServerException { @Override
public void initialize() throws ServerException {
InetSocketAddress address = new InetSocketAddress(host, port); InetSocketAddress address = new InetSocketAddress(host, port);
nettyServerBuilder = NettyServerBuilder.forAddress(address); nettyServerBuilder = NettyServerBuilder.forAddress(address);
logger.info("Server started, host {} listening on {}", host, port); logger.info("Server started, host {} listening on {}", host, port);
} }
@Override public void start() throws ServerException { @Override
public void start() throws ServerException {
try { try {
if (sslContextBuilder != null) {
nettyServerBuilder = nettyServerBuilder.sslContext(
GrpcSslContexts.configure(sslContextBuilder,
SslProvider.OPENSSL).build());
}
server = nettyServerBuilder.build(); server = nettyServerBuilder.build();
server.start(); server.start();
} catch (IOException e) { } catch (IOException e) {
...@@ -68,7 +103,24 @@ public class GRPCServer implements Server { ...@@ -68,7 +103,24 @@ public class GRPCServer implements Server {
} }
} }
@Override public void addHandler(ServerHandler handler) { @Override
nettyServerBuilder.addService((io.grpc.BindableService)handler); public void addHandler(ServerHandler handler) {
nettyServerBuilder.addService((io.grpc.BindableService) handler);
}
@Override
public boolean isSSLOpen() {
return sslContextBuilder == null;
}
@Override
public boolean isStatusEqual(Server target) {
if (this == target) return true;
if (target == null || getClass() != target.getClass()) return false;
GRPCServer that = (GRPCServer) target;
return port == that.port &&
Objects.equals(host, that.host) &&
Objects.equals(certChainFile, that.certChainFile) &&
Objects.equals(privateKeyFile, that.privateKeyFile);
} }
} }
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
package org.apache.skywalking.apm.collector.server.jetty; package org.apache.skywalking.apm.collector.server.jetty;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Objects;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
...@@ -31,7 +32,7 @@ import org.slf4j.Logger; ...@@ -31,7 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* @author peng-yongsheng * @author peng-yongsheng, wusheng
*/ */
public class JettyServer implements Server { public class JettyServer implements Server {
...@@ -73,6 +74,16 @@ public class JettyServer implements Server { ...@@ -73,6 +74,16 @@ public class JettyServer implements Server {
servletContextHandler.addServlet(servletHolder, ((JettyHandler)handler).pathSpec()); servletContextHandler.addServlet(servletHolder, ((JettyHandler)handler).pathSpec());
} }
@Override
public boolean isSSLOpen() {
return false;
}
@Override
public boolean isStatusEqual(Server target) {
return equals(target);
}
@Override public void start() throws ServerException { @Override public void start() throws ServerException {
logger.info("start server, host: {}, port: {}", host, port); logger.info("start server, host: {}, port: {}", host, port);
try { try {
...@@ -84,4 +95,18 @@ public class JettyServer implements Server { ...@@ -84,4 +95,18 @@ public class JettyServer implements Server {
throw new JettyServerException(e.getMessage(), e); throw new JettyServerException(e.getMessage(), e);
} }
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
JettyServer that = (JettyServer) o;
return port == that.port &&
Objects.equals(host, that.host);
}
@Override
public int hashCode() {
return Objects.hash(host, port);
}
} }
...@@ -22,9 +22,13 @@ package org.apache.skywalking.apm.collector.grpc.manager.service; ...@@ -22,9 +22,13 @@ package org.apache.skywalking.apm.collector.grpc.manager.service;
import org.apache.skywalking.apm.collector.core.module.Service; import org.apache.skywalking.apm.collector.core.module.Service;
import org.apache.skywalking.apm.collector.server.Server; import org.apache.skywalking.apm.collector.server.Server;
import java.io.File;
/** /**
* @author peng-yongsheng * @author peng-yongsheng, wusheng
*/ */
public interface GRPCManagerService extends Service { public interface GRPCManagerService extends Service {
Server createIfAbsent(String host, int port); Server createIfAbsent(String host, int port) throws ServerCanNotBeCreatedException;
Server createIfAbsent(String host, int port, File certChainFile, File privateKeyFile) throws ServerCanNotBeCreatedException;
} }
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.skywalking.apm.collector.grpc.manager.service;
import org.apache.skywalking.apm.collector.core.module.ServiceNotProvidedException;
/**
* gRPC Server can't be created under certain circumstance
*
* @author wusheng
*/
public class ServerCanNotBeCreatedException extends ServiceNotProvidedException {
public ServerCanNotBeCreatedException(String message) {
super(message);
}
}
...@@ -19,13 +19,15 @@ ...@@ -19,13 +19,15 @@
package org.apache.skywalking.apm.collector.grpc.manager.service; package org.apache.skywalking.apm.collector.grpc.manager.service;
import java.util.Map;
import org.apache.skywalking.apm.collector.server.Server; import org.apache.skywalking.apm.collector.server.Server;
import org.apache.skywalking.apm.collector.server.ServerException; import org.apache.skywalking.apm.collector.server.ServerException;
import org.apache.skywalking.apm.collector.server.grpc.GRPCServer; import org.apache.skywalking.apm.collector.server.grpc.GRPCServer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Map;
/** /**
* @author peng-yongsheng * @author peng-yongsheng
*/ */
...@@ -39,19 +41,33 @@ public class GRPCManagerServiceImpl implements GRPCManagerService { ...@@ -39,19 +41,33 @@ public class GRPCManagerServiceImpl implements GRPCManagerService {
this.servers = servers; this.servers = servers;
} }
@Override public Server createIfAbsent(String host, int port) { @Override
public Server createIfAbsent(String host, int port) throws ServerCanNotBeCreatedException {
return createOrChooseServer(host, port, new GRPCServer(host, port));
}
@Override
public Server createIfAbsent(String host, int port, File certChainFile, File privateKeyFile) throws ServerCanNotBeCreatedException {
return createOrChooseServer(host, port, new GRPCServer(host, port, certChainFile, privateKeyFile));
}
private Server createOrChooseServer(String host, int port, GRPCServer newServer) throws ServerCanNotBeCreatedException {
String id = host + String.valueOf(port); String id = host + String.valueOf(port);
if (servers.containsKey(id)) { GRPCServer existServer = servers.get(id);
return servers.get(id); if (existServer != null) {
if (existServer.isStatusEqual(newServer)) {
return existServer;
} else {
throw new ServerCanNotBeCreatedException("Can't create server with same port but different setting. SSL setting must equal too.");
}
} else { } else {
GRPCServer server = new GRPCServer(host, port);
try { try {
server.initialize(); newServer.initialize();
} catch (ServerException e) { } catch (ServerException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
servers.put(id, server); servers.put(id, newServer);
return server; return newServer;
} }
} }
} }
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<grpc.version>1.8.0</grpc.version> <grpc.version>1.10.0</grpc.version>
<netty.version>4.1.17.Final</netty.version> <netty.version>4.1.17.Final</netty.version>
<compiler.version>1.6</compiler.version> <compiler.version>1.6</compiler.version>
</properties> </properties>
...@@ -39,20 +39,6 @@ ...@@ -39,20 +39,6 @@
<groupId>io.grpc</groupId> <groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId> <artifactId>grpc-netty</artifactId>
<version>${grpc.version}</version> <version>${grpc.version}</version>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http2</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-handler-proxy</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.grpc</groupId> <groupId>io.grpc</groupId>
...@@ -66,18 +52,8 @@ ...@@ -66,18 +52,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-codec-http2</artifactId> <artifactId>netty-tcnative-boringssl-static</artifactId>
<version>${netty.version}</version> <version>2.0.7.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler-proxy</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jetty.version>9.4.2.v20170220</jetty.version> <jetty.version>9.4.2.v20170220</jetty.version>
<grpc.version>1.8.0</grpc.version> <grpc.version>1.10.0</grpc.version>
<bytebuddy.version>1.7.9</bytebuddy.version> <bytebuddy.version>1.7.9</bytebuddy.version>
<shade.package>org.apache.skywalking.apm.dependencies</shade.package> <shade.package>org.apache.skywalking.apm.dependencies</shade.package>
...@@ -219,6 +219,25 @@ ...@@ -219,6 +219,25 @@
</tasks> </tasks>
</configuration> </configuration>
</execution> </execution>
<execution>
<id>unpack</id>
<phase>package</phase>
<configuration>
<target>
<echo message="unjar" />
<unzip src="${project.build.directory}/${artifactId}-${version}.jar" dest="${project.build.directory}/unpacked/" />
<echo message="rename service providers in META-INF/services" />
<move file="${project.build.directory}/unpacked/META-INF/native/libnetty_tcnative_osx_x86_64.jnilib" tofile="${project.build.directory}/unpacked/META-INF/native/liborg_apache_skywalking_apm_dependencies_netty_tcnative_osx_x86_64.jnilib"/>
<move file="${project.build.directory}/unpacked/META-INF/native/libnetty_tcnative_linux_x86_64.so" tofile="${project.build.directory}/unpacked/META-INF/native/liborg_apache_skywalking_apm_dependencies_netty_tcnative_linux_x86_64.so"/>
<move file="${project.build.directory}/unpacked/META-INF/native/netty_tcnative_windows_x86_64.dll" tofile="${project.build.directory}/unpacked/META-INF/native/org_apache_skywalking_apm_dependencies_netty_tcnative_windows_x86_64.dll"/>
<echo message="jar back" />
<jar destfile="${project.build.directory}/${artifactId}-${version}.jar" basedir="${project.build.directory}/unpacked" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions> </executions>
</plugin> </plugin>
</plugins> </plugins>
......
...@@ -20,11 +20,11 @@ ...@@ -20,11 +20,11 @@
package org.apache.skywalking.apm.agent.core.remote; package org.apache.skywalking.apm.agent.core.remote;
import io.grpc.ManagedChannel; import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Status; import io.grpc.Status;
import io.grpc.StatusRuntimeException; import io.grpc.StatusRuntimeException;
import io.grpc.internal.DnsNameResolverProvider; import io.grpc.internal.DnsNameResolverProvider;
import io.grpc.netty.NettyChannelBuilder; import io.grpc.netty.NettyChannelBuilder;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
...@@ -32,6 +32,7 @@ import java.util.Random; ...@@ -32,6 +32,7 @@ import java.util.Random;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.skywalking.apm.agent.core.boot.BootService; import org.apache.skywalking.apm.agent.core.boot.BootService;
import org.apache.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory; import org.apache.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory;
import org.apache.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; import org.apache.skywalking.apm.agent.core.conf.RemoteDownstreamConfig;
...@@ -62,7 +63,8 @@ public class GRPCChannelManager implements BootService, Runnable { ...@@ -62,7 +63,8 @@ public class GRPCChannelManager implements BootService, Runnable {
connectCheckFuture = Executors connectCheckFuture = Executors
.newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("GRPCChannelManager")) .newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("GRPCChannelManager"))
.scheduleAtFixedRate(new RunnableWithExceptionProtection(this, new RunnableWithExceptionProtection.CallbackWhenException() { .scheduleAtFixedRate(new RunnableWithExceptionProtection(this, new RunnableWithExceptionProtection.CallbackWhenException() {
@Override public void handle(Throwable t) { @Override
public void handle(Throwable t) {
logger.error("unexpected exception.", t); logger.error("unexpected exception.", t);
} }
}), 0, Config.Collector.GRPC_CHANNEL_CHECK_INTERVAL, TimeUnit.SECONDS); }), 0, Config.Collector.GRPC_CHANNEL_CHECK_INTERVAL, TimeUnit.SECONDS);
...@@ -92,11 +94,13 @@ public class GRPCChannelManager implements BootService, Runnable { ...@@ -92,11 +94,13 @@ public class GRPCChannelManager implements BootService, Runnable {
int index = Math.abs(random.nextInt()) % RemoteDownstreamConfig.Collector.GRPC_SERVERS.size(); int index = Math.abs(random.nextInt()) % RemoteDownstreamConfig.Collector.GRPC_SERVERS.size();
server = RemoteDownstreamConfig.Collector.GRPC_SERVERS.get(index); server = RemoteDownstreamConfig.Collector.GRPC_SERVERS.get(index);
String[] ipAndPort = server.split(":"); String[] ipAndPort = server.split(":");
ManagedChannelBuilder<?> channelBuilder = NettyChannelBuilder channelBuilder =
new TLSChannelBuilder(
NettyChannelBuilder.forAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1])) NettyChannelBuilder.forAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1]))
.nameResolverFactory(new DnsNameResolverProvider()) .nameResolverFactory(new DnsNameResolverProvider())
.maxInboundMessageSize(1024 * 1024 * 50) .maxInboundMessageSize(1024 * 1024 * 50)
.usePlaintext(true); .usePlaintext(true)
).buildTLS();
managedChannel = channelBuilder.build(); managedChannel = channelBuilder.build();
if (!managedChannel.isShutdown() && !managedChannel.isTerminated()) { if (!managedChannel.isShutdown() && !managedChannel.isTerminated()) {
reconnect = false; reconnect = false;
...@@ -146,7 +150,7 @@ public class GRPCChannelManager implements BootService, Runnable { ...@@ -146,7 +150,7 @@ public class GRPCChannelManager implements BootService, Runnable {
private boolean isNetworkError(Throwable throwable) { private boolean isNetworkError(Throwable throwable) {
if (throwable instanceof StatusRuntimeException) { if (throwable instanceof StatusRuntimeException) {
StatusRuntimeException statusRuntimeException = (StatusRuntimeException)throwable; StatusRuntimeException statusRuntimeException = (StatusRuntimeException) throwable;
return statusEquals(statusRuntimeException.getStatus(), return statusEquals(statusRuntimeException.getStatus(),
Status.UNAVAILABLE, Status.UNAVAILABLE,
Status.PERMISSION_DENIED, Status.PERMISSION_DENIED,
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.remote;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
import io.netty.handler.ssl.SslContextBuilder;
import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath;
import org.apache.skywalking.apm.agent.core.conf.Constants;
import javax.net.ssl.SSLException;
import java.io.File;
/**
* Detect the `/ca` folder in agent package, if `ca.crt` exists, start TLS (no mutual auth).
*
* @author wusheng
*/
public class TLSChannelBuilder {
private static String CA_FILE_NAME = "ca" + Constants.PATH_SEPARATOR + "ca.crt";
private NettyChannelBuilder nettyChannelBuilder;
public TLSChannelBuilder(NettyChannelBuilder nettyChannelBuilder) {
this.nettyChannelBuilder = nettyChannelBuilder;
}
/**
* Build a TLS supported channel is necessary.
*
* @return chanel builder
* @throws AgentPackageNotFoundException
* @throws SSLException
*/
NettyChannelBuilder buildTLS() throws AgentPackageNotFoundException, SSLException {
File caFile = new File(AgentPackagePath.getPath(), CA_FILE_NAME);
if (caFile.exists() && caFile.isFile()) {
SslContextBuilder builder = GrpcSslContexts.forClient();
builder.trustManager(caFile);
nettyChannelBuilder = nettyChannelBuilder.negotiationType(NegotiationType.TLS)
.sslContext(builder.build());
}
return nettyChannelBuilder;
}
}
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
#
# Changes these CN's to match your hosts in your environment if needed.
SERVER_CN=localhost
CLIENT_CN=localhost # Used when doing mutual TLS
echo Generate CA key:
openssl genrsa -passout pass:1111 -des3 -out ca.key 4096
echo Generate CA certificate:
# Generates ca.crt which is the trustCertCollectionFile
openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/CN=${SERVER_CN}"
echo Generate server key:
openssl genrsa -passout pass:1111 -des3 -out server.key 4096
echo Generate server signing request:
openssl req -passin pass:1111 -new -key server.key -out server.csr -subj "/CN=${SERVER_CN}"
echo Self-signed server certificate:
# Generates server.crt which is the certChainFile for the server
openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
echo Remove passphrase from server key:
openssl rsa -passin pass:1111 -in server.key -out server.key
echo Generate client key
openssl genrsa -passout pass:1111 -des3 -out client.key 4096
echo Generate client signing request:
openssl req -passin pass:1111 -new -key client.key -out client.csr -subj "/CN=${CLIENT_CN}"
echo Self-signed client certificate:
# Generates client.crt which is the clientCertChainFile for the client (need for mutual TLS only)
openssl x509 -passin pass:1111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
echo Remove passphrase from client key:
openssl rsa -passin pass:1111 -in client.key -out client.key
echo Converting the private keys to X.509:
# Generates client.pem which is the clientPrivateKeyFile for the Client (needed for mutual TLS only)
openssl pkcs8 -topk8 -nocrypt -in client.key -out client.pem
# Generates server.pem which is the privateKeyFile for the Server
openssl pkcs8 -topk8 -nocrypt -in server.key -out server.pem
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册