基于cookie的會(huì)話保持

在 HAProxy 中,可以通過使用 cookie 配置來實(shí)現(xiàn)基于 Cookie 的會(huì)話保持。cookie 配置用于配置與會(huì)話保持相關(guān)的選項(xiàng),允許您定義要在HTTP響應(yīng)中插入或重寫的Cookie以及其他與Cookie會(huì)話保持相關(guān)的參數(shù)。 以下是一些常用的 cookie 配置選項(xiàng): cookie <cookie-name> <type> [prefix|postfix] [indirect] [nocache]: <cookie-name>: 要使用的Cookie名稱。 <type>: 定義Cookie的類型,可以是insert, rewrite, 或者 insert indirect。insert 表示在響應(yīng)中插入新的Cookie,rewrite 表示重寫已有的Cookie,insert indirect 表示在響應(yīng)中插入新的Cookie,并將值保存到一個(gè)間接的Cookie中。 prefix|postfix: 用于定義插入的Cookie值是作為前綴還是后綴添加到Cookie中,默認(rèn)為前綴。 indirect: 與insert indirect 配合使用,將Cookie值保存到一個(gè)間接的Cookie中。 nocache: 表示HAProxy不會(huì)在響應(yīng)中添加"Cache-Control"和"Expires"頭部,防止緩存Cookie。 cookie <cookie-name> insert indirect nocache: 這是一個(gè)常用的基于Cookie的會(huì)話保持配置選項(xiàng)。它在響應(yīng)中插入一個(gè)新的Cookie,并將值保存到一個(gè)間接的Cookie中。同時(shí)禁用緩存,確保會(huì)話保持的Cookie不會(huì)被緩存。 cookie <cookie-name> rewrite: 這個(gè)選項(xiàng)用于重寫已有的Cookie的值。如果請(qǐng)求中已經(jīng)包含指定名稱的Cookie,HAProxy會(huì)根據(jù)會(huì)話保持策略更新Cookie的值。 image.png image.png

HAProxy狀態(tài)頁

HAProxy提供了一個(gè)狀態(tài)頁面,也稱為HAProxy統(tǒng)計(jì)頁面(HAProxy Stats Page),它是一個(gè)Web界面,用于查看和監(jiān)控HAProxy的實(shí)時(shí)狀態(tài)信息。通過訪問這個(gè)狀態(tài)頁面,您可以獲取HAProxy的運(yùn)行狀態(tài)、負(fù)載均衡信息、后端服務(wù)器的狀態(tài)等,幫助您了解HAProxy的性能和連接情況。

stats enable #基于默認(rèn)的參數(shù)啟用stats page
stats hide-version #隱藏版本
stats refresh <delay> #設(shè)定自動(dòng)刷新時(shí)間間隔
stats uri <prefix> #自定義stats page uri,默認(rèn)值:/haproxy?stats
stats realm <realm> #賬戶認(rèn)證時(shí)的提示信息,示例:stats realm : HAProxy\ Statistics
stats auth <user>:<passwd> #認(rèn)證時(shí)的賬號(hào)和密碼,可使用多次,默認(rèn):no authentication
stats admin { if | unless } <cond> #啟用stats page中的管理功能

image.png image.png

報(bào)文修改

在 HAProxy 中,可以通過使用報(bào)文修改(Message Modification)來修改請(qǐng)求和響應(yīng)報(bào)文的內(nèi)容。報(bào)文修改允許您在 HAProxy 轉(zhuǎn)發(fā)請(qǐng)求和響應(yīng)之前,對(duì)報(bào)文進(jìn)行自定義的編輯、增加、刪除或替換操作。這樣您可以實(shí)現(xiàn)一些高級(jí)功能,例如重寫請(qǐng)求URL、修改請(qǐng)求頭部、處理響應(yīng)內(nèi)容等。 HAProxy 提供了兩種報(bào)文修改的方式: HTTP 請(qǐng)求和響應(yīng)報(bào)文修改: 通過使用 http-request 和 http-response 配置項(xiàng),您可以在 HTTP 請(qǐng)求和響應(yīng)處理階段修改報(bào)文。 TCP 請(qǐng)求和響應(yīng)報(bào)文修改: 通過使用 tcp-request 和 tcp-response 配置項(xiàng),您可以在 TCP 請(qǐng)求和響應(yīng)處理階段修改報(bào)文。

