Webserver: Subdomains auf verschiedene Dienste/Ports weiterleiten

Wenn ein Webserver betrieben wird, kommt es ab und zu vor, dass verschiedene Subdomains einrichtet und diese an verschiedene Dienste weitergeleitet werden sollen. Am einfachsten teilt man jedem (Sub-)Domain eine eigene IP zu und macht das Ganze IP-basiert. Da IPv4-Adressen langsam rar werden, ist dies für die Meisten keine Option.

Eine einfache Alternative ist folgendes: Jede Subdomain zeigt auf die selbe IP-Adresse. Alle Requests werden von einem Zentralen Webserver angenommen und (wie bei einem LoadBalancer) auf verschiedene Ports/andere IPs/Dienste/… weitergeleitet.

Je nach Webserver/LoadBalancer hat man verschiedene Möglichkeiten zur Konfiguration. Man kann nach Subdomain sortieren, Dienste sogar für einzelne Unterverzeichnisse anders Umleiten oder sogar nach Cookies oder Header-Informationen ausschau halten. Speziell beim LoadBalancing kann dies von Vorteil sein.

Hier sind nun zwei Ausschnitte aus einer Webserver-Konfiguration, welche genau dies macht:

LigHTTPD

  • “Standard Konfiguration” wurde weggelassen (Port 80, Standard-Pfad, etc)
  • Leitet 3 Subdomains an verschiedene ports/IPs weiter
  • Bei Lighttpd wird bei solchen Regeln immer die letzte gültige angewendet. Deshalb hat es vor dem 2. und 3. Subdomain ein “else”.
  • Die Regeln sehen in etwa so aus: "Bedingung" { "Block mit Aktionen/Konfiguration" }

Bei den server-modulen sollte "mod_proxy" hinzugefügt werden.

# VHOSTS
$HTTP["host"] =~ "code\.mydomain\.com" {
    proxy.server = (
        "" => (
            "RhodeCode" => (
                "host" => "192.168.137.4",
                "port" => 5000
            )
        )
    )
}
else $HTTP["host"] =~ "jenkins\.mydomain\.com" {
    proxy.server = (
        "" => (
            "Jenkins" => (
                "host" => "127.0.0.1",
                "port" => 8080
            )
        )
    )
}
else $HTTP["host"] =~ "test\.mydomain\.com" {
    proxy.server = (
        "" => (
            "whatever" => (
                "host" => "127.0.0.1",
                "port" => 9000
            )
        )
    )
}

Apache

  • Wir setzten wieder eine Standard-Konfiguration für Apache voraus
  • Die Weiterleitungen werden als name based VHOST konfiguriert. Doku: https://httpd.apache.org/docs/2.4/vhosts/name-based.html
  • Mittels Mod_Proxy werden die Requests dem jeweiligen Dienst/Port weitergeleitet.
  • In dieser Konfiguration wurde gleich noch SSL mit eingebaut. Der Webserver akzeptiert SSL-Verbindungen, leitet an den anderen Service aber unverschlüsselte http-requests weiter. So kann zum Beispiel die gesamte SSL-Konfiguration für alle WebServices an einem zentralen Ort gemacht werden. Bei wirklich grossen Webseiten kann dies dann von einem eigenen Webserver erledigt werden.

 

LoadModule proxy_module modules/mod_proxy.so
#Apache kann mit diversen Protokollen umgehen... http dürfte in der Regel das einfachste sein:
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
ServerName iro.mydomain.com:443
DocumentRoot "D:/web/htdocs"
ServerAdmin webmaster@mydomain.com
SSLEngine On
SSLCertificateFile "mycert.crt"
SSLCertificateChainFile "ca.pem"
SSLCACertificateFile "ca.pem"
SSLCertificateKeyFile "mycert.key"

ProxyRequests Off
Order deny,allow
Allow from all

ProxyPass / http://127.0.0.1:4201/
ProxyPassReverse / http://127.0.0.1:4201/

 

nginx

Vielen Dank an Nick, welcher mor folgende Konfiguration als Beispiel für nginx geschickt hat:


#user html;
worker_processes  8;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen 80;
        listen [::]:80 ipv6only=on;
        server_name www.example.com;
        return 301 https://$server_name$request_uri;
    }

    server {
        listen       443;
        server_name  localhost;
        server_name  www.example.com;

        include common.conf;

        location / {
            root   /usr/share/nginx/data;
            index  index.html index.htm;
        }
    }

    server {
	listen 443;
	server_name subdomain1.example.com;

	include common.conf;

	location / {
	    proxy_pass http://192.168.1.163:5050;
	}
    }

    server {
	listen 443;
	server_name subdomain2.example.com;

	include common.conf;

	location / {
	   proxy_pass http://192.168.1.222:80;
	}
    }
}