Назад | Перейти на главную страницу

Простое перенаправление на внутренние серверы HAproxy

Я хочу настроить простое перенаправление с помощью HAproxy.

Желаемое поведение: HAProxy получает запрос на example.com или https://example.com и возвращает стартовую страницу веб-сервера https из списка серверов, исключая себя из цепочки. Я пробовал с redirect location https://web1.com code 301 if example_acl и он работает для одного сервера, но мне нужно 5 серверов за перенаправлением, с web1.com, web2.com ... и циклическим перебором. Может быть, есть какая-то конкретная конфигурация для backend-раздела? пожалуйста помоги

Моя текущая конфигурация

-#------------------- GLOBAL SETTINGS ---------------------------
...
-#------------------- FRONTEND HTTP ---------------------------
frontend http_in
       mode http
       option httplog
       bind *:80
       stats enable

    redirect scheme https if { hdr(Host) -i example.com }

-#------------------- FRONTEND TCP ---------------------------
frontend tcp_in
       mode tcp
       option tcplog
       bind *:443

       tcp-request inspect-delay 5s
       tcp-request content accept if { req.ssl_hello_type 1 }

       acl example_acl req.ssl_sni -i example.com
       use_backend special_example if example_acl

-#------------------- Server Farms ---------------------------
backend special_example
    mode tcp
    balance roundrobin

    ?

Я согласен с комментатором, это кажется необычным приложением, но тем не менее, HAProxy проходит.

Я создал запись в файле hosts на своем тестовом прокси-сервере, так что example.com фактически указывает на 127.0.0.1, поэтому приведенные ниже тесты являются фактическими ответами прокси.

Скажем я хочу example.com перенаправить на один из четырех серверов, external-1.example.com через external-4.example.com.

Это однострочный текст - все в одной строке, показанное здесь для ясности в виде нескольких строк.

Это идет в frontend раздел.

http-request redirect code 301 
location http://external-%[rand(4),add(1)].%[req.hdr(host)]%[url] 
if { req.hdr(host) -m str example.com }

{ req.hdr(host) -m str example.com } анонимный ACL, который разрешает перенаправление if он соответствует текущему запросу. В location использует rand(n) выборка, который генерирует случайное число от 0 до n-1; за ним следует (передает свое значение) add(x) конвертер, который добавляет x к значению - в этом случае мы берем возможные значения от 0 до (4-1) включительно и добавляем 1, так что %[rand(4),add(1)] Выражение выражается числом от 1 до 4 включительно, которое неявно приводится к строке. Мы объединяем http://external- с этим целым числом, точкой, заголовок входящего хоста %[req.hdr(host)] и URL %[url], который включает путь и строку запроса.

Тест 1:

$ curl -v http://example.com
* Rebuilt URL to: http://example.com/
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to example.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: example.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Content-length: 0
< Location: http://external-4.example.com/
< Connection: close

Тест 2:

< HTTP/1.1 301 Moved Permanently
< Content-length: 0
< Location: http://external-2.example.com/
< Connection: close

Ага, это работает.

Если вам нужно перенаправить на набор имен хостов, которые не были последовательно пронумерованы, решение будет аналогичным, но вы должны использовать http-request set-var для хранения случайного числа в переменной транзакции, затем ряд операторов перенаправления, по одному для каждого хоста, каждый из которых со своим собственным анонимным ACL, который будет оценивать случайное значение на равенство целому числу, соответствующему этому хосту, и перенаправлять, если переменная содержит это значение.

В rand() fetch не является генератором случайных чисел криптографического качества, но, безусловно, кажется достаточным для этого варианта использования.