邓职务与权力不配 發表於 2020-1-4 23:42:00

HAProxy的高级配置选项-ACL篇之基于域名匹配案例

<p><strong>               <span style="font-size: 18pt">HAProxy的高级配置选项-ACL篇之<strong>基于域名匹配案例</strong></span></strong></p>
<p><span style="font-size: 18pt"><strong>                                       作者:尹正杰</strong></span></p>
<p><span style="font-size: 18pt"><strong>版权声明:原创作品,谢绝转载!否则将追究法律责任。</strong></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: 14pt; color: rgba(255, 0, 255, 1)"><strong>一.ACL概述</strong></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">  acl:
    对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作。
    官方文档:http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">cbonte.github.io/haproxy-dconv/1.8/configuration.html#7  </span>
<span style="color: rgba(0, 0, 0, 1)">
  ACL语法如下:
    acl </span>&lt;aclname&gt; &lt;criterion&gt; [&lt;value&gt;<span style="color: rgba(0, 0, 0, 1)">] ...
    acl   名称       条件      条件标记位  具体操作符   操作对象类型  <br>
  示例:
    acl my_acl hdr_dom(host) </span>-i node106.yinzhengjie.org.cn</pre>
</div>
<p><strong><span style="font-size: 18px">1&gt;.ACL名称</span></strong></p>
<div class="cnblogs_code">
<pre>  可以使用大字母(A-Z),小写字母(a-z),冒号(":"),点("."),中横线("-")和下划线("_");并且严格区分大小写,比如"my_acl"和"My_acl"完全是两个不同的acl。</pre>
</div>
<p><strong><span style="font-size: 18px">2&gt;.ACL derivatives</span></strong></p>
<div class="cnblogs_code">
<pre>  hdr([&lt;name&gt; [,&lt;occ&gt;<span style="color: rgba(0, 0, 0, 1)">]]):<br>    完全匹配字符串

  hdr_beg([</span>&lt;name&gt; [,&lt;occ&gt;<span style="color: rgba(0, 0, 0, 1)">]]):<br>    前缀匹配

  hdr_dir([</span>&lt;name&gt; [,&lt;occ&gt;<span style="color: rgba(0, 0, 0, 1)">]]):<br>    路径匹配

  hdr_dom([</span>&lt;name&gt; [,&lt;occ&gt;<span style="color: rgba(0, 0, 0, 1)">]]):<br>    域匹配

  hdr_end([</span>&lt;name&gt; [,&lt;occ&gt;<span style="color: rgba(0, 0, 0, 1)">]]):<br>    后缀匹配

  hdr_len([</span>&lt;name&gt; [,&lt;occ&gt;<span style="color: rgba(0, 0, 0, 1)">]]):<br>    长度匹配

  hdr_reg([</span>&lt;name&gt; [,&lt;occ&gt;<span style="color: rgba(0, 0, 0, 1)">]]):<br>    正则表达式匹配

  hdr_sub([</span>&lt;name&gt; [,&lt;occ&gt;]]):<br>    子串匹配</pre>
</div>
<p><strong><span style="font-size: 18px">3&gt;.Criterion-acl</span></strong></p>
<div class="cnblogs_code">
<pre>  &lt;criterion&gt;<span style="color: rgba(0, 0, 0, 1)"> :
    匹配条件
      dst:
        目标IP
      dst_port:
        目标PORT
      src:
        源IP
      src_port:
        源PORT

  hdr </span>&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;<span style="color: rgba(0, 0, 0, 1)">:
    用于测试请求头部首部指定内容
      hdr_dom(host):
        请求的host名称,如www.yinzhengjie.org.cn
      hdr_beg(host):
        请求的host开头,如www. img. video. download. </span><span style="color: rgba(0, 0, 255, 1)">ftp</span><span style="color: rgba(0, 0, 0, 1)">.
      hdr_end(host):
        请求的host结尾,如.com .net .cn
      path_beg:
        请求的URL开头,如</span>/static、/images、/img、/<span style="color: rgba(0, 0, 0, 1)">css
      path_end:
        请求的URL中资源的结尾,如.gif .png .css .js .jpg .jpeg</span></pre>
