F5常用iRule

首页 / 🍁F5 / 正文

背景:积累常见irule


1. 友好界面

背景:客户要求需要在停机更新或者系统出故障时进行页面提示【系统维护中】 F5判断系统各节点是否存活 如果全部不存活就跳到指定提示页面 如果至少一台就不用跳转到提示页面,正常进行负载。

when HTTP_REQUEST {
    if { [ active_members test_pool ]==0 } {
        HTTP::respond 200 content {
            <html>
                <head>
                    <title>维护界面</title>
                </head>
                <body>
                    界面维护中!!!
                </body>
            </html>
        }     
    }   
}

2. 基于源地址负载均衡

背景:并配置负载均衡算法为基于源地址负载均衡算法,将192.168.11.0/24的IP地址访问分配给服务器A,将192.168.12.0/24的IP地址访问分配给服务器B。

when HTTP_REQUEST {
if { [IP::addr [IP::client_addr] equals 192.168.11.0/24] }{
     pool pool_A member 211.136.2.11 80
  } elseif { [IP::addr [IP::client_addr] equals 192.168.12.0/24] } {
     pool pool_A member 211.136.2.12 80
  }
}
when LB_FAILED {
log local0. "src_shibai"
LB::reselect pool pool_A
}

3. 基于URI负载均衡

示例一:配置负载均衡算法为基于http uri请求内容的负载均衡算法,将请求URL中含有“test1”的发送给服务器A,将请求URL中含有“test2”的发送给服务器B。

when HTTP_REQUEST {
 set url [HTTP::uri]
if { ([string match  {*test1*} $url]) & ([active_members pool_A]==1)} {
     pool pool_A  
     log local0.info "[HTTP::uri] -- pool_A"
  } elseif { ([string match  {*test2*} $url]) & ([active_members pool_B]==1)} {
     pool pool_B 
     log local0.info "[HTTP::uri] -- POOL_B"
  } else {
        pool pool_default 
  }
}

示例二:配置负载均衡算法为基于http uri请求内容的负载均衡算法,如果URI中以“test1”开始开始,则把流量发送给pool_A,如果以其他字段开头,则拒绝接受流量。

when HTTP_REQUEST {
if { [HTTP::uri] starts_with "/test" } {
    pool pool_A
}else {
    reject
}
}

4. 基于客户端浏览器负载均衡

背景:配置负载均衡算法为基于HTTP Header信息的负载均衡算法,按照HTTP请求的Header中User-Agent类型(包含终端或浏览器等信息)进行负载均衡,将匹配User-Agent类型为Chrome的发送给服务器组A,将匹配User-Agent类型Firefox发送给服务器组B,其它HTTP请求发送给服务器组C。

when HTTP_REQUEST {
      if { [HTTP::header User-Agent] contains "Chrome"  } {
        pool pool_A }
    elseif { [HTTP::header User-Agent] contains "Firefox"    } {
        pool pool_B }
    else { pool pool_C }
}

5. http头部插入字段

背景:需要在http头部插入字段。

when HTTP_REQUEST {
    HTTP::header insert "CLIENT_ORG_IP" [IP::client_addr]
    if { [HTTP::header CLIENT_ORG_IP] contains [IP::client_addr]  } {
        log local0. "ok"
    }
    HTTP::header insert "CLIENT_ORG_PORT" [TCP::client_port]
}

6. 流量通过F5访问流程

背景:通过Irule查看流量地址信息

when SERVER_CONNECTED {
    log local0.info "
    client connection from [IP::client_addr]:[TCP::client_port]
    access to [clientside {IP::local_addr}]:[clientside {TCP::local_port}]
    Snat to [IP::local_addr]:[TCP::local_port]
    TO server [IP::server_addr]:[TCP::server_port]"
}

7. DNS解析

背景:在本地GTM进行A记录域名解析,当客户端来本地访问AAAA记录信息时,则去另外的GTM进行AAAA地址解析。再把解析结果返回给客户端。

when DNS_REQUEST {
    switch [string toupper [DNS::question type]] {
        "AAAA" {
            pool v6_dns
            }
        "MX" {
            pool v6_dns
            }
        "TXT" {
            pool v6_dns
        }
    }
}
when DNS_RESPONSE {
    if {([DNS::header rcode] equals "NXDOMAIN") or ([DNS::header rcode] equals "REFUSED") }{
    DNS::header rcode NOERROR
    }
}

8. 基于域名的出向选路规则

1. 当接收DNS流量时,配置出向dns请求。如果请求域名以date_group中配置的域名结尾,则去pool_dns_test去进行域名解析,否则去pool_dns_default中进行域名解析。

when DNS_REQUEST {
    if {[class match [DNS::question name] ends_with data_group] }  {
        #log local0. "client =[IP::client_addr] NXDOMAIN111 question name: [DNS::question name]"
        pool pool_dns_test
    }else {
        pool pool_dns_default
            }
}

