Search in sources :

Example 1 with ClientAuth

use of io.netty.handler.ssl.ClientAuth in project flink by apache.

the class SSLUtils method createRestClientSSLEngineFactory.

/**
 * Creates a {@link SSLHandlerFactory} to be used by the REST Clients.
 *
 * @param config The application configuration.
 */
public static SSLHandlerFactory createRestClientSSLEngineFactory(final Configuration config) throws Exception {
    ClientAuth clientAuth = SecurityOptions.isRestSSLAuthenticationEnabled(config) ? ClientAuth.REQUIRE : ClientAuth.NONE;
    SslContext sslContext = createRestNettySSLContext(config, true, clientAuth);
    if (sslContext == null) {
        throw new IllegalConfigurationException("SSL is not enabled for REST endpoints.");
    }
    return new SSLHandlerFactory(sslContext, -1, -1);
}
Also used : IllegalConfigurationException(org.apache.flink.configuration.IllegalConfigurationException) SSLHandlerFactory(org.apache.flink.runtime.io.network.netty.SSLHandlerFactory) ClientAuth(org.apache.flink.shaded.netty4.io.netty.handler.ssl.ClientAuth) JdkSslContext(org.apache.flink.shaded.netty4.io.netty.handler.ssl.JdkSslContext) SslContext(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslContext)

Example 2 with ClientAuth

use of io.netty.handler.ssl.ClientAuth in project flink by apache.

the class SSLUtils method createInternalNettySSLContext.

/**
 * Creates the SSL Context for internal SSL, if internal SSL is configured. For internal SSL,
 * the client and server side configuration are identical, because of mutual authentication.
 */
@Nullable
private static SslContext createInternalNettySSLContext(Configuration config, boolean clientMode, SslProvider provider) throws Exception {
    checkNotNull(config, "config");
    if (!SecurityOptions.isInternalSSLEnabled(config)) {
        return null;
    }
    String[] sslProtocols = getEnabledProtocols(config);
    List<String> ciphers = Arrays.asList(getEnabledCipherSuites(config));
    int sessionCacheSize = config.getInteger(SecurityOptions.SSL_INTERNAL_SESSION_CACHE_SIZE);
    int sessionTimeoutMs = config.getInteger(SecurityOptions.SSL_INTERNAL_SESSION_TIMEOUT);
    KeyManagerFactory kmf = getKeyManagerFactory(config, true, provider);
    TrustManagerFactory tmf = getTrustManagerFactory(config, true);
    ClientAuth clientAuth = ClientAuth.REQUIRE;
    final SslContextBuilder sslContextBuilder;
    if (clientMode) {
        sslContextBuilder = SslContextBuilder.forClient().keyManager(kmf);
    } else {
        sslContextBuilder = SslContextBuilder.forServer(kmf);
    }
    return sslContextBuilder.sslProvider(provider).protocols(sslProtocols).ciphers(ciphers).trustManager(tmf).clientAuth(clientAuth).sessionCacheSize(sessionCacheSize).sessionTimeout(sessionTimeoutMs / 1000).build();
}
Also used : SslContextBuilder(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslContextBuilder) TrustManagerFactory(javax.net.ssl.TrustManagerFactory) FingerprintTrustManagerFactory(org.apache.flink.shaded.netty4.io.netty.handler.ssl.util.FingerprintTrustManagerFactory) ClientAuth(org.apache.flink.shaded.netty4.io.netty.handler.ssl.ClientAuth) OpenSslX509KeyManagerFactory(org.apache.flink.shaded.netty4.io.netty.handler.ssl.OpenSslX509KeyManagerFactory) KeyManagerFactory(javax.net.ssl.KeyManagerFactory) Nullable(javax.annotation.Nullable)

Example 3 with ClientAuth

use of io.netty.handler.ssl.ClientAuth in project zuul by Netflix.

the class SslHandshakeInfoHandler method userEventTriggered.