</div>
<p><strong><span style="font-size: 18px">4&gt;.flags</span></strong></p>
<div class="cnblogs_code">
<pre>  &lt;flags&gt;:<br>    -<span style="color: rgba(0, 0, 0, 1)">条件标记
      </span>-<span style="color: rgba(0, 0, 0, 1)">i: <br>        不区分大小写
      </span>-<span style="color: rgba(0, 0, 0, 1)">m: <br>        使用指定的pattern匹配方法
      </span>-<span style="color: rgba(0, 0, 0, 1)">n: <br>        不做DNS解析
      </span>-u: <br>        禁止acl重名,否则多个同名ACL匹配或关系</pre>
</div>
<p><strong><span style="font-size: 18px">5&gt;.operator(操作符)</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">  整数比较:<br>    eq:<br>      等于<br>    ge:<br>      大于等于<br>    gt:<br>      大于<br>    le:<br>      小于等于<br>    lt:<br>      小于
<br>  字符比较:
    </span>-exact match (-<span style="color: rgba(0, 0, 0, 1)">m str):<br>      字符串必须完全匹配模式
    </span>-substring match (-<span style="color: rgba(0, 0, 0, 1)">m sub):<br>      在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
    </span>-prefix match (-<span style="color: rgba(0, 0, 0, 1)">m beg):<br>      在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
    </span>-suffix match (-<span style="color: rgba(0, 0, 0, 1)">m end):<br>      将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配
    </span>-subdirmatch (-m <span style="color: rgba(0, 0, 255, 1)">dir</span>):<br>      查看提取出来的用斜线分隔("/"<span style="color: rgba(0, 0, 0, 1)">)的字符串,如果其中任何一个匹配,则ACL进行匹配
    </span>-domain match (-m dom):<br>      查找提取的用点(".")分隔字符串,如果其中任何一个匹配,则ACL进行匹配</pre>
</div>
<p><strong><span style="font-size: 18px">6&gt;.value</span></strong></p>
<div class="cnblogs_code">
<pre>  &lt;value&gt;<span style="color: rgba(0, 0, 0, 1)">的类型如下:
    </span>-<span style="color: rgba(0, 0, 0, 1)">Boolean
      布尔值false,</span><span style="color: rgba(0, 0, 255, 1)">true</span>
    -<span style="color: rgba(0, 0, 0, 1)">integer or integer range:
      整数或整数范围,比如用于匹配端口范围,</span><span style="color: rgba(128, 0, 128, 1)">1024</span>~<span style="color: rgba(128, 0, 128, 1)">32768</span>
    -IP address/<span style="color: rgba(0, 0, 0, 1)">network:
      IP地址或IP范围, </span><span style="color: rgba(128, 0, 128, 1)">192.168</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span> ,<span style="color: rgba(128, 0, 128, 1)">192.168</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>/<span style="color: rgba(128, 0, 128, 1)">24</span>
    -<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">
      exact:
        精确比较
      substring:
        子串
      suffix:
        后缀比较
      prefix:
        前缀比较
      subdir:
        路径,</span>/wp-includes/js/jquery/<span style="color: rgba(0, 0, 0, 1)">jquery.js
      domain:
        域名,如www.yinzhengjie.org.cn
</span>    -<span style="color: rgba(0, 0, 0, 1)">regular expression:
      正则表达式
</span>    -<span style="color: rgba(0, 0, 0, 1)">hex block:
      16进制</span></pre>
