Search in sources :

Example 1 with LogCapturer

use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.

the class TestSecureOzoneManager method testSecureOmInitFailures.

/**
 * Test failure cases for secure OM initialization.
 */
@Test
public void testSecureOmInitFailures() throws Exception {
    PrivateKey privateKey;
    PublicKey publicKey;
    LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
    OMStorage omStorage = new OMStorage(conf);
    omStorage.setClusterId(clusterId);
    omStorage.setOmId(omId);
    omLogs.clearOutput();
    // Case 1: When keypair as well as certificate is missing. Initial keypair
    // boot-up. Get certificate will fail when SCM is not running.
    SecurityConfig securityConfig = new SecurityConfig(conf);
    CertificateClient client = new OMCertificateClient(securityConfig, omStorage.getOmCertSerialId());
    Assert.assertEquals(CertificateClient.InitResponse.GETCERT, client.init());
    privateKey = client.getPrivateKey();
    publicKey = client.getPublicKey();
    Assert.assertNotNull(client.getPrivateKey());
    Assert.assertNotNull(client.getPublicKey());
    Assert.assertNull(client.getCertificate());
    // Case 2: If key pair already exist than response should be RECOVER.
    client = new OMCertificateClient(securityConfig, omStorage.getOmCertSerialId());
    Assert.assertEquals(CertificateClient.InitResponse.RECOVER, client.init());
    Assert.assertNotNull(client.getPrivateKey());
    Assert.assertNotNull(client.getPublicKey());
    Assert.assertNull(client.getCertificate());
    // Case 3: When public key as well as certificate is missing.
    client = new OMCertificateClient(securityConfig);
    FileUtils.deleteQuietly(Paths.get(securityConfig.getKeyLocation(COMPONENT).toString(), securityConfig.getPublicKeyFileName()).toFile());
    Assert.assertEquals(CertificateClient.InitResponse.FAILURE, client.init());
    Assert.assertNotNull(client.getPrivateKey());
    Assert.assertNull(client.getPublicKey());
    Assert.assertNull(client.getCertificate());
    // Case 4: When private key and certificate is missing.
    client = new OMCertificateClient(securityConfig);
    KeyCodec keyCodec = new KeyCodec(securityConfig, COMPONENT);
    keyCodec.writePublicKey(publicKey);
    FileUtils.deleteQuietly(Paths.get(securityConfig.getKeyLocation(COMPONENT).toString(), securityConfig.getPrivateKeyFileName()).toFile());
    Assert.assertEquals(CertificateClient.InitResponse.FAILURE, client.init());
    Assert.assertNull(client.getPrivateKey());
    Assert.assertNotNull(client.getPublicKey());
    Assert.assertNull(client.getCertificate());
    // Case 5: When only certificate is present.
    FileUtils.deleteQuietly(Paths.get(securityConfig.getKeyLocation(COMPONENT).toString(), securityConfig.getPublicKeyFileName()).toFile());
    CertificateCodec certCodec = new CertificateCodec(securityConfig, COMPONENT);
    X509Certificate x509Certificate = KeyStoreTestUtil.generateCertificate("CN=Test", new KeyPair(publicKey, privateKey), 10, securityConfig.getSignatureAlgo());
    certCodec.writeCertificate(new X509CertificateHolder(x509Certificate.getEncoded()));
    client = new OMCertificateClient(securityConfig, x509Certificate.getSerialNumber().toString());
    omStorage.setOmCertSerialId(x509Certificate.getSerialNumber().toString());
    Assert.assertEquals(CertificateClient.InitResponse.FAILURE, client.init());
    Assert.assertNull(client.getPrivateKey());
    Assert.assertNull(client.getPublicKey());
    Assert.assertNotNull(client.getCertificate());
    // Case 6: When private key and certificate is present.
    client = new OMCertificateClient(securityConfig, x509Certificate.getSerialNumber().toString());
    FileUtils.deleteQuietly(Paths.get(securityConfig.getKeyLocation(COMPONENT).toString(), securityConfig.getPublicKeyFileName()).toFile());
    keyCodec.writePrivateKey(privateKey);
    Assert.assertEquals(CertificateClient.InitResponse.SUCCESS, client.init());
    Assert.assertNotNull(client.getPrivateKey());
    Assert.assertNotNull(client.getPublicKey());
    Assert.assertNotNull(client.getCertificate());
    // Case 7 When keypair and certificate is present.
    client = new OMCertificateClient(securityConfig, x509Certificate.getSerialNumber().toString());
    Assert.assertEquals(CertificateClient.InitResponse.SUCCESS, client.init());
    Assert.assertNotNull(client.getPrivateKey());
    Assert.assertNotNull(client.getPublicKey());
    Assert.assertNotNull(client.getCertificate());
}
Also used : OMCertificateClient(org.apache.hadoop.hdds.security.x509.certificate.client.OMCertificateClient) CertificateClient(org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient) KeyPair(java.security.KeyPair) PrivateKey(java.security.PrivateKey) SecurityConfig(org.apache.hadoop.hdds.security.x509.SecurityConfig) PublicKey(java.security.PublicKey) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) LogCapturer(org.apache.ozone.test.GenericTestUtils.LogCapturer) CertificateCodec(org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec) KeyCodec(org.apache.hadoop.hdds.security.x509.keys.KeyCodec) OMCertificateClient(org.apache.hadoop.hdds.security.x509.certificate.client.OMCertificateClient) X509Certificate(java.security.cert.X509Certificate) Test(org.junit.Test)

