Search in sources :

Example 61 with SecurityProtocol

use of org.apache.kafka.common.security.auth.SecurityProtocol in project apache-kafka-on-k8s by banzaicloud.

the class SaslAuthenticatorTest method testUnknownUserSaslScram.

/**
 * Tests that SASL/SCRAM clients without valid username fail authentication.
 */
@Test
public void testUnknownUserSaslScram() throws Exception {
    SecurityProtocol securityProtocol = SecurityProtocol.SASL_SSL;
    TestJaasConfig jaasConfig = configureMechanisms("SCRAM-SHA-256", Arrays.asList("SCRAM-SHA-256"));
    Map<String, Object> options = new HashMap<>();
    options.put("username", "unknownUser");
    options.put("password", TestJaasConfig.PASSWORD);
    jaasConfig.createOrUpdateEntry(TestJaasConfig.LOGIN_CONTEXT_CLIENT, ScramLoginModule.class.getName(), options);
    String node = "0";
    server = createEchoServer(securityProtocol);
    updateScramCredentialCache(TestJaasConfig.USERNAME, TestJaasConfig.PASSWORD);
    createAndCheckClientAuthenticationFailure(securityProtocol, node, "SCRAM-SHA-256", null);
    server.verifyAuthenticationMetrics(0, 1);
}
Also used : HashMap(java.util.HashMap) ScramLoginModule(org.apache.kafka.common.security.scram.ScramLoginModule) SecurityProtocol(org.apache.kafka.common.security.auth.SecurityProtocol) Test(org.junit.Test)

Example 62 with SecurityProtocol

use of org.apache.kafka.common.security.auth.SecurityProtocol in project apache-kafka-on-k8s by banzaicloud.

the class SaslAuthenticatorTest method testUnauthenticatedApiVersionsRequest.

/**
 * Tests that Kafka ApiVersionsRequests are handled by the SASL server authenticator
 * prior to SASL handshake flow and that subsequent authentication succeeds
 * when transport layer is PLAINTEXT/SSL. This test uses a non-SASL client that simulates
 * SASL authentication after ApiVersionsRequest.
 * <p>
 * Test sequence (using <tt>securityProtocol=PLAINTEXT</tt> as an example):
 * <ol>
 *   <li>Starts a SASL_PLAINTEXT test server that simply echoes back client requests after authentication.</li>
 *   <li>A (non-SASL) PLAINTEXT test client connects to the SASL server port. Client is now unauthenticated.<./li>
 *   <li>The unauthenticated non-SASL client sends an ApiVersionsRequest and validates the response.
 *       A valid response indicates that {@link SaslServerAuthenticator} of the test server responded to
 *       the ApiVersionsRequest even though the client is not yet authenticated.</li>
 *   <li>The unauthenticated non-SASL client sends a SaslHandshakeRequest and validates the response. A valid response
 *       indicates that {@link SaslServerAuthenticator} of the test server responded to the SaslHandshakeRequest
 *       after processing ApiVersionsRequest.</li>
 *   <li>The unauthenticated non-SASL client sends the SASL/PLAIN packet containing username/password to authenticate
 *       itself. The client is now authenticated by the server. At this point this test client is at the
 *       same state as a regular SASL_PLAINTEXT client that is <tt>ready</tt>.</li>
 *   <li>The authenticated client sends random data to the server and checks that the data is echoed
 *       back by the test server (ie, not Kafka request-response) to ensure that the client now
 *       behaves exactly as a regular SASL_PLAINTEXT client that has completed authentication.</li>
 * </ol>
 */
