fix(router): ship audit bundle frontdoor cutover

This commit is contained in:
master
2026-03-08 14:30:12 +02:00
parent 8852928115
commit 30532800ec
9 changed files with 367 additions and 16 deletions

View File

@@ -24,7 +24,10 @@ using StellaOps.Router.Gateway.Middleware;
using StellaOps.Router.Gateway.OpenApi;
using StellaOps.Router.Gateway.RateLimit;
using StellaOps.Router.Gateway.Routing;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Loader;
using System.Security.Cryptography.X509Certificates;
var builder = WebApplication.CreateBuilder(args);
@@ -157,7 +160,14 @@ var routerEnabled = builder.Services.AddRouterMicroservice(
builder.Services.AddStellaOpsCors(builder.Environment, builder.Configuration);
builder.TryAddStellaOpsLocalBinding("router");
if (ShouldApplyStellaOpsLocalBinding())
{
builder.TryAddStellaOpsLocalBinding("router");
}
else
{
ConfigureContainerFrontdoorBindings(builder);
}
var app = builder.Build();
app.LogStellaOpsLocalHostname("router");
@@ -378,6 +388,116 @@ static void ConfigureGatewayOptionsMapping(WebApplicationBuilder builder, Gatewa
}
static bool ShouldApplyStellaOpsLocalBinding()
{
var runningInContainer = string.Equals(
Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER"),
"true",
StringComparison.OrdinalIgnoreCase);
if (!runningInContainer)
{
return true;
}
// Compose-published container runs already define the frontdoor port contract.
// Respect explicit container port settings instead of replacing them with 80/443.
var explicitUrls = Environment.GetEnvironmentVariable("ASPNETCORE_URLS");
var explicitHttpPorts = Environment.GetEnvironmentVariable("ASPNETCORE_HTTP_PORTS");
var explicitHttpsPorts = Environment.GetEnvironmentVariable("ASPNETCORE_HTTPS_PORTS");
return string.IsNullOrWhiteSpace(explicitUrls)
&& string.IsNullOrWhiteSpace(explicitHttpPorts)
&& string.IsNullOrWhiteSpace(explicitHttpsPorts);
}
static void ConfigureContainerFrontdoorBindings(WebApplicationBuilder builder)
{
var currentUrls = builder.WebHost.GetSetting(WebHostDefaults.ServerUrlsKey) ?? string.Empty;
builder.WebHost.ConfigureKestrel((context, kestrel) =>
{
var defaultCert = LoadDefaultCertificate(context.Configuration);
foreach (var rawUrl in currentUrls.Split(';', StringSplitOptions.RemoveEmptyEntries))
{
if (!Uri.TryCreate(rawUrl.Trim(), UriKind.Absolute, out var uri))
{
continue;
}
var address = ResolveListenAddress(uri.Host);
if (string.Equals(uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
{
kestrel.Listen(address, uri.Port, listenOptions =>
{
if (defaultCert is not null)
{
listenOptions.UseHttps(defaultCert);
}
else
{
listenOptions.UseHttps();
}
});
continue;
}
kestrel.Listen(address, uri.Port);
}
if (defaultCert is not null && IsPortAvailable(443, IPAddress.Any))
{
kestrel.ListenAnyIP(443, listenOptions => listenOptions.UseHttps(defaultCert));
}
});
}
static X509Certificate2? LoadDefaultCertificate(IConfiguration configuration)
{
var certPath = configuration["Kestrel:Certificates:Default:Path"];
var certPass = configuration["Kestrel:Certificates:Default:Password"];
if (string.IsNullOrWhiteSpace(certPath) || !File.Exists(certPath))
{
return null;
}
return X509CertificateLoader.LoadPkcs12FromFile(certPath, certPass);
}
static IPAddress ResolveListenAddress(string host)
{
if (string.IsNullOrWhiteSpace(host) ||
string.Equals(host, "*", StringComparison.OrdinalIgnoreCase) ||
string.Equals(host, "+", StringComparison.OrdinalIgnoreCase) ||
string.Equals(host, "0.0.0.0", StringComparison.OrdinalIgnoreCase))
{
return IPAddress.Any;
}
if (string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase))
{
return IPAddress.Loopback;
}
return IPAddress.Parse(host);
}
static bool IsPortAvailable(int port, IPAddress address)
{
try
{
using var listener = new TcpListener(address, port);
listener.Start();
listener.Stop();
return true;
}
catch
{
return false;
}
}
static string? ResolveAuthorityClaimsUrl(GatewayAuthorityOptions authorityOptions)
{
if (!string.IsNullOrWhiteSpace(authorityOptions.ClaimsOverridesUrl))
@@ -418,5 +538,3 @@ static string? ResolveAuthorityClaimsUrl(GatewayAuthorityOptions authorityOption
return builder.Uri.GetLeftPart(UriPartial.Authority).TrimEnd('/');
}