Example 2 with LogCapturer

use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.

the class TestSecureOzoneCluster method testDelegationTokenRenewal.

/**
 * Tests delegation token renewal.
 */
@Test
public void testDelegationTokenRenewal() throws Exception {
    GenericTestUtils.setLogLevel(LoggerFactory.getLogger(Server.class.getName()), INFO);
    LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
    // Setup secure OM for start.
    OzoneConfiguration newConf = new OzoneConfiguration(conf);
    int tokenMaxLifetime = 1000;
    newConf.setLong(DELEGATION_TOKEN_MAX_LIFETIME_KEY, tokenMaxLifetime);
    setupOm(newConf);
    OzoneManager.setTestSecureOmFlag(true);
    try {
        om.setCertClient(new CertificateClientTestImpl(conf));
        om.start();
        UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
        // Get first OM client which will authenticate via Kerberos
        omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
        // Since client is already connected get a delegation token
        Token<OzoneTokenIdentifier> token = omClient.getDelegationToken(new Text("om"));
        // Check if token is of right kind and renewer is running om instance
        assertNotNull(token);
        assertEquals("OzoneToken", token.getKind().toString());
        assertEquals(OmUtils.getOmRpcAddress(conf), token.getService().toString());
        // Renew delegation token
        long expiryTime = omClient.renewDelegationToken(token);
        assertTrue(expiryTime > 0);
        omLogs.clearOutput();
        // Test failure of delegation renewal
        // 1. When token maxExpiryTime exceeds
        Thread.sleep(tokenMaxLifetime);
        OMException ex = LambdaTestUtils.intercept(OMException.class, "TOKEN_EXPIRED", () -> omClient.renewDelegationToken(token));
        assertEquals(TOKEN_EXPIRED, ex.getResult());
        omLogs.clearOutput();
        // 2. When renewer doesn't match (implicitly covers when renewer is
        // null or empty )
        Token<OzoneTokenIdentifier> token2 = omClient.getDelegationToken(new Text("randomService"));
        assertNotNull(token2);
        LambdaTestUtils.intercept(OMException.class, "Delegation token renewal failed", () -> omClient.renewDelegationToken(token2));
        assertTrue(omLogs.getOutput().contains(" with non-matching " + "renewer randomService"));
        omLogs.clearOutput();
        // 3. Test tampered token
        OzoneTokenIdentifier tokenId = OzoneTokenIdentifier.readProtoBuf(token.getIdentifier());
        tokenId.setRenewer(new Text("om"));
        tokenId.setMaxDate(System.currentTimeMillis() * 2);
        Token<OzoneTokenIdentifier> tamperedToken = new Token<>(tokenId.getBytes(), token2.getPassword(), token2.getKind(), token2.getService());
        LambdaTestUtils.intercept(OMException.class, "Delegation token renewal failed", () -> omClient.renewDelegationToken(tamperedToken));
        assertTrue(omLogs.getOutput().contains("can't be found in " + "cache"));
        omLogs.clearOutput();
    } finally {
        om.stop();
        om.join();
    }
}
Also used : OzoneManagerProtocolClientSideTranslatorPB(org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB) CertificateClientTestImpl(org.apache.hadoop.ozone.client.CertificateClientTestImpl) OzoneTokenIdentifier(org.apache.hadoop.ozone.security.OzoneTokenIdentifier) LogCapturer(org.apache.ozone.test.GenericTestUtils.LogCapturer) OzoneConfiguration(org.apache.hadoop.hdds.conf.OzoneConfiguration) Text(org.apache.hadoop.io.Text) Token(org.apache.hadoop.security.token.Token) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 3 with LogCapturer