在請(qǐng)求報(bào)文尾部添加指定首部
reqadd <string> [{if | unless} <cond>]
從請(qǐng)求報(bào)文中刪除匹配正則表達(dá)式的首部
reqdel <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>]
在響應(yīng)報(bào)文尾部添加指定首部
rspadd <string> [{if | unless} <cond>]
示例:
rspadd X-Via:\ HAPorxy
從響應(yīng)報(bào)文中刪除匹配正則表達(dá)式的首部
rspdel <search> [{if | unless} <cond>]
rspidel <search> [{if | unless} <cond>]
示例:
rspidel server.* #從響應(yīng)報(bào)文刪除server信息
rspidel X-Powered-By:.* #從響應(yīng)報(bào)文刪除X-Powered-By信息

image.png image.pngimage.png

HAProxy日志配置

在 HAProxy 中,您可以通過配置日志來記錄關(guān)于請(qǐng)求、響應(yīng)和HAProxy運(yùn)行狀態(tài)的信息。通過日志記錄,您可以監(jiān)控流量、故障排查、性能優(yōu)化以及分析用戶行為。HAProxy 支持將日志輸出到不同的目標(biāo),例如文件、遠(yuǎn)程服務(wù)器、syslog 等。

globallog /dev/log local0log /dev/log local1 noticedefaultslog globalmode httpoption httplogoption dontlognulltimeout connect 5000timeout client 50000timeout server 50000frontend http_frontbind *:80default_backend http_backbackend http_backserver web1 192.168.1.101:80 checkserver web2 192.168.1.102:80 check
在上述示例中,我們配置了兩個(gè)日志輸出目標(biāo),一個(gè)是 /dev/log,使用 local0 設(shè)施(facility),另一個(gè)是 /dev/log,使用 local1 設(shè)施。設(shè)施是 syslog 的一部分,用于將日志分配到不同的系統(tǒng)設(shè)施中。
日志配置項(xiàng)解釋:
log /dev/log local0: 將日志輸出到 /dev/log,使用 local0 設(shè)施。這是系統(tǒng)日志默認(rèn)使用的設(shè)施,您可以在 syslog 配置中指定將該設(shè)施的日志輸出到特定文件或遠(yuǎn)程服務(wù)器。
log /dev/log local1 notice: 將日志輸出到 /dev/log,使用 local1 設(shè)施,并指定日志級(jí)別為 notice。notice 級(jí)別意味著只記錄比 notice 級(jí)別更高的日志消息,例如 warning、err、alert 和 emerg 等。
log global: 在默認(rèn)配置部分使用 log global,表示將使用全局配置的日志設(shè)置。
option httplog: 啟用 HTTP 日志記錄,這將記錄關(guān)于 HTTP 請(qǐng)求和響應(yīng)的信息,包括客戶端IP、請(qǐng)求方法、請(qǐng)求URL、HTTP狀態(tài)碼等。
option dontlognull: 防止記錄空連接的日志

Rsyslog配置

vim /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
local3.* /var/log/haproxy.log
# systemctl restart rsyslog

自定義日志格式

在 HAProxy 中,除了使用預(yù)定義的占位符來定義自定義日志格式外,還可以使用 capture 來自定義捕獲特定請(qǐng)求或響應(yīng)的信息,并將其包含在日志中。 capture 是一個(gè)強(qiáng)大的選項(xiàng),允許您從請(qǐng)求和響應(yīng)中提取關(guān)鍵信息,并將其記錄在日志中。您可以在 http-request 和 http-response 配置中使用 capture 來捕獲所需的信息。

capture cookie <name> len <length> #捕獲請(qǐng)求和響應(yīng)報(bào)文中的 cookie并記錄日志
capture request header <name> len <length> #捕獲請(qǐng)求報(bào)文中指定的首部內(nèi)容和長度并記錄日志
capture response header <name> len <length> #捕獲響應(yīng)報(bào)文中指定的內(nèi)容和長度首部并記錄日志
示例:
capture request header Host len 256
capture request header User-Agent len 512
capture request header Referer len 15
globallog /dev/log local0log /dev/log local1 noticedefaultslog globallog-format "%ci:%cp [%t] %ft %b/%s %hrl %hs %[capture.req.hdr(0)] %[capture.res.hdr(0)]"mode httpoption httplogoption dontlognulltimeout connect 5000timeout client 50000timeout server 50000frontend http_frontbind *:80http-request capture req.hdr(Host) len 64default_backend http_backbackend http_backserver web1 192.168.1.101:80 checkserver web2 192.168.1.102:80 check

