Letsencrypt acme-challenge on wordpress or asp.net mvc Letsencrypt acme-challenge on wordpress or asp.net mvc wordpress wordpress

Letsencrypt acme-challenge on wordpress or asp.net mvc


For ASP.Net MVC or Web Forms, with certain Routing configs, you'll end up treating this URL as something for the Routing Engine to hand off to the MVC/Forms Handler, not a static file return. The result will be a 404 or a 503. The solution is surprisingly very simple:

If you haven't already, place the Challenge file:

  1. Create the necessary dirs - .well-known is tricky mostly because Microsoft is lazy, but you can either do it from cmdline or create the folder as .well-known. and Windows Explorer will notice the workaround and remove the trailing period for you.
  2. Inside \.well-known\acme-challenge place the challenge file with the proper name and contents. You can go about this part any way you like; I happen to use Git Bash like echo "oo0acontents" > abcdefilename

Then make a Web.Config file in the acme-challenge dir with these contents:

<?xml version = "1.0" encoding="UTF-8"?><configuration>    <system.webServer>        <staticContent>            <clear />            <mimeMap fileExtension = ".*" mimeType="text/json" />        </staticContent>        <handlers>            <clear />            <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule"             resourceType="Either" requireAccess="Read" />          </handlers>    </system.webServer></configuration>

Source: https://github.com/Lone-Coder/letsencrypt-win-simple/issues/37

Done. The file will start returning instead of 404/503 allowing the Challenge to complete - you can now Submit and get your domain validated.

Aside: The above code snippet sets the content-type to json, a historical requirement that is no longer relevant to letsencrypt. The current requirement is there is no requirement - you can send a content-type of pantsless/elephants and it'll still work.

More for Asp.Net

I like to redirect all HTTP requests back to HTTPS to ensure users end up on a secure connection even if they didn't know to ask. There are a lot of easy ways to do that, until you're using LetsEncrypt - because you're going to break requests for .well-known. You can setup a static method in a class, like this:

public static class HttpsHelper{    public static bool AppLevelUseHttps =#if DEBUG        false;#else        true;#endif    public static bool Application_BeginRequest(HttpRequest Request, HttpResponse Response)    {        if (!AppLevelUseHttps)            return false;        switch (Request.Url.Scheme)        {            case "https":                return false;#if !DEBUG            case "http":                var reqUrl = Request.Url;                var pathAndQuery = reqUrl.PathAndQuery;                // Let's Encrypt exception                if (pathAndQuery.StartsWith("/.well-known"))                    return false;                // http://stackoverflow.com/a/21226409/176877                var url = "https://" + reqUrl.Host + pathAndQuery;                Response.Redirect(url, true);                return true;#endif        }        return false;    }}

Now that can do a great job of redirecting to HTTPS except when LetsEncrypt comes knocking. Tie it in, in Global.asax.cs:

    protected void Application_BeginRequest(object sender, EventArgs ev)    {        HttpsHelper.Application_BeginRequest(Request, Response);    }

Notice that the bool returned is discarded here. You can use it if you like to decide whether to end the request/response immediately, true meaning, end it.

Finally, if you like, you can use the AppLevelUseHttps variable to turn off this behavior if need-be, for example to test if things are working without HTTPS. For example, you can have it set to the value of a Web.Config variable.