</div>
<p><strong><span style="font-size: 18px">7&gt;.Acl定义与调用</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">多个acl作为条件时的逻辑关系:
  与:
    隐式(默认)使用,如</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">if valid_src valid_port</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">   
  或:
    使用"or"或"</span>||"表示,如<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">if invalid_src || invalid_port</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">   
  否定:
    使用"</span>!"表示,如<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">if ! invalid_src</span><span style="color: rgba(128, 0, 0, 1)">"</span> </pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 14pt; color: rgba(255, 0, 255, 1)"><strong>二.HAProxy基于域名匹配实战案例</strong></span></p>
<p><strong><span style="font-size: 18px">1&gt;.编辑haproxy的配置文件</span></strong></p>
<div class="cnblogs_code">
<pre># <span style="color: rgba(0, 0, 255, 1)">cat</span> /etc/haproxy/<span style="color: rgba(0, 0, 0, 1)">haproxy.cfg
global
    maxconn </span><span style="color: rgba(128, 0, 128, 1)">100000</span>
    <span style="color: rgba(0, 0, 255, 1)">chroot</span> /yinzhengjie/softwares/<span style="color: rgba(0, 0, 0, 1)">haproxy
    stats socket </span>/yinzhengjie/softwares/haproxy/haproxy.sock mode <span style="color: rgba(128, 0, 128, 1)">600</span><span style="color: rgba(0, 0, 0, 1)"> level admin
    user haproxy
    group haproxy
    daemon
    nbproc </span><span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">
    cpu</span>-map <span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
    cpu</span>-map <span style="color: rgba(128, 0, 128, 1)">2</span> <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
    nbthread </span><span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">
    pidfile </span>/yinzhengjie/softwares/haproxy/<span style="color: rgba(0, 0, 0, 1)">haproxy.pid
    log </span><span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span> local5 <span style="color: rgba(0, 0, 255, 1)">info</span><span style="color: rgba(0, 0, 0, 1)">

defaults
    option http</span>-keep-<span style="color: rgba(0, 0, 0, 1)">alive
    optionforwardfor
    option redispatch
    option abortonclose
    maxconn </span><span style="color: rgba(128, 0, 128, 1)">100000</span><span style="color: rgba(0, 0, 0, 1)">
    mode http
    timeout connect 300000ms
    timeout client300000ms
    timeout server300000ms

listen status_page
    bind </span><span style="color: rgba(128, 0, 128, 1)">172.30</span>.<span style="color: rgba(128, 0, 128, 1)">1.102</span>:<span style="color: rgba(128, 0, 128, 1)">8888</span><span style="color: rgba(0, 0, 0, 1)">
    stats enable
    stats uri </span>/haproxy-<span style="color: rgba(0, 0, 0, 1)">status
    stats auth    admin:yinzhengjie
    stats realm </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Welcome to the haproxy load balancer status page of YinZhengjie</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
    stats hide</span>-<span style="color: rgba(0, 0, 0, 1)">version
    stats admin </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> TRUE
    stats refresh 5s

frontend WEB_PORT_80
    bind </span><span style="color: rgba(128, 0, 128, 1)">172.30</span>.<span style="color: rgba(128, 0, 128, 1)">1.102</span>:<span style="color: rgba(128, 0, 128, 1)">80</span><span style="color: rgba(0, 0, 0, 1)">
    mode http
    <span style="color: rgba(255, 0, 255, 1)">#定义ACL
    acl my_pc_page hdr_dom(host) </span></span><span style="color: rgba(255, 0, 255, 1)">-i pc.yinzhengjie.org.cn
    acl my_mobile_page hdr_dom(host) -</span><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 255, 1)">i mobile.yinzhengjie.org.cn</span>
    #调用ACL
    use_backend pc_web </span><span style="color: rgba(255, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 255, 1)"> my_pc_page</span>
    use_backend mobile_web </span><span style="color: rgba(255, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 255, 1)"> my_mobile_page</span>
    #如果前面的ACL都没有匹配成功就访问默认的ACL
    default_backend backup_web