use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.

the class TestSecureOzoneCluster method testSecureOmInitSuccess.

/**
 * Test functionality to get SCM signed certificate for OM.
 */
@Test
public void testSecureOmInitSuccess() throws Exception {
    LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
    omLogs.clearOutput();
    initSCM();
    try {
        scm = HddsTestUtils.getScmSimple(conf);
        scm.start();
        OMStorage omStore = new OMStorage(conf);
        initializeOmStorage(omStore);
        OzoneManager.setTestSecureOmFlag(true);
        om = OzoneManager.createOm(conf);
        assertNotNull(om.getCertificateClient());
        assertNotNull(om.getCertificateClient().getPublicKey());
        assertNotNull(om.getCertificateClient().getPrivateKey());
        assertNotNull(om.getCertificateClient().getCertificate());
        assertTrue(omLogs.getOutput().contains("Init response: GETCERT"));
        assertTrue(omLogs.getOutput().contains("Successfully stored " + "SCM signed certificate"));
        X509Certificate certificate = om.getCertificateClient().getCertificate();
        validateCertificate(certificate);
        String pemEncodedCACert = scm.getSecurityProtocolServer().getCACertificate();
        X509Certificate caCert = CertificateCodec.getX509Cert(pemEncodedCACert);
        X509Certificate caCertStored = om.getCertificateClient().getCertificate(caCert.getSerialNumber().toString());
        assertEquals(caCert, caCertStored);
    } finally {
        if (scm != null) {
            scm.stop();
        }
        if (om != null) {
            om.stop();
        }
        IOUtils.closeQuietly(om);
    }
}
Also used : LogCapturer(org.apache.ozone.test.GenericTestUtils.LogCapturer) OMStorage(org.apache.hadoop.ozone.om.OMStorage) X509Certificate(java.security.cert.X509Certificate) Test(org.junit.Test)

Example 4 with LogCapturer

use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.

the class TestSecureOzoneCluster method testAccessControlExceptionOnClient.