在上述示例中,我們使用 %[capture] 來顯示捕獲的請(qǐng)求頭部的值,并且使用了 %[capture.req.hdr(0)],表示從請(qǐng)求頭部中捕獲了第一個(gè)頭部的值(在本例中,我們捕獲了 "Host" 頭部的值)。同樣的,如果您需要顯示捕獲的響應(yīng)頭部的值,可以使用 %[capture.res.hdr(0)]。

壓縮功能

對(duì)響應(yīng)給客戶端的報(bào)文進(jìn)行壓縮,以節(jié)省網(wǎng)絡(luò)帶寬,但是會(huì)占用部分CPU性能。在 HAProxy 中,可以通過配置壓縮功能來對(duì)傳輸?shù)膬?nèi)容進(jìn)行壓縮,從而減少數(shù)據(jù)傳輸?shù)拇笮?#xff0c;提高網(wǎng)絡(luò)性能,以及減少帶寬消耗。壓縮功能通常用于減輕網(wǎng)絡(luò)負(fù)載和加快頁面加載速度,特別是對(duì)于文本內(nèi)容(例如 HTML、CSS、JavaScript)來說效果明顯 HAProxy 提供了兩種壓縮方式:Gzip 壓縮和Brotli 壓縮。您可以根據(jù)需求選擇適合您場景的壓縮算法。

以下是如何在 HAProxy 中配置壓縮功能的示例

global# 其他全局配置defaults# 其他默認(rèn)配置frontend http_frontbind *:80mode httpdefault_backend http_backbackend http_backmode httpcompression algo gzipcompression type text/html text/plain text/css application/javascriptserver web1 192.168.1.101:80 checkserver web2 192.168.1.102:80 check
global# 其他全局配置defaults# 其他默認(rèn)配置frontend http_frontbind *:80mode httpdefault_backend http_backbackend http_backmode httpcompression algo brcompression type text/html text/plain text/css application/javascriptserver web1 192.168.1.101:80 checkserver web2 192.168.1.102:80 check
#通過設(shè)置 compression algo gzip 來指定壓縮算法為 Gzip。然后,使用 compression type

image.png

web服務(wù)器狀態(tài)監(jiān)測

在 HAProxy 中,可以使用健康檢查來監(jiān)測后端Web服務(wù)器的狀態(tài),以確保它們正常工作并提供服務(wù)。通過定期進(jìn)行健康檢查,HAProxy可以自動(dòng)發(fā)現(xiàn)不可用的服務(wù)器,并將流量從故障服務(wù)器轉(zhuǎn)移到其他健康的服務(wù)器,從而提高系統(tǒng)的可用性和穩(wěn)定性。

option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
基于四層的傳輸端口做狀態(tài)監(jiān)測
基于指定URI 做狀態(tài)監(jiān)測
基于指定URI的request請(qǐng)求頭部內(nèi)容做狀態(tài)監(jiān)測

在 HAProxy 中,可以使用多種方式來進(jìn)行后端服務(wù)器的健康檢查。每種方式都適用于不同的應(yīng)用場景和后端服務(wù)器類型。以下是一些常見的健康檢查方式: TCP 健康檢查: 使用TCP健康檢查時(shí),HAProxy會(huì)簡單地嘗試連接到后端服務(wù)器的指定端口。如果連接成功,則認(rèn)為服務(wù)器是健康的,否則被視為不健康。TCP健康檢查適用于不需要檢查具體服務(wù)狀態(tài)的場景,例如數(shù)據(jù)庫服務(wù)器。

backend my_backendmode tcpserver web1 192.168.1.101:3306 checkserver web2 192.168.1.102:3306 check

HTTP 健康檢查: 使用HTTP健康檢查時(shí),HAProxy會(huì)發(fā)送HTTP請(qǐng)求到后端服務(wù)器的特定URL,并檢查響應(yīng)狀態(tài)碼是否符合預(yù)期。HTTP健康檢查適用于Web服務(wù)器或應(yīng)用服務(wù)器,可以檢查具體的應(yīng)用狀態(tài)。

