Laden...

ASP.NET Core mit Nginx Reverse Proxy - Auflösen des Hostnamens

Erstellt von fluxy vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.627 Views
F
fluxy Themenstarter:in
183 Beiträge seit 2009
vor 5 Jahren
ASP.NET Core mit Nginx Reverse Proxy - Auflösen des Hostnamens

Hallo zusammen,

für die Frage werdet ihr mich auslachen, aber ich bekomme es einfach nicht hin und hoffe auf eure Hilfe. Ich frage mich gerade: Wie wird in Asp.net core eigentlich der Hostname aufgelöst? Hintergrund ist folgendes:

Ich habe mehrere Docker container (API's und eine Web UI) und möchte jetzt die container auf konkrete URL's mappen. Der direkte Zugriff über Ports funktioniert. Also:

container1 => localhost:5000 => localhost/webui
container2 => localhost:5001 => localhost/api/service1
container2 => localhost:5002 => localhost/api/service2

Die Web UI selber kann auch aufgelöst werden, aber da über den Reverse Proxy die URL's umgebogen werden, können die restlichen Resourcen (CSS, JS, Medien, etc.) nicht mehr geladen werden. Dazu einmal meine nginx.config:


http
{
	
	server {
		listen       80;
		server_name 192.168.7.113;
    
		location /webui/ {  
			proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Scheme $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header Referer $http_referer;

			
			proxy_pass http://container1/;
			
			
		}
    }
}

Ich bitte zu entschuldigen, dass noch kein HTTPS da ist. Die im Servernamen eingetragene IP ist die externe IP meines Rechners in meinem Netzwerk. Ich wollte nicht localhost nehmen, um zu sehen, welche URL genommen wird (auf dem Webserver gibt es ja auch ein anderes localhost)

Wenn ich jetzt einen Request starte auf http://192.168.7.113/webui wird dieser Request folgerichtig umgeleitet auf http://container1. Soweit funktioniert das auch. Allerdings wird von der Webseite (1:1 Visual Studio Template) unter anderem versucht die bootstrap.css zu laden:


<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />

Dieser Aufruf endet in http://localhost/lib/bootstrap/dist/css/bootstrap.css . Auf dem Server zweifelslos richtig, allerdings wäre die richtige Url http://192.168.7.113/webui/lib/bootstrap/dist/css/bootstrap.css, denn auch der Request muss über den Proxy Server gerootet werden.

Wie ihr seht, habe ich bereits bestimmte Header mitgeschickt, die meinen Informationen nach bnötigt werden, damit .net den Hostnamen richtig auflösen kann. Jedoch funktioniert das nicht. Ich habe zwei Middlewares gefunden, die man wohl einbinden soll, damit der Hostname richtig aufgelöst wird, die habe ich eingebunden:


		
			services.Configure<ForwardedHeadersOptions>(options =>
			{
				options.ForwardedHeaders =
					ForwardedHeaders.All;
			});
		

und


		
			app.UseForwardedHeaders(new ForwardedHeadersOptions()
			{
				ForwardedHeaders = ForwardedHeaders.All
			});

Aber irgendwie scheint noch etwas zu fehlen. Ich habe mir auch nie über die Hostauflösung gedanken gemacht. Könnte jemand meine Wissenslücke schließen?

Viele Grüße,
fluxy

16.835 Beiträge seit 2008
vor 5 Jahren

Das Mapping ist nicht Aufgabe Deiner Anwendung oder Deiner Container.
Diese werden prinzipiell nur über die IP angesprochen.

Namen werden zB. in einem Egde Router / Load Balancer verwaltet; zB. Traefik oder eben einem Orchestrator wie Docker Swam oder Kubernetes.
Ansonsten wären Szenarien wie eben Load Balancing gar nicht möglich.

Prinzipiell kannst Du bei einem statischen Reverse Proxy wie NGINX ebenfalls so arbeiten.
Kenne dazu folgendes Beispiel: https://github.com/embarced/micro-moves

PS: Visual Studio Templates - auch im Falle von Docker - sind Basis-Beispiele.
Nicht unbedingt eine Basis für Real World Szenarien.

F
fluxy Themenstarter:in
183 Beiträge seit 2009
vor 5 Jahren

Sicher. Die Container haben damit nichts zu tun. Ich habe sie hier auch nur genannt, damit ihr wisst, woher die hostnamen kommen. Bei der Anwendung bin ich mir nicht ganz so sicher - scheinbar (siehe code beispiele) muss man der Anwendung schon beibringen, bestimmte Header zu akzeptieren.

In dem Beispiel wird nur ein proxy_pass gemacht, das mache ich ja genauso. Also wo ist der Unterschied? Ich habe das Beispiel jetzt nicht ausprobiert (könnte ich auch nicht), aber ich gehe mal davon aus, dass es funktioniert - nur bei mir eben nicht.



        location /games/ {
             proxy_pass http://games:8080/;
        }


Meist Du also, dass der Fehler allein im NGINX-Server zu suchen ist?

Viele Grüße,
Fluxy

16.835 Beiträge seit 2008
vor 5 Jahren

Die Forward-Headers sind prinzipiell keine Pflicht; einige sind auch per default aktiv - aber sehr restriktiv.

Sie werden nur benötigt, wenn Du gewisse Dinge brauchst, die der Reverse Proxy verarbeitetet (zB HTTPS wegen Policies, Client Location, Request Host wegen Fullname URLs...) bzw. nicht an die Container von Haus aus weiter gibt.

Ich sehe in Deinem Szenario nirgends den sinnvollen Einsatz von Headern; Du brauchst ja prinzipiell im Container nirgends den Hostname.
Denn für das Routing sind diese ja nicht relevant. Das Routing ist Aufgabe von NGINX.

F
fluxy Themenstarter:in
183 Beiträge seit 2009
vor 5 Jahren

Ich sehe in Deinem Szenario nirgends den sinnvollen Einsatz von Headern; Du brauchst ja prinzipiell im Container nirgends den Hostname.
Denn für das Routing sind diese ja nicht relevant. Das Routing ist Aufgabe von NGINX.

Okay, dazu noch eine Frage zu meiner Config. Ich habe ja nur eine Location für /webui/ bedeutet:

http://192.168.7.113/webui/* -> http://containername/*

http://192.168.7.113 -> keine regel vorhanden

Der Request zur Web-App wird ja richtig geroutet. Nur Links im HTML-Dokument werden nicht richtig aufgelöst. Im übertragenen HTML-Code steht beispielsweise


<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.css" />

Dieser wird zu http://localhost//lib/bootstrap/dist/css/bootstrap.css was ja falsch ist. Dazu die Fragen
1.Wie funktioniert die auflösung der virtuellen Pfade generell? Woher kommt der Server localhost, ud nwer macht das? 1.Warum wird mein Pfad dann nicht zurück übersetzt, bzw. welche Möglichkeiten habe ich, das zu debuggen?

Ich möchte nicht ausschließen, dass das ganze ein konzeptionelles Problem mit meinem Routing ist. Wie würdet ihr weiter vorgehen?

Viele Grüße

16.835 Beiträge seit 2008
vor 5 Jahren

Meiner Ansicht nach vermischt Du hier ganz arg vieles, allen voran wie HTML und Taghelper in ASP.NET funktioniert.

<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.css" />
heisst: "nimm den aktuellen Host aus der Adressleiste, und kleb das href ran".

Das heisst, wenn Deine Adressleiste "localhost" ist, dann wird raus
localhost/lib/bootstrap/dist/css/bootstrap.css

Ist in Deiner Adressleiste eben http://192.168.7.113 dann wird draus beim Laden
http://192.168.7.113/lib/bootstrap/dist/css/bootstrap.css

ASP.NET Core ist weder in der Aufgabe noch in der Kenntnis Deine Content-Href-Verweise auf einen anderen Subfolder zu schieben.
Mal die Grundlagen vom Routing anschauen 😉

Das heisst im Endeffekt musst Du folgendermaßen arbeiten, damit Du auf webui kommst:
<link rel="stylesheet" href="**/webui**/lib/bootstrap/dist/css/bootstrap.css&quot; /&gt;
ASP.NET jedenfalls kann nicht hellsehen und zaubert Dir nicht "webui" an Deine href-Tags aus dem Hut.

Nicht anders funktionieren Content Delivery Network-Middlewares.
Aber im Endeffekt bist Du auf den typischen (Anfänger, sorry!)-Fehler reingefallen, dass Visual Studio -> Start new Project einfach Minimalbeispiele sind.

Wie Links durch HTML interpretiert werden -> HTML Basics
Wie Links erzeugt werden -> ASP.NET Basics 😉