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

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

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

Мой текущий конфиг

-#------------------- 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

    ?

1 ответ

Я согласен с комментатором, это выглядит как необычное приложение, но, тем не менее, 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 не является генератором случайных чисел криптографического качества, но, безусловно, кажется достаточным для этого варианта использования.

Другие вопросы по тегам