Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor with SSL on Ubuntu and Certbot

Here's my question: How do I get two simultaneous instances of Kestrel (behind Apache on the same domain) to bind to their respective SSL ports using the certificate produced by Certbot (Let's Encrypt). Do I really need to bind all the endpoints in an app as suggested by several articles that I have found?

Here's the background:

I have a domain with three dotnet apps behind an Apache server on Ubuntu 18. I have the apps working in my development environment which is Visual Studio 19 on Windows 10.

The apps are: MVC main site app which is a essentially a blog, a Blazor game and an API that controls the game. The API is also used by the main site to co-ordinate games between players.

Both the MVC and the Blazor app use Identity Framework and access the same users database. Apache redirects requests to the root to the MVC app and anything preceded by /blazor to the blazor app. So if a user logs into the main app the browser cookie should allow that user to continue to the game without having to login again.

I have learned that Blazor requires SSL for its authentication and in my DEV environment the apps are bound to ssl ports simply using the UseUrls call. They all work fine, however...

The problem is with deployment.

Executing the Blazor app on the server results in: Unable to configure HTTPS endpoint. Needless to say, altering the UseUrls call not to use SSL means that authentication fails.

Now, my server uses Certbot and can provide a secure connection to Apache and the MVC frontend works ok (the app itself is not https).

I've been researching SSL and found many articles on setting up SSL with dotnet. None seem to talk about the reverse proxy situation. None of them seem to talk about multiple apps within a domain. And in the case of Let's Encript suggest the apps should get and renew the cert themselves. This last option seems it would be a problem for challenges if one of the apps is only available from a specific endpoint. And wouldn't different certs mean that the login detail would get lost between the apps?

I want to specify the Certbot cert and get Kestrel to bind to the port specified on both front end apps.

Can anyone suggest the best way forward or point me to an article that might help?

like image 704
Kelvintronic Avatar asked Nov 15 '25 23:11

Kelvintronic


1 Answers

Ok. Got it sorted.

The first thing that needs to be done is to combine fullchain.pem and privkey.pem that are found in /etc/letsencrypt/live/domain/ into a .pfx file that is required by Kestrel:

sudo openssl pkcs12 -export -out https-le.pfx -inkey live/domain/privkey.pem -in live/domain/fullchain.pem

This will prompt for a password. This will be needed to allow Kestrel to access the file. And, speaking of access, the file needs to have appropriate file permissions. I copied the file to /usr/share/ca-certificates/dotnet/ then changed the file permissions:

sudo chmod 644 https-le.pfx

Below this the code I used in the ConfigureServices() method in Startup.cs. I chose to configure Kestrel in this location to easily gain access to the environment variable and appsettings.json.

             byte[] localhost = { 127, 0, 0, 1 };
             IPAddress address = new IPAddress(localhost);
             options.Listen(address, Int32.Parse(Configuration["GnomePorts:Https"]), listenOptions =>
             {
                 if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") != "Development")
                     listenOptions.UseHttps(Configuration["SSL_Cert:Path"],
                                             Configuration["SSL_Cert:Password"]);
                 else
                     listenOptions.UseHttps();
             });

Next, the certificate should be trusted locally. I took the fullchain.pem file and copied it to /usr/share/ca-certificates/dotnet/http-le.crt (the file types are interchangable) and changed its permissions also:

sudo chmod 644 https-le.crt

Then update the trusted certs like this:

sudo dpkg-reconfigure ca-certificates

This will allow you to choose which certs are added to the trusted certs bundle file.

Next, to allow Apache to forward to SSL connections the SSLProxyEngine should be set to on and point SSLCACertificateFile to the bundle file:

SSLProxyEngine on
SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt
    ProxyPass /gnomes https://127.0.0.1:5003/gnomes
    ProxyPassReverse /gnomes https://127.0.0.1:5003/gnomes

    ProxyPass / https://127.0.0.1:5001/
    ProxyPassReverse / https://127.0.0.1:5001/

Note this is done in the virtual host for port 443 and SSLEngine is already set to on by an include added by certbot.

After all this is done, the applications will happily bind to SSL and Apache will redirect successfully.

If you try this, don't forget that Let's Encrypt certs expire after 90 days so you might consider scheduling a script to update the files when the main cert is updated.

Further to this:

In my question I wrote: Both the MVC and the Blazor app use Identity Framework and access the same users database. Apache redirects requests to the root to the MVC app and anything preceded by /blazor to the blazor app. So if a user logs into the main app the browser cookie should allow that user to continue to the game without having to login again.

I have discovered that further configuration of both of the apps is required to get this functionality.

Both apps must have access to a shared keyfile for the authentication cookie and the cookie needs to have a common name. Add the following code to Startup.cs in both applications:

    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo("{keyfilepath}"))
        .SetApplicationName("CommonAppName");
    }

    services.ConfigureApplicationCookie(options => {
        options.Cookie.Name = ".AspNet.SharedCookie";
    });

Note this is for dotnet core apps only.

like image 200
Kelvintronic Avatar answered Nov 17 '25 13:11

Kelvintronic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!