Redirect
基於路徑的 Haproxy 重定向
類似於HAProxy reqrep remove URI on backend request。
以下問題適用於我們。
我們有一些應用程序在一個域之外以不同的上下文根執行。然而,並非所有 url 的客戶端都被更改了。
如果請求與舊路徑匹配,我想在 haproxy 中使用 301 重定向進行重定向。
舉個例子
http://example.com/abc
和http://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 } ...
問題是如何在重定向中保留路徑。我可以做一個絕對重定向。
看起來,
reqrep
但這似乎是在傳遞到後端之前更改請求。我想告訴所有訪問者他們應該去新域。
這可以使用一些像這樣的臨時標題來完成,插入在您的
acl
定義和use_backend
關鍵字之間: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
根據您的域/路徑的實際配置和所需的重定向,甚至可以將其全部折疊成一組指令,如下所示:
... 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 } ...
如果路徑和域的數量很大,您可以使用映射(其中鍵是路徑,值是目標主機)來進一步簡化事情。