.NET Core Linux Kestrel https configuration - linux

We are deploying our first .NET Core application on Linux (Ubuntu 18.04 LTS and Apache2).
We do not know the certificates of the servers where they will be deployed nor the ports where they will be deployed, since they are the client's and we do not have access, so we need to be able to enter them by configuration in the appsettings (Kestrel configuration).
In windows the api works without problems in both http and https, putting this configuration in the appsettings.json and reading it in the Startup.cs like this:
// kestrel configuration
services.Configure<KestrelServerOptions>(Configuration.GetSection("Kestrel"));
Our windows configuration of the appsettings.json is:
"AllowedHosts": "*.mydomain.es;*.mydomain-eu.com;test-win;test-linux;localhost;127.0.0.1;*.myActiveDirectoryDomain.ad",
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5009"
}
,"Https": {
"Url": "https://localhost:5010"
}
}
}
When deployed on Linux with the same configuration, the Kestrel service does not start. Kestrel service error:
sudo systemctl status kestrel-apieu.service
● kestrel-apieu.service -
Example ASP .NET Api running on Ubuntu 18.04 Loaded: loaded
(/etc/systemd/system/kestrel-apieu.service; enabled; vendor preset:
enabled) Active: activating (auto-restart) (Result: core-dump)
since Thu 2020-02-06 09:13:20 CET; 4s ago Process: 4449
ExecStart=/usr/bin/dotnet
/var/www/core/api/apieu/HHHHH.JJJJJJJJ.Api.UnitsEuApi.dll
(code=dumped, signal=ABRT) Main PID: 4449 (code=dumped, signal=ABRT)
Removing the https part works in http without any problems, like this:
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5009"
}
}
}
Kestrel service running:
sudo systemctl status kestrel-apieu.service
● kestrel-apieu.service -
Example ASP .NET Api running on Ubuntu 18.04 Loaded: loaded
(/etc/systemd/system/kestrel-apieu.service; enabled; vendor preset:
enabled) Active: active (running) since Thu 2020-02-06 09:16:19
CET; 2s ago Main PID: 5504 (dotnet)
Tasks: 17 (limit: 4660) CGroup: /system.slice/kestrel-apieu.service
└─5504 /usr/bin/dotnet /var/www/core/api/apieu/HHHHH.JJJJJJJJ.Api.UnitsEuApi.dll
When we set this configuration, to the server's self-signed certificates .crt the Kestrel service lifts but does not work on https.
Configuration appsetings:
"AllowedHosts": "*.mydomain.es;*.mydomain-eu.com;test-win;test-linux;localhost;127.0.0.1;*.myActiveDirectoryDomain.ad",
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5009"
}
,"Https": {
"Url": "https://localhost:5010", // we also tried: "https://*:5010"
"Certificate": {
"Path": "/etc/apache2/ssl/apache.crt",
"Password": "/etc/apache2/ssl/apache.key",
"AllowInvalid": true
}
}
}
http://localhost:5009/test work's perfectly, but https://localhost:5010/test send error:
Secure Connection Failed
An error occurred during a connection to localhost:5010.
PR_END_OF_FILE_ERROR
The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.
Please contact the website owners to inform them of this problem.
But the self-signed certificate does allow you to enter https://localhost without problems (once you trust the certificate).
We have also tried to convert the self-signed .crt certificate to .pfx (with OpenSSL -> convert crt to pfx certificate) and configure it this way:
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5009"
}
,"Https": {
"Url": "https://*:5010",
"Certificate": {
"Path": "/etc/apache2/ssl/apache.pfx",
"Password": "passwdExport"
,"AllowInvalid": true
}
}
}
}
But it also doesn't lift the service and it doesn't work on either http or https.
We've looked at all these help pages, among others:
.net core Kestrel server SSL issue
Certificate issue in Kestrel ssl JSON configuration using .net Core 3.1
Asp.Net Core 2.0 HTTP -> HTTPS on Kestrel
Will a self-signed certificate work behind an Apache reverse-proxy?
The problem seems to be that we're not properly configuring the Kestrel with the self-signed certificate. But we can't find our mistake. Can you help us?
In case you can give more information we opened another previous post, it was more generic because we did not know that the problem came from the Kestrel but we thought it was from the Apache2: deploy NET Core Linux HTTPS SSL

I use .net6 and reccomend you to try this :
"Kestrel": {
"EndPoints": {
"Https": {
"Url": "https://domain:port",
"Certificate": {
"Path": "path_to.pfx",
"Password": "password"
}
}
}
}
And in your Program.cs file enter this:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
#if RELEASE
webBuilder.UseKestrel();
#endif
webBuilder.UseStartup<Startup>();
});
It will help you!
Also useful links:
https://learn.microsoft.com/en-us/answers/questions/613333/loading-certificatepfx-with-password-in-linux-does.html
https://learn.microsoft.com/ru-ru/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-6.0

Related

How to disable App Service authentication for a path?

