A reverse proxy scenario exists when there are multiple apps that share the same IP and port running on a single server. Kestrel doesn’t support this scenario because Kestrel doesn’t support sharing the same IP and port among multiple processes. When Kestrel is configured to listen on a port, Kestrel handles all of the traffic for that port regardless of requests’ host header. A reverse proxy that can share ports has the ability to forward requests to Kestrel on a unique IP and port. When Kestrel is configured to listen on a port, Kestrel handles all of the traffic for that port regardless of requests’ host header. A reverse proxy that can share ports has the ability to forward requests to Kestrel on a unique IP and port.

Even if a reverse proxy server isn’t required, using a reverse proxy server might be a good choice:

  • It can limit the exposed public surface area of the apps that it hosts.
  • It provides an additional layer of configuration and defense.
  • It might integrate better with existing infrastructure.
  • It simplifies load balancing and SSL configuration. Only the reverse proxy server requires an SSL certificate, and that server can communicate with your app servers on the internal network using plain HTTP.


1. Register the Microsoft Product key as trusted.

curl | gpg --dearmor > microsoft.gpg

sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg

2. Set up the desired version host package feed.

sudo sh -c 'echo "deb [arch=amd64] xenial main" > /etc/apt/sources.list.d/dotnetdev.list'

microsoft-ubuntu-xenial-prod > ubuntu 16.04.5 LTS
microsoft-ubuntu-bionic-prod > ubuntu 18.04 LTS
microsoft-ubuntu-cosmic-prod > ubuntu 18.10 LTS

3. Update software package index.

sudo apt update

4. Install .NET Core.

sudo apt install dotnet-sdk-2.2
dotnet-sdk-2.0.0  dotnet-sdk-2.1.102 dotnet-sdk-2.1.202
dotnet-sdk-2.0.0-preview2-006497 dotnet-sdk-2.1.103 dotnet-sdk-2.1.3
dotnet-sdk-2.0.2 dotnet-sdk-2.1.104 dotnet-sdk-2.1.300-preview1-008174
dotnet-sdk-2.0.3 dotnet-sdk-2.1.105 dotnet-sdk-2.1.300-preview2-008533
dotnet-sdk-2.1  dotnet-sdk-2.1.2 dotnet-sdk-2.1.300-rc1-008673
dotnet-sdk-2.1.100 dotnet-sdk-2.1.200 dotnet-sdk-2.1.4
dotnet-sdk-2.1.101 dotnet-sdk-2.1.201 dotnet-sdk-2.2


Step 1

Although the ASP.NET Core web app running on web server Kestrel works locally, it can not be accessed externally at this time. This section provides the instruction to install Web server nginx and configure nginx as reverse proxy server to forward request to Kestrel so the web app can be accessed externally through http port 80.

  • sudo apt-get install nginx
  • sudo nano /etc/nginx/sites-available/default
server {
    listen 80;
    listen [::]:80;

    #root /var/www/html;
    # Add index.php to the list if you are using PHP
    #index index.html index.htm;

    access_log /var/log/nginx/access.log combined;
    error_log /var/log/nginx/error.log error;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        # try_files $uri $uri/ =404;

        proxy_pass http://localhost:7001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;        
  • sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

to activate the host by creating a symbolic link between the sites-available directory and the sites-enabled directory. In apache, the command to accomplish this is “a2ensite”. Nginx does not have an equivalent shortcut, but it’s an easy command nonetheless.

  • sudo service nginx start
  • sudo nginx -t      (to verify the syntax of the configuration file is correct)
  • sudo nginx -s reload       (to reload nginx service to pick up only the changes without restarting all the web server system  whenever you change the /etc/nginx/sites-available/default)

Step 2

  • dotnet new mvc -n coretest -o ~/coretest
  • sudo nano ~/coretest/Program.cs
public static void Main(string[] args)

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

        .UseConfiguration(new ConfigurationBuilder()

http://localhost:7001 -> accept only local connections

http://*:7001 -> accept remote connections -> accept remote connections

  • dotnet publish -c Release -o ~/coretest/publish

Step 3

  • sudo nano /etc/systemd/system/kestrel-coretest.service
 Description=Example ASP -NET Web Application running on Ubuntu 16.04
 ExecStart=/usr/bin/dotnet /home/kaya/coretest/publish/coretest.dll
  • sudo systemctl enable kestrel-coretest.service
  • sudo systemctl start kestrel-coretest.service

Step 4)

Instead of step 3 we can run the command line to start listening the application.

To get this command line ->  in program.cs use .UseConfiguration

dotnet run –-urls “http://localhost:7001

Step 5

  • sudo nano /etc/hosts 
  • sudo systemd-resolve –flush-caches


Kestrel web server implementation in ASP.NET Core

1 Comment

geek · March 21, 2019 at 9:05 pm

I found this web site very useful. I appreciate you putting effort into practice. Good luck..

Leave a Reply

Your email address will not be published. Required fields are marked *