Skip to content

Commit

Permalink
Fix kerberos setting registration (#35986)
Browse files Browse the repository at this point in the history
In #30241 Realm settings were changed, but the Kerberos realm settings
were not registered correctly. This change fixes the registration of
those Kerberos settings.

Also adds a new integration test that ensures every internal realm can
be configured in a test cluster.

Also fixes the QA test for kerberos.

Resolves: #35942
  • Loading branch information
tvernum committed Nov 29, 2018
1 parent 6d01170 commit 609f742
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
import org.elasticsearch.xpack.core.security.authc.file.FileRealmSettings;
import org.elasticsearch.xpack.core.security.authc.kerberos.KerberosRealmSettings;
import org.elasticsearch.xpack.core.security.authc.ldap.LdapRealmSettings;
import org.elasticsearch.xpack.core.security.authc.pki.PkiRealmSettings;
import org.elasticsearch.xpack.core.security.authc.saml.SamlRealmSettings;
Expand All @@ -32,6 +33,7 @@ public static Set<Setting.AffixSetting<?>> getSettings() {
set.addAll(LdapRealmSettings.getSettings(LdapRealmSettings.LDAP_TYPE));
set.addAll(PkiRealmSettings.getSettings());
set.addAll(SamlRealmSettings.getSettings());
set.addAll(KerberosRealmSettings.getSettings());
return Collections.unmodifiableSet(set);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public static Set<Setting.AffixSetting<?>> getSettings() {
final Set<Setting.AffixSetting<?>> settings = Sets.newHashSet(HTTP_SERVICE_KEYTAB_PATH, CACHE_TTL_SETTING, CACHE_MAX_USERS_SETTING,
SETTING_KRB_DEBUG_ENABLE, SETTING_REMOVE_REALM_NAME);
settings.addAll(DelegatedAuthorizationSettings.getSettings(TYPE));
settings.addAll(RealmSettings.getStandardSettings(TYPE));
return settings;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -73,6 +74,10 @@ static boolean isXPackRealm(String type) {
return ReservedRealm.TYPE.equals(type);
}

static Collection<String> getConfigurableRealmsTypes() {
return Collections.unmodifiableSet(XPACK_TYPES);
}

/**
* Determines whether <code>type</code> is an internal realm-type that is provided by x-pack,
* excluding the {@link ReservedRealm} and realms that have extensive interaction with
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.security.authc;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.xpack.core.security.action.user.AuthenticateAction;
import org.elasticsearch.xpack.core.security.action.user.AuthenticateRequest;
import org.elasticsearch.xpack.core.security.action.user.AuthenticateResponse;
import org.elasticsearch.xpack.core.security.authc.Realm;
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
import org.elasticsearch.xpack.core.security.authc.RealmSettings;
import org.elasticsearch.xpack.security.authc.kerberos.KerberosRealmTestCase;
import org.elasticsearch.xpack.security.authc.saml.SamlRealmTestHelper;
import org.hamcrest.Matchers;
import org.junit.AfterClass;

import java.io.Closeable;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

/**
* An integration test that configures one of each realm type.
* This acts as a basic smoke test that every realm is supported, and can be configured.
*/
public class SecurityRealmSettingsTests extends SecurityIntegTestCase {

@Override
protected Settings nodeSettings(int nodeOrdinal) {
final Settings settings;
try {
final String samlIdpEntityId = "urn:idp:entity";
final Path samlIdpPath = createTempFile("idp", "xml");
SamlRealmTestHelper.writeIdpMetaData(samlIdpPath, samlIdpEntityId);

final Path kerbKeyTab = createTempFile("es", "keytab");
KerberosRealmTestCase.writeKeyTab(kerbKeyTab, null);

settings = Settings.builder()
.put(super.nodeSettings(nodeOrdinal).filter(s -> s.startsWith("xpack.security.authc.realms.") == false))
.put("xpack.security.authc.token.enabled", true)
.put("xpack.security.authc.realms.file.file1.order", 1)
.put("xpack.security.authc.realms.native.native1.order", 2)
.put("xpack.security.authc.realms.ldap.ldap1.order", 3)
.put("xpack.security.authc.realms.ldap.ldap1.url", "ldap://127.0.0.1:389")
.put("xpack.security.authc.realms.ldap.ldap1.user_dn_templates", "cn={0},dc=example,dc=com")
.put("xpack.security.authc.realms.active_directory.ad1.order", 4)
.put("xpack.security.authc.realms.active_directory.ad1.url", "ldap://127.0.0.1:389")
.put("xpack.security.authc.realms.pki.pki1.order", 5)
.put("xpack.security.authc.realms.saml.saml1.order", 6)
.put("xpack.security.authc.realms.saml.saml1.idp.metadata.path", samlIdpPath.toAbsolutePath())
.put("xpack.security.authc.realms.saml.saml1.idp.entity_id", samlIdpEntityId)
.put("xpack.security.authc.realms.saml.saml1.sp.entity_id", "urn:sp:entity")
.put("xpack.security.authc.realms.saml.saml1.sp.acs", "http://localhost/acs")
.put("xpack.security.authc.realms.saml.saml1.attributes.principal", "uid")
.put("xpack.security.authc.realms.kerberos.kerb1.order", 7)
.put("xpack.security.authc.realms.kerberos.kerb1.keytab.path", kerbKeyTab.toAbsolutePath())
.build();
} catch (IOException e) {
throw new RuntimeException(e);
}

final Set<String> configuredRealmTypes = RealmSettings.getRealmSettings(settings)
.keySet()
.stream()
.map(RealmConfig.RealmIdentifier::getType)
.collect(Collectors.toSet());
assertThat("One or more realm type are not configured " + configuredRealmTypes,
configuredRealmTypes, Matchers.containsInAnyOrder(InternalRealms.getConfigurableRealmsTypes().toArray(Strings.EMPTY_ARRAY)));

return settings;
}

/**
* Some realms (currently only SAML, but maybe more in the future) hold on to resources that may need to be explicitly closed.
*/
@AfterClass
public static void closeRealms() throws IOException {
final Logger logger = LogManager.getLogger(SecurityRealmSettingsTests.class);
final Iterable<Realms> realms = internalCluster().getInstances(Realms.class);
for (Realms rx : realms) {
for (Realm r : rx) {
if (r instanceof Closeable) {
logger.info("Closing realm [{}] [{} @ {}]", r, r.getClass().getSimpleName(), System.identityHashCode(r));
((Closeable) r).close();
}
}
}
}

/**
* Always enable transport SSL so that it is possible to have a PKI Realm
*/
protected boolean transportSSLEnabled() {
return true;
}

public void testClusterStarted() {
final AuthenticateRequest request = new AuthenticateRequest();
request.username(nodeClientUsername());
final AuthenticateResponse authenticate = client().execute(AuthenticateAction.INSTANCE, request).actionGet(10, TimeUnit.SECONDS);
assertThat(authenticate.authentication(), notNullValue());
assertThat(authenticate.authentication().getUser(), notNullValue());
assertThat(authenticate.authentication().getUser().enabled(), is(true));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
*/
package org.elasticsearch.xpack.security.authc.saml;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;

Expand Down Expand Up @@ -42,4 +45,15 @@ public static SamlRealm buildRealm(RealmConfig realmConfig, @Nullable X509Creden
return new SamlRealm(realmConfig, mock(UserRoleMapper.class), mock(SamlAuthenticator.class),
mock(SamlLogoutRequestHandler.class), () -> idpDescriptor, spConfiguration);
}

public static void writeIdpMetaData(Path path, String idpEntityId) throws IOException {
Files.write(path, Arrays.asList(
"<?xml version=\"1.0\"?>",
"<md:EntityDescriptor xmlns:md='urn:oasis:names:tc:SAML:2.0:metadata' entityID='" + idpEntityId + "'>",
"<md:IDPSSODescriptor protocolSupportEnumeration='urn:oasis:names:tc:SAML:2.0:protocol'>",
"<md:SingleSignOnService Binding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' Location='http://localhost/sso/' />",
"</md:IDPSSODescriptor>",
"</md:EntityDescriptor>"
));
}
}
12 changes: 5 additions & 7 deletions x-pack/qa/kerberos-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,14 @@ integTestCluster {
setting 'http.host', '127.0.0.1'
setting 'xpack.license.self_generated.type', 'trial'
setting 'xpack.security.enabled', 'true'
setting 'xpack.security.authc.realms.file.type', 'file'
setting 'xpack.security.authc.realms.file.order', '0'
setting 'xpack.security.authc.realms.file.file1.order', '0'
setting 'xpack.ml.enabled', 'false'
setting 'xpack.security.audit.enabled', 'true'
// Kerberos realm
setting 'xpack.security.authc.realms.kerberos.type', 'kerberos'
setting 'xpack.security.authc.realms.kerberos.order', '1'
setting 'xpack.security.authc.realms.kerberos.keytab.path', 'es.keytab'
setting 'xpack.security.authc.realms.kerberos.krb.debug', 'true'
setting 'xpack.security.authc.realms.kerberos.remove_realm_name', 'false'
setting 'xpack.security.authc.realms.kerberos.kerberos.order', '1'
setting 'xpack.security.authc.realms.kerberos.kerberos.keytab.path', 'es.keytab'
setting 'xpack.security.authc.realms.kerberos.kerberos.krb.debug', 'true'
setting 'xpack.security.authc.realms.kerberos.kerberos.remove_realm_name', 'false'

Path krb5conf = project(':test:fixtures:krb5kdc-fixture').buildDir.toPath().resolve("conf").resolve("krb5.conf").toAbsolutePath()
String jvmArgsStr = " -Djava.security.krb5.conf=${krb5conf}" + " -Dsun.security.krb5.debug=true"
Expand Down

0 comments on commit 609f742

Please sign in to comment.