private void testUnauthenticatedApiVersionsRequest(SecurityProtocol securityProtocol, short saslHandshakeVersion) throws Exception {
    configureMechanisms("PLAIN", Arrays.asList("PLAIN"));
    server = createEchoServer(securityProtocol);
    // Create non-SASL connection to manually authenticate after ApiVersionsRequest
    String node = "1";
    SecurityProtocol clientProtocol;
    switch(securityProtocol) {
        case SASL_PLAINTEXT:
            clientProtocol = SecurityProtocol.PLAINTEXT;
            break;
        case SASL_SSL:
            clientProtocol = SecurityProtocol.SSL;
            break;
        default:
            throw new IllegalArgumentException("Server protocol " + securityProtocol + " is not SASL");
    }
    createClientConnection(clientProtocol, node);
    NetworkTestUtils.waitForChannelReady(selector, node);
    // Send ApiVersionsRequest and check response
    ApiVersionsResponse versionsResponse = sendVersionRequestReceiveResponse(node);
    assertEquals(ApiKeys.SASL_HANDSHAKE.oldestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_HANDSHAKE.id).minVersion);
    assertEquals(ApiKeys.SASL_HANDSHAKE.latestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_HANDSHAKE.id).maxVersion);
    assertEquals(ApiKeys.SASL_AUTHENTICATE.oldestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_AUTHENTICATE.id).minVersion);
    assertEquals(ApiKeys.SASL_AUTHENTICATE.latestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_AUTHENTICATE.id).maxVersion);
    // Send SaslHandshakeRequest and check response
    SaslHandshakeResponse handshakeResponse = sendHandshakeRequestReceiveResponse(node, saslHandshakeVersion);
    assertEquals(Collections.singletonList("PLAIN"), handshakeResponse.enabledMechanisms());
    // Complete manual authentication and check send/receive succeed
    authenticateUsingSaslPlainAndCheckConnection(node, saslHandshakeVersion > 0);
}
Also used : ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) SaslHandshakeResponse(org.apache.kafka.common.requests.SaslHandshakeResponse) SecurityProtocol(org.apache.kafka.common.security.auth.SecurityProtocol)

Example 63 with SecurityProtocol

use of org.apache.kafka.common.security.auth.SecurityProtocol in project apache-kafka-on-k8s by banzaicloud.

the class SslTransportLayerTest method testEndpointIdentificationDisabled.

/**
 * Tests that server certificate with invalid IP address is accepted by
 * a client that has disabled endpoint validation
 */
@Test
public void testEndpointIdentificationDisabled() throws Exception {
    String node = "0";
    String serverHost = InetAddress.getLocalHost().getHostAddress();
    SecurityProtocol securityProtocol = SecurityProtocol.SSL;
    server = new NioEchoServer(ListenerName.forSecurityProtocol(securityProtocol), securityProtocol, new TestSecurityConfig(sslServerConfigs), serverHost, null, null);
    server.start();
    sslClientConfigs.remove(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG);
    createSelector(sslClientConfigs);
    InetSocketAddress addr = new InetSocketAddress(serverHost, server.port());
    selector.connect(node, addr, BUFFER_SIZE, BUFFER_SIZE);
    NetworkTestUtils.checkClientConnection(selector, node, 100, 10);
}
Also used : InetSocketAddress(java.net.InetSocketAddress) SecurityProtocol(org.apache.kafka.common.security.auth.SecurityProtocol) TestSecurityConfig(org.apache.kafka.common.security.TestSecurityConfig) Test(org.junit.Test)

Example 64 with SecurityProtocol

use of org.apache.kafka.common.security.auth.SecurityProtocol in project apache-kafka-on-k8s by banzaicloud.

the class SslTransportLayerTest method testServerKeystoreDynamicUpdate.

/**
 * Tests reconfiguration of server keystore. Verifies that existing connections continue
 * to work with old keystore and new connections work with new keystore.
 */