I enabled identity federation V2 for an App Service that hosts a single page app. This works fine but now I need to disable it again for routes that start with /.well-known/ because that's where I store files that don't require authentication, e.g. apple-app-site-associations.
In previous versions, I was able to upload an authorization.json file to my App Service to disable authentication for this path, but this no longer works?
{
"routes": [
{
"path_prefix": "/",
"policies": {
"unauthenticated_action": "RedirectToLoginPage"
}
},
{
"path_prefix": "/.well-known/",
"policies": {
"unauthenticated_action": "AllowAnonymous"
}
}
]
}
I'm still unsure why the old way of configuring path exclusions stopped working, but I figured out how to do it with V2 configuration.
First migrate to file-based configuration as documented here: https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-file-based#enabling-file-based-configuration
In short, copy all config from Microsoft.Web/sites/<siteName>/config/authsettingsV2 to a file in your wwwroot folder, e.g. wwwroot/auth.json. This file will be accessible over HTTP so remove secrets from configuration as documented. Set platform.configFilePath to auth.json and restart the app service.
Once you've confirmed that everything still works with file-based configuration, you can add path exclusions to the configuration file.
{
"platform": {
"enabled": true
},
"globalValidation": {
...
"excludedPaths": [
"/.well-known/apple-app-site-association",
"/.well-known/assetlinks.json"
]
},
...
}
Restart the app service one more time for changes to take effect.
If you're trying this 12/2022, it seems that "configFilePath" is not working for quite some time (evidence)
If you change directly on Azure Resource Explorer, it works.

How to set X-Content-Type-Options on Azure App Service Linux?

