AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 738363
Accepted
UpTheCreek
UpTheCreek
Asked: 2015-11-24 07:28:05 +0800 CST2015-11-24 07:28:05 +0800 CST 2015-11-24 07:28:05 +0800 CST

Haproxy - 从子域中动态选择后端

  • 772

我最近发现,您可以根据请求主机头动态匹配后端,如下所示:

 use_backend %[req.hdr(host),lower]

但是,有谁知道我可以使用请求主机头的子域来匹配后端吗?

例如,沿着这些思路:

backend one
backend two

use_backend %[<SUBDOMAIN OF HOSTHEADER>,lower]

这将像这样匹配:

 one.example.com -> backend one
 two.example.com -> backend two
haproxy
  • 2 2 个回答
  • 9056 Views

2 个回答

  • Voted
  1. Best Answer
    GregL
    2015-11-24T12:29:56+08:002015-11-24T12:29:56+08:00

    添加和删​​除 DNS 条目允许您将子域即时路由到各种后端,但您仍然需要定义这些后端,因此仍然需要重新启动服务。因此,我不完全确定此配置的有用性。

    无论如何,这就是你的做法。

    我们知道我们可以host使用req.hdr ( req.hdr(host)) 找到标头的内容,但这给了我们请求的 FQDN,而不是子域。

    值得庆幸的是,我们应该能够将一个regsub转换器应用于示例,以剪掉基域和 TLD。req.hdr

    regsub(<regex>,<subst>[,<flags>])
    将基于正则表达式的替换应用于输入字符串。它与
    著名的“sed”实用程序使用“s/<regex>/<​​subst>/”执行相同的操作。默认
    情况下,它将用替换 字符串 <subst>替换输入字符串中
    与正则表达式 <regex> 匹配的最大部分的第一次出现。 可以通过在第三个参数 <flags> 中添加标志“g”
    来替换所有出现的情况。
    也可以
    通过在 <flags> 中添加标志“i”来使正则表达式不区分大小写。由于 <flags> 是一个
    字符串,它由所有所需标志的串联组成。

    需要注意的是,由于当前
    配置解析器的限制,某些字符(例如右括号或逗号
    )无法在参数中使用。
    该转换器的第一个用途是
    将某些字符或字符序列替换为其他字符。

    该引用中的重点是我的,旨在表明在这种情况下,您需要的正则表达式是^(.*)(?:\..*){2}$,由于括号,它不起作用。

    因此,您需要使用现场转换器。

    field(<index>,<delimiters>)考虑 输入字符串
    中的给定分隔符,提取给定索引处的子字符串。
    索引从 1 开始,分隔符是字符串格式
    的字符列表。

    field(1,'.')
    

    如果我们将整个示例管道放在一起,则该use_backend行如下所示:

    use_backend BE:subs-%[req.hdr(host),lower,field(1,'.')]
    

    现在,这开启了将进入同一后端的事实one.*.*,并可能导致一些非常奇怪的情况。

    检查基本域和 TLD 以确保它们是您所期望的可能是有意义的。假设您只有两个 (example.com和foo.com),您将使用req.hdr_end(host)它们来检查它们,使 ACL 看起来像:

     acl is_valid_base_domain  req.hdr_end(host) -i example.com foo.com
    

    如果我们把它们放在一起,整个配置看起来像这样:

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

    如果您愿意,您可以通过为每个子域、每个基本域设置不同的“动态”后端来获得更高级的体验;你只需要使用上面的部分来解决这个问题。

    • 7
  2. Tubeless
    2015-11-24T07:56:29+08:002015-11-24T07:56:29+08:00

    据我所知,HAProxy 不支持正则表达式从 Host 标头中提取子域的特定部分,然后将该值分配给一个变量,该变量稍后用于形成完整的后端名称。

    但是,解决问题的一种方法是使用映射:

    frontend frontend_main
    ...
    use_backend %[req.hdr(host),lower,map(/etc/haproxy/subdomains.map,backend_main)]
    

    的内容/etc/haproxy/subdomains.map如下所示:

    #domainname  backendname
    one.example.com backend_one
    two.example.com backend_two
    etc.domain1.com backend_etc
    

    所有与该文件中的任何子域都不匹配的请求都将转到backend_main后端。

    • 5

相关问题

  • 具有动态路由的代理服务器

  • nginx 访问日志忽略某些请求

  • HAProxy 和“分片”

  • 带有 HAProxy 的远程 IP

  • SSL 网站的高可用性

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve