Haproxy-Umleitung basierend auf dem Pfad

Haproxy-Umleitung basierend auf dem Pfad

Ähnlich zuHAProxy reqrep entfernt URI bei Backend-Anforderung.

Für uns gelten folgende Anliegen:

Wir haben Anwendungen, die mit unterschiedlichen Kontextstämmen aus einer Domäne heraus liefen. Allerdings wurden nicht alle Clients der URLs geändert.

Ich möchte mit einer 301-Weiterleitung in Haproxy umleiten, wenn eine Anforderung mit einem Legacy-Pfad übereinstimmt.

Nehmen wir zum http://example.com/abcBeispielhttp://example.com/def

...
frontend https
  bind *:{{ proxy_port }} ssl crt /etc/haproxy/bundle_dh.pem ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 no-sslv3
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  http-request set-header X-Forwarded-Port %[dst_port]

  acl has_legacy_abc path_beg /abc
  acl has_legacy_def path_beg /def
  redirect location 301 https://abcdomain.com/{PATH_WITHOUT_ABC} if { has_legacy_abc }
  redirect location 301 https://defdomain.com/{PATH_WITHOUT_ABC} if { has_legacy_def }

  use backend abc_backend if { hdr(Host) -i abcdomain.com }
  use backend def_backend if { hdr(Host) -i defdomain.com }
...

Das Problem besteht darin, den Pfad bei der Weiterleitung beizubehalten. Ich kann eine absolute Weiterleitung durchführen.

Habe nachgesehen, reqrepaber das scheint dazu zu dienen, eine Anfrage zu ändern, bevor sie an ein Backend weitergeleitet wird. Ich möchte allen Besuchern sagen, dass sie zur neuen Domäne gehen sollen.

Antwort1

Dies lässt sich mithilfe einiger temporärer Header wie diesen erreichen, die zwischen Ihren aclDefinitionen und use_backendSchlüsselwörtern eingefügt werden:

http-request set-header X-Location-Path %[capture.req.uri] if has_legacy_abc OR has_legacy_def

http-request replace-header X-Location-Path [^/]+/(.*) \1 if has_legacy_abc OR has_legacy_def

http-request redirect location https://abcdomain.com/%[hdr(X-Location-Path)] if has_legacy_abc
http-request redirect location https://defdomain.com/%[hdr(X-Location-Path)] if has_legacy_def

Abhängig von der tatsächlichen Konfiguration Ihrer Domänen/Pfade und den erforderlichen Weiterleitungen ist es möglicherweise sogar möglich, alles in einem einzigen Satz von Anweisungen zusammenzufassen, etwa so:

...
frontend https
  bind *:{{ proxy_port }} ssl crt /etc/haproxy/bundle_dh.pem ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 no-sslv3
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  http-request set-header X-Forwarded-Port %[dst_port]

  acl has_legacy path_beg /abc /def

  http-request set-header X-Location-Path %[capture.req.uri] if has_legacy
  http-request set-header X-Location-Host %[capture.req.uri] if has_legacy

  http-request replace-header X-Location-Host /([^/]*)/ \1 if has_legacy
  http-request replace-header X-Location-Path [^/]+/(.*) \1 if has_legacy

  http-request redirect location https://%[hdr(X-Location-Host)]domain.com/%[hdr(X-Location-Path)] if has_legacy_abc

  use backend abc_backend if { hdr(Host) -i abcdomain.com }
  use backend def_backend if { hdr(Host) -i defdomain.com }
...

Sollte die Anzahl der Pfade und Domänen sehr groß sein, können SieKarten(wobei der Schlüssel der Pfad und der Wert der Zielhost ist), um die Dinge noch weiter zu vereinfachen.

Antwort2

Ich habe das gleiche Problem und habe eine andere Lösung gefunden, die meiner Meinung nach besser ist. Diese andere Lösung funktioniert gut mit Version 1.6+ von haproxy. Es verwendethttp-request und regsub.

Wenn ich Ihr Beispiel umschreibe:

frontend https
  bind *:{{ proxy_port }} ssl crt /etc/haproxy/bundle_dh.pem ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 no-sslv3
  acl has_legacy_abc path_beg /abc
  acl has_legacy_def path_beg /def
  http-request redirect code 301 location https://%[hdr(host)]%[url,regsub(^/abc,/newabc,)] if has_legacy_abc

verwandte Informationen