I'm trying to deploy my ASP.NET web Application (with .NET 5.0 and ASP.NET MVC) to an debian 10 server with NGINX. I followed Microsoft's tutorial and after numerous testings can't find something that will work.
My current NGINX configuration:
server {
listen 80 default_server;
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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Querying localhost with curl -v localhost:5000
gives me HTTP 307 redirect.
Querying curl -v --insecure https://localhost:5001
returns the actual content of my webpage, so kestrel is running fine.
My Startup.cs looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SmapOneUpdater.Frontend.Model.Sortenumbuchung.Data;
namespace SmapOneUpdater.Frontend
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddDbContext<SortenumbuchungContext>(options =>
options.UseSqlite(Configuration.GetConnectionString("SortenumbuchungContext")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Overview}/{action=Index}/{id?}");
});
}
}
}
Connecting to the ip-address of my server returns "This site can't be reached x.x.x.x unexpectedly closed the connection" after some loading. and it automatically changes the url to x.x.x.x:5001 which should be wrong since I'm not trying to directly access port 5001, or am I?
Nevertheless, I'm pretty sure it's not my NGINX configuration, since my browser somehow gets the information that he needs port 5001 AND because if I change the proxy_pass to https://www.google.com it works and redirects me to google
EDIT: SOLVED
The problem was inside my Properties/launchSettings.json. I had the applicationUrl set to http://localhost:5000;https://localhost:5001
It seems like ASP then only allows connections which call localhost (or 127.0.0.1). Since I couldn't reach kestrel from the server when calling it by ip. After that, I had to change nginx to forward the servers IP address, so the accessing client won't try to access localhost:5001 but the servers IP address with port 5001.
I'm setting the urls on the runtime environment now with the --urls
command.
So my call looks like this:
dotnet /path/to/application/dll --urls "http://*:5000;https://*:5001"
As for NGINX, after reading TheRoadrunner's answer, I changed the config to redirect HTTP requests to HTTPS. Following the tutorial from NGINX I also created a self signed ssl certificate with:
openssl req -x509 -subj /CN=localhost -days 365 -set_serial 2 -newkey rsa:4096 -keyout /etc/nginx/cert.key -nodes -out /etc/nginx/cert.pem
My working NGINX config looks like this:
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/cert.pem;
ssl_certificate_key /etc/nginx/cert.key;
location / {
proxy_pass https://192.168.4.156:5001;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Interestengly enough, with this working configuration the port in my url bar in the browser does not show, that it's accessing port 5001
How did I found out
Maybe this will be interesting for some readers. I figured the issue out, by creating a local debian instance with virtualbox. I configured it just as my real server. But I installed GNOME, because I wanted to make sure, whether I can actually see the page with a local browser or not (In retrospective, I probably could've achieved this with curl).
It seemed interesting to me, since the redirect worked on the vm. entering localhost:80 in firefox redirected me to localhost:5001 and I saw the page. After some testing I tried it with the IP of the VM and had the exact same issue as on the other machines. So I tried to change the application URL.
I think this is interesting, since it seems so obvious, but was never mentioned in the documentation. As a proxy/nginx/webdev newbie I was not exactly sure how all of this works. Especially since the documentation mentions to redirect HTTPS to http://localhost:5000