backend my_backendmode httpoption httpchk GET /healthcheck HTTP/1.1\r\nHost:\ www.example.comhttp-check expect status 200server web1 192.168.1.101:80 checkserver web2 192.168.1.102:80 check
#通過設(shè)置 option httpchk 來指定HTTP健康檢查的請(qǐng)求,并使用 http-check expect status 200 來指定期望的響應(yīng)狀態(tài)碼。

SMTP 健康檢查: 使用SMTP健康檢查時(shí),HAProxy會(huì)嘗試連接到后端服務(wù)器的SMTP端口,并檢查服務(wù)器是否響應(yīng)了有效的SMTP協(xié)議。

backend my_backendmode tcpoption smtpchkserver smtp1 192.168.1.101:25 checkserver smtp2 192.168.1.102:25 check

其他健康檢查選項(xiàng): HAProxy還支持其他健康檢查選項(xiàng),例如使用ssl-hello-chk進(jìn)行SSL握手檢查,使用ldap-check進(jìn)行LDAP檢查等。這些健康檢查方式適用于特定的應(yīng)用場景和協(xié)議。

ACL

在 HAProxy 中,acl(Access Control List)是用來定義訪問控制規(guī)則的功能。ACL允許您根據(jù)特定條件對(duì)請(qǐng)求進(jìn)行分類和匹配,然后根據(jù)匹配結(jié)果執(zhí)行相應(yīng)的操作。這使得您能夠?qū)φ?qǐng)求進(jìn)行高級(jí)的路由和過濾。

acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名稱 匹配規(guī)范 匹配模式 具體操作符 操作對(duì)象類型<aclname>:ACL 的名稱,用于標(biāo)識(shí) ACL 規(guī)則,可以自定義。
<criterion>:ACL 規(guī)則的匹配條件,可以是以下 ACL 配置選項(xiàng)之一,如 path_beg、hdr_dom、src 等。具體可以參考之前回答中提到的 ACL 配置選項(xiàng)。
[flags]:(可選)用于指定額外的標(biāo)志,比如 i 表示大小寫不敏感匹配,-i 表示大小寫敏感匹配。
[operator]:(可選)用于指定匹配操作符,例如 eq 表示等于,ne 表示不等于,lt 表示小于,gt 表示大于,等。
[<value>]:(可選)用于指定要匹配的具體對(duì)象類型。

criterion

hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息
hdr_beg([<name> [,<occ>]]):前綴匹配,header中指定匹配內(nèi)容的begin
hdr_end([<name> [,<occ>]]):后綴匹配,header中指定匹配內(nèi)容end
hdr_dom([<name> [,<occ>]]):域匹配,header中的domain name
hdr_dir([<name> [,<occ>]]):路徑匹配,header的uri路徑
hdr_len([<name> [,<occ>]]):長度匹配,header的長度匹配
hdr_reg([<name> [,<occ>]]):正則表達(dá)式匹配,自定義表達(dá)式(regex)模糊匹配
hdr_sub([<name> [,<occ>]]):子串匹配,header中的uri模糊匹配
dst 目標(biāo)IP
dst_port 目標(biāo)PORT
src 源IP
src_port 源PORT
url_param():用于檢查請(qǐng)求 URL 中的參數(shù)值
req_ 和 res_ 前綴**:用于檢查請(qǐng)求和響應(yīng)中的其他屬性,例如 Cookies、HTTP 方法等。
ssl_fc:用于檢查請(qǐng)求是否使用 SSL/TLS 加密。示例
# 檢查 User-Agent 請(qǐng)求頭是否包含 "Mozilla"
acl is_mozilla hdr(User-Agent) -i Mozilla
# 檢查 Host 請(qǐng)求頭是否以 "example.com" 結(jié)束
acl is_example hdr_end(Host) -i example.com
# 檢查請(qǐng)求是否使用 HTTPS 加密
acl is_https ssl_fc
# 檢查請(qǐng)求的 HTTP 方法是否為 POST
acl is_post_method req.method POST
# 檢查請(qǐng)求的來源 IP 地址是否在指定的 IP 段內(nèi)
acl is_internal src 192.168.0.0/16
# 檢查請(qǐng)求 URL 中的參數(shù) "id" 是否等于 "123"
acl is_id_123 url_param(id) eq 123
# 檢查請(qǐng)求的來源端口是否為 8080
acl is_src_port_8080 src_port 8080
# 檢查請(qǐng)求的目標(biāo)端口是否為 443
acl is_dst_port_443 dst_port 443
path_beg 請(qǐng)求的URL開頭,如/static、/images、/img、/css
path_end 請(qǐng)求的URL中資源的結(jié)尾,如 .gif .png .css .js .jpg .jpe

