When developing and deploying web applications using ASP.NET Core, the default web server used is Kestrel — a high-performance, cross-platform web server built by Microsoft. While Kestrel is powerful and fast, it is often not recommended to expose it directly to the internet in production. Instead, it’s commonly used behind a reverse proxy server like Nginx (Linux) or IIS (Windows).
But why is that necessary? In this article, we’ll explore the reasons behind this practice, how reverse proxies work, and how they improve the security, scalability, and reliability of your ASP.NET Core applications.
What is Kestrel Server?
Kestrel is the default web server used by ASP.NET Core applications. It is a cross-platform, high-performance, and lightweight HTTP server built on top of libuv (in earlier versions) and now uses managed sockets in newer .NET versions. Kestrel is responsible for handling HTTP requests and forwarding them to the ASP.NET Core middleware pipeline for processing.
Kestrel supports key features like HTTPS, HTTP/2, and WebSockets, and can be run in two ways:
- Standalone (directly exposed to the internet, suitable for internal services or development)
- Behind a reverse proxy like Nginx (Linux) or IIS (Windows), which is recommended for production environments for better security, SSL termination, and static content handling.
Thanks to its asynchronous architecture, Kestrel can handle thousands of concurrent connections efficiently, making it ideal for modern web applications and APIs.
However, while Kestrel is excellent for handling application-level logic, it lacks some advanced features that full-fledged web servers like Nginx or IIS provide, particularly in edge-facing, production-grade deployments.
What is a Reverse Proxy?
A reverse proxy is a server that sits between client devices and backend servers, forwarding incoming requests to one or more internal servers and then returning the server's response to the client.
In simple terms, the client interacts with the reverse proxy, not directly with your application server.
How It Works:
Client → Reverse Proxy (e.g., Nginx/IIS) → Backend Server (e.g., Kestrel)
1. The request goes to the reverse proxy.
2. The proxy server forwards the request to the actual application server.
3. The application processes it and returns the result to the proxy, which then delivers it to the user.
Benefits of Using a Reverse Proxy:
- Improved security (hides your backend server)
- SSL termination (handles HTTPS at the edge)
- Load balancing (distributes traffic across multiple servers)
- Caching and compression for static files
- Request filtering and rate limiting
In production, Kestrel (the ASP.NET Core server) is often placed behind a reverse proxy like:
- Nginx (on Linux)
- IIS (on Windows)
This setup enhances security, performance, and scalability while letting Kestrel focus on running your app logic.
This architecture adds a layer of control and protection between the external internet and your application logic.
Why Use Kestrel Behind Nginx or IIS?
In production environments, Kestrel is typically used behind a reverse proxy like Nginx (Linux) or IIS (Windows) because, while Kestrel is a fast and lightweight web server, it lacks certain edge-facing features needed for robust, secure deployments.
1. Security
Exposing Kestrel directly to the internet can be risky. It does not have built-in protections like:
- Request filtering
- IP blocking
- Rate limiting
- Header manipulation
Using a reverse proxy like Nginx or IIS allows you to enforce security policies before requests reach your application.
Example: You can use Nginx to block access to certain IP ranges or enforce HTTPS:
server { listen 443 ssl; server_name myapp.com; ssl_certificate /etc/ssl/certs/myapp.crt; ssl_certificate_key /etc/ssl/private/myapp.key; location / { proxy_pass http://localhost:5000; } }
- Tells Nginx to listen on port 443, the default port for HTTPS.
- The ssl directive enables SSL/TLS support on this port.
server_name myapp.com;
- Specifies the domain name (or hostname) this configuration applies to.
- When users browse to https://myapp.com, Nginx knows to use this block.
ssl_certificate /etc/ssl/certs/myapp.crt;
- Points to the SSL certificate file (public key) for your domain.
- This is what browsers use to verify that the site is secure and trusted.
ssl_certificate_key /etc/ssl/private/myapp.key;
- Points to the private key for the certificate.
- It is used by the server to establish secure (encrypted) connections.
2. TLS Termination (HTTPS Support)
Handling SSL/TLS certificates and encryption can be offloaded to the reverse proxy, reducing overhead on your app.
- Kestrel supports HTTPS, but managing certificates and security policies is easier with IIS or Nginx.
- This also helps when you want to use Let's Encrypt with automatic renewal via Nginx.
3. Static File Handling
Web servers like Nginx and IIS are optimized for serving static assets (CSS, JS, images) quickly. Kestrel can serve static files, but it's not as efficient.
Offloading static content to a reverse proxy reduces load on your app and improves performance.
4. Load Balancing and Scalability
Reverse proxies can distribute traffic to multiple instances of your app, improving scalability and availability.
Example: You can set up Nginx to round-robin requests across multiple Kestrel instances:
upstream myappcluster { server 127.0.0.1:5000; server 127.0.0.1:5001; } server { listen 80; location / { proxy_pass http://myappcluster; } }
5. Advanced Features in IIS
If you're deploying on Windows, using IIS as a reverse proxy enables enterprise-grade features such as:
- Windows Authentication (NTLM/Kerberos)
- Centralized logging
- URL rewriting
- Application pool isolation
In such scenarios, IIS handles incoming requests and forwards them to the ASP.NET Core application running on Kestrel, using the ASP.NET Core Module (ANCM).
6. Better Error Handling and Logging
Reverse proxies can handle and log requests that never reach your application, such as malformed or malicious ones. They can also return custom error pages for 404s or 500s.
Example: ASP.NET Core Behind Nginx on Linux.
You have an ASP.NET Core application running on Kestrel (e.g., localhost:5000), and you want to serve it via Nginx with HTTPS enabled at https://myapp.com.
Step-by-Step Guide.
Step 1: Publish Your ASP.NET Core App
On your development machine:
dotnet publish -c Release -o /var/www/myapp
Step 2: Install .NET Runtime on the Server
On Ubuntu:
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb sudo apt-get update sudo apt-get install -y aspnetcore-runtime-7.0
Step 3: Create a Systemd Service for Kestrel
Create a file: /etc/systemd/system/myapp.service
[Unit] Description=My ASP.NET Core App After=network.target [Service] WorkingDirectory=/var/www/myapp ExecStart=/usr/bin/dotnet /var/www/myapp/MyApp.dll Restart=always RestartSec=10 SyslogIdentifier=myapp User=www-data Environment=ASPNETCORE_ENVIRONMENT=Production [Install] WantedBy=multi-user.target
sudo systemctl daemon-reexec sudo systemctl start myapp sudo systemctl enable myapp
Step 4: Install Nginx and SSL
sudo apt update sudo apt install nginx
sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d myapp.com
Step 5: Configure Nginx as a Reverse Proxy
Edit or create a file:
/etc/nginx/sites-available/myapp
server { listen 80; server_name myapp.com; location / { proxy_pass http://localhost:5000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx
server { listen 80; server_name myapp.com; return 301 https://$host$request_uri; }
Final Flow.
Client (HTTPS)
↓
Nginx (port 443, SSL)
↓
Kestrel (localhost:5000, HTTP)
↓
ASP.NET Core App
Summary
Kestrel is a fast and reliable web server designed for ASP.NET Core, but it lacks certain edge-facing capabilities required in real-world production deployments. That’s why it’s commonly used behind a reverse proxy like Nginx (Linux) or IIS (Windows). These proxy servers handle critical tasks like HTTPS, security filtering, load balancing, and static content delivery, allowing Kestrel to focus purely on application logic.
Using this layered architecture ensures security, performance, scalability, and maintainability of ASP.NET Core applications in production.
No comments:
Post a Comment