From 65a71c5b5f0a628dcb078b60ea56f83aa2c6890e Mon Sep 17 00:00:00 2001 From: Ross Miller Date: Sat, 7 Mar 2026 15:51:01 +0000 Subject: [PATCH] Update cert config --- BudgetApp/Program.cs | 44 +++++++++++++++++++++++++++++++++----------- Dockerfile | 20 ++++---------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/BudgetApp/Program.cs b/BudgetApp/Program.cs index cacf33e..ad25836 100644 --- a/BudgetApp/Program.cs +++ b/BudgetApp/Program.cs @@ -9,6 +9,28 @@ using BudgetApp.Data.Interfaces; var builder = WebApplication.CreateBuilder(args); +builder.Host.ConfigureWebHostDefaults(webBuilder => +{ + webBuilder.ConfigureKestrel(options => + { + options.ConfigureHttpsDefaults(adapterOptions => + { + var pemCertFile = "app/data/certs/cert.pem"; + var pemKeyFile = "app/data/certs/key.pem"; + + if (File.Exists(pemCertFile) && File.Exists(pemKeyFile)) + { + adapterOptions.ServerCertificate = System.Security.Cryptography.X509Certificates.X509Certificate2.CreateFromPemFile(pemCertFile, pemKeyFile); + } + else + { + // No certificate found — fallback to default development certificate + adapterOptions.ServerCertificate = null; + } + }); + }); +}); + // Database builder.Services.AddDbContext(options => options.UseSqlite( @@ -82,17 +104,16 @@ builder.Services.AddScoped(); builder.Services.AddCascadingAuthenticationState(); -// HSTS -//if (bool.Parse(Environment.GetEnvironmentVariable("ENABLE_HSTS") ?? "false")) -//{ -// builder.Services.AddHsts(options => -// { -// var hstsSection = builder.Configuration.GetSection("Hsts"); -// options.MaxAge = TimeSpan.FromDays(hstsSection.GetValue("MaxAgeDays", 365)); -// options.IncludeSubDomains = hstsSection.GetValue("IncludeSubDomains", true); -// options.Preload = hstsSection.GetValue("Preload", false); -// }); -//} +if (bool.Parse(Environment.GetEnvironmentVariable("ENABLE_HSTS") ?? "false")) +{ + builder.Services.AddHsts(options => + { + var hstsSection = builder.Configuration.GetSection("Hsts"); + options.MaxAge = TimeSpan.FromDays(hstsSection.GetValue("MaxAgeDays", 365)); + options.IncludeSubDomains = hstsSection.GetValue("IncludeSubDomains", true); + options.Preload = hstsSection.GetValue("Preload", false); + }); +} // Add services to the container. builder.Services.AddRazorComponents() @@ -112,6 +133,7 @@ if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error", createScopeForErrors: true); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); } app.UseStatusCodePagesWithReExecute("/not-found"); diff --git a/Dockerfile b/Dockerfile index 5df99a1..84024b8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,28 +32,15 @@ LABEL org.opencontainers.image.title="Budgeteer" \ # Ensure the SQLite data directory exists and is writable RUN mkdir -p /app/data +# Ensure the cert directory exists and is writable +RUN mkdir -p /app/data/certs + # HSTS domain — read by the app via Hsts:Domain config ENV Hsts__Domain=nas.oneputleygreen.com -# Copy the SSL certificate (CN=nas.oneputleygreen.com). -# Place cert.pem and key.pem in certs/ before building — excluded from git via certs/* in .gitignore. -# If cert.pem is absent (e.g. CI builds) a self-signed fallback is generated automatically. -COPY certs/ /app/certs/ -RUN if [ ! -f /app/certs/cert.pem ]; then \ - echo "No cert.pem found — generating self-signed certificate for ${Hsts__Domain}" && \ - openssl req -x509 -newkey rsa:4096 \ - -keyout /app/certs/key.pem \ - -out /app/certs/cert.pem \ - -days 3650 \ - -nodes \ - -subj "/C=GB/ST=England/O=Budgeteer/CN=${Hsts__Domain}"; \ - fi - # Serve on both HTTP and HTTPS ENV ASPNETCORE_HTTP_PORTS=8181 ENV ASPNETCORE_HTTPS_PORTS=8282 -ENV ASPNETCORE_Kestrel__Certificates__Default__Path=/app/certs/cert.pem -ENV ASPNETCORE_Kestrel__Certificates__Default__KeyPath=/app/certs/key.pem # Store the database in the volume-mountable /app/data directory ENV ConnectionStrings__DefaultConnection="Data Source=/app/data/budgetapp.db" @@ -67,5 +54,6 @@ ENV Authentication__Google__ClientId="" \ Authentication__Facebook__ClientSecret="" VOLUME ["/app/data"] +VOLUME ["/app/data/certs"] ENTRYPOINT ["dotnet", "BudgetApp.dll"]