Adicionar e remover entradas de DNS permite rotear subdomínios para vários backends instantaneamente, mas você ainda precisa definir esses back-ends para que ainda haja uma reinicialização do serviço. Como tal, não tenho certeza da utilidade dessa configuração.
De qualquer forma, veja como você faria isso.
Sabemos que podemos encontrar o conteúdo do cabeçalho host
usando req .hdr ( req.hdr(host)
), mas isso nos dá o FQDN da solicitação, não o subdomínio.
Felizmente, há um conversor regsub que devemos consiga se inscrever na amostra req.hdr
para cortar o domínio base e o DPN.
regsub(<regex>,<subst>[,<flags>])
Applies a regex-based substitution to the input string. It does the same
operation as the well-known "sed" utility with "s/<regex>/<subst>/". By
default it will replace in the input string the first occurrence of the
largest part matching the regular expression <regex> with the substitution
string <subst>. It is possible to replace all occurrences instead by adding
the flag "g" in the third argument <flags>. It is also possible to make the
regex case insensitive by adding the flag "i" in <flags>. Since <flags> is a
string, it is made up from the concatenation of all desired flags. Thus if
both "i" and "g" are desired, using "gi" or "ig" will have the same effect.
It is important to note that due to the current limitations of the
configuration parser, some characters such as closing parenthesis or comma
are not possible to use in the arguments. The first use of this converter is
to replace certain characters or sequence of characters with other ones.
A ênfase nessa citação é minha e visa mostrar que, neste caso, onde a regex que você precisa é de ^(.*)(?:\..*){2}$
, não funcionará por causa dos parênteses.
Assim, você precisará usar o conversor campo .
field(<index>,<delimiters>)
Extracts the substring at the given index considering given delimiters from
an input string. Indexes start at 1 and delimiters are a string formatted
list of chars.
field(1,'.')
Se colocarmos a amostra inteira pipline juntos, a linha use_backend
se parece com:
use_backend BE:subs-%[req.hdr(host),lower,field(1,'.')]
Agora, isso abre o fato de que one.*.*
irá para o mesmo backend e pode levar a algumas situações muito estranhas.
Pode fazer algum sentido verificar o domínio base e o TLD para garantir que eles são o que você espera. Supondo que você tenha apenas dois ( example.com
e foo.com
) deles, você usaria req.hdr_end(host)
para verificá-los, fazendo com que a ACL pareça:
acl is_valid_base_domain req.hdr_end(host) -i example.com foo.com
E se colocarmos tudo junto, toda a configuração será algo assim:
frontend FE:subs
...
acl is_valid_base_domain req.hdr_end(host) -i example.com foo.com
use_backend BE:subs-%[req.hdr(host),lower,field(1,'.')] if is_valid_base_domain
default_backend BE:subs:default
backend BE:subs-one
#matches one.example.com, one.foo.com
...
backend BE:subs-two
#matches two.example.com, two.foo.com
...
backend BE:subs-three
#matches three.example.com, three.foo.com
...
backend BE:subs:default
#matches *.example.com, *.foo.com
...
Você pode ficar ainda mais sofisticado se quiser ter back-ends "dinâmicos" diferentes para cada subdomínio, por domínio de base; você só precisa usar as peças acima para resolver isso.