Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -27,7 +27,7 @@ public class AuthorizationPolicyRegistryFactory : SubsystemsPlugin
public AuthorizationPolicyRegistryFactory(ClusterVNodeOptions options, IConfiguration configuration,
PluginLoader pluginLoader)
{
if (options.Application.Insecure)
if (options.Application.AuthDisabled())
{
_createRegistry = _ => new StaticAuthorizationPolicyRegistry([]);
return;
Expand Down
4 changes: 2 additions & 2 deletions src/EventStore.ClusterNode/ClusterVNodeHostedService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public ClusterVNodeHostedService(

(ClusterVNodeOptions, AuthorizationProviderFactory) GetAuthorizationProviderFactory()
{
if (_options.Application.Insecure)
if (_options.Application.AuthDisabled())
{
return (_options, new AuthorizationProviderFactory(_ => new PassthroughAuthorizationProviderFactory()));
}
Expand Down Expand Up @@ -241,7 +241,7 @@ IPersistentSubscriptionConsumerStrategyFactory[] GetPersistentSubscriptionConsum

AuthenticationProviderFactory GetAuthenticationProviderFactory()
{
if (_options.Application.Insecure)
if (_options.Application.AuthDisabled())
{
return new AuthenticationProviderFactory(_ => new PassthroughAuthenticationProviderFactory());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public ConfigurationPage Read()
var options = hostedService.Options;
var features = new[] {
new ConfigurationFeature("Projections", options.Projection.RunProjections != ProjectionType.None || options.DevMode.Dev),
new ConfigurationFeature("User management", options.Auth.AuthenticationType == Opts.AuthenticationTypeDefault && !options.Application.Insecure)
new ConfigurationFeature("User management",
options.Auth.AuthenticationType == Opts.AuthenticationTypeDefault && !options.Application.AuthDisabled())
};

var subsystems = hostedService.EnabledNodeSubsystems
Expand All @@ -46,6 +47,7 @@ public ConfigurationPage Read()
canInspectRuntimeDetails ? options.Auth.AuthenticationType : "",
canInspectRuntimeDetails ? options.Auth.AuthorizationType : "",
options.Application.Insecure,
options.Application.TlsDisabled(),
canInspectRuntimeDetails,
features,
subsystems,
Expand All @@ -66,14 +68,15 @@ public sealed record ConfigurationPage(
string AuthenticationType,
string AuthorizationType,
bool IsInsecure,
bool IsTlsDisabled,
bool CanInspectRuntimeDetails,
IReadOnlyList<ConfigurationFeature> Features,
IReadOnlyList<ConfigurationSubsystem> Subsystems,
IReadOnlyList<ConfigurationOption> LoadedOptions,
string OptionsMessage)
{
public string SecurityMode => IsInsecure ? "Insecure" : "Secure";
public string SecurityTone => IsInsecure ? "warn" : "good";
public string SecurityMode => IsInsecure ? "Insecure" : IsTlsDisabled ? "TLS disabled" : "Secure";
public string SecurityTone => IsInsecure || IsTlsDisabled ? "warn" : "good";
public bool HasSubsystems => Subsystems.Count > 0;
public bool HasLoadedOptions => LoadedOptions.Count > 0;
}
Expand Down
8 changes: 8 additions & 0 deletions src/EventStore.ClusterNode/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@ public static async Task<int> Main(string[] args)
"INSECURE MODE WILL DISABLE ALL AUTHENTICATION, AUTHORIZATION AND TRANSPORT SECURITY FOR ALL CLIENTS AND NODES.\n" +
"==============================================================================================================\n");
}
else if (options.Application.DisableTls)
{
Log.Warning(
"\n==============================================================================================================\n" +
"TLS IS DISABLED. THIS MODE IS *NOT* RECOMMENDED FOR PRODUCTION USE.\n" +
"AUTHENTICATION AND AUTHORIZATION REMAIN ENABLED, BUT TRAFFIC IS NOT ENCRYPTED.\n" +
"==============================================================================================================\n");
}

if (options.Application.WhatIf)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public void should_set_command_line_args_to_default_values()
Assert.AreEqual(true, _options.Cluster.DiscoverViaDns, "DiscoverViaDns");
Assert.AreEqual(30, _options.Application.StatsPeriodSec, "StatsPeriod");
Assert.AreEqual(false, _options.Application.DisableHttpCaching, "DisableHTTPCaching");
Assert.AreEqual(false, _options.Application.DisableTls, "DisableTls");
Assert.AreEqual(false, _options.Database.SkipDbVerify, "VerifyDbHash");
Assert.AreEqual(TFConsts.MinFlushDelayMs.TotalMilliseconds, _options.Database.MinFlushDelayMs, "MinFlushDelay");
Assert.AreEqual(30, _options.Database.ScavengeHistoryMaxAge,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using EventStore.Common.Utils;
using EventStore.Core.Authentication;
using EventStore.Core.Authentication.DelegatedAuthentication;
using EventStore.Core.Authentication.InternalAuthentication;
using EventStore.Core.Authorization;
using EventStore.Core.Authorization.AuthorizationPolicies;
using EventStore.Core.Certificates;
using EventStore.Core.Tests;
using EventStore.Core.Tests.Services.Transport.Tcp;
Expand Down Expand Up @@ -117,3 +123,60 @@ public void should_throw_an_exception()
Assert.IsNotNull(_caughtException);
}
}

[TestFixture(typeof(LogFormat.V2), typeof(string))]
public class with_tls_disabled_and_auth_enabled<TLogFormat, TStreamId> : SpecificationWithDirectoryPerTestFixture
{
private ClusterVNode<TStreamId> _node;
private ClusterVNodeOptions _options;

[OneTimeSetUp]
public override async Task TestFixtureSetUp()
{
await base.TestFixtureSetUp();

_options = new ClusterVNodeOptions()
.ReduceMemoryUsageForTests()
.RunOnDisk(PathName);
_options = _options with
{
Application = _options.Application with
{
DisableTls = true,
},
};

_node = new ClusterVNode<TStreamId>(_options, LogFormatHelper<TLogFormat, TStreamId>.LogFormatFactory,
new AuthenticationProviderFactory(c =>
new InternalAuthenticationProviderFactory(c, _options.DefaultUser)),
new AuthorizationProviderFactory(c => new InternalAuthorizationProviderFactory(
new StaticAuthorizationPolicyRegistry([new LegacyPolicySelectorFactory(
_options.Application.AllowAnonymousEndpointAccess,
_options.Application.AllowAnonymousStreamAccess,
_options.Application.OverrideAnonymousEndpointAccessForGossip).Create(c.MainQueue)]))),
certificateProvider: new OptionsCertificateProvider());
}

[Test]
public void should_not_require_certificates()
{
Assert.IsNotNull(_node);
}

[Test]
public void should_disable_transport_tls()
{
Assert.IsTrue(_node.DisableHttps);
Assert.IsTrue(_options.Application.TlsDisabled());
Assert.AreEqual(new IPEndPoint(IPAddress.Loopback, 1112), _node.NodeInfo.InternalTcp);
}

[Test]
public void should_keep_auth_enabled()
{
Assert.IsFalse(_options.Application.AuthDisabled());
Assert.IsInstanceOf<DelegatedAuthenticationProvider>(_node.AuthenticationProvider);
var delegatedAuthenticationProvider = (DelegatedAuthenticationProvider)_node.AuthenticationProvider;
Assert.IsInstanceOf<InternalAuthenticationProvider>(delegatedAuthenticationProvider.Inner);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,28 @@ public void valid_parameters()
Assert.Empty(values);
}

[Fact]
public void disable_tls_is_a_valid_parameter()
{
var options = GetOptions("--disable-tls true");

options.Application.DisableTls.Should().BeTrue();
options.Application.TlsDisabled().Should().BeTrue();
options.Application.AuthDisabled().Should().BeFalse();
Assert.Empty(options.Unknown.Options);
}

[Fact]
public void insecure_disables_tls_and_auth()
{
var options = GetOptions("--insecure true");

options.Application.Insecure.Should().BeTrue();
options.Application.TlsDisabled().Should().BeTrue();
options.Application.AuthDisabled().Should().BeTrue();
Assert.Empty(options.Unknown.Options);
}

[Fact]
public void stream_info_cache_scales_automatically_by_default()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class OptionsCertificateProvider : CertificateProvider

public override LoadCertificateResult LoadCertificates(ClusterVNodeOptions options)
{
if (options.Application.Insecure)
if (options.Application.TlsDisabled())
{
Log.Information("Skipping reload of certificates since TLS is disabled.");
return LoadCertificateResult.Skipped;
Expand Down
38 changes: 19 additions & 19 deletions src/EventStore.Core/ClusterVNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,14 @@ public ClusterVNode(ClusterVNodeOptions options,
throw new ArgumentException("InstanceId may not be empty.", nameof(instanceId));
}

if (!options.Application.Insecure)
if (!options.Application.TlsDisabled())
{
ReloadCertificates(options);

if (_certificateProvider?.TrustedRootCerts == null || _certificateProvider?.Certificate == null)
{
throw new InvalidConfigurationException(
"A certificate is required unless insecure mode (--insecure) is set.");
"A certificate is required unless TLS is disabled.");
}
}

Expand All @@ -285,8 +285,8 @@ public ClusterVNode(ClusterVNodeOptions options,
archiveOptions.Validate();
OptionsFormatter.LogConfig("Archive", archiveOptions);

var disableInternalTcpTls = options.Application.Insecure;
var disableExternalTcpTls = options.Application.Insecure;
var disableInternalTcpTls = options.Application.TlsDisabled();
var disableExternalTcpTls = options.Application.TlsDisabled();
var nodeTcpOptions = configuration.GetSection("EventStore:TcpPlugin").Get<NodeTcpOptions>() ?? new();
var enableExternalTcp = nodeTcpOptions.EnableExternalTcp;

Expand Down Expand Up @@ -496,7 +496,7 @@ TFChunkDbConfig CreateDbConfig(
streamExistenceFilterCheckpoint, streamExistenceFilterCheckpoint);

var isSingleNode = options.Cluster.ClusterSize == 1;
_disableHttps = options.Application.Insecure;
_disableHttps = options.Application.TlsDisabled();
_enableUnixSocket = options.Interface.EnableUnixSocket;
_queueStatsManager = new QueueStatsManager();

Expand Down Expand Up @@ -572,7 +572,7 @@ void StartSubsystems()
_mainBus.Subscribe<SystemMessage.ComponentTerminated>(shutdownService);
_mainBus.Subscribe<SystemMessage.PeripheralShutdownTimeout>(shutdownService);

var uriScheme = options.Application.Insecure ? Uri.UriSchemeHttp : Uri.UriSchemeHttps;
var uriScheme = options.Application.TlsDisabled() ? Uri.UriSchemeHttp : Uri.UriSchemeHttps;
var clusterDns = options.Cluster.DiscoverViaDns ? options.Cluster.ClusterDns : null;

_nodeHttpClientFactory = new NodeHttpClientFactory(
Expand Down Expand Up @@ -973,11 +973,11 @@ GossipAdvertiseInfo GetGossipAdvertiseInfo()
};

// AUTHENTICATION INFRASTRUCTURE - delegate to plugins
authorizationProviderFactory ??= !options.Application.Insecure
authorizationProviderFactory ??= !options.Application.AuthDisabled()
? throw new InvalidConfigurationException(
$"An {nameof(AuthorizationProviderFactory)} is required when running securely.")
: new AuthorizationProviderFactory(_ => new PassthroughAuthorizationProviderFactory());
authenticationProviderFactory ??= !options.Application.Insecure
authenticationProviderFactory ??= !options.Application.AuthDisabled()
? throw new InvalidConfigurationException(
$"An {nameof(AuthenticationProviderFactory)} is required when running securely.")
: new AuthenticationProviderFactory(_ => new PassthroughAuthenticationProviderFactory());
Expand Down Expand Up @@ -1074,21 +1074,21 @@ GossipAdvertiseInfo GetGossipAdvertiseInfo()
$"The server does not support any authentication scheme supported by the '{_authenticationProvider.Name}' authentication provider.");
}

if (!options.Application.Insecure)
if (!options.Application.TlsDisabled())
{
//transport-level authentication providers
httpAuthenticationProviders.Add(
new NodeCertificateAuthenticationProvider(() => _certificateProvider.GetReservedNodeCommonName()));
}

if (options.Interface.EnableTrustedAuth)
{
httpAuthenticationProviders.Add(new TrustedHttpAuthenticationProvider());
}
if (!options.Application.AuthDisabled() && options.Interface.EnableTrustedAuth)
{
httpAuthenticationProviders.Add(new TrustedHttpAuthenticationProvider());
}

if (EnableUnixSocket)
{
httpAuthenticationProviders.Add(new UnixSocketAuthenticationProvider());
}
if (!options.Application.AuthDisabled() && EnableUnixSocket)
{
httpAuthenticationProviders.Add(new UnixSocketAuthenticationProvider());
}

//default authentication provider
Expand All @@ -1106,7 +1106,7 @@ GossipAdvertiseInfo GetGossipAdvertiseInfo()
["projections"] = options.Projection.RunProjections != ProjectionType.None || options.DevMode.Dev,
["userManagement"] =
options.Auth.AuthenticationType == Opts.AuthenticationTypeDefault &&
!options.Application.Insecure
!options.Application.AuthDisabled()
},
_authenticationProvider
);
Expand Down Expand Up @@ -2235,7 +2235,7 @@ private void ReloadLogOptions(ClusterVNodeOptions options)

private void ReloadCertificates(ClusterVNodeOptions options)
{
if (options.Application.Insecure)
if (options.Application.TlsDisabled())
{
Log.Information("Skipping reload of certificates since TLS is disabled.");
return;
Expand Down
7 changes: 7 additions & 0 deletions src/EventStore.Core/Configuration/ClusterVNodeOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ public record ApplicationOptions
[Description("Disable Authentication, Authorization and TLS on all TCP/HTTP interfaces.")]
public bool Insecure { get; init; } = false;

[Description("Disable TLS on all TCP/HTTP interfaces while keeping authentication and authorization enabled.")]
public bool DisableTls { get; init; } = false;

public bool AuthDisabled() => Insecure;

public bool TlsDisabled() => Insecure || DisableTls;

[Description("Allow anonymous access to HTTP API endpoints.")]
public bool AllowAnonymousEndpointAccess { get; init; } = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public static bool ValidateForStartup(ClusterVNodeOptions options)
return false;
}

if (options.Application.Insecure || options.Auth.AuthenticationType != Opts.AuthenticationTypeDefault)
if (options.Application.AuthDisabled() || options.Auth.AuthenticationType != Opts.AuthenticationTypeDefault)
{
if (options.DefaultUser.DefaultAdminPassword != SystemUsers.DefaultAdminPassword)
{
Expand Down
1 change: 1 addition & 0 deletions src/EventStore.Core/Telemetry/TelemetryService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ private async ValueTask Handle(TelemetryMessage.Request message, CancellationTok
{
["clusterSize"] = _nodeOptions.Cluster.ClusterSize,
["insecure"] = _nodeOptions.Application.Insecure,
["disableTls"] = _nodeOptions.Application.DisableTls,
["runProjections"] = _nodeOptions.Projection.RunProjections.ToString(),
["authorizationType"] = _nodeOptions.Auth.AuthorizationType,
["authenticationType"] = _nodeOptions.Auth.AuthenticationType
Expand Down
Loading