Haproxy

haproxy 如何在任何重定向之前處理 /.well-known ?

  • February 5, 2021

我想創建一個監聽埠 80 的 haproxy 配置,並且:

  1. 當路徑以 /.well-known/acme-challenge 開頭時使用_backend,與域無關
  2. 將 http 重定向到 https 以獲取多個域的其他路徑,例如將 http://a.test 重定向到https://a.test

我試過這個配置:

use_backend certbot_80 if { path -m reg ^/.well-known/acme-challenge/ } 
redirect prefix https://a.test if { hdr_reg(host) '^a\.test(?::.*)?$' }

但它不起作用,因為 haproxy 程序在 use_backend 之前重定向。

這有效:

acl certbot path -m reg ^/.well-known/acme-challenge/
redirect prefix https://a.test if ! certbot { hdr_reg(host)  '^a\.test(?::.*)?$' }
use_backend certbot_80 if certbot

但是我必須在每個重定向中專門排除 certbot 條件。而且,如果我有更多要首先處理的路徑,則必須在每個重定向中排除所有路徑。

有沒有辦法在保持每個條件與其他條件分開的同時做到這一點?

我之前使用的是 pound,它按順序處理混合重定向和後端。

恐怕無法處理use_backend之前的redirect陳述。我相信 HAPROXY 會在收到來自客戶端的整個 HTTP 請求後評估重定向,並且只有在發現客戶端不會被重定向後才會選擇後端。

您無需修改每個重定向規則即可添加其他排除路徑。您可以改用唯一的 ACL。例如,這個配置片段可以工作:

acl noredirects path -m reg ^/.well-known/acme-challenge/
acl noredirects path -m beg /static/ /images/ /css/
acl noredirects req.hdr(host) -i httpsite.example.com
redirect prefix https://a.test if ! noredirects { req.hdr(host) -m reg ^a\.test(?::.*)?$ }
use_backend certbot_80 if noredirects

您還可以在後端處理重定向。例如:

frontend http *:80
   acl certbot  path -m beg /.well-known/acme-challenge/
   acl httpsite path -m beg /public/
   use_backend certbot_80 if certbot
   use_backend httpbackend if httpsite
   default_backend redirector

backend redirector
   redirect prefix https://a.test if { req.hdr(host) -m reg ^a\.test(?::.*)?$ }
   redirect prefix https://b.test if { req.hdr(host) -m reg ^b\.test(?::.*)?$ }

backend httpbackend
   server httpserver httpserver.example.com:80

引用自:https://serverfault.com/questions/939114