flags

-i 不區(qū)分大小寫
-m 使用指定的pattern匹配方法
-n 不做DNS解析
-u 禁止acl重名,否則多個(gè)同名ACL匹配或關(guān)系
-f:從文件中讀取條件,比如黑名單或白名單

operator

整數(shù)比較:eq、ge、gt、le、lt
字符比較:
- exact match (-m str) :字符串必須完全匹配模式
- substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一個(gè)被發(fā)現(xiàn),ACL將匹配
- prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一個(gè)被發(fā)現(xiàn),ACL將匹配
- suffix match (-m end) :將模式與提取字符串的尾部進(jìn)行比較,如果其中任何一個(gè)匹配,則ACL進(jìn)行匹配
- subdir match (-m dir) :查看提取出來的用斜線分隔(“/”)的字符串,如果其中任何一個(gè)匹配,則ACL進(jìn)行
匹配
- domain match (-m dom) :查找提取的用點(diǎn)(“.”)分隔字符串,如果其中任何一個(gè)匹配,則ACL進(jìn)行匹配

value

- Boolean #布爾值
- integer or integer range #整數(shù)或整數(shù)范圍,比如用于匹配端口范圍
- IP address / network #IP地址或IP范圍, 192.168.0.1 ,192.168.0.1/24
- string--> www.lgw.com
exact –精確比較
substring—子串
suffix-后綴比較
prefix-前綴比較
subdir-路徑, /wp-includes/js/jquery/jquery.js
domain-域名,www.lgw.com
- regular expression #正則表達(dá)式
- hex block #16進(jìn)制

ACL調(diào)用方式

在 HAProxy 中,可以通過以下方式來使用 ACL(Access Control List):

- 與:隱式(默認(rèn))使用
- 或:使用“or” 或 “||”表示
- 否定:使用“!“ 表示
示例:
if valid_src valid_port #與關(guān)系,A和B都要滿足為true
if invalid_src || invalid_port #或,A或者B滿足一個(gè)為true
if ! invalid_src #非,取反,A和B哪個(gè)也不滿足為true

用于條件判斷:將 ACL 用于條件判斷,例如在 use_backend 或 use-server 語句中,根據(jù)請(qǐng)求的特征選擇后端服務(wù)器或服務(wù)器組

# 定義 ACL 條件
acl is_example_com hdr(host) -i example.com
acl is_secure_req ssl_fc# 根據(jù) ACL 條件選擇后端服務(wù)器
use_backend backend_secure if is_secure_req
use_backend backend_example if is_example_com

用于拒絕請(qǐng)求:在 http-request 或 http-response 中使用 ACL 條件,以便在特定情況下拒絕或重定向請(qǐng)求。

# 定義 ACL 條件
acl is_banned_ip src 192.168.0.100# 拒絕來自被禁止 IP 的請(qǐng)求
http-request deny if is_banned_ip

自定義日志

# 定義 ACL 條件
acl is_api_request path_beg /api/# 自定義日志格式,根據(jù) ACL 條件輸出不同的信息
log-format "%ci - [%t] %r %ST %B %ts %ac %HM %HV %hrl %hsl %hcl %{+Q}r \"%[capture.req.method] %[capture.req.uri]\""

image.png image.pngimage.pngimage.png

預(yù)定義ACL

image.pngimage.png

自定義錯(cuò)誤頁面

錯(cuò)誤頁面

image.png image.png

http重定向

image.png

ssl實(shí)現(xiàn)

配置HAProxy支持https協(xié)議:
支持ssl會(huì)話;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
crt 后證書文件為PEM格式,且同時(shí)包含證書和所有私鑰
cat demo.crt demo.key > demo.pem
把80端口的請(qǐng)求重向定443
bind *:80
redirect scheme https if !{ ssl_fc }
向后端傳遞用戶請(qǐng)求的協(xié)議和端口(frontend或backend)
http_request set-header X-Forwarded-Port %[dst_port]
http_request add-header X-Forwared-Proto https if { ssl_fc }