@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    if (evt instanceof SslHandshakeCompletionEvent) {
        try {
            SslHandshakeCompletionEvent sslEvent = (SslHandshakeCompletionEvent) evt;
            if (sslEvent.isSuccess()) {
                CurrentPassport.fromChannel(ctx.channel()).add(PassportState.SERVER_CH_SSL_HANDSHAKE_COMPLETE);
                SslHandler sslhandler = ctx.channel().pipeline().get(SslHandler.class);
                SSLSession session = sslhandler.engine().getSession();
                ClientAuth clientAuth = whichClientAuthEnum(sslhandler);
                Certificate serverCert = null;
                X509Certificate peerCert = null;
                if ((clientAuth == ClientAuth.REQUIRE || clientAuth == ClientAuth.OPTIONAL) && session.getPeerCertificates() != null && session.getPeerCertificates().length > 0) {
                    peerCert = (X509Certificate) session.getPeerCertificates()[0];
                }
                if (session.getLocalCertificates() != null && session.getLocalCertificates().length > 0) {
                    serverCert = session.getLocalCertificates()[0];
                }
                SslHandshakeInfo info = new SslHandshakeInfo(isSSlFromIntermediary, session.getProtocol(), session.getCipherSuite(), clientAuth, serverCert, peerCert);
                ctx.channel().attr(ATTR_SSL_INFO).set(info);
                // Metrics.
                incrementCounters(sslEvent, info);
                logger.debug("Successful SSL Handshake: {}", info);
            } else {
                String clientIP = ctx.channel().attr(SourceAddressChannelHandler.ATTR_SOURCE_ADDRESS).get();
                Throwable cause = sslEvent.cause();
                PassportState passportState = CurrentPassport.fromChannel(ctx.channel()).getState();
                if (cause instanceof ClosedChannelException && (PassportState.SERVER_CH_INACTIVE.equals(passportState) || PassportState.SERVER_CH_IDLE_TIMEOUT.equals(passportState))) {
                    // Either client closed the connection without/before having completed a handshake, or
                    // the connection idle timed-out before handshake.
                    // NOTE: we were seeing a lot of these in prod and can repro by just telnetting to port and then closing terminal
                    // without sending anything.
                    // So don't treat these as SSL handshake failures.
                    logger.debug("Client closed connection or it idle timed-out without doing an ssl handshake. " + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
                } else if (cause instanceof SSLException && cause.getMessage().contains("handshake timed out")) {
                    logger.debug("Client timed-out doing the ssl handshake. " + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
                } else if (cause instanceof SSLException && cause.getMessage().contains("failure when writing TLS control frames")) {
                    // This can happen if the ClientHello is sent followed  by a RST packet, before we can respond.
                    logger.debug("Client terminated handshake early." + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
                } else {
                    String msg = "Unsuccessful SSL Handshake: " + sslEvent + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()) + ", error = " + cause;
                    if (cause instanceof ClosedChannelException) {
                        logger.debug(msg);
                    } else {
                        logger.debug(msg, cause);
                    }
                    incrementCounters(sslEvent, null);
                }
            }
        } catch (Throwable e) {
            logger.warn("Error getting the SSL handshake info.", e);
        } finally {
            // Now remove this handler from the pipeline as no longer needed once the ssl handshake has completed.
            ctx.pipeline().remove(this);
        }
    } else if (evt instanceof SslCloseCompletionEvent) {
    // TODO - increment a separate metric for this event?
    } else if (evt instanceof SniCompletionEvent) {
        logger.debug("SNI Parsing Complete: {}", evt);
        SniCompletionEvent sniCompletionEvent = (SniCompletionEvent) evt;
        if (sniCompletionEvent.isSuccess()) {
            spectatorRegistry.counter("zuul.sni.parse.success").increment();
        } else {
            Throwable cause = sniCompletionEvent.cause();
            spectatorRegistry.counter("zuul.sni.parse.failure", "cause", cause != null ? cause.getMessage() : "UNKNOWN").increment();
        }
    }
    super.userEventTriggered(ctx, evt);
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) SniCompletionEvent(io.netty.handler.ssl.SniCompletionEvent) SSLSession(javax.net.ssl.SSLSession) ClientAuth(io.netty.handler.ssl.ClientAuth) SSLException(javax.net.ssl.SSLException) SslHandler(io.netty.handler.ssl.SslHandler) X509Certificate(java.security.cert.X509Certificate) PassportState(com.netflix.zuul.passport.PassportState) SslHandshakeInfo(com.netflix.netty.common.ssl.SslHandshakeInfo) SslCloseCompletionEvent(io.netty.handler.ssl.SslCloseCompletionEvent) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 4 with ClientAuth

use of io.netty.handler.ssl.ClientAuth in project xipki by xipki.

the class HttpServers method buildSslContext.

private SslContext buildSslContext(HttpserverType conf) throws Exception {
    TlsType tt = conf.getTls();
    if (tt == null) {
        return null;
    }
    KeystoreType kst = tt.getKeystore();
    SslContextBuilder builder;
    // key and certificate
    if (kst == null) {
        throw new IllegalArgumentException("no keystore is configured");
    } else {
        char[] kstPwd = passwordResolver.resolvePassword(kst.getPassword());
        KeyStore ks = loadKeyStore(kst.getType(), kst.getStore(), kstPwd);
        String alias = kst.getKeyAlias();
        if (alias != null) {
            if (!ks.isKeyEntry(alias)) {
                throw new Exception("'" + alias + "' is not a valid key alias");
            }
        } else {
            Enumeration<String> aliases = ks.aliases();
            while (aliases.hasMoreElements()) {
                String al = aliases.nextElement();
                if (ks.isKeyEntry(al)) {
                    alias = al;
                    break;
                }
            }
            if (alias == null) {
                throw new Exception("found no key entries in the keystore");
            }
        }
        char[] keypwd = (kst.getKeyPassword() == null) ? kstPwd : passwordResolver.resolvePassword(kst.getKeyPassword());
        PrivateKey key = (PrivateKey) ks.getKey(alias, keypwd);
        Certificate[] certs = ks.getCertificateChain(alias);
        X509Certificate[] keyCertChain = new X509Certificate[certs.length];
        for (int i = 0; i < certs.length; i++) {
            keyCertChain[i] = (X509Certificate) certs[i];
        }
        builder = SslContextBuilder.forServer(key, keyCertChain);
    }
    boolean opensslAvailable = OpenSsl.isAvailable();
    // providers
    SslProvider sslProvider;
    if (tt.getProvider() == null) {
        if (!opensslAvailable) {
            logOpenSslWarning();
        }
        sslProvider = SslContext.defaultServerProvider();
    } else {
        String providerStr = tt.getProvider();
        String providerStr0 = providerStr.toLowerCase().replaceAll("[^a-z0-9]+", "");
        if ("jdk".equals(providerStr0)) {
            sslProvider = SslProvider.JDK;
        } else if ("openssl".equals(providerStr0) || "opensslrefcnt".equals(providerStr0)) {
            if (!opensslAvailable) {
                logOpenSslWarning();
                throw new Exception("OpenSSL not available");
            }
            sslProvider = "openssl".equals(providerStr0) ? SslProvider.OPENSSL : SslProvider.OPENSSL_REFCNT;
        } else {
            throw new Exception("unknwon SSL provider " + providerStr);
        }
    }
    LOG.info("use SSL provider {}", sslProvider);
    builder.sslProvider(sslProvider);
    List<String> availableProtocols;
    List<String> availableCiphersuits;
    switch(sslProvider) {
        case JDK:
            SSLParameters sslParams = SSLContext.getDefault().getSupportedSSLParameters();
            availableProtocols = Arrays.asList(sslParams.getProtocols());
            availableCiphersuits = Arrays.asList(sslParams.getCipherSuites());
            break;
        case OPENSSL:
        case OPENSSL_REFCNT:
            // any way to get the supported protocols of OpenSSL?
            availableProtocols = Arrays.asList("TLSv1.1", "TLSv1.2");
            availableCiphersuits = new ArrayList<>(OpenSsl.availableJavaCipherSuites());
            break;
        default:
            throw new RuntimeException("should not reach here, unknown SssProvider " + sslProvider);
    }
    // protocols
    List<String> protocols;
    if (tt.getProtocols() != null) {
        protocols = tt.getProtocols().getProtocol();
    } else {
        protocols = Arrays.asList("TLSv1.1", "TLSv1.2");
    }
    final String[] strArray = new String[0];
    Set<String> usedProtocols = new HashSet<>();
    for (String protocol : protocols) {
        boolean added = false;
        for (String supported : availableProtocols) {
            if (protocol.equalsIgnoreCase(supported)) {
                usedProtocols.add(supported);
                added = true;
                break;
            }
        }
        if (!added) {
            LOG.warn("SSL Protocol {} unsupported, ignore it", protocol);
        }
    }
    if (usedProtocols.isEmpty()) {
        throw new Exception("None of the configured SSL protocols is supported");
    }
    LOG.info("use SSL protocols {}", usedProtocols);
    builder.protocols(usedProtocols.toArray(strArray));
    // canonicalize the cipher suites
    boolean cipherWithTls = availableCiphersuits.get(0).startsWith("TLS_");
    // cipher suites
    Set<String> usedCipherSuites = new HashSet<>();
    if (tt.getCiphersuites() != null) {
        for (String cipherSuite : tt.getCiphersuites().getCiphersuite()) {
            if (cipherSuite.length() < 5) {
                LOG.warn("cipher suite {} unsupported, ignore it", cipherSuite);
                continue;
            }
            String adaptedCipher;
            if (cipherWithTls == cipherSuite.startsWith("TLS_")) {
                adaptedCipher = cipherSuite;
            } else {
                if (cipherWithTls) {
                    adaptedCipher = "TLS_" + cipherSuite.substring(4);
                } else {
                    adaptedCipher = "SSL_" + cipherSuite.substring(4);
                }
            }
            boolean added = false;
            for (String supported : availableCiphersuits) {
                if (adaptedCipher.equalsIgnoreCase(supported)) {
                    usedCipherSuites.add(supported);
                    added = true;
                    break;
                }
            }
            if (!added) {
                LOG.warn("SSL cipher suite {} unsupported, ignore it", cipherSuite);
            }
        }
    } else {
        String[] excludeMiddlePatterns = { "_3DES", "_DES", "EMPTY", "EXPORT", "anno", "NULL" };
        String[] excludeEndPatterns = { "MD5", "SHA" };
        for (String cipherSuite : availableCiphersuits) {
            boolean add = true;
            for (String p : excludeMiddlePatterns) {
                if (cipherSuite.contains(p)) {
                    add = false;
                    break;
                }
            }
            if (add) {
                for (String p : excludeEndPatterns) {
                    if (cipherSuite.endsWith(p)) {
                        add = false;
                        break;
                    }
                }
            }
            if (add) {
                usedCipherSuites.add(cipherSuite);
            }
        }
    }
    LOG.info("use SSL cipher suites {}", usedCipherSuites);
    builder.ciphers(usedCipherSuites);
    // client authentication
    ClientAuth clientAuth;
    String str = tt.getClientauth();
    if ("none".equalsIgnoreCase(str)) {
        clientAuth = ClientAuth.NONE;
    } else if ("optional".equalsIgnoreCase(str)) {
        clientAuth = ClientAuth.OPTIONAL;
    } else if ("require".equalsIgnoreCase(str)) {
        clientAuth = ClientAuth.REQUIRE;
    } else {
        throw new Exception("invalid client authentication '" + str + "'");
    }
    builder.clientAuth(clientAuth);
    if (clientAuth != ClientAuth.NONE) {
        TruststoreType tst = tt.getTruststore();
        if (tst == null) {
            throw new Exception("Client authentication is activated, but no truststore is configured");
        }
        char[] pwd = passwordResolver.resolvePassword(tst.getPassword());
        KeyStore ks = loadKeyStore(tst.getType(), tst.getStore(), pwd);
        List<X509Certificate> trustcerts = new LinkedList<>();
        Enumeration<String> aliases = ks.aliases();
        while (aliases.hasMoreElements()) {
            String alias = aliases.nextElement();
            Certificate cert = ks.getCertificate(alias);
            trustcerts.add((X509Certificate) cert);
        }
        if (trustcerts.isEmpty()) {
            throw new Exception("No certificates found int the truststore. Please verify it via" + " JDK's keytool.");
        }
        builder.trustManager(trustcerts.toArray(new X509Certificate[0]));
    }
    return builder.build();
}
Also used : PrivateKey(java.security.PrivateKey) KeystoreType(org.xipki.httpserver.v1.jaxb.KeystoreType) ClientAuth(io.netty.handler.ssl.ClientAuth) SSLParameters(javax.net.ssl.SSLParameters) HashSet(java.util.HashSet) TlsType(org.xipki.httpserver.v1.jaxb.TlsType) KeyStore(java.security.KeyStore) KeyStoreException(java.security.KeyStoreException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) X509Certificate(java.security.cert.X509Certificate) LinkedList(java.util.LinkedList) TruststoreType(org.xipki.httpserver.v1.jaxb.TruststoreType) SslContextBuilder(io.netty.handler.ssl.SslContextBuilder) SslProvider(io.netty.handler.ssl.SslProvider) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 5 with ClientAuth

use of io.netty.handler.ssl.ClientAuth in project flink by apache.

the class SSLUtils method createRestServerSSLEngineFactory.

/**
 * Creates a {@link SSLHandlerFactory} to be used by the REST Servers.
 *
 * @param config The application configuration.
 */
public static SSLHandlerFactory createRestServerSSLEngineFactory(final Configuration config) throws Exception {
    ClientAuth clientAuth = SecurityOptions.isRestSSLAuthenticationEnabled(config) ? ClientAuth.REQUIRE : ClientAuth.NONE;
    SslContext sslContext = createRestNettySSLContext(config, false, clientAuth);
    if (sslContext == null) {
        throw new IllegalConfigurationException("SSL is not enabled for REST endpoints.");
    }
    return new SSLHandlerFactory(sslContext, -1, -1);
}
Also used : IllegalConfigurationException(org.apache.flink.configuration.IllegalConfigurationException) SSLHandlerFactory(org.apache.flink.runtime.io.network.netty.SSLHandlerFactory) ClientAuth(org.apache.flink.shaded.netty4.io.netty.handler.ssl.ClientAuth) JdkSslContext(org.apache.flink.shaded.netty4.io.netty.handler.ssl.JdkSslContext) SslContext(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslContext)

Aggregations

ClientAuth (org.apache.flink.shaded.netty4.io.netty.handler.ssl.ClientAuth)4 ClientAuth (io.netty.handler.ssl.ClientAuth)3 JdkSslContext (org.apache.flink.shaded.netty4.io.netty.handler.ssl.JdkSslContext)3 Certificate (java.security.cert.Certificate)2 X509Certificate (java.security.cert.X509Certificate)2 Nullable (javax.annotation.Nullable)2 IllegalConfigurationException (org.apache.flink.configuration.IllegalConfigurationException)2 SSLHandlerFactory (org.apache.flink.runtime.io.network.netty.SSLHandlerFactory)2 SslContext (org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslContext)2 SslHandshakeInfo (com.netflix.netty.common.ssl.SslHandshakeInfo)1 PassportState (com.netflix.zuul.passport.PassportState)1 SniCompletionEvent (io.netty.handler.ssl.SniCompletionEvent)1 SslCloseCompletionEvent (io.netty.handler.ssl.SslCloseCompletionEvent)1 SslContextBuilder (io.netty.handler.ssl.SslContextBuilder)1 SslHandler (io.netty.handler.ssl.SslHandler)1 SslHandshakeCompletionEvent (io.netty.handler.ssl.SslHandshakeCompletionEvent)1 SslProvider (io.netty.handler.ssl.SslProvider)1 SelfSignedCertificate (io.netty.handler.ssl.util.SelfSignedCertificate)1 File (java.io.File)1 IOException (java.io.IOException)1