@Test
public void testAccessControlExceptionOnClient() throws Exception {
    initSCM();
    // Create a secure SCM instance as om client will connect to it
    scm = HddsTestUtils.getScmSimple(conf);
    LogCapturer logs = LogCapturer.captureLogs(OzoneManager.getLogger());
    GenericTestUtils.setLogLevel(OzoneManager.getLogger(), INFO);
    setupOm(conf);
    try {
        om.setCertClient(new CertificateClientTestImpl(conf));
        om.start();
    } catch (Exception ex) {
        // Expects timeout failure from scmClient in om but om user login via
        // kerberos should succeed.
        assertTrue(logs.getOutput().contains("Ozone Manager login successful"));
    }
    UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(testUserPrincipal, testUserKeytab.getCanonicalPath());
    ugi.setAuthenticationMethod(KERBEROS);
    OzoneManagerProtocolClientSideTranslatorPB secureClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), ClientId.randomId().toString());
    try {
        secureClient.createVolume(new OmVolumeArgs.Builder().setVolume("vol1").setOwnerName("owner1").setAdminName("admin").build());
    } catch (IOException ex) {
        fail("Secure client should be able to create volume.");
    }
    ugi = UserGroupInformation.createUserForTesting("testuser1", new String[] { "test" });
    OzoneManagerProtocolClientSideTranslatorPB unsecureClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), ClientId.randomId().toString());
    String exMessage = "org.apache.hadoop.security.AccessControlException: " + "Client cannot authenticate via:[TOKEN, KERBEROS]";
    logs = LogCapturer.captureLogs(Client.LOG);
    LambdaTestUtils.intercept(IOException.class, exMessage, () -> unsecureClient.listAllVolumes(null, null, 0));
    assertEquals("There should be no retry on AccessControlException", 1, StringUtils.countMatches(logs.getOutput(), exMessage));
}
Also used : OzoneManagerProtocolClientSideTranslatorPB(org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB) OmVolumeArgs(org.apache.hadoop.ozone.om.helpers.OmVolumeArgs) CertificateClientTestImpl(org.apache.hadoop.ozone.client.CertificateClientTestImpl) LogCapturer(org.apache.ozone.test.GenericTestUtils.LogCapturer) IOException(java.io.IOException) AuthenticationException(org.apache.hadoop.security.authentication.client.AuthenticationException) KerberosAuthException(org.apache.hadoop.security.KerberosAuthException) IOException(java.io.IOException) SCMSecurityException(org.apache.hadoop.hdds.security.exception.SCMSecurityException) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 5 with LogCapturer

use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.

the class TestDelegationToken method testDelegationToken.

/**
 * Performs following tests for delegation token.
 * 1. Get valid delegation token
 * 2. Test successful token renewal.
 * 3. Client can authenticate using token.
 * 4. Delegation token renewal without Kerberos auth fails.
 * 5. Test success of token cancellation.
 * 5. Test failure of token cancellation.
 */
