diff --git a/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/AgentModuleGRPCProvider.java b/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/AgentModuleGRPCProvider.java index f3dcdeb29a5337bb9c6cb210c0b624b45134f304..24441829bd05d1c15b4faedd1194f8239cfc7d05 100644 --- a/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/AgentModuleGRPCProvider.java +++ b/apm-collector/apm-collector-agent/agent-grpc/agent-grpc-provider/src/main/java/org/apache/skywalking/apm/collector/agent/grpc/provider/AgentModuleGRPCProvider.java @@ -18,7 +18,9 @@ package org.apache.skywalking.apm.collector.agent.grpc.provider; +import java.io.File; import java.util.Properties; + 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.InstanceDiscoveryServiceHandler; @@ -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.service.NamingHandlerRegisterService; import org.apache.skywalking.apm.collector.server.Server; +import org.eclipse.jetty.util.StringUtil; /** * @author peng-yongsheng @@ -50,22 +53,44 @@ public class AgentModuleGRPCProvider extends ModuleProvider { public static final String NAME = "gRPC"; private static final String HOST = "host"; 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; } - @Override public Class module() { + @Override + public Class module() { 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); - 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.register(AgentGRPCModule.NAME, this.name(), new AgentModuleGRPCRegistration(host, port)); @@ -78,17 +103,24 @@ public class AgentModuleGRPCProvider extends ModuleProvider { namingHandlerRegisterService.register(new AgentGRPCNamingHandler(namingListener)); 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); } - @Override public void notifyAfterCompleted() throws ServiceNotProvidedException { + @Override + public void notifyAfterCompleted() throws ServiceNotProvidedException { } - @Override public String[] requiredModules() { - return new String[] {ClusterModule.NAME, NamingModule.NAME, GRPCManagerModule.NAME, AnalysisSegmentParserModule.NAME, AnalysisMetricModule.NAME}; + @Override + public String[] requiredModules() { + return new String[]{ClusterModule.NAME, NamingModule.NAME, GRPCManagerModule.NAME, AnalysisSegmentParserModule.NAME, AnalysisMetricModule.NAME}; } private void addHandlers(Server gRPCServer) { diff --git a/apm-collector/apm-collector-boot/src/main/resources/application.yml b/apm-collector/apm-collector-boot/src/main/resources/application.yml index aa38e37993a0dd97a9e7e19a787397d5b91911d9..3303acf6b404d969bd39482a84b3f4b62c47826a 100644 --- a/apm-collector/apm-collector-boot/src/main/resources/application.yml +++ b/apm-collector/apm-collector-boot/src/main/resources/application.yml @@ -15,6 +15,9 @@ agent_gRPC: gRPC: host: localhost port: 11800 + #Set these two setting to open ssl + #ssl_cert_chain_file: $path + #ssl_private_key_file: $path agent_jetty: jetty: host: localhost diff --git a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/Server.java b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/Server.java index efb0f5684829599c34e5082b38cf4359bea2349e..efd15378a2c09b2702b91e0c5fe7c6a8edccc635 100644 --- a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/Server.java +++ b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/Server.java @@ -20,7 +20,7 @@ package org.apache.skywalking.apm.collector.server; /** - * @author peng-yongsheng + * @author peng-yongsheng, wusheng */ public interface Server { @@ -33,4 +33,8 @@ public interface Server { void start() throws ServerException; void addHandler(ServerHandler handler); + + boolean isSSLOpen(); + + boolean isStatusEqual(Server target); } diff --git a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/grpc/GRPCServer.java b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/grpc/GRPCServer.java index 490461281f7627297f55956de19d48890c90140e..876c7d34c2f6689288886b29777991be9c5f1756 100644 --- a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/grpc/GRPCServer.java +++ b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/grpc/GRPCServer.java @@ -19,17 +19,23 @@ package org.apache.skywalking.apm.collector.server.grpc; +import io.grpc.netty.GrpcSslContexts; import io.grpc.netty.NettyServerBuilder; -import java.io.IOException; -import java.net.InetSocketAddress; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.SslProvider; import org.apache.skywalking.apm.collector.server.Server; import org.apache.skywalking.apm.collector.server.ServerException; import org.apache.skywalking.apm.collector.server.ServerHandler; import org.slf4j.Logger; 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 { @@ -39,28 +45,57 @@ public class GRPCServer implements Server { private final int port; private io.grpc.Server server; private NettyServerBuilder nettyServerBuilder; + private SslContextBuilder sslContextBuilder; + private File certChainFile; + private File privateKeyFile; public GRPCServer(String host, int port) { this.host = host; 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; } - @Override public String serverClassify() { + @Override + public String serverClassify() { return "Google-RPC"; } - @Override public void initialize() throws ServerException { + @Override + public void initialize() throws ServerException { InetSocketAddress address = new InetSocketAddress(host, port); nettyServerBuilder = NettyServerBuilder.forAddress(address); logger.info("Server started, host {} listening on {}", host, port); } - @Override public void start() throws ServerException { + @Override + public void start() throws ServerException { try { + if (sslContextBuilder != null) { + nettyServerBuilder = nettyServerBuilder.sslContext( + GrpcSslContexts.configure(sslContextBuilder, + SslProvider.OPENSSL).build()); + } server = nettyServerBuilder.build(); server.start(); } catch (IOException e) { @@ -68,7 +103,24 @@ public class GRPCServer implements Server { } } - @Override public void addHandler(ServerHandler handler) { - nettyServerBuilder.addService((io.grpc.BindableService)handler); + @Override + 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); } } diff --git a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyServer.java b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyServer.java index 8e6008eebc756cd8df87dfe593c4ccf9d41c829a..5f267c68f5c073544dcc3e4536b3de6942426024 100644 --- a/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyServer.java +++ b/apm-collector/apm-collector-component/server-component/src/main/java/org/apache/skywalking/apm/collector/server/jetty/JettyServer.java @@ -20,6 +20,7 @@ package org.apache.skywalking.apm.collector.server.jetty; import java.net.InetSocketAddress; +import java.util.Objects; import javax.servlet.http.HttpServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; @@ -31,7 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * @author peng-yongsheng + * @author peng-yongsheng, wusheng */ public class JettyServer implements Server { @@ -73,6 +74,16 @@ public class JettyServer implements Server { 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 { logger.info("start server, host: {}, port: {}", host, port); try { @@ -84,4 +95,18 @@ public class JettyServer implements Server { 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); + } } diff --git a/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-define/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/GRPCManagerService.java b/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-define/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/GRPCManagerService.java index 59cf7aeb218183985cde2927f7db89435bc5902b..d633866a052754bc05893a6f289a84380f5f527b 100644 --- a/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-define/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/GRPCManagerService.java +++ b/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-define/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/GRPCManagerService.java @@ -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.server.Server; +import java.io.File; + /** - * @author peng-yongsheng + * @author peng-yongsheng, wusheng */ 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; } diff --git a/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-define/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/ServerCanNotBeCreatedException.java b/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-define/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/ServerCanNotBeCreatedException.java new file mode 100644 index 0000000000000000000000000000000000000000..5f7886358105f9bb95247096d15011a7efe7d0b1 --- /dev/null +++ b/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-define/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/ServerCanNotBeCreatedException.java @@ -0,0 +1,32 @@ +/* + * 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); + } +} diff --git a/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-provider/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/GRPCManagerServiceImpl.java b/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-provider/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/GRPCManagerServiceImpl.java index efd7de39c9a010ec675f8612512237cd92b2a217..ea58acbe32dd0643021decdd370ddcd3260de23b 100644 --- a/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-provider/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/GRPCManagerServiceImpl.java +++ b/apm-collector/apm-collector-grpc-manager/collector-grpc-manager-provider/src/main/java/org/apache/skywalking/apm/collector/grpc/manager/service/GRPCManagerServiceImpl.java @@ -19,13 +19,15 @@ 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.ServerException; import org.apache.skywalking.apm.collector.server.grpc.GRPCServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.util.Map; + /** * @author peng-yongsheng */ @@ -39,19 +41,33 @@ public class GRPCManagerServiceImpl implements GRPCManagerService { 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); - if (servers.containsKey(id)) { - return servers.get(id); + GRPCServer existServer = 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 { - GRPCServer server = new GRPCServer(host, port); try { - server.initialize(); + newServer.initialize(); } catch (ServerException e) { logger.error(e.getMessage(), e); } - servers.put(id, server); - return server; + servers.put(id, newServer); + return newServer; } } } diff --git a/apm-protocol/apm-network/pom.xml b/apm-protocol/apm-network/pom.xml index b203f97b0286d2ba2e973d9af59ed5f743f8bb1e..1481c67e1f2034c15e5711ef5781bee4c8f9c79d 100644 --- a/apm-protocol/apm-network/pom.xml +++ b/apm-protocol/apm-network/pom.xml @@ -29,7 +29,7 @@ UTF-8 - 1.8.0 + 1.10.0 4.1.17.Final 1.6 @@ -39,20 +39,6 @@ io.grpc grpc-netty ${grpc.version} - - - io.netty - netty-codec-http2 - - - io.netty - netty-transport-native-epoll - - - io.netty - netty-handler-proxy - - io.grpc @@ -66,18 +52,8 @@ io.netty - netty-codec-http2 - ${netty.version} - - - io.netty - netty-handler-proxy - ${netty.version} - - - io.netty - netty-transport-native-epoll - ${netty.version} + netty-tcnative-boringssl-static + 2.0.7.Final diff --git a/apm-sniffer/apm-agent-core/pom.xml b/apm-sniffer/apm-agent-core/pom.xml index ddd9942d26c639a784cc5c400fe675c410b16b5c..2dbb3d804fd86ff874271799c4fe3e4054635eb8 100644 --- a/apm-sniffer/apm-agent-core/pom.xml +++ b/apm-sniffer/apm-agent-core/pom.xml @@ -34,7 +34,7 @@ UTF-8 9.4.2.v20170220 - 1.8.0 + 1.10.0 1.7.9 org.apache.skywalking.apm.dependencies @@ -219,6 +219,25 @@ + + unpack + package + + + + + + + + + + + + + + run + + diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java index 2f522f0fcc95de07ce1d93c421f66970863c1759..785bc0da9f34bccc876a62292c43e70145b56d5f 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java @@ -20,11 +20,11 @@ package org.apache.skywalking.apm.agent.core.remote; import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; import io.grpc.Status; import io.grpc.StatusRuntimeException; import io.grpc.internal.DnsNameResolverProvider; import io.grpc.netty.NettyChannelBuilder; + import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -32,6 +32,7 @@ import java.util.Random; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; + 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.conf.RemoteDownstreamConfig; @@ -60,12 +61,13 @@ public class GRPCChannelManager implements BootService, Runnable { @Override public void boot() throws Throwable { connectCheckFuture = Executors - .newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("GRPCChannelManager")) - .scheduleAtFixedRate(new RunnableWithExceptionProtection(this, new RunnableWithExceptionProtection.CallbackWhenException() { - @Override public void handle(Throwable t) { - logger.error("unexpected exception.", t); - } - }), 0, Config.Collector.GRPC_CHANNEL_CHECK_INTERVAL, TimeUnit.SECONDS); + .newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("GRPCChannelManager")) + .scheduleAtFixedRate(new RunnableWithExceptionProtection(this, new RunnableWithExceptionProtection.CallbackWhenException() { + @Override + public void handle(Throwable t) { + logger.error("unexpected exception.", t); + } + }), 0, Config.Collector.GRPC_CHANNEL_CHECK_INTERVAL, TimeUnit.SECONDS); } @Override @@ -92,11 +94,13 @@ public class GRPCChannelManager implements BootService, Runnable { int index = Math.abs(random.nextInt()) % RemoteDownstreamConfig.Collector.GRPC_SERVERS.size(); server = RemoteDownstreamConfig.Collector.GRPC_SERVERS.get(index); String[] ipAndPort = server.split(":"); - ManagedChannelBuilder channelBuilder = - NettyChannelBuilder.forAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1])) - .nameResolverFactory(new DnsNameResolverProvider()) - .maxInboundMessageSize(1024 * 1024 * 50) - .usePlaintext(true); + NettyChannelBuilder channelBuilder = + new TLSChannelBuilder( + NettyChannelBuilder.forAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1])) + .nameResolverFactory(new DnsNameResolverProvider()) + .maxInboundMessageSize(1024 * 1024 * 50) + .usePlaintext(true) + ).buildTLS(); managedChannel = channelBuilder.build(); if (!managedChannel.isShutdown() && !managedChannel.isTerminated()) { reconnect = false; @@ -146,13 +150,13 @@ public class GRPCChannelManager implements BootService, Runnable { private boolean isNetworkError(Throwable throwable) { if (throwable instanceof StatusRuntimeException) { - StatusRuntimeException statusRuntimeException = (StatusRuntimeException)throwable; + StatusRuntimeException statusRuntimeException = (StatusRuntimeException) throwable; return statusEquals(statusRuntimeException.getStatus(), - Status.UNAVAILABLE, - Status.PERMISSION_DENIED, - Status.UNAUTHENTICATED, - Status.RESOURCE_EXHAUSTED, - Status.UNKNOWN + Status.UNAVAILABLE, + Status.PERMISSION_DENIED, + Status.UNAUTHENTICATED, + Status.RESOURCE_EXHAUSTED, + Status.UNKNOWN ); } return false; diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/TLSChannelBuilder.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/TLSChannelBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..ce4569dbfa153316a00024efb82ca73757be3941 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/TLSChannelBuilder.java @@ -0,0 +1,63 @@ +/* + * 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; + } +} diff --git a/tools/TLS/tls_key_generate.sh b/tools/TLS/tls_key_generate.sh new file mode 100644 index 0000000000000000000000000000000000000000..53b24724a4dfa8efe4408bc26c4b31e65b09a9a7 --- /dev/null +++ b/tools/TLS/tls_key_generate.sh @@ -0,0 +1,49 @@ +# +# 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