Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Kerberos] Remove Kerberos bootstrap checks #32451

Merged
merged 2 commits into from
Jul 31, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@
import org.elasticsearch.xpack.security.authc.TokenService;
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.elasticsearch.xpack.security.authc.kerberos.KerberosRealmBootstrapCheck;
import org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore;
import org.elasticsearch.xpack.security.authz.AuthorizationService;
import org.elasticsearch.xpack.security.authz.SecuritySearchOperationListener;
Expand Down Expand Up @@ -306,8 +305,7 @@ public Security(Settings settings, final Path configPath) {
new PasswordHashingAlgorithmBootstrapCheck(),
new FIPS140SecureSettingsBootstrapCheck(settings, env),
new FIPS140JKSKeystoreBootstrapCheck(settings),
new FIPS140PasswordHashingAlgorithmBootstrapCheck(settings),
new KerberosRealmBootstrapCheck(env)));
new FIPS140PasswordHashingAlgorithmBootstrapCheck(settings)));
checks.addAll(InternalRealms.getBootstrapChecks(settings, env));
this.bootstrapChecks = Collections.unmodifiableList(checks);
Automatons.updateMaxDeterminizedStates(settings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.elasticsearch.xpack.core.security.authc.file.FileRealmSettings;
import org.elasticsearch.xpack.core.security.authc.kerberos.KerberosRealmSettings;


/**
Expand Down Expand Up @@ -152,6 +153,7 @@ protected List<Realm> initRealms() throws Exception {
Settings realmsSettings = RealmSettings.get(settings);
Set<String> internalTypes = new HashSet<>();
List<Realm> realms = new ArrayList<>();
boolean isKerberosRealmConfigured = false;
for (String name : realmsSettings.names()) {
Settings realmSettings = realmsSettings.getAsSettings(name);
String type = realmSettings.get("type");
Expand All @@ -178,6 +180,13 @@ protected List<Realm> initRealms() throws Exception {
}
internalTypes.add(type);
}
if (KerberosRealmSettings.TYPE.equals(type)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as a followup PR to this change, lets combine the logic with the internalTypes logic and we can just have the same message that we're using for kerberos.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can discuss this and I will raise followup PR. Thank you.

if (isKerberosRealmConfigured) {
throw new IllegalArgumentException(
"multiple [" + type + "] realms are configured. [" + type + "] can only have one such realm configured");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is the same message as before - but could you extend it to include the names of the realms?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I have updated the message. Thank you.

}
isKerberosRealmConfigured = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When lookup-realms is merged, we'll have the initialize method available which would allow us to move this into the realm itself which would be a bit neater.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if I followed your thought here if you could elaborate. I think you want to make this realm singleton and throw an error in initialize if it is being initialized again. Not sure if this is what you had in mind, as does not seem a pattern to create a singleton and then initialize it. Thank you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The not-yet-merged initialize method gets passed a list of all the configured realms (which includes access to their type). A Kerberos realm can use that metohd to check that it is the only realm with type == "kerberos" and throw an exception is there are multiple such realms.

That would allow the kerberos has special requirements logic to be contained within the Kerberos realm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes, I forgot the list of realms. Thanks.

realms.add(factory.create(config));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore;
import org.ietf.jgss.GSSException;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -87,6 +88,16 @@ public KerberosRealm(final RealmConfig config, final NativeRoleMappingStore nati
this.kerberosTicketValidator = kerberosTicketValidator;
this.threadPool = threadPool;
this.keytabPath = config.env().configFile().resolve(KerberosRealmSettings.HTTP_SERVICE_KEYTAB_PATH.get(config.settings()));

if (Files.exists(keytabPath) == false) {
throw new IllegalArgumentException("configured service key tab file [" + keytabPath + "] does not exist");
}
if (Files.isDirectory(keytabPath)) {
throw new IllegalArgumentException("configured service key tab file [" + keytabPath + "] is a directory");
}
if (Files.isReadable(keytabPath) == false) {
throw new IllegalArgumentException("configured service key tab file [" + keytabPath + "] must have read permission");
}
this.enableKerberosDebug = KerberosRealmSettings.SETTING_KRB_DEBUG_ENABLE.get(config.settings());
this.removeRealmName = KerberosRealmSettings.SETTING_REMOVE_REALM_NAME.get(config.settings());
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.junit.Before;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -51,13 +52,16 @@ public class RealmsTests extends ESTestCase {
private XPackLicenseState licenseState;
private ThreadContext threadContext;
private ReservedRealm reservedRealm;
private int randomRealmTypesCount;

@Before
public void init() throws Exception {
factories = new HashMap<>();
factories.put(FileRealmSettings.TYPE, config -> new DummyRealm(FileRealmSettings.TYPE, config));
factories.put(NativeRealmSettings.TYPE, config -> new DummyRealm(NativeRealmSettings.TYPE, config));
for (int i = 0; i < randomIntBetween(1, 5); i++) {
factories.put(KerberosRealmSettings.TYPE, config -> new DummyRealm(KerberosRealmSettings.TYPE, config));
randomRealmTypesCount = randomIntBetween(1, 5);
for (int i = 0; i < randomRealmTypesCount; i++) {
String name = "type_" + i;
factories.put(name, config -> new DummyRealm(name, config));
}
Expand All @@ -73,13 +77,13 @@ public void init() throws Exception {
public void testWithSettings() throws Exception {
Settings.Builder builder = Settings.builder()
.put("path.home", createTempDir());
List<Integer> orders = new ArrayList<>(factories.size() - 2);
for (int i = 0; i < factories.size() - 2; i++) {
List<Integer> orders = new ArrayList<>(randomRealmTypesCount);
for (int i = 0; i < randomRealmTypesCount; i++) {
orders.add(i);
}
Collections.shuffle(orders, random());
Map<Integer, Integer> orderToIndex = new HashMap<>();
for (int i = 0; i < factories.size() - 2; i++) {
for (int i = 0; i < randomRealmTypesCount; i++) {
builder.put("xpack.security.authc.realms.realm_" + i + ".type", "type_" + i);
builder.put("xpack.security.authc.realms.realm_" + i + ".order", orders.get(i));
orderToIndex.put(orders.get(i), i);
Expand Down Expand Up @@ -107,14 +111,14 @@ public void testWithSettings() throws Exception {
public void testWithSettingsWhereDifferentRealmsHaveSameOrder() throws Exception {
Settings.Builder builder = Settings.builder()
.put("path.home", createTempDir());
List<Integer> randomSeq = new ArrayList<>(factories.size() - 2);
for (int i = 0; i < factories.size() - 2; i++) {
List<Integer> randomSeq = new ArrayList<>(randomRealmTypesCount);
for (int i = 0; i < randomRealmTypesCount; i++) {
randomSeq.add(i);
}
Collections.shuffle(randomSeq, random());

TreeMap<String, Integer> nameToRealmId = new TreeMap<>();
for (int i = 0; i < factories.size() - 2; i++) {
for (int i = 0; i < randomRealmTypesCount; i++) {
int randomizedRealmId = randomSeq.get(i);
String randomizedRealmName = randomAlphaOfLengthBetween(12,32);
nameToRealmId.put("realm_" + randomizedRealmName, randomizedRealmId);
Expand Down Expand Up @@ -181,13 +185,13 @@ public void testWithEmptySettings() throws Exception {
public void testUnlicensedWithOnlyCustomRealms() throws Exception {
Settings.Builder builder = Settings.builder()
.put("path.home", createTempDir());
List<Integer> orders = new ArrayList<>(factories.size() - 2);
for (int i = 0; i < factories.size() - 2; i++) {
List<Integer> orders = new ArrayList<>(randomRealmTypesCount);
for (int i = 0; i < randomRealmTypesCount; i++) {
orders.add(i);
}
Collections.shuffle(orders, random());
Map<Integer, Integer> orderToIndex = new HashMap<>();
for (int i = 0; i < factories.size() - 2; i++) {
for (int i = 0; i < randomRealmTypesCount; i++) {
builder.put("xpack.security.authc.realms.realm_" + i + ".type", "type_" + i);
builder.put("xpack.security.authc.realms.realm_" + i + ".order", orders.get(i));
orderToIndex.put(orders.get(i), i);
Expand Down Expand Up @@ -384,13 +388,13 @@ public void testUnlicensedWithNonStandardRealms() throws Exception {
public void testDisabledRealmsAreNotAdded() throws Exception {
Settings.Builder builder = Settings.builder()
.put("path.home", createTempDir());
List<Integer> orders = new ArrayList<>(factories.size() - 2);
for (int i = 0; i < factories.size() - 2; i++) {
List<Integer> orders = new ArrayList<>(randomRealmTypesCount);
for (int i = 0; i < randomRealmTypesCount; i++) {
orders.add(i);
}
Collections.shuffle(orders, random());
Map<Integer, Integer> orderToIndex = new HashMap<>();
for (int i = 0; i < factories.size() - 2; i++) {
for (int i = 0; i < randomRealmTypesCount; i++) {
builder.put("xpack.security.authc.realms.realm_" + i + ".type", "type_" + i);
builder.put("xpack.security.authc.realms.realm_" + i + ".order", orders.get(i));
boolean enabled = randomBoolean();
Expand Down Expand Up @@ -520,6 +524,20 @@ public void testUsageStats() throws Exception {
}
}

public void testInitRealmsFailsForMultipleKerberosRealms() throws IOException {
final Settings.Builder builder = Settings.builder().put("path.home", createTempDir());
builder.put("xpack.security.authc.realms.realm_1.type", "kerberos");
builder.put("xpack.security.authc.realms.realm_1.order", 1);
builder.put("xpack.security.authc.realms.realm_2.type", "kerberos");
builder.put("xpack.security.authc.realms.realm_2.order", 2);
final Settings settings = builder.build();
Environment env = TestEnvironment.newEnvironment(settings);
final IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
() -> new Realms(settings, env, factories, licenseState, threadContext, reservedRealm));
assertThat(iae.getMessage(),
is(equalTo("multiple [kerberos] realms are configured. [kerberos] can only have one such realm configured")));
}

static class DummyRealm extends Realm {

DummyRealm(String type, RealmConfig config) {
Expand Down

This file was deleted.

Loading