@Test
public void testServerKeystoreDynamicUpdate() throws Exception {
    SecurityProtocol securityProtocol = SecurityProtocol.SSL;
    TestSecurityConfig config = new TestSecurityConfig(sslServerConfigs);
    ListenerName listenerName = ListenerName.forSecurityProtocol(securityProtocol);
    ChannelBuilder serverChannelBuilder = ChannelBuilders.serverChannelBuilder(listenerName, false, securityProtocol, config, null, null);
    server = new NioEchoServer(listenerName, securityProtocol, config, "localhost", serverChannelBuilder, null);
    server.start();
    InetSocketAddress addr = new InetSocketAddress("localhost", server.port());
    // Verify that client with matching truststore can authenticate, send and receive
    String oldNode = "0";
    Selector oldClientSelector = createSelector(sslClientConfigs);
    oldClientSelector.connect(oldNode, addr, BUFFER_SIZE, BUFFER_SIZE);
    NetworkTestUtils.checkClientConnection(selector, oldNode, 100, 10);
    CertStores newServerCertStores = new CertStores(true, "server", "localhost");
    sslServerConfigs = newServerCertStores.getTrustingConfig(clientCertStores);
    assertTrue("SslChannelBuilder not reconfigurable", serverChannelBuilder instanceof ListenerReconfigurable);
    ListenerReconfigurable reconfigurableBuilder = (ListenerReconfigurable) serverChannelBuilder;
    assertEquals(listenerName, reconfigurableBuilder.listenerName());
    reconfigurableBuilder.validateReconfiguration(sslServerConfigs);
    reconfigurableBuilder.reconfigure(sslServerConfigs);
    // Verify that new client with old truststore fails
    oldClientSelector.connect("1", addr, BUFFER_SIZE, BUFFER_SIZE);
    NetworkTestUtils.waitForChannelClose(oldClientSelector, "1", ChannelState.State.AUTHENTICATION_FAILED);
    // Verify that new client with new truststore can authenticate, send and receive
    sslClientConfigs = clientCertStores.getTrustingConfig(newServerCertStores);
    Selector newClientSelector = createSelector(sslClientConfigs);
    newClientSelector.connect("2", addr, BUFFER_SIZE, BUFFER_SIZE);
    NetworkTestUtils.checkClientConnection(newClientSelector, "2", 100, 10);
    // Verify that old client continues to work
    NetworkTestUtils.checkClientConnection(oldClientSelector, oldNode, 100, 10);
    CertStores invalidCertStores = new CertStores(true, "server", "127.0.0.1");
    Map<String, Object> invalidConfigs = invalidCertStores.getTrustingConfig(clientCertStores);
    try {
        reconfigurableBuilder.validateReconfiguration(invalidConfigs);
        fail("Should have failed validation with an exception with different SubjectAltName");
    } catch (KafkaException e) {
    // expected exception
    }
    try {
        reconfigurableBuilder.reconfigure(invalidConfigs);
        fail("Should have failed to reconfigure with different SubjectAltName");
    } catch (KafkaException e) {
    // expected exception
    }
    // Verify that new connections continue to work with the server with previously configured keystore after failed reconfiguration
    newClientSelector.connect("3", addr, BUFFER_SIZE, BUFFER_SIZE);
    NetworkTestUtils.checkClientConnection(newClientSelector, "3", 100, 10);
}
Also used : InetSocketAddress(java.net.InetSocketAddress) SecurityProtocol(org.apache.kafka.common.security.auth.SecurityProtocol) TestSecurityConfig(org.apache.kafka.common.security.TestSecurityConfig) KafkaException(org.apache.kafka.common.KafkaException) Test(org.junit.Test)

Example 65 with SecurityProtocol

use of org.apache.kafka.common.security.auth.SecurityProtocol in project kafka by apache.

the class ClientUtils method createChannelBuilder.

/**
 * Create a new channel builder from the provided configuration.
 *
 * @param config client configs
 * @param time the time implementation
 * @param logContext the logging context
 *
 * @return configured ChannelBuilder based on the configs.
 */
public static ChannelBuilder createChannelBuilder(AbstractConfig config, Time time, LogContext logContext) {
    SecurityProtocol securityProtocol = SecurityProtocol.forName(config.getString(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG));
    String clientSaslMechanism = config.getString(SaslConfigs.SASL_MECHANISM);
    return ChannelBuilders.clientChannelBuilder(securityProtocol, JaasContext.Type.CLIENT, config, null, clientSaslMechanism, time, true, logContext);
}
Also used : SecurityProtocol(org.apache.kafka.common.security.auth.SecurityProtocol)

Aggregations

SecurityProtocol (org.apache.kafka.common.security.auth.SecurityProtocol)106 Test (org.junit.jupiter.api.Test)50 Test (org.junit.Test)29 HashMap (java.util.HashMap)22 InetSocketAddress (java.net.InetSocketAddress)14 NetworkSend (org.apache.kafka.common.network.NetworkSend)11 RequestHeader (org.apache.kafka.common.requests.RequestHeader)11 IOException (java.io.IOException)10 PlainLoginModule (org.apache.kafka.common.security.plain.PlainLoginModule)10 TestSecurityConfig (org.apache.kafka.common.security.TestSecurityConfig)9 ScramLoginModule (org.apache.kafka.common.security.scram.ScramLoginModule)9 File (java.io.File)8 ByteBuffer (java.nio.ByteBuffer)8 Properties (java.util.Properties)8 ApiVersionsRequest (org.apache.kafka.common.requests.ApiVersionsRequest)7 ApiVersionsResponse (org.apache.kafka.common.requests.ApiVersionsResponse)7 LogContext (org.apache.kafka.common.utils.LogContext)6 Random (java.util.Random)5 Password (org.apache.kafka.common.config.types.Password)5 ListenerName (org.apache.kafka.common.network.ListenerName)5