Merge branch 'master' into tls_6.0
Original commit: elastic/x-pack-elasticsearch@4a36f0c2be
This commit is contained in:
commit
3b00251a96
10
dev-tools/ci
10
dev-tools/ci
|
@ -57,6 +57,16 @@ case $key in
|
|||
"-Dtests.badapples=true"
|
||||
)
|
||||
;;
|
||||
releaseTest)
|
||||
GRADLE_CLI_ARGS=(
|
||||
"--info"
|
||||
"check"
|
||||
"-Dtests.network=true"
|
||||
"-Dtests.badapples=true"
|
||||
"-Dbuild.snapshot=false"
|
||||
"-Dtests.jvm.argline=-Dbuild.snapshot=false"
|
||||
)
|
||||
;;
|
||||
jdk9)
|
||||
GRADLE_CLI_ARGS=(
|
||||
"-Pxpack.kibana.build=false"
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
[role="xpack"]
|
||||
[[xpack-commands]]
|
||||
= {xpack} Commands
|
||||
|
||||
[partintro]
|
||||
--
|
||||
|
||||
{xpack} includes commands that help you configure security:
|
||||
|
||||
//* <<certgen>>
|
||||
//* <<setup-passwords>>
|
||||
* <<users-command>>
|
||||
|
||||
--
|
||||
|
||||
include::users-command.asciidoc[]
|
|
@ -0,0 +1,138 @@
|
|||
[role="xpack"]
|
||||
[[users-command]]
|
||||
== Users Command
|
||||
++++
|
||||
<titleabbrev>users</titleabbrev>
|
||||
++++
|
||||
|
||||
If you use file-based user authentication, the `users` command enables you to
|
||||
add and remove users, assign user roles, and manage passwords.
|
||||
|
||||
[float]
|
||||
=== Synopsis
|
||||
|
||||
[source,shell]
|
||||
--------------------------------------------------
|
||||
bin/x-pack/users
|
||||
([useradd <username>] [-p <password>] [-r <roles>]) |
|
||||
([list] <username>) |
|
||||
([passwd <username>] [-p <password>]) |
|
||||
([roles <username>] [-a <roles>] [-r <roles>]) |
|
||||
([userdel <username>])
|
||||
--------------------------------------------------
|
||||
|
||||
[float]
|
||||
=== Description
|
||||
|
||||
If you use the built-in `file` internal realm, users are defined in local files
|
||||
on each node in the cluster.
|
||||
|
||||
Usernames and roles must be at least 1 and no more than 1024 characters. They
|
||||
can contain alphanumeric characters (`a-z`, `A-Z`, `0-9`), spaces, punctuation,
|
||||
and printable symbols in the
|
||||
https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)[Basic Latin (ASCII) block].
|
||||
Leading or trailing whitespace is not allowed.
|
||||
|
||||
Passwords must be at least 6 characters long.
|
||||
|
||||
For more information, see {xpack-ref}/file-realm.html[File-based User Authentication].
|
||||
|
||||
TIP: To ensure that {es} can read the user and role information at startup, run
|
||||
`users useradd` as the same user you use to run {es}. Running the command as
|
||||
root or some other user updates the permissions for the `users` and `users_roles`
|
||||
files and prevents {es} from accessing them.
|
||||
|
||||
[float]
|
||||
=== Parameters
|
||||
|
||||
`-a <roles>`:: If used with the `roles` parameter, adds a comma-separated list
|
||||
of roles to a user.
|
||||
|
||||
//`-h, --help`:: Returns all of the command parameters.
|
||||
|
||||
`list`:: List the users that are registered with the `file` realm
|
||||
on the local node. If you also specify a user name, the command provides
|
||||
information for that user.
|
||||
|
||||
`-p <password>`:: Specifies the user's password. If you do not specify this
|
||||
parameter, the command prompts you for the password.
|
||||
+
|
||||
--
|
||||
TIP: Omit the `-p` option to keep
|
||||
plaintext passwords out of the terminal session's command history.
|
||||
|
||||
--
|
||||
|
||||
`passwd <username>`:: Resets a user's password. You can specify the new
|
||||
password directly with the `-p` parameter.
|
||||
|
||||
`-r <roles>`::
|
||||
* If used with the `useradd` parameter, defines a user's roles. This option
|
||||
accepts a comma-separated list of role names to assign to the user.
|
||||
* If used with the `roles` parameter, removes a comma-separated list of roles
|
||||
from a user.
|
||||
|
||||
`roles`:: Manages the roles of a particular user. You can combine adding and
|
||||
removing roles within the same command to change a user's roles.
|
||||
|
||||
//`-s, --silent`:: Shows minimal output.
|
||||
|
||||
`useradd <username>`:: Adds a user to your local node.
|
||||
|
||||
`userdel <username>`:: Deletes a user from your local node.
|
||||
|
||||
//`-v, --verbose`:: Shows verbose output.
|
||||
|
||||
//[float]
|
||||
//=== Authorization
|
||||
|
||||
[float]
|
||||
=== Examples
|
||||
|
||||
The following example adds a new user named `jacknich` to the `file` realm. The
|
||||
password for this user is `theshining`, and this user is associated with the
|
||||
`network` and `monitoring` roles.
|
||||
|
||||
[source,shell]
|
||||
-------------------------------------------------------------------
|
||||
bin/x-pack/users useradd jacknich -p theshining -r network,monitoring
|
||||
-------------------------------------------------------------------
|
||||
|
||||
The following example lists the users that are registered with the `file` realm
|
||||
on the local node:
|
||||
|
||||
[source, shell]
|
||||
----------------------------------
|
||||
bin/x-pack/users list
|
||||
rdeniro : admin
|
||||
alpacino : power_user
|
||||
jacknich : monitoring,network
|
||||
----------------------------------
|
||||
|
||||
Users are in the left-hand column and their corresponding roles are listed in
|
||||
the right-hand column.
|
||||
|
||||
The following example resets the `jacknich` user's password:
|
||||
|
||||
[source,shell]
|
||||
--------------------------------------------------
|
||||
bin/x-pack/users passwd jachnich
|
||||
--------------------------------------------------
|
||||
|
||||
Since the `-p` parameter was omitted, the command prompts you to enter and
|
||||
confirm a password in interactive mode.
|
||||
|
||||
The following example removes the `network` and `monitoring` roles from the
|
||||
`jacknich` user and adds the `user` role:
|
||||
|
||||
[source,shell]
|
||||
------------------------------------------------------------
|
||||
bin/x-pack/users roles jacknich -r network,monitoring -a user
|
||||
------------------------------------------------------------
|
||||
|
||||
The following example deletes the `jacknich` user:
|
||||
|
||||
[source,shell]
|
||||
--------------------------------------------------
|
||||
bin/x-pack/users userdel jacknich
|
||||
--------------------------------------------------
|
|
@ -20,5 +20,8 @@ include::{es-repo-dir}/reference/index-shared2.asciidoc[]
|
|||
:edit_url!:
|
||||
include::rest-api/index.asciidoc[]
|
||||
|
||||
:edit_url!:
|
||||
include::commands/index.asciidoc[]
|
||||
|
||||
:edit_url:
|
||||
include::{es-repo-dir}/reference/index-shared3.asciidoc[]
|
||||
|
|
|
@ -187,8 +187,8 @@ public class IndexDeprecationChecks {
|
|||
indexMetaData.getSettings().get("index.shared_filesystem") != null) {
|
||||
return new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
|
||||
"[index.shared_filesystem] setting should be removed",
|
||||
"https://www.elastic.co/guide/en/elasticsearch/reference/master/" +
|
||||
"breaking_60_settings_changes.html#_shadow_replicas_have_been_removed", null);
|
||||
"https://www.elastic.co/guide/en/elasticsearch/reference/6.0/" +
|
||||
"breaking_60_indices_changes.html#_shadow_replicas_have_been_removed", null);
|
||||
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -7,6 +7,7 @@ package org.elasticsearch.xpack.ml;
|
|||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.common.lease.Releasable;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
|
@ -18,6 +19,7 @@ import org.joda.time.DateTime;
|
|||
import org.joda.time.chrono.ISOChronology;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -28,6 +30,8 @@ public class MlDailyMaintenanceService implements Releasable {
|
|||
|
||||
private static final Logger LOGGER = Loggers.getLogger(MlDailyMaintenanceService.class);
|
||||
|
||||
private static final int MAX_TIME_OFFSET_MINUTES = 120;
|
||||
|
||||
private final ThreadPool threadPool;
|
||||
private final Client client;
|
||||
|
||||
|
@ -45,16 +49,26 @@ public class MlDailyMaintenanceService implements Releasable {
|
|||
this.schedulerProvider = Objects.requireNonNull(scheduleProvider);
|
||||
}
|
||||
|
||||
public MlDailyMaintenanceService(ThreadPool threadPool, Client client) {
|
||||
this(threadPool, client, createAfterMidnightScheduleProvider());
|
||||
public MlDailyMaintenanceService(ClusterName clusterName, ThreadPool threadPool, Client client) {
|
||||
this(threadPool, client, () -> delayToNextTime(clusterName));
|
||||
}
|
||||
|
||||
private static Supplier<TimeValue> createAfterMidnightScheduleProvider() {
|
||||
return () -> {
|
||||
DateTime now = DateTime.now(ISOChronology.getInstance());
|
||||
DateTime next = now.plusDays(1).withTimeAtStartOfDay().plusMinutes(30);
|
||||
return TimeValue.timeValueMillis(next.getMillis() - now.getMillis());
|
||||
};
|
||||
/**
|
||||
* Calculates the delay until the next time the maintenance should be triggered.
|
||||
* The next time is 30 minutes past midnight of the following day plus a random
|
||||
* offset. The random offset is added in order to avoid multiple clusters
|
||||
* running the maintenance tasks at the same time. A cluster with a given name
|
||||
* shall have the same offset throughout its life.
|
||||
*
|
||||
* @param clusterName the cluster name is used to seed the random offset
|
||||
* @return the delay to the next time the maintenance should be triggered
|
||||
*/
|
||||
private static TimeValue delayToNextTime(ClusterName clusterName) {
|
||||
Random random = new Random(clusterName.hashCode());
|
||||
int minutesOffset = random.ints(0, MAX_TIME_OFFSET_MINUTES).findFirst().getAsInt();
|
||||
DateTime now = DateTime.now(ISOChronology.getInstance());
|
||||
DateTime next = now.plusDays(1).withTimeAtStartOfDay().plusMinutes(30).plusMinutes(minutesOffset);
|
||||
return TimeValue.timeValueMillis(next.getMillis() - now.getMillis());
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
|
|
@ -63,7 +63,7 @@ class MlInitializationService extends AbstractComponent implements ClusterStateL
|
|||
private void installMlMetadata(MetaData metaData) {
|
||||
if (metaData.custom(MlMetadata.TYPE) == null) {
|
||||
if (installMlMetadataCheck.compareAndSet(false, true)) {
|
||||
threadPool.executor(ThreadPool.Names.GENERIC).execute(() -> {
|
||||
threadPool.executor(ThreadPool.Names.GENERIC).execute(() ->
|
||||
clusterService.submitStateUpdateTask("install-ml-metadata", new ClusterStateUpdateTask() {
|
||||
@Override
|
||||
public ClusterState execute(ClusterState currentState) throws Exception {
|
||||
|
@ -83,8 +83,8 @@ class MlInitializationService extends AbstractComponent implements ClusterStateL
|
|||
installMlMetadataCheck.set(false);
|
||||
logger.error("unable to install ml metadata", e);
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
} else {
|
||||
installMlMetadataCheck.set(false);
|
||||
|
@ -93,7 +93,7 @@ class MlInitializationService extends AbstractComponent implements ClusterStateL
|
|||
|
||||
private void installDailyMaintenanceService() {
|
||||
if (mlDailyMaintenanceService == null) {
|
||||
mlDailyMaintenanceService = new MlDailyMaintenanceService(threadPool, client);
|
||||
mlDailyMaintenanceService = new MlDailyMaintenanceService(clusterService.getClusterName(), threadPool, client);
|
||||
mlDailyMaintenanceService.start();
|
||||
clusterService.addLifecycleListener(new LifecycleListener() {
|
||||
@Override
|
||||
|
|
|
@ -41,6 +41,7 @@ import java.util.EnumMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
|
@ -352,12 +353,13 @@ public class DatafeedConfig extends AbstractDiffable<DatafeedConfig> implements
|
|||
public static class Builder {
|
||||
|
||||
private static final int DEFAULT_SCROLL_SIZE = 1000;
|
||||
private static final TimeValue DEFAULT_QUERY_DELAY = TimeValue.timeValueMinutes(1);
|
||||
private static final TimeValue MIN_DEFAULT_QUERY_DELAY = TimeValue.timeValueMinutes(1);
|
||||
private static final TimeValue MAX_DEFAULT_QUERY_DELAY = TimeValue.timeValueMinutes(2);
|
||||
private static final int DEFAULT_AGGREGATION_CHUNKING_BUCKETS = 1000;
|
||||
|
||||
private String id;
|
||||
private String jobId;
|
||||
private TimeValue queryDelay = DEFAULT_QUERY_DELAY;
|
||||
private TimeValue queryDelay;
|
||||
private TimeValue frequency;
|
||||
private List<String> indices = Collections.emptyList();
|
||||
private List<String> types = Collections.emptyList();
|
||||
|
@ -460,6 +462,7 @@ public class DatafeedConfig extends AbstractDiffable<DatafeedConfig> implements
|
|||
}
|
||||
validateAggregations();
|
||||
setDefaultChunkingConfig();
|
||||
setDefaultQueryDelay();
|
||||
return new DatafeedConfig(id, jobId, queryDelay, frequency, indices, types, query, aggregations, scriptFields, scrollSize,
|
||||
chunkingConfig);
|
||||
}
|
||||
|
@ -530,6 +533,15 @@ public class DatafeedConfig extends AbstractDiffable<DatafeedConfig> implements
|
|||
}
|
||||
}
|
||||
|
||||
private void setDefaultQueryDelay() {
|
||||
if (queryDelay == null) {
|
||||
Random random = new Random(jobId.hashCode());
|
||||
long delayMillis = random.longs(MIN_DEFAULT_QUERY_DELAY.millis(), MAX_DEFAULT_QUERY_DELAY.millis())
|
||||
.findFirst().getAsLong();
|
||||
queryDelay = TimeValue.timeValueMillis(delayMillis);
|
||||
}
|
||||
}
|
||||
|
||||
private static ElasticsearchException invalidOptionValue(String fieldName, Object value) {
|
||||
String msg = Messages.getMessage(Messages.DATAFEED_CONFIG_INVALID_OPTION_VALUE, fieldName, value);
|
||||
throw ExceptionsHelper.badRequestException(msg);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package org.elasticsearch.xpack.security;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapCheck;
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xpack.security.authc.RealmSettings;
|
||||
import org.elasticsearch.xpack.security.authc.pki.PkiRealm;
|
||||
|
@ -20,10 +21,8 @@ import static org.elasticsearch.xpack.security.Security.setting;
|
|||
class PkiRealmBootstrapCheck implements BootstrapCheck {
|
||||
|
||||
private final SSLService sslService;
|
||||
private final Settings settings;
|
||||
|
||||
PkiRealmBootstrapCheck(Settings settings, SSLService sslService) {
|
||||
this.settings = settings;
|
||||
PkiRealmBootstrapCheck(SSLService sslService) {
|
||||
this.sslService = sslService;
|
||||
}
|
||||
|
||||
|
@ -32,7 +31,8 @@ class PkiRealmBootstrapCheck implements BootstrapCheck {
|
|||
* least one network communication layer.
|
||||
*/
|
||||
@Override
|
||||
public boolean check() {
|
||||
public BootstrapCheckResult check(BootstrapContext context) {
|
||||
final Settings settings = context.settings;
|
||||
final boolean pkiRealmEnabled = settings.getGroups(RealmSettings.PREFIX).values().stream()
|
||||
.filter(s -> PkiRealm.TYPE.equals(s.get("type")))
|
||||
.anyMatch(s -> s.getAsBoolean("enabled", true));
|
||||
|
@ -42,34 +42,30 @@ class PkiRealmBootstrapCheck implements BootstrapCheck {
|
|||
Settings httpSSLSettings = SSLService.getHttpTransportSSLSettings(settings);
|
||||
final boolean httpClientAuth = sslService.isSSLClientAuthEnabled(httpSSLSettings);
|
||||
if (httpSsl && httpClientAuth) {
|
||||
return false;
|
||||
return BootstrapCheckResult.success();
|
||||
}
|
||||
|
||||
// Default Transport
|
||||
final Settings transportSSLSettings = settings.getByPrefix(setting("transport.ssl."));
|
||||
final boolean clientAuthEnabled = sslService.isSSLClientAuthEnabled(transportSSLSettings);
|
||||
if (clientAuthEnabled) {
|
||||
return false;
|
||||
return BootstrapCheckResult.success();
|
||||
}
|
||||
|
||||
// Transport Profiles
|
||||
Map<String, Settings> groupedSettings = settings.getGroups("transport.profiles.");
|
||||
for (Map.Entry<String, Settings> entry : groupedSettings.entrySet()) {
|
||||
if (sslService.isSSLClientAuthEnabled(SecurityNetty4Transport.profileSslSettings(entry.getValue()), transportSSLSettings)) {
|
||||
return false;
|
||||
return BootstrapCheckResult.success();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return BootstrapCheckResult.failure(
|
||||
"a PKI realm is enabled but cannot be used as neither HTTP or Transport have SSL and client authentication enabled");
|
||||
} else {
|
||||
return false;
|
||||
return BootstrapCheckResult.success();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String errorMessage() {
|
||||
return "A PKI realm is enabled but cannot be used as neither HTTP or Transport have SSL and client authentication enabled";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alwaysEnforce() {
|
||||
return true;
|
||||
|
|
|
@ -245,9 +245,9 @@ public class Security implements ActionPlugin, IngestPlugin, NetworkPlugin, Clus
|
|||
// fetched
|
||||
final List<BootstrapCheck> checks = new ArrayList<>();
|
||||
checks.addAll(Arrays.asList(
|
||||
new SSLBootstrapCheck(sslService, settings, env),
|
||||
new TokenSSLBootstrapCheck(settings),
|
||||
new PkiRealmBootstrapCheck(settings, sslService)));
|
||||
new SSLBootstrapCheck(sslService, env),
|
||||
new TokenSSLBootstrapCheck(),
|
||||
new PkiRealmBootstrapCheck(sslService)));
|
||||
checks.addAll(InternalRealms.getBootstrapChecks(settings));
|
||||
this.bootstrapChecks = Collections.unmodifiableList(checks);
|
||||
} else {
|
||||
|
|
|
@ -6,33 +6,34 @@
|
|||
package org.elasticsearch.xpack.security;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapCheck;
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.network.NetworkModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xpack.XPackSettings;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Bootstrap check to ensure that the user has enabled HTTPS when using the token service
|
||||
*/
|
||||
final class TokenSSLBootstrapCheck implements BootstrapCheck {
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
TokenSSLBootstrapCheck(Settings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check() {
|
||||
if (NetworkModule.HTTP_ENABLED.get(settings)) {
|
||||
return XPackSettings.HTTP_SSL_ENABLED.get(settings) == false && XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.get(settings);
|
||||
public BootstrapCheckResult check(BootstrapContext context) {
|
||||
final Boolean httpEnabled = NetworkModule.HTTP_ENABLED.get(context.settings);
|
||||
final Boolean httpsEnabled = XPackSettings.HTTP_SSL_ENABLED.get(context.settings);
|
||||
final Boolean tokenServiceEnabled = XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.get(context.settings);
|
||||
if (httpEnabled && httpsEnabled == false && tokenServiceEnabled) {
|
||||
final String message = String.format(
|
||||
Locale.ROOT,
|
||||
"HTTPS is required in order to use the token service; "
|
||||
+ "please enable HTTPS using the [%s] setting or disable the token service using the [%s] setting",
|
||||
XPackSettings.HTTP_SSL_ENABLED.getKey(),
|
||||
XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey());
|
||||
return BootstrapCheckResult.failure(message);
|
||||
} else {
|
||||
return BootstrapCheckResult.success();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String errorMessage() {
|
||||
return "HTTPS is required in order to use the token service. Please enable HTTPS using the [" +
|
||||
XPackSettings.HTTP_SSL_ENABLED.getKey() + "] setting or disable the token service using the [" +
|
||||
XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey() + "] setting.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,6 +209,7 @@ public class PkiRealm extends Realm {
|
|||
|
||||
settings.add(SSL_SETTINGS.truststorePath);
|
||||
settings.add(SSL_SETTINGS.truststorePassword);
|
||||
settings.add(SSL_SETTINGS.legacyTruststorePassword);
|
||||
settings.add(SSL_SETTINGS.truststoreAlgorithm);
|
||||
settings.add(SSL_SETTINGS.caPaths);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.nio.file.Path;
|
|||
|
||||
import org.apache.lucene.util.SetOnce;
|
||||
import org.elasticsearch.bootstrap.BootstrapCheck;
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.xpack.security.authc.RealmConfig;
|
||||
|
||||
/**
|
||||
|
@ -19,30 +20,22 @@ public class RoleMappingFileBootstrapCheck implements BootstrapCheck {
|
|||
private final RealmConfig realmConfig;
|
||||
private final Path path;
|
||||
|
||||
private final SetOnce<String> error = new SetOnce<>();
|
||||
|
||||
public RoleMappingFileBootstrapCheck(RealmConfig config, Path path) {
|
||||
RoleMappingFileBootstrapCheck(RealmConfig config, Path path) {
|
||||
this.realmConfig = config;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check() {
|
||||
public BootstrapCheckResult check(BootstrapContext context) {
|
||||
try {
|
||||
DnRoleMapper.parseFile(path, realmConfig.logger(getClass()), realmConfig.type(), realmConfig.name(), true);
|
||||
return false;
|
||||
return BootstrapCheckResult.success();
|
||||
} catch (Exception e) {
|
||||
error.set(e.getMessage());
|
||||
return true;
|
||||
return BootstrapCheckResult.failure(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String errorMessage() {
|
||||
return error.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alwaysEnforce() {
|
||||
return true;
|
||||
|
@ -55,4 +48,5 @@ public class RoleMappingFileBootstrapCheck implements BootstrapCheck {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package org.elasticsearch.xpack.ssl;
|
|||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.bootstrap.BootstrapCheck;
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.inject.internal.Nullable;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
@ -33,20 +34,23 @@ import java.util.stream.Stream;
|
|||
public final class SSLBootstrapCheck implements BootstrapCheck {
|
||||
|
||||
private final SSLService sslService;
|
||||
private final Settings settings;
|
||||
private final Environment environment;
|
||||
|
||||
public SSLBootstrapCheck(SSLService sslService, Settings settings, @Nullable Environment environment) {
|
||||
public SSLBootstrapCheck(SSLService sslService, @Nullable Environment environment) {
|
||||
this.sslService = sslService;
|
||||
this.settings = settings;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check() {
|
||||
final Settings transportSSLSettings = settings.getByPrefix(XPackSettings.TRANSPORT_SSL_PREFIX);
|
||||
return sslService.sslConfiguration(transportSSLSettings).keyConfig() == KeyConfig.NONE
|
||||
|| isDefaultCACertificateTrusted() || isDefaultPrivateKeyUsed();
|
||||
public BootstrapCheckResult check(BootstrapContext context) {
|
||||
final Settings transportSSLSettings = context.settings.getByPrefix(XPackSettings.TRANSPORT_SSL_PREFIX);
|
||||
if (sslService.sslConfiguration(transportSSLSettings).keyConfig() == KeyConfig.NONE
|
||||
|| isDefaultCACertificateTrusted() || isDefaultPrivateKeyUsed()) {
|
||||
return BootstrapCheckResult.failure(
|
||||
"default SSL key and certificate do not provide security; please generate keys and certificates");
|
||||
} else {
|
||||
return BootstrapCheckResult.success();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,8 +96,4 @@ public final class SSLBootstrapCheck implements BootstrapCheck {
|
|||
.anyMatch(defaultPrivateKey::equals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String errorMessage() {
|
||||
return "Default SSL key and certificate do not provide security; please generate keys and certificates";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,10 +47,12 @@ public class SSLConfigurationSettings {
|
|||
public final Setting<Optional<SSLClientAuth>> clientAuth;
|
||||
public final Setting<Optional<VerificationMode>> verificationMode;
|
||||
|
||||
// public for PKI realm
|
||||
public final Setting<SecureString> legacyTruststorePassword;
|
||||
|
||||
// pkg private for tests
|
||||
final Setting<SecureString> legacyKeystorePassword;
|
||||
final Setting<SecureString> legacyKeystoreKeyPassword;
|
||||
final Setting<SecureString> legacyTruststorePassword;
|
||||
final Setting<SecureString> legacyKeyPassword;
|
||||
|
||||
private final List<Setting<?>> allSettings;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package org.elasticsearch.xpack.watcher;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapCheck;
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.xpack.XPackPlugin;
|
||||
|
@ -15,35 +16,35 @@ import java.nio.file.Path;
|
|||
|
||||
final class EncryptSensitiveDataBootstrapCheck implements BootstrapCheck {
|
||||
|
||||
private final Settings settings;
|
||||
private final Environment environment;
|
||||
|
||||
EncryptSensitiveDataBootstrapCheck(Settings settings, Environment environment) {
|
||||
this.settings = settings;
|
||||
EncryptSensitiveDataBootstrapCheck(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check() {
|
||||
return Watcher.ENCRYPT_SENSITIVE_DATA_SETTING.get(settings) && Watcher.ENCRYPTION_KEY_SETTING.exists(settings) == false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String errorMessage() {
|
||||
final Path sysKeyPath = environment.configFile().resolve(XPackPlugin.NAME).resolve("system_key").toAbsolutePath();
|
||||
if (Files.exists(sysKeyPath)) {
|
||||
return "Encryption of sensitive data requires the key to be placed in the secure setting store. Run " +
|
||||
"'bin/elasticsearch-keystore add-file " + Watcher.ENCRYPTION_KEY_SETTING.getKey() + " " +
|
||||
environment.configFile().resolve(XPackPlugin.NAME).resolve("system_key").toAbsolutePath() +
|
||||
"' to import the file.\nAfter importing, the system_key file should be removed from the " +
|
||||
"filesystem.\nRepeat this on every node in the cluster.";
|
||||
public BootstrapCheckResult check(BootstrapContext context) {
|
||||
if (Watcher.ENCRYPT_SENSITIVE_DATA_SETTING.get(context.settings)
|
||||
&& Watcher.ENCRYPTION_KEY_SETTING.exists(context.settings) == false) {
|
||||
final Path systemKeyPath = environment.configFile().resolve(XPackPlugin.NAME).resolve("system_key").toAbsolutePath();
|
||||
final String message;
|
||||
if (Files.exists(systemKeyPath)) {
|
||||
message = "Encryption of sensitive data requires the key to be placed in the secure setting store. Run " +
|
||||
"'bin/elasticsearch-keystore add-file " + Watcher.ENCRYPTION_KEY_SETTING.getKey() + " " +
|
||||
systemKeyPath +
|
||||
"' to import the file.\nAfter importing, the system_key file should be removed from the " +
|
||||
"filesystem.\nRepeat this on every node in the cluster.";
|
||||
} else {
|
||||
message = "Encryption of sensitive data requires a key to be placed in the secure setting store. First run the " +
|
||||
"bin/x-pack/syskeygen tool to generate a key file.\nThen run 'bin/elasticsearch-keystore add-file " +
|
||||
Watcher.ENCRYPTION_KEY_SETTING.getKey() + " " +
|
||||
systemKeyPath + "' to import the key into" +
|
||||
" the secure setting store. Finally, remove the system_key file from the filesystem.\n" +
|
||||
"Repeat this on every node in the cluster";
|
||||
}
|
||||
return BootstrapCheckResult.failure(message);
|
||||
} else {
|
||||
return "Encryption of sensitive data requires a key to be placed in the secure setting store. First run the " +
|
||||
"bin/x-pack/syskeygen tool to generate a key file.\nThen run 'bin/elasticsearch-keystore add-file " +
|
||||
Watcher.ENCRYPTION_KEY_SETTING.getKey() + " " +
|
||||
environment.configFile().resolve(XPackPlugin.NAME).resolve("system_key").toAbsolutePath() + "' to import the key into" +
|
||||
" the secure setting store. Finally, remove the system_key file from the filesystem.\n" +
|
||||
"Repeat this on every node in the cluster";
|
||||
return BootstrapCheckResult.success();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -518,6 +518,6 @@ public class Watcher implements ActionPlugin {
|
|||
}
|
||||
|
||||
public List<BootstrapCheck> getBootstrapChecks() {
|
||||
return Collections.singletonList(new EncryptSensitiveDataBootstrapCheck(settings, new Environment(settings)));
|
||||
return Collections.singletonList(new EncryptSensitiveDataBootstrapCheck(new Environment(settings)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,11 +142,11 @@ public class IndexDeprecationChecksTests extends ESTestCase {
|
|||
}
|
||||
public void testStoreThrottleSettingsCheck() {
|
||||
assertSettingsAndIssue("index.store.throttle.max_bytes_per_sec", "32",
|
||||
new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
|
||||
"index.store.throttle settings are no longer recognized. these settings should be removed",
|
||||
"https://www.elastic.co/guide/en/elasticsearch/reference/master/" +
|
||||
"breaking_60_settings_changes.html#_store_throttling_settings",
|
||||
"present settings: [index.store.throttle.max_bytes_per_sec]"));
|
||||
new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
|
||||
"index.store.throttle settings are no longer recognized. these settings should be removed",
|
||||
"https://www.elastic.co/guide/en/elasticsearch/reference/master/" +
|
||||
"breaking_60_settings_changes.html#_store_throttling_settings",
|
||||
"present settings: [index.store.throttle.max_bytes_per_sec]"));
|
||||
assertSettingsAndIssue("index.store.throttle.type", "none",
|
||||
new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
|
||||
"index.store.throttle settings are no longer recognized. these settings should be removed",
|
||||
|
@ -159,7 +159,7 @@ public class IndexDeprecationChecksTests extends ESTestCase {
|
|||
assertSettingsAndIssue("index.shared_filesystem", "true",
|
||||
new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
|
||||
"[index.shared_filesystem] setting should be removed",
|
||||
"https://www.elastic.co/guide/en/elasticsearch/reference/master/" +
|
||||
"breaking_60_settings_changes.html#_shadow_replicas_have_been_removed", null));
|
||||
"https://www.elastic.co/guide/en/elasticsearch/reference/6.0/" +
|
||||
"breaking_60_indices_changes.html#_shadow_replicas_have_been_removed", null));
|
||||
}
|
||||
}
|
|
@ -40,6 +40,8 @@ import static org.mockito.Mockito.when;
|
|||
|
||||
public class MlInitializationServiceTests extends ESTestCase {
|
||||
|
||||
private static final ClusterName CLUSTER_NAME = new ClusterName("my_cluster");
|
||||
|
||||
private ThreadPool threadPool;
|
||||
private ExecutorService executorService;
|
||||
private ClusterService clusterService;
|
||||
|
@ -60,6 +62,8 @@ public class MlInitializationServiceTests extends ESTestCase {
|
|||
|
||||
ScheduledFuture scheduledFuture = mock(ScheduledFuture.class);
|
||||
when(threadPool.schedule(any(), any(), any())).thenReturn(scheduledFuture);
|
||||
|
||||
when(clusterService.getClusterName()).thenReturn(CLUSTER_NAME);
|
||||
}
|
||||
|
||||
public void testInitialize() throws Exception {
|
||||
|
@ -93,7 +97,6 @@ public class MlInitializationServiceTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testInitialize_alreadyInitialized() throws Exception {
|
||||
ClusterService clusterService = mock(ClusterService.class);
|
||||
MlInitializationService initializationService = new MlInitializationService(Settings.EMPTY, threadPool, clusterService, client);
|
||||
|
||||
ClusterState cs = ClusterState.builder(new ClusterName("_name"))
|
||||
|
@ -113,7 +116,6 @@ public class MlInitializationServiceTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testInitialize_onlyOnce() throws Exception {
|
||||
ClusterService clusterService = mock(ClusterService.class);
|
||||
MlInitializationService initializationService = new MlInitializationService(Settings.EMPTY, threadPool, clusterService, client);
|
||||
|
||||
ClusterState cs = ClusterState.builder(new ClusterName("_name"))
|
||||
|
|
|
@ -33,18 +33,23 @@ import org.elasticsearch.search.builder.SearchSourceBuilder.ScriptField;
|
|||
import org.elasticsearch.test.AbstractSerializingTestCase;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.ml.datafeed.ChunkingConfig.Mode;
|
||||
import org.elasticsearch.xpack.ml.job.config.JobTests;
|
||||
import org.elasticsearch.xpack.ml.job.messages.Messages;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.lessThan;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
public class DatafeedConfigTests extends AbstractSerializingTestCase<DatafeedConfig> {
|
||||
|
||||
|
@ -162,15 +167,36 @@ public class DatafeedConfigTests extends AbstractSerializingTestCase<DatafeedCon
|
|||
}
|
||||
}
|
||||
|
||||
public void testFillDefaults() {
|
||||
public void testDefaults() {
|
||||
DatafeedConfig.Builder expectedDatafeedConfig = new DatafeedConfig.Builder("datafeed1", "job1");
|
||||
expectedDatafeedConfig.setIndices(Collections.singletonList("index"));
|
||||
expectedDatafeedConfig.setQueryDelay(TimeValue.timeValueMinutes(1));
|
||||
expectedDatafeedConfig.setScrollSize(1000);
|
||||
DatafeedConfig.Builder defaultedDatafeedConfig = new DatafeedConfig.Builder("datafeed1", "job1");
|
||||
defaultedDatafeedConfig.setIndices(Collections.singletonList("index"));
|
||||
DatafeedConfig.Builder defaultFeedBuilder = new DatafeedConfig.Builder("datafeed1", "job1");
|
||||
defaultFeedBuilder.setIndices(Collections.singletonList("index"));
|
||||
DatafeedConfig defaultFeed = defaultFeedBuilder.build();
|
||||
|
||||
assertEquals(expectedDatafeedConfig.build(), defaultedDatafeedConfig.build());
|
||||
|
||||
assertThat(defaultFeed.getScrollSize(), equalTo(1000));
|
||||
assertThat(defaultFeed.getQueryDelay().seconds(), greaterThanOrEqualTo(60L));
|
||||
assertThat(defaultFeed.getQueryDelay().seconds(), lessThan(120L));
|
||||
}
|
||||
|
||||
public void testDefaultQueryDelay() {
|
||||
DatafeedConfig.Builder feedBuilder1 = new DatafeedConfig.Builder("datafeed1", "job1");
|
||||
feedBuilder1.setIndices(Arrays.asList("foo"));
|
||||
DatafeedConfig.Builder feedBuilder2 = new DatafeedConfig.Builder("datafeed2", "job1");
|
||||
feedBuilder2.setIndices(Arrays.asList("foo"));
|
||||
DatafeedConfig.Builder feedBuilder3 = new DatafeedConfig.Builder("datafeed3", "job2");
|
||||
feedBuilder3.setIndices(Arrays.asList("foo"));
|
||||
DatafeedConfig feed1 = feedBuilder1.build();
|
||||
DatafeedConfig feed2 = feedBuilder2.build();
|
||||
DatafeedConfig feed3 = feedBuilder3.build();
|
||||
|
||||
// Two datafeeds with the same job id should have the same random query delay
|
||||
assertThat(feed1.getQueryDelay(), equalTo(feed2.getQueryDelay()));
|
||||
// But the query delay of a datafeed with a different job id should differ too
|
||||
assertThat(feed1.getQueryDelay(), not(equalTo(feed3.getQueryDelay())));
|
||||
}
|
||||
|
||||
public void testCheckValid_GivenNullIndices() throws IOException {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.security;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
@ -14,8 +15,9 @@ import org.elasticsearch.xpack.ssl.SSLService;
|
|||
public class PkiRealmBootstrapCheckTests extends ESTestCase {
|
||||
|
||||
public void testPkiRealmBootstrapDefault() throws Exception {
|
||||
assertFalse(new PkiRealmBootstrapCheck(Settings.EMPTY, new SSLService(Settings.EMPTY,
|
||||
new Environment(Settings.builder().put("path.home", createTempDir()).build()))).check());
|
||||
assertFalse(new PkiRealmBootstrapCheck(new SSLService(Settings.EMPTY,
|
||||
new Environment(Settings.builder().put("path.home", createTempDir()).build()))).check((new BootstrapContext(Settings
|
||||
.EMPTY, null))).isFailure());
|
||||
}
|
||||
|
||||
public void testBootstrapCheckWithPkiRealm() throws Exception {
|
||||
|
@ -24,42 +26,42 @@ public class PkiRealmBootstrapCheckTests extends ESTestCase {
|
|||
.put("path.home", createTempDir())
|
||||
.build();
|
||||
Environment env = new Environment(settings);
|
||||
assertFalse(new PkiRealmBootstrapCheck(settings, new SSLService(settings, env)).check());
|
||||
assertFalse(new PkiRealmBootstrapCheck(new SSLService(settings, env)).check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
// disable client auth default
|
||||
settings = Settings.builder().put(settings)
|
||||
.put("xpack.ssl.client_authentication", "none")
|
||||
.build();
|
||||
env = new Environment(settings);
|
||||
assertTrue(new PkiRealmBootstrapCheck(settings, new SSLService(settings, env)).check());
|
||||
assertTrue(new PkiRealmBootstrapCheck(new SSLService(settings, env)).check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
// enable ssl for http
|
||||
settings = Settings.builder().put(settings)
|
||||
.put("xpack.security.http.ssl.enabled", true)
|
||||
.build();
|
||||
env = new Environment(settings);
|
||||
assertTrue(new PkiRealmBootstrapCheck(settings, new SSLService(settings, env)).check());
|
||||
assertTrue(new PkiRealmBootstrapCheck(new SSLService(settings, env)).check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
// enable client auth for http
|
||||
settings = Settings.builder().put(settings)
|
||||
.put("xpack.security.http.ssl.client_authentication", randomFrom("required", "optional"))
|
||||
.build();
|
||||
env = new Environment(settings);
|
||||
assertFalse(new PkiRealmBootstrapCheck(settings, new SSLService(settings, env)).check());
|
||||
assertFalse(new PkiRealmBootstrapCheck(new SSLService(settings, env)).check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
// disable http ssl
|
||||
settings = Settings.builder().put(settings)
|
||||
.put("xpack.security.http.ssl.enabled", false)
|
||||
.build();
|
||||
env = new Environment(settings);
|
||||
assertTrue(new PkiRealmBootstrapCheck(settings, new SSLService(settings, env)).check());
|
||||
assertTrue(new PkiRealmBootstrapCheck(new SSLService(settings, env)).check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
// set transport client auth
|
||||
settings = Settings.builder().put(settings)
|
||||
.put("xpack.security.transport.client_authentication", randomFrom("required", "optional"))
|
||||
.build();
|
||||
env = new Environment(settings);
|
||||
assertTrue(new PkiRealmBootstrapCheck(settings, new SSLService(settings, env)).check());
|
||||
assertTrue(new PkiRealmBootstrapCheck(new SSLService(settings, env)).check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
// test with transport profile
|
||||
settings = Settings.builder().put(settings)
|
||||
|
@ -67,7 +69,7 @@ public class PkiRealmBootstrapCheckTests extends ESTestCase {
|
|||
.put("transport.profiles.foo.xpack.security.ssl.client_authentication", randomFrom("required", "optional"))
|
||||
.build();
|
||||
env = new Environment(settings);
|
||||
assertFalse(new PkiRealmBootstrapCheck(settings, new SSLService(settings, env)).check());
|
||||
assertFalse(new PkiRealmBootstrapCheck(new SSLService(settings, env)).check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
|
||||
public void testBootstrapCheckWithDisabledRealm() throws Exception {
|
||||
|
@ -78,6 +80,6 @@ public class PkiRealmBootstrapCheckTests extends ESTestCase {
|
|||
.put("path.home", createTempDir())
|
||||
.build();
|
||||
Environment env = new Environment(settings);
|
||||
assertFalse(new PkiRealmBootstrapCheck(settings, new SSLService(settings, env)).check());
|
||||
assertFalse(new PkiRealmBootstrapCheck(new SSLService(settings, env)).check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,39 +5,40 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.security;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.network.NetworkModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.XPackSettings;
|
||||
import org.elasticsearch.xpack.security.TokenSSLBootstrapCheck;
|
||||
|
||||
public class TokenSSLBootsrapCheckTests extends ESTestCase {
|
||||
|
||||
public void testTokenSSLBootstrapCheck() {
|
||||
Settings settings = Settings.EMPTY;
|
||||
assertFalse(new TokenSSLBootstrapCheck(settings).check());
|
||||
|
||||
assertFalse(new TokenSSLBootstrapCheck().check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
settings = Settings.builder()
|
||||
.put(NetworkModule.HTTP_ENABLED.getKey(), false)
|
||||
.put(XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey(), true).build();
|
||||
assertFalse(new TokenSSLBootstrapCheck(settings).check());
|
||||
assertFalse(new TokenSSLBootstrapCheck().check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
settings = Settings.builder().put(XPackSettings.HTTP_SSL_ENABLED.getKey(), true).build();
|
||||
assertFalse(new TokenSSLBootstrapCheck(settings).check());
|
||||
assertFalse(new TokenSSLBootstrapCheck().check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
// XPackSettings.HTTP_SSL_ENABLED default false
|
||||
settings = Settings.builder().put(XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey(), true).build();
|
||||
assertTrue(new TokenSSLBootstrapCheck(settings).check());
|
||||
assertTrue(new TokenSSLBootstrapCheck().check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
settings = Settings.builder()
|
||||
.put(XPackSettings.HTTP_SSL_ENABLED.getKey(), false)
|
||||
.put(XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey(), true).build();
|
||||
assertTrue(new TokenSSLBootstrapCheck(settings).check());
|
||||
assertTrue(new TokenSSLBootstrapCheck().check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
settings = Settings.builder()
|
||||
.put(XPackSettings.HTTP_SSL_ENABLED.getKey(), false)
|
||||
.put(XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey(), true)
|
||||
.put(NetworkModule.HTTP_ENABLED.getKey(), false).build();
|
||||
assertFalse(new TokenSSLBootstrapCheck(settings).check());
|
||||
assertFalse(new TokenSSLBootstrapCheck().check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,25 +11,31 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.support.PlainActionFuture;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||
import org.elasticsearch.common.settings.SecureString;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.security.authc.AuthenticationResult;
|
||||
import org.elasticsearch.xpack.security.authc.RealmConfig;
|
||||
import org.elasticsearch.xpack.security.authc.RealmSettings;
|
||||
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
|
||||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||
import org.elasticsearch.xpack.security.support.NoOpLogger;
|
||||
import org.elasticsearch.xpack.security.user.User;
|
||||
import org.elasticsearch.xpack.ssl.SSLConfigurationSettings;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
|
@ -248,6 +254,20 @@ public class PkiRealmTests extends ESTestCase {
|
|||
assertThat(token.dn(), is("EMAILADDRESS=pki@elastic.co, CN=PKI Client, OU=Security"));
|
||||
}
|
||||
|
||||
public void testPKIRealmSettingsPassValidation() throws Exception {
|
||||
Settings settings = Settings.builder()
|
||||
.put("xpack.security.authc.realms.pki1.type", "pki")
|
||||
.put("xpack.security.authc.realms.pki1.truststore.path", "/foo/bar")
|
||||
.put("xpack.security.authc.realms.pki1.truststore.password", "supersecret")
|
||||
.build();
|
||||
List<Setting<?>> settingList = new ArrayList<>();
|
||||
RealmSettings.addSettings(settingList, Collections.emptyList());
|
||||
ClusterSettings clusterSettings = new ClusterSettings(settings, new HashSet<>(settingList));
|
||||
clusterSettings.validate(settings);
|
||||
|
||||
assertSettingDeprecationsAndWarnings(new Setting[] { SSLConfigurationSettings.withoutPrefix().legacyTruststorePassword });
|
||||
}
|
||||
|
||||
static X509Certificate readCert(Path path) throws Exception {
|
||||
try (InputStream in = Files.newInputStream(path)) {
|
||||
CertificateFactory factory = CertificateFactory.getInstance("X.509");
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.nio.file.Path;
|
|||
import java.util.Collections;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapCheck;
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
@ -45,7 +46,7 @@ public class RoleMappingFileBootstrapCheckTests extends ESTestCase {
|
|||
final BootstrapCheck check = RoleMappingFileBootstrapCheck.create(config);
|
||||
assertThat(check, notNullValue());
|
||||
assertThat(check.alwaysEnforce(), equalTo(true));
|
||||
assertThat(check.check(), equalTo(false));
|
||||
assertFalse(check.check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
|
||||
public void testBootstrapCheckOfMissingFile() {
|
||||
|
@ -58,10 +59,11 @@ public class RoleMappingFileBootstrapCheckTests extends ESTestCase {
|
|||
final BootstrapCheck check = RoleMappingFileBootstrapCheck.create(config);
|
||||
assertThat(check, notNullValue());
|
||||
assertThat(check.alwaysEnforce(), equalTo(true));
|
||||
assertThat(check.check(), equalTo(true));
|
||||
assertThat(check.errorMessage(), containsString("the-realm-name"));
|
||||
assertThat(check.errorMessage(), containsString(fileName));
|
||||
assertThat(check.errorMessage(), containsString("does not exist"));
|
||||
final BootstrapCheck.BootstrapCheckResult result = check.check(new BootstrapContext(settings, null));
|
||||
assertTrue(result.isFailure());
|
||||
assertThat(result.getMessage(), containsString("the-realm-name"));
|
||||
assertThat(result.getMessage(), containsString(fileName));
|
||||
assertThat(result.getMessage(), containsString("does not exist"));
|
||||
}
|
||||
|
||||
public void testBootstrapCheckWithInvalidYaml() throws IOException {
|
||||
|
@ -76,10 +78,11 @@ public class RoleMappingFileBootstrapCheckTests extends ESTestCase {
|
|||
final BootstrapCheck check = RoleMappingFileBootstrapCheck.create(config);
|
||||
assertThat(check, notNullValue());
|
||||
assertThat(check.alwaysEnforce(), equalTo(true));
|
||||
assertThat(check.check(), equalTo(true));
|
||||
assertThat(check.errorMessage(), containsString("the-realm-name"));
|
||||
assertThat(check.errorMessage(), containsString(file.toString()));
|
||||
assertThat(check.errorMessage(), containsString("could not read"));
|
||||
final BootstrapCheck.BootstrapCheckResult result = check.check(new BootstrapContext(settings, null));
|
||||
assertTrue(result.isFailure());
|
||||
assertThat(result.getMessage(), containsString("the-realm-name"));
|
||||
assertThat(result.getMessage(), containsString(file.toString()));
|
||||
assertThat(result.getMessage(), containsString("could not read"));
|
||||
}
|
||||
|
||||
public void testBootstrapCheckWithInvalidDn() throws IOException {
|
||||
|
@ -94,10 +97,11 @@ public class RoleMappingFileBootstrapCheckTests extends ESTestCase {
|
|||
final BootstrapCheck check = RoleMappingFileBootstrapCheck.create(config);
|
||||
assertThat(check, notNullValue());
|
||||
assertThat(check.alwaysEnforce(), equalTo(true));
|
||||
assertThat(check.check(), equalTo(true));
|
||||
assertThat(check.errorMessage(), containsString("the-realm-name"));
|
||||
assertThat(check.errorMessage(), containsString(file.toString()));
|
||||
assertThat(check.errorMessage(), containsString("invalid DN"));
|
||||
assertThat(check.errorMessage(), containsString("not-a-dn"));
|
||||
final BootstrapCheck.BootstrapCheckResult result = check.check(new BootstrapContext(settings, null));
|
||||
assertTrue(result.isFailure());
|
||||
assertThat(result.getMessage(), containsString("the-realm-name"));
|
||||
assertThat(result.getMessage(), containsString(file.toString()));
|
||||
assertThat(result.getMessage(), containsString("invalid DN"));
|
||||
assertThat(result.getMessage(), containsString("not-a-dn"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.ssl;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
@ -14,8 +15,8 @@ public class SSLBootstrapCheckTests extends ESTestCase {
|
|||
|
||||
public void testSSLBootstrapCheckWithNoKey() throws Exception {
|
||||
SSLService sslService = new SSLService(Settings.EMPTY, null);
|
||||
SSLBootstrapCheck bootstrapCheck = new SSLBootstrapCheck(sslService, Settings.EMPTY, null);
|
||||
assertTrue(bootstrapCheck.check());
|
||||
SSLBootstrapCheck bootstrapCheck = new SSLBootstrapCheck(sslService, null);
|
||||
assertTrue(bootstrapCheck.check(new BootstrapContext(Settings.EMPTY, null)).isFailure());
|
||||
}
|
||||
|
||||
public void testSSLBootstrapCheckWithKey() throws Exception {
|
||||
|
@ -31,8 +32,8 @@ public class SSLBootstrapCheckTests extends ESTestCase {
|
|||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
final Environment env = randomBoolean() ? new Environment(settings) : null;
|
||||
SSLBootstrapCheck bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), settings, env);
|
||||
assertFalse(bootstrapCheck.check());
|
||||
SSLBootstrapCheck bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), env);
|
||||
assertFalse(bootstrapCheck.check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
|
||||
public void testSSLBootstrapCheckWithDefaultCABeingTrusted() throws Exception {
|
||||
|
@ -51,15 +52,15 @@ public class SSLBootstrapCheckTests extends ESTestCase {
|
|||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
final Environment env = randomBoolean() ? new Environment(settings) : null;
|
||||
SSLBootstrapCheck bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), settings, env);
|
||||
assertTrue(bootstrapCheck.check());
|
||||
SSLBootstrapCheck bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), env);
|
||||
assertTrue(bootstrapCheck.check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
settings = Settings.builder().put(settings.filter((s) -> s.contains(".certificate_authorities")))
|
||||
.put("xpack.security.http.ssl.certificate_authorities",
|
||||
getDataPath("/org/elasticsearch/xpack/ssl/ca.pem").toString())
|
||||
.build();
|
||||
bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), settings, env);
|
||||
assertTrue(bootstrapCheck.check());
|
||||
bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), env);
|
||||
assertTrue(bootstrapCheck.check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
|
||||
public void testSSLBootstrapCheckWithDefaultKeyBeingUsed() throws Exception {
|
||||
|
@ -77,8 +78,8 @@ public class SSLBootstrapCheckTests extends ESTestCase {
|
|||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
final Environment env = randomBoolean() ? new Environment(settings) : null;
|
||||
SSLBootstrapCheck bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), settings, env);
|
||||
assertTrue(bootstrapCheck.check());
|
||||
SSLBootstrapCheck bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), env);
|
||||
assertTrue(bootstrapCheck.check(new BootstrapContext(settings, null)).isFailure());
|
||||
|
||||
settings = Settings.builder().put(settings.filter((s) -> s.contains(".http.ssl.")))
|
||||
.put("xpack.security.transport.profiles.foo.xpack.security.ssl.key",
|
||||
|
@ -86,7 +87,7 @@ public class SSLBootstrapCheckTests extends ESTestCase {
|
|||
.put("xpack.security.transport.profiles.foo.xpack.security.ssl.certificate",
|
||||
getDataPath("/org/elasticsearch/xpack/ssl/ca.pem").toString())
|
||||
.build();
|
||||
bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), settings, env);
|
||||
assertTrue(bootstrapCheck.check());
|
||||
bootstrapCheck = new SSLBootstrapCheck(new SSLService(settings, env), env);
|
||||
assertTrue(bootstrapCheck.check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.watcher;
|
||||
|
||||
import org.elasticsearch.bootstrap.BootstrapContext;
|
||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
@ -16,8 +17,8 @@ public class EncryptSensitiveDataBootstrapCheckTests extends ESTestCase {
|
|||
public void testDefaultIsFalse() {
|
||||
Settings settings = Settings.builder().put("path.home", createTempDir()).build();
|
||||
Environment env = new Environment(settings);
|
||||
EncryptSensitiveDataBootstrapCheck check = new EncryptSensitiveDataBootstrapCheck(settings, env);
|
||||
assertFalse(check.check());
|
||||
EncryptSensitiveDataBootstrapCheck check = new EncryptSensitiveDataBootstrapCheck(env);
|
||||
assertFalse(check.check(new BootstrapContext(settings, null)).isFailure());
|
||||
assertTrue(check.alwaysEnforce());
|
||||
}
|
||||
|
||||
|
@ -27,8 +28,8 @@ public class EncryptSensitiveDataBootstrapCheckTests extends ESTestCase {
|
|||
.put(Watcher.ENCRYPT_SENSITIVE_DATA_SETTING.getKey(), true)
|
||||
.build();
|
||||
Environment env = new Environment(settings);
|
||||
EncryptSensitiveDataBootstrapCheck check = new EncryptSensitiveDataBootstrapCheck(settings, env);
|
||||
assertTrue(check.check());
|
||||
EncryptSensitiveDataBootstrapCheck check = new EncryptSensitiveDataBootstrapCheck(env);
|
||||
assertTrue(check.check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
|
||||
public void testKeyInKeystore() {
|
||||
|
@ -40,7 +41,8 @@ public class EncryptSensitiveDataBootstrapCheckTests extends ESTestCase {
|
|||
.setSecureSettings(secureSettings)
|
||||
.build();
|
||||
Environment env = new Environment(settings);
|
||||
EncryptSensitiveDataBootstrapCheck check = new EncryptSensitiveDataBootstrapCheck(settings, env);
|
||||
assertFalse(check.check());
|
||||
EncryptSensitiveDataBootstrapCheck check = new EncryptSensitiveDataBootstrapCheck(env);
|
||||
assertFalse(check.check(new BootstrapContext(settings, null)).isFailure());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue