ASP.NET web development framework

Common Core

Assigning Ports

A simple Kestrel application with default settings always binds to port 5000 for HTTP and port 5001 for HTTPS. Because the ASP.NET Core has no TCP port sharing, as in the original .NET framework, the port is now busy and not available for other processes. Also, the .NET runtime does not implement a mechanism to increment TCP ports automatically when other applications start on the same machine. Therefore, you have to keep track of the port assignments yourself and, if possible, store them in the configuration file of your Visual Studio project so that you don't have to rebuild the application every time you make changes. This characteristic of Kestrel is not Linux-specific, but also applies to Windows.

In professional use, you will of course run several applications on the same server, and in the best case, they should all be accessible on the standard HTTPS port 443. Additional security features such as pre-authentication or content caching, which Kestrel lacks, are also essential in enterprise scenarios. This is where true web servers like Apache, Nginx, or (on Windows) IIS come in, which you can add to Kestrel to gain the missing features.

In this way, the Kestrel instances can be operated as a kind of mixture of application pool and web worker. The upstream web server handles the requests and forwards them to the correct Kestrel instance on the respective port. This mode of operation is known as "reverse proxy." TLS processing can also be offloaded to the full-fledged server in this way, which is especially valuable if the TLS certificates to be used change frequently or if you want to deploy the application to a large number of machines. In this case, you only need to maintain the certificate for all application instances of a web server on the frontend server. However, communication between the frontend web server and Kestrel instances takes place without encryption, which is normally not a good choice.

Hosting Models for ASP.NET

The origin of ASP.NET in the IIS universe is illustrated by the two models that IIS provides for hosting ASP.NET core applications:

  • The out-of-process hosting model works exactly as outlined above and is very well suited for applications that you want to run on Linux and IIS. Here, IIS simply routes client requests to the Kestrel application, with no need to customize the application itself, because IIS integration is configured in the release properties.
  • The in-process hosting model involves running the ASP.NET Core applications in an IIS (Application Pool) worker process. The Windows Process Activation Service (WAS) is responsible for control. Here, you have to adapt the source code of the application to be hosted on, instead of downstream of, IIS. To do this, you set additional configuration options in the Host Builder that have no function outside of IIS.

Regardless of the hosting model, Core middleware and the ASP.NET Core module are required on the affected IIS. The necessary adjustments to the application itself and to the configuration of the IIS instance are described in detail in Microsoft Docs [4]. Visual Studio also offers the possibility of testing the development states of your ASP.NET Core application in IIS (Express).

If a special module in IIS handles the entire integration of ASP.NET Core into the web server, the frontend web server on Linux only plays the role of a reverse proxy. For the reverse proxy to handle requests correctly, additional headers (e.g., X-Forwarded-For and X-Forwarded-Proto) must be interpreted by the Kestrel application. You also need this customization if the application is delivered purely by Kestrel but is deployed with a load balancer. To do this, integrate the Microsoft.AspNetCore.HttpOverrides middleware into your project. Then, you can reference this namespace in your Startup.cs file and add the following call to the Configure() method:

app.UseForwardedHeaders(new ForwardedHeadersOptions
  ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto

In this article, I assume that the reverse proxy is running on the same system as the Kestrel application and is therefore trusted implicitly. Otherwise, the addresses of the trusted proxies must be added to the application.

Using an Apache Frontend

If your Kestrel application is installed on a Linux server, you can add an Apache frontend by installing the appropriate packages:

sudo dnf install httpd mod_ssl

I used CentOS 8 as an example; other Linux distributions may have a different package manager. If no SSL is required, an additional file named /etc/httpd/conf.d/netcoreapp01.conf with the content shown in Listing 3 is sufficient.

Listing 3


<VirtualHost *:*>
  RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
<VirtualHost *:80>
  ProxyPreserveHost On
  ProxyPass /
  ProxyPassReverse /
  ServerAlias *
  ErrorLog ${APACHE_LOG_DIR}netcoreapp01-error.log
  CustomLog ${APACHE_LOG_DIR}netcoreapp01-access.log common

After subsequently restarting the HTTPD service, the application is available on port 80 tunneled through Apache. The SSL configuration follows a similar approach and is described in the official Apache documentation, along with countless books and Internet articles. The necessary adjustments to the ASP.NET Core application are documented online [5], where you will also find notes on the above-mentioned middleware packages and its integration into your source code.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.