@Test
public void testDelegationToken() throws Exception {
    // Capture logs for assertions
    LogCapturer logs = LogCapturer.captureLogs(Server.AUDITLOG);
    LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
    GenericTestUtils.setLogLevel(LoggerFactory.getLogger(Server.class.getName()), INFO);
    // Setup secure OM for start
    setupOm(conf);
    // These are two very important lines: ProtobufRpcEngine uses ClientCache
    // which caches clients until no more references. Cache key is the
    // SocketFactory which means that we use one Client instance for
    // all the Hadoop RPC.
    // 
    // Hadoop Client caches connections with a connection pool. Even if you
    // close the client here, if you have ANY Hadoop RPC clients which uses the
    // same Client, connections can be reused.
    // 
    // Here we closed all the OTHER Hadoop RPC clients to have only the clients
    // from this unit test.
    // 
    // With this approach all the following client.close() calls trigger a
    // Client.close (if there is no other open Hadoop RPC client) which triggers
    // connection close for all the available connection.
    // 
    // The following test tests the authorization of the new client calls, it
    // requires a real connection close and connection open as the authorization
    // is part the initial handhsake of Hadoop RPC.
    om.getScmClient().getBlockClient().close();
    om.getScmClient().getContainerClient().close();
    try {
        // Start OM
        om.setCertClient(new CertificateClientTestImpl(conf));
        om.start();
        UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
        String username = ugi.getUserName();
        // Get first OM client which will authenticate via Kerberos
        omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
        // Assert if auth was successful via Kerberos
        assertFalse(logs.getOutput().contains("Auth successful for " + username + " (auth:KERBEROS)"));
        // Case 1: Test successful delegation token.
        Token<OzoneTokenIdentifier> token = omClient.getDelegationToken(new Text("om"));
        // Case 2: Test successful token renewal.
        long renewalTime = omClient.renewDelegationToken(token);
        assertTrue(renewalTime > 0);
        // Check if token is of right kind and renewer is running om instance
        assertNotNull(token);
        assertEquals("OzoneToken", token.getKind().toString());
        assertEquals(OmUtils.getOmRpcAddress(conf), token.getService().toString());
        omClient.close();
        // Create a remote ugi and set its authentication method to Token
        UserGroupInformation testUser = UserGroupInformation.createRemoteUser(TEST_USER);
        testUser.addToken(token);
        testUser.setAuthenticationMethod(AuthMethod.TOKEN);
        UserGroupInformation.setLoginUser(testUser);
        // Get Om client, this time authentication should happen via Token
        testUser.doAs((PrivilegedExceptionAction<Void>) () -> {
            omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, testUser, null), RandomStringUtils.randomAscii(5));
            return null;
        });
        // Case 3: Test Client can authenticate using token.
        assertFalse(logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
        OzoneTestUtils.expectOmException(VOLUME_NOT_FOUND, () -> omClient.deleteVolume("vol1"));
        assertTrue("Log file doesn't contain successful auth for user " + username, logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
        // Case 4: Test failure of token renewal.
        // Call to renewDelegationToken will fail but it will confirm that
        // initial connection via DT succeeded
        omLogs.clearOutput();
        OMException ex = LambdaTestUtils.intercept(OMException.class, "INVALID_AUTH_METHOD", () -> omClient.renewDelegationToken(token));
        assertEquals(INVALID_AUTH_METHOD, ex.getResult());
        assertTrue(logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
        omLogs.clearOutput();
        // testUser.setAuthenticationMethod(AuthMethod.KERBEROS);
        omClient.close();
        UserGroupInformation.setLoginUser(ugi);
        omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
        // Case 5: Test success of token cancellation.
        omClient.cancelDelegationToken(token);
        omClient.close();
        // Wait for client to timeout
        Thread.sleep(CLIENT_TIMEOUT);
        assertFalse(logs.getOutput().contains("Auth failed for"));
        // Case 6: Test failure of token cancellation.
        // Get Om client, this time authentication using Token will fail as
        // token is not in cache anymore.
        omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, testUser, null), RandomStringUtils.randomAscii(5));
        ex = LambdaTestUtils.intercept(OMException.class, "Cancel delegation token failed", () -> omClient.cancelDelegationToken(token));
        assertEquals(TOKEN_ERROR_OTHER, ex.getResult());
        assertTrue(logs.getOutput().contains("Auth failed for"));
    } finally {
        om.stop();
        om.join();
    }
}
Also used : OzoneManagerProtocolClientSideTranslatorPB(org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB) CertificateClientTestImpl(org.apache.hadoop.ozone.client.CertificateClientTestImpl) OzoneTokenIdentifier(org.apache.hadoop.ozone.security.OzoneTokenIdentifier) LogCapturer(org.apache.ozone.test.GenericTestUtils.LogCapturer) Text(org.apache.hadoop.io.Text) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Aggregations

LogCapturer (org.apache.ozone.test.GenericTestUtils.LogCapturer)10 Test (org.junit.Test)10 IOException (java.io.IOException)4 OMException (org.apache.hadoop.ozone.om.exceptions.OMException)4 X509Certificate (java.security.cert.X509Certificate)3 CertificateClientTestImpl (org.apache.hadoop.ozone.client.CertificateClientTestImpl)3 OzoneManagerProtocolClientSideTranslatorPB (org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB)3 UserGroupInformation (org.apache.hadoop.security.UserGroupInformation)3 SCMSecurityException (org.apache.hadoop.hdds.security.exception.SCMSecurityException)2 Text (org.apache.hadoop.io.Text)2 KeyValueContainerData (org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData)2 OMStorage (org.apache.hadoop.ozone.om.OMStorage)2 OzoneTokenIdentifier (org.apache.hadoop.ozone.security.OzoneTokenIdentifier)2 KerberosAuthException (org.apache.hadoop.security.KerberosAuthException)2 AuthenticationException (org.apache.hadoop.security.authentication.client.AuthenticationException)2 File (java.io.File)1 KeyPair (java.security.KeyPair)1 PrivateKey (java.security.PrivateKey)1 PublicKey (java.security.PublicKey)1 OzoneConfiguration (org.apache.hadoop.hdds.conf.OzoneConfiguration)1