2. 当收到DNS响应时,如果请求的域名在domain_test中,就把A记录或者AAAA记录以及对应的域名存储在test_table表中。

when DNS_RESPONSE {       
    if  { ([DNS::question type] eq "A") or ([DNS::question type] eq "AAAA")  }  {
        if {[class match [DNS::question name] contains domain_test] }  {
            set rrs [DNS::answer] 
            foreach rr $rrs {
            table set -subtable "test_teble" [DNS::rdata $rr] [DNS::question name]         
        }    
    }
}

3. 配置出向选路,如果出向访问的IP在test_teble表中,则出向流量走pool_test,否则出向流量走Default_pool。注意:设备配置在出口位置,还需要把地址转换为公网地址。

when CLIENT_ACCEPTED {
    if { [table lookup -subtable "test_teble" [IP::local_addr] ]  != "" }  {
        pool pool_test
    }else {
        pool Default_pool
    }
}
when LB_SELECTED {
    if  {  [IP::addr [LB::server addr]  equals 1.1.1.1]} {
        snatpool snat_test
    }else { 
        snat automap
    }
}

9. 清空http uri

背景:清除http uri。

when HTTP_REQUEST {
    HTTP::uri "/"
}

10. 一个vs运行http和https

背景:客户需要使用同一个vs,接收并处理https和http业务请求。
实现方式:配置https虚拟服务并配置证书,配置irule,https用户使用特定网段正常负载转发,http用户关闭ssl profile并负载转发

when CLIENT_ACCEPTED {
    if { [IP::addr [IP::client_addr] equals 192.168.10.0/24 ] } {
    pool test_side_2
    } else {
    SSL::disable clientside
    pool test_side_1
    }
}

11. 多条策略使用switch命中规则案例

when CLIENT_ACCEPTED {
    switch [string toupper [IP::client_addr]] {
        "10.252.149.11" {
            snatpool sp_10.252.255.11
        }
        "10.252.149.12" {
            snatpool sp_10.252.255.12
        }
        "default" {
            drop
        }
    }
}

12. irule 防止x-forwarded-for 攻击

when HTTP_REQUEST {
    set xff 0
    foreach x [HTTP::header names] {
        if { [string tolower $x] equals "x-forwarded-for" } {
            set xff 1
            HTTP::header remove $x
            HTTP::header insert X-FORWARDED-FOR [IP::client_addr]
        }
    }   
    if { $xff == 0 } {
        HTTP::header insert X-FORWARDED-FOR [IP::client_addr]
    }
}

13. https业务指定源地址迁移

when CLIENT_ACCEPTED {
    if { [IP::addr [IP::client_addr] equals 111.20.119.234/32 ] }{
        pool pool_159_443
    } else {
        SSL::disable serverside
        pool g_KHDQ3_VSMobileJieru_01
    }
}

14. http uri 替换

For Example:

Original HTTP Request
https://www.yourdomain.test/public/page/login.html

New HTTP Request
https://www.yourdomain.test/private/page/login.html

方式一: Using String Map : 字符串映射会将 URI 中找到的键字符串的每个实例替换为新值。

when HTTP_REQUEST {
if {[HTTP::uri] starts_with "/public/"} {
HTTP::uri [string map {"/public/" "/private/"}[HTTP::uri]]
pool pool_web
}
}

方式二:Using RegSub : (不带 -all 选项)将仅将 URI 中找到的密钥字符串的第一个实例替换为新值。

when HTTP_REQUEST {
if {[HTTP::uri] starts_with "/public/"} {
if { [regsub -nocase /public/ [HTTP::uri] /private/ new_uri] > 0 } {
HTTP::uri $new_uri
}
pool pool_web
}
}

15、允许指定Host访问vs

方式一:

when HTTP_REQUEST {
      if { [HTTP::host] !=  "192.168.10.96" } {
        reject
        }
}

方式二:

when HTTP_REQUEST {
    if {not ([string tolower [HTTP::host]] starts_with "link.it.10086.cn")}{
       reject
    }
}

方式三:使用data group

when HTTP_REQUEST {
    if {not [class match [HTTP::host] equals host_reject ]}{
       reject
    }
}

方式四:使用data group和正则匹配

when HTTP_REQUEST {
    if {[string tolower [HTTP::host]] ends_with host_reject } {
      pool test_side_1
    } 
    elseif {[string tolower [HTTP::host]] matches_regex {^ec\.it\.10086\.cn$}} {
      pool test_side_1
    }
    elseif {[class match [HTTP::host] equals host_reject1 ]} {
      pool test_side_1
    }
    else{
      reject
    }
}

16、根据edns客户端地址的最后一段奇偶性选择pool

when DNS_REQUEST {
  if { [DNS::edns0 exists] } {
    set endip [string tolower [getfield [DNS::edns0 subnet address] "." 4]]
    if { [expr $endip % 2] == 0}{
    pool a.com
    }
    else {
    pool b.com
  }
}
}
打赏
文章目录