Default webRootPath for linux based webapps is incorrect/undocumented.
profet23 opened this issue · 2 comments
When targeting Linux based asp.net core web apps the default webRootPath
puts the .well-known/acme-challenge
directory in:
/home/site/wwwroot
When it actually needs to be in:
/home/site/wwwroot/wwwroot
I couldn't get this to work by setting webRootPath
to the full path. But by using the following relative path, it seems to be working fine.
./site/wwwroot/wwwroot
Just putting this here to save someone a few hours of debugging and some letsencrypt rate limiting... /sigh
Thank you for the information.
- Would you mind submitting a PR to fix the docs?
- I suggest you work against the Let's Encrypt staging endpoint to avoid rate limits.
I had a difficult time getting this working for a .NET 5.0 app being deployed to Azure App Service in a Linux container. Posting what I had to do here for anyone else that might come across this.
-
For the web job set webRootPath to
./acme
. This ends up/home/acme
. Eg:letsencrypt:appname-webRootPath=./acme
The guide says to use./site/wwwroot/wwwroot
but bothContentRootPath
(./site/wwwroot) andWebRootPath
(./site/wwwroot/wwwroot) were ending up as read-only inside the container./home
seems visible and writable. -
I added this
IApplicationBuilder
extension based on Hammad Ahmad's blog:
private const string WellKnownFolder = ".well-known";
private const string WellKnownRequestPath = "/.well-known";
private const string WellKnownContentType = "text/plain";
/// <summary>
/// Adds ACME challenge static file support into an application's startup configuration.
/// </summary>
/// <param name="builder"><see cref="IApplicationBuilder"/> being configured.</param>
/// <param name="acmeRootPath">Root folder for ACME challenge files. Default value: <see cref="IWebHostEnvironment.WebRootPath"/>.</param>
/// <returns>Supplied <see cref="IApplicationBuilder"/> for chaining.</returns>
public static IApplicationBuilder UseAcmeChallengeStaticFiles(this IApplicationBuilder builder, string? acmeRootPath = null)
{
if (builder == null)
throw new ArgumentNullException(nameof(builder));
if (string.IsNullOrEmpty(acmeRootPath))
{
acmeRootPath = builder.ApplicationServices.GetRequiredService<IWebHostEnvironment>().WebRootPath;
}
string acmeChallengeWellKnownFolderPath = $"{acmeRootPath}{Path.DirectorySeparatorChar}{WellKnownFolder}";
if (!Directory.Exists(acmeChallengeWellKnownFolderPath))
Directory.CreateDirectory(acmeChallengeWellKnownFolderPath);
return builder
.UseStaticFiles(new StaticFileOptions
{
RequestPath = WellKnownRequestPath,
FileProvider = new PhysicalFileProvider(acmeChallengeWellKnownFolderPath),
ServeUnknownFileTypes = true,
DefaultContentType = WellKnownContentType
});
}
- Then register that in startup:
public void Configure(IApplicationBuilder app, IConfiguration config)
{
app.UseAcmeChallengeStaticFiles(config.GetValue<string?>("AcmeChallengeRootFolder", null));
app.UseStaticFiles();
}
- Hooked up to a config setting for convenience:
{
"AcmeChallengeRootFolder": "/home/acme",
}
Working for me!