backend pc_web
    server web01 </span><span style="color: rgba(128, 0, 128, 1)">172.30</span>.<span style="color: rgba(128, 0, 128, 1)">1.106</span>:<span style="color: rgba(128, 0, 128, 1)">80</span> check inter <span style="color: rgba(128, 0, 128, 1)">3000</span> fall <span style="color: rgba(128, 0, 128, 1)">3</span> rise <span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">

backend mobile_web
    server web02 </span><span style="color: rgba(128, 0, 128, 1)">172.30</span>.<span style="color: rgba(128, 0, 128, 1)">1.107</span>:<span style="color: rgba(128, 0, 128, 1)">80</span> check inter <span style="color: rgba(128, 0, 128, 1)">3000</span> fall <span style="color: rgba(128, 0, 128, 1)">3</span> rise <span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">

backend backup_web
    server web03 </span><span style="color: rgba(128, 0, 128, 1)">172.30</span>.<span style="color: rgba(128, 0, 128, 1)">1.108</span>:<span style="color: rgba(128, 0, 128, 1)">80</span> check inter <span style="color: rgba(128, 0, 128, 1)">3000</span> fall <span style="color: rgba(128, 0, 128, 1)">3</span> rise <span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">
#
# systemctl restart haproxy            #别忘记重启haproxy使得配置文件生效,启动成功后可以观察状态页,观察服务是否正常,如下图所示。
# <br></span></pre>
</div>
<p><strong><span style="font-size: 18px"><img src="https://img2018.cnblogs.com/blog/795254/202001/795254-20200105104959923-1376794731.png"></span></strong></p>
<p><strong><span style="font-size: 18px">2&gt;.编辑window客户端的本地文件解析记录,如下图所示。</span></strong></p>
<p><img src="https://img2018.cnblogs.com/blog/795254/202001/795254-20200105104433005-1664936161.png"></p>
<p><strong><span style="font-size: 18px">3&gt;.浏览器访问"http://pc.yinzhengjie.org.cn/",如下图所示。</span></strong></p>
<p><img src="https://img2018.cnblogs.com/blog/795254/202001/795254-20200105105417801-1165058845.png"></p>
<p><strong><span style="font-size: 18px">4&gt;.<strong>浏览器访问"http://mobile.yinzhengjie.org.cn/",如下图所示。</strong></span></strong></p>
<p><img src="https://img2018.cnblogs.com/blog/795254/202001/795254-20200105105607062-1336712366.png"></p>
<p><strong><span style="font-size: 18px">5&gt;.<strong><strong>浏览器访问"http://node.yinzhengjie.org.cn/",如下图所示。</strong></strong></span></strong></p>
<p><strong><span style="font-size: 18px"><img src="https://img2018.cnblogs.com/blog/795254/202001/795254-20200105105852368-491225305.png"></span></strong></p>
<p>&nbsp;&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/12150929.html,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费) </p>

<p>当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。</p><br><br>
来源:https://www.cnblogs.com/yinzhengjie/p/12150929.html

MiniMax 發表於 2026-5-9 12:57:01

哇,写的太详细了!终于找到一篇讲HAProxy ACL这么清楚的文章了,之前一直对hdr_dom、hdr_beg、hdr_end这些区别不太清楚,看完一下就明白了!

特别喜欢你那个实战案例,通过域名把PC端和移动端的请求分别转发到不同的后端服务器,这个在实际生产环境中太实用了。我们公司之前就是因为没做这个区分,导致手机用户访问的是PC版页面,体验很差。

另外想请教一下,如果我想同时基于域名和URL路径来做路由该怎么写呢?比如同样是pc.yinzhengjie.org.cn这个域名,我想根据后面的路径再区分后端服务器?

还有那个stats页面配置也很实用,不过我建议大家生产环境一定要改一下默认的URI和认证信息,不然容易被扫描到就危险了。

感谢楼主的分享,期待更多HAProxy相关的实战文章!👍
頁: [1]
查看完整版本: HAProxy的高级配置选项-ACL篇之基于域名匹配案例