什么是ACL
- ACL只要对请求报文和相应报文进行过滤和匹配,其配置方法主要分两步:
1.首先定义ACL规则,既定义一个测试条件,条件可以是请求报文中的 源地址,源端口,目标地址,目标端口,请求方法,URL,文件后缀等
2.然后在条件得到满足时执行相应的动作;比如阻止请求,又或者转发请求到某特定的后端服务器
ACL定义方法
# ACL语法
acl <aclname> <criterion> [flags] [operator] [value] ...
#acl 名称 条件 条件标记位 具体操作府 操作对象类型
# ACL示例
acl my_chrome hdr(User-Agent) -m sub -i chrom
-
: ACL名称,可使用字母 数字 : . - _ 区分字符大小写 -
: 比对的标准和条件
1.基于源地址,源端口 目标地址,目标端口: src,src_port,dst,dst_port
2.基于Header信息比对: hdr,hdr_beg,hdr_end,hdr_dom
3.基于路径和后缀比对: path_beg,path_end
4.基于请求方法比对: method -
: 条件标记 - -i 不区分大小写
- -m 使用pattern匹配方法
- -n 不做dns解析
- -u 禁止acl重名,否则多个同名的ACL为或的关系
-
:
其中flag中的 -m 选项可使用的模式匹配方法如下,需要说明的是有些方法已被默认指定无需声明,例如int,ip- -eq、-ne、 -ge、 -le、 -gt、 -lt
2.(-m str): 字符串必须完全匹配 精确匹配 - (-m sub): 在字符串中查找 如果找到则匹配 模糊匹配
- (-m beg): 在字符串首部查找 如果找到则匹配 首部匹配
- (-m end): 在字符串尾部查找 如果找到则匹配 尾部匹配
- (-m dir): 提取用斜线/分隔的字符串
- (-m dom): 提取用点.分隔字符串
- -eq、-ne、 -ge、 -le、 -gt、 -lt
path_beg
path_beg
# 示例: 测试URL是否以<string>指定的模式开头
acl url_static path_beg -i /static /images /javascript
path_end
path_end
# 示例: 下面的例子用户测试URL是否以jpg gif png css或js结尾
acl url_static path_end -i .jpg .gif .png .css .js
hdr_beg
hdr_beg
# 示例:测试请求的host开头是否为 img,video,static
acl host_static hdr_beg(host) -i img. video. static.
hdr_end
hdr_end
# 示例: 测试请求的host的结尾是否为 .com .cn
acl host_static hdr_end(host) -i .com .cn
hdr_dom
hdr_dom(host): 用于测试请求的host名称
# 示例: 测试请求的host是否为 www.yangyijing.cn
acl my_www_host hdr_dom(host) -i www.yangyijing.cn
hdr
hdr
# 示例: 测试请求的User-Agent是否为chrome
acl my_chrome hdr(User-Agent) -m sub -i chrom
ACL逻辑关系
多个acl作为条件时的逻辑关系:
- 与: 默认,如if acl1 acl2 表示同时满足第一个acl的同时要满足第二acl 此条件为真
- 或: 使用 or 或者 || 表示,如 if acl1 || acl2 表示满足其中一个条件则为真
- 非: 使用!表示,如if ! acl2 表示对acl2规则进行取反 则为真
http和tcp的访问控制
http
listen haproxy-stats
mode http
bind *:7777
stats enable # 启用stats功能
stats refresh 2s # 设定自动刷新时间间隔
stats hide-version # 隐藏haproxy版本
stats uri /haproxy?stats # stats页面的访问路径
stats realm "HAProxy stats" # 认证提示信息
stats auth oldxu:123456 # 认证的账号和密码
stats admin if TRUE # 启用管理功能
# 基于http访问控制 来源的用户非10.0.0.1 或者使用的是curl则拒绝
acl source_ip src 10.0.0.1
acl deny_agent hdr(User-Agent) -m sub -i Curl
http-request deny if !source_ip || deny_agent
tcp
基于tcp访问控制,结合acl规则来实现:
listen ssh
bind *:2222
mode tcp
balance roundrobin
server sshsrv1 172.16.1.7:22 check
server sshsrv2 172.16.1.8:22 check
acl invalid_src src 172.16.1.9
tcp-request connection reject if invalid_src
基于域名的调度
haproxy基于域名调度:
frontend web
bind *:80
mode http
# acl规则
acl www_site hdr(host) -i www.oldxu.net
acl m_site hdr(host) -i m.oldxu.net
# 调用
use_backend www_cluster if www_site
use_backend m_cluster if m_site
default_backend www_cluster
backend www_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ m.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 8080 inter 3s rise 2 fall 3
backend m_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ m.oldxu.net
server 172.16.1.7 172.16.1.7:8080 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:8080 check port 8080 inter 3s rise 2 fall 3
基于设备的调度
frontend web
bind *:80
mode http
# acl规则-基于设备调度 chrome --www firefox -- m
acl chrome_agent hdr(User-Agent) -m sub -i chrome
acl firefox_agent hdr(User-Agent) -m sub -i firefox
# 调用
use_backend www_cluster if chrome_agent
use_backend m_cluster if firefox_agent
default_backend www_cluster
backend www_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ m.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 8080 inter 3s rise 2 fall 3
backend m_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ m.oldxu.net
server 172.16.1.7 172.16.1.7:8080 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:8080 check port 8080 inter 3s rise 2 fall 3
基于uri进行调度
基于请求的uri进行调度到不同集群资源池
frontend web
bind *:80
mode http
# acl规则
acl www_site hdr(host) -i www.oldxu.net
# acl规则-请求/static www_cluster /user --- m_cluster
acl req_static path_beg -i /static
acl req_user path_beg -i /user
# 调用
use_backend www_cluster if www_site req_static
use_backend m_cluster if www_site req_user
default_backend www_cluster
backend www_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ m.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 80 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 80 inter 3s rise 2 fall 3
backend m_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ m.oldxu.net
server 172.16.1.7 172.16.1.7:8080 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:8080 check port 8080 inter 3s rise 2 fall 3
基于后缀的调度:
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend web
bind *:80
mode http
# acl规则
acl www_site hdr(host) -i www.oldxu.net
# acl规则-请求txt --》 www 请求 pdf --m
acl req_txt path_end -i .txt
acl req_pdf path_end -i .pdf
# 调用
use_backend www_cluster if www_site req_txt
use_backend m_cluster if www_site req_pdf
default_backend www_cluster
backend www_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ m.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 80 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 80 inter 3s rise 2 fall 3
backend m_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ m.oldxu.net
server 172.16.1.7 172.16.1.7:8080 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:8080 check port 8080 inter 3s rise 2 fall 3
动静分离效果:
动静分离示例:
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 30000
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend http-in
bind *:80
mode http
log global
capture request header Host len 20
capture request header Referer len 60
# acl规则
acl domain_site hdr(host) -i www.oldxu.net
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .jpeg .gif .png .css .js
use_backend static_servers if domain_site url_static
use_backend dynamic_servers if domain_site
backend static_servers
balance roundrobin
server imgsrv1 172.16.200.7:80 check maxconn 6000
server imgsrv2 172.16.200.8:80 check maxconn 6000
backend dynamic_servers
cookie srv insert nocache
balance roundrobin
server websrv1 172.16.200.7:80 check maxconn 1000 cookie websrv1
server websrv2 172.16.200.8:80 check maxconn 1000 cookie websrv2
server websrv3 172.16.200.9:80 check maxconn 1000 cookie websrv3
tcp-mysql代理:
[root@proxy01 ~]# cat /etc/haproxy/conf.d/mysql.cfg
frontend mysql
bind *:3366
mode tcp
use_backend mysql_read_servers
#acl access_user src 10.0.0.1
#tcp-request connection reject if !access_user
backend mysql_read_servers
mode tcp
server 172.16.1.7 172.16.1.7:3306 check port 3306
server 172.16.1.8 172.16.1.8:3306 check port 3306
https:
1.准备证书
[root@proxy01 ~]# cat /etc/nginx/ssl_key/6152893_blog.oldxu.net.pem > /ssl/blog_key.pem
[root@proxy01 ~]# cat /etc/nginx/ssl_key/6152893_blog.oldxu.net.key >> /ssl/blog_key.pem
2.配置单个域名https
frontend web
bind *:80
bind *:443 ssl crt /ssl/blog_key.pem
mode http
# acl 规则将blog 调度到blog_cluster
acl blog_domain hdr(host) -i blog.oldxu.net
redirect scheme https code 301 if !{ ssl_fc } blog_domain
use_backend blog_cluster if blog_domain
# zh
acl zh_domain hdr(host) -i zh.oldxu.net
use_backend zh_cluster if zh_domain
backend blog_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ blog.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 80 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 80 inter 3s rise 2 fall 3
backend zh_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ zh.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 8080 inter 3s rise 2 fall 3
3.多域名多证书
frontend web
bind *:80
bind *:443 ssl crt /ssl/blog_key.pem crt /ssl/zh_key.pem
mode http
# acl 规则将blog 调度到blog_cluster
acl blog_domain hdr(host) -i blog.oldxu.net
use_backend blog_cluster if blog_domain
# zh
acl zh_domain hdr(host) -i zh.oldxu.net
use_backend zh_cluster if zh_domain
# 全部都跳转https
redirect scheme https code 301 if !{ ssl_fc }
backend blog_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ blog.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 80 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 80 inter 3s rise 2 fall 3
backend zh_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ zh.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 8080 inter 3s rise 2 fall 3
4.配置多域名,部分uri走https
frontend web
bind *:80
bind *:443 ssl crt /ssl/blog_key.pem crt /ssl/zh_key.pem
mode http
# acl 规则将blog 调度到blog_cluster
acl blog_domain hdr(host) -i blog.oldxu.net
acl blog_ssl_path path_beg -i /login /pay
# 请求域名为 blog.oldxu.net 并且不是https协议,并且请求的是 /login 则全部跳https协议
redirect scheme https code 301 if !{ ssl_fc } blog_domain blog_ssl_path
# 请求域名为 blog.oldxu.net 并且是https协议,但不是 /login 则全部跳转至http协议
redirect scheme http code 301 if { ssl_fc } blog_domain !blog_ssl_path
use_backend blog_cluster if blog_domain
# zh
acl zh_domain hdr(host) -i zh.oldxu.net
use_backend zh_cluster if zh_domain
redirect scheme https code 301 if !{ ssl_fc } zh_domain
# 全部都跳转https
#redirect scheme https code 301 if !{ ssl_fc }
backend blog_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ blog.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 80 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 80 inter 3s rise 2 fall 3
backend zh_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ zh.oldxu.net
server 172.16.1.7 172.16.1.7:80 check port 8080 inter 3s rise 2 fall 3
server 172.16.1.8 172.16.1.8:80 check port 8080 inter 3s rise 2 fall 3
高可用:
1、要保证两台节点的配置一样;
如下操作在172.16.1.5节点上进行
scp haproxy22.rpm.tar.gz root@10.0.0.6:~
scp /etc/haproxy/haproxy.cfg root@172.16.1.6:/etc/haproxy/haproxy.cfg
scp -rp /ssl root@172.16.1.6:/
systemctl start haproxy
systemctl start keepalived
如下操作在172.16.1.6节点上进行
yum localinstall haproxy/*.rpm -y
systemctl start haproxy
systemctl start keepalived
haproxy优化
[root@oldxu ~]# vim /etc/sysct.conf
# tcp优化
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_tw_reuse = 1 # 端口复用
net.ipv4.tcp_max_tw_buckets = 5000 # TIME-WAIT最大数量
net.ipv4.tcp_syncookies = 1 # 防止SYN Flood攻击,开启后max_syn_backlog理论上没有最大值
net.ipv4.tcp_max_syn_backlog = 8192 # SYN半连接队列可存储的最大值
net.core.somaxconn = 65535 # SYN全连接队列可存储的最大值
# 修改TCP TIME-WAIT超时时间 https://help.aliyun.com/document_detail/155470.html
net.ipv4.tcp_tw_timeout = 5
net.core.netdev_max_backlog = 2000000 # 调网卡缓存队列,默认为1000
# 重试
net.ipv4.tcp_syn_retries=2 # 发送SYN包重试次数,默认6
net.ipv4.tcp_synack_retries = 2 # 返回syn+ack重试次数,默认5
# 系统中允许存在文件句柄最大数目(系统级)
fs.file-max = 204800
vm.swappiness = 0 # 最大限度使用物理内存
[root@oldxu ~]# tail /etc/security/limits.conf
# max user processes
* soft nproc 60000
* hard nproc 60000
# open files
* soft nofile 100000
* hard nofile 100000
------------------------------------------------------------------------
haproxy基本配置
haproxy调度算法
roundrobin;
static-rr;
leastconn;
uri;
url_param;
source;
haproxy ACL规则
src:
path_beg;
path_end;
hdr_beg;
bdr_eng;
hdr;
-m sub;
-i 忽略大小写;
http-request;
tcp-request;
Hpaorxy场景示例
https
http
tcp
keepalived