I have an Angular2 web app deployed on Azure App Service Linux. I ran OWASP ZAP to attack my website and it alerted about X-Content-Type-Options Header missing. I was looking for the httpd file in etc/ to set X-Content-Type-Options = 'nosniff' but I couldn't find it. I assumed that the web app is running on Apache.
Reference:
The Anti-MIME-Sniffing header X-Content-Type-Options was not set to 'nosniff'. This allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. Current (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing.
We solved the issue by having the two files ecosystem.config.js and serve.json be part of our deployed artifact.
ecosystem.config.js
// https://burkeknowswords.com/this-is-how-to-easily-deploy-a-static-site-to-azure-96c77f0301ff
// Use PM2 to serve files on Linux App Service
module.exports = {
apps: [
{
script: "npx serve -s"
}
]
};
serve.json
{
"headers": [
{
"source" : "**",
"headers" : [
{
"key" : "X-Content-Type-Options",
"value" : "nosniff"
},
// more headers

Is Blazor app with Open ID Connect supported by Azure App Service Containers?

Problem
We are getting the following error in the browser after deploying Blazor webassembly app as an App Service Container:
AuthenticationService.js:1 Mixed Content: The page at 'https://YYY.azurewebsites.net/authentication/login?returnUrl=https%3A%2F%2FYYY.azurewebsites.net%2Ffetchdata' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://YYY.azurewebsites.net/.well-known/openid-configuration'. This request has been blocked; the content must be served over HTTPS.
Wondering if docker deployment is supported in Blazor at this moment, if yes, how can we fix this?
Steps to re-pro:
1. In VS 2019 Professional preview Version 16.7.0 Preview 2.0: create Blazor app (standard "Blazor WebAssembly App" template) with Hosted option on and in-app authentication with Identity Server
2. Deploy linux docker container to Azure Web App for containers service (B1)
3. HTTPS Only setting is ON for the App Service
We are using the following simple docker file for that:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
WORKDIR /app
EXPOSE 80
COPY . .
ENTRYPOINT ["dotnet", "AppNameHere.Server.dll"]
Somehow OIDC JS library used by Blazor is not picking up the fact that we are runnig over HTTPS (although HTTP is used between the container instance and App service load balancer).
You should either :
Install an HTTPS certificate for your endpoint and run a full end-to-end HTTPS (Recommended)
To setup kestrel with a certificate on docker read this doc
Override the OIDC config used by your app :
Create a metadata.json file
{
"issuer": "http://YYY.azurewebsites.net",
"jwks_uri": "https://YYY.azurewebsites.net/.well-known/openid-configuration/jwks",
"authorization_endpoint": "https://YYY.azurewebsites.net/connect/authorize",
"token_endpoint": "https://YYY.azurewebsites.net/connect/token",
"userinfo_endpoint": "https://YYY.azurewebsites.net/connect/userinfo",
"end_session_endpoint": "https://YYY.azurewebsites.net/connect/endsession",
"check_session_iframe": "https://YYY.azurewebsites.net/connect/checksession"
}
"issuer": "http://YYY.azurewebsites.net" is an HTTP url not HTTPS
Configure the application to get metadata from your custom file
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddOidcAuthentication<RemoteAuthenticationState, RemoteUserAccount>(options =>
{
var providerOptions = options.ProviderOptions;
providerOptions.Authority = "https://YYY.azurewebsites.net";
providerOptions.MetadataUrl = "https://YYY.azurewebsites.net/metadata.json";
providerOptions.PostLogoutRedirectUri = "https://YYY.azurewebsites.net/authentication/logout-callback";
providerOptions.RedirectUri = "https://YYY.azurewebsites.net/login-callback";
});
await builder.Build().RunAsync();
}
}

Unable to start Kestrel. System.IO.IOException: Failed to bind to address http://127.0.0.1:5000: address already in use

I followed the steps from this URL to publish .NET core 2.1 web application code to Linux Centos 7 server.
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-2.2
I tried to run "sudo dotnet application_name.dll". I received this following error message. Am I missing something? I published code using Visual Studio 2017 on windows machine and copied code to Linux server.
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.IO.IOException: Failed to bind to address http://127.0.0.1:5000: address already in use. ---> Microsoft.AspNetCore.Connections.AddressInUseException: Address already in use ---> System.Net.Sockets.SocketException: Address already in use
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
Startup.cs config
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
}
launchSettings.json:
"applicationUrl": "https://localhost:5001;http://localhost:5000"
Restarting this service may fix the issue : Host Network Service on windows Services program
Goto Powershell in admin mode and write the following command:
netsh interface ipv4 show excludedportrange protocol=tcp
Check port exclusion ranges whether your port falls under this list; if yes then use the following commands:
net stop winnat
net start winnat
The issue should be resolved.
In my case, I was able to work around this by changing the port Kestrel was using. Here are two options that worked for me (pick one):
Add an "applicationUrl" setting to the launchSettings.json file (found under the Properties folder in VS2019). Using "https://localhost:5201" in the example below:
"profiles": {
"IIS Express": {
...
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"Host": {
...
}
},
"Your.App.Namespace.Api": {
...
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5201;http://localhost:5200"
}
}
Add a "UseUrls" fluent method invocation to the WebHostBuilder in Program.Main(). i.e. "http://localhost:5200/" in the example below:
using (var host = new WebHostBuilder()
.UseKestrel(o => o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30))
...
.UseStartup<Startup>()
.UseUrls("http://localhost:5200/")
After Windows 10 Update KB4074588, some ports are reserved by Windows and applications cannot bind to these ports. 50067 is in the blocked range.
You can use netsh interface ipv4 show excludedportrange protocol=tcp to list the reserved ranges.
excludedportrange list
ref Issue: https://superuser.com/questions/1486417/unable-to-start-kestrel-getting-an-attempt-was-made-to-access-a-socket-in-a-way
I just restart IIS then remove and create a website again and it's works fine!
If you are using Mac "Kestrel doesn't support HTTP/2 with TLS on macOS and older Windows versions such as Windows 7" please see https://learn.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-6.0#unable-to-start-aspnet-core-grpc-app-on-macos for more details. A quick fix (only DEV ) is to remove the HTTPS URL from applicationUrl in the launchsettings.json
...
"applicationUrl": "http://localhost:5126",
...
This issue is easily resolved by changing the Port number.
This works for me with Windows 10
Open CMD Prompt as Administrator and run:
net stop hns
net start hns
Killing processes by port, restarted my Visual Studio, but did not solve my problem.

How to setup a proxy using web sockets and angular CLI

I have a simple web app built using the angular CLI. I want it to communicate with a backend using web sockets. I have the backend already written and have tested with a simple index.html page that the server can send and receive on sockets.
In my angular-cli project I have setup a proxy config file to setup a proxy to the backend.
proxy.conf.json
{
"/sock": {
"target": "http://localhost:3000",
"changeOrigin": true,
"ws": true,
"logLevel": "debug"
}
}
Then start the server with the following.
ng serve --proxy-config proxy.conf.json
For now I have a service that simply attempts to open a socket and send a fixed string which I'm expecting to see logged by the backend.
import { Injectable } from '#angular/core';
import * as io from 'socket.io-client';
#Injectable()
export class ChatService {
private socket: any;
constructor() {
this.socket = io({ 'path': '/sock' });
this.socket.emit('chat message', 'Hello World from browser!');
}
}
Note: I've had several go's at this with and without the /sock part of the url.
I start both servers. Get no console errors in the browser. But in the angular CLI web pack server I get the following messages.
10% building modules 2/2 modules 0 active[HPM] Proxy created: /sock -> http://localhost:3000
[HPM] Subscribed to http-proxy events: [ 'error', 'close' ]
[HPM] GET /sockjs-node/530/z1z3teld/websocket -> http://localhost:3000
[HPM] Upgrading to WebSocket
[HPM] Error occurred while trying to proxy request /sockjs-node/530/z1z3teld/websocket from localhost:4200 to http://localhost:3000 (ECONNRESET) (https://nodejs.org/api/errors.html#errors_common_system_errors)
Are web sockets supported or have I made a silly mistake?
Thanks
I managed to figure it out with a bit of trial and error. I looked at the console for the basic index.html page that works within the backend project. This backend project is basically the chat server demo application on the socket.io website. I noticed that when it opens up the web socket the url looks like the following:
http://localhost:3000/socket.io/EIO=3&transport=websocket&sid=wTvdQTclHXJSUmAmAAAA
So back in the angular CLI project I modified my proxy config to include the /socket.io/ part plus also added a wildcard.
{
"/sock/*": {
"target": "http://localhost:3000/socket.io/",
"ws": true,
"logLevel": "debug"
}
}
Bingo! Now when the service is constructed it opens the socket and emits a message which I can see logged in the backend.

Resources