配置 Haproxy 防范 DDOS 攻击
作为 load balancer, Happroxy 常常作为服务器的前端,向外界用户提供服务的入口,如果能在入口处处理安全相关问题,将极大简化后端的设计。事实上,Haproxy 不仅仅是一款开源出色的 load balancer(四层和七层),而且在安全上也相当出色。它配合内核 IP/TCP 协议栈,能够较好的抵抗 DOS, DDOS 攻击,还能通过限制单个 IP 的连接数和请求速率等,防止用户的恶意行为。
TCP syn flood attacks
通过向服务器发送大量的 TCP syn 分组,恶意用户实现了了 TCP syn flood 攻击,幸运的是,简单的配置内核网络参数即可防止这种攻击。
#vim /etc/sysctl.conf 然后 sysctl -p
-
[root@kaka-games-balancers
-02 ~]# vim /etc/sysctl.conf
-
-
.....................
-
.....................
-
.....................
-
-
# Protection SYN flood
-
net.ipv4.tcp_syncookies =
1
-
net.ipv4.conf.all.rp_filter =
1
-
net.ipv4.tcp_max_syn_backlog =
1024
-
-
-
[root@kaka-games-balancers
-02 ~]# sysctl -p
Slowloris like attacks
一个 Http 请求通常包括头部、url、methods 等,服务器需要接收整个 Http 请求后会做出响应。恶意用户发送缓慢的 Http 请求,比如一个字节一个字节的发送头部,服务器将一直处于 wating 状态,从而耗费服务器的资源。Haproxy 通过配置 timeout http-request 参数,当一个用户的请求时间超过设定值时,Haproxy 断开与该用户的连接。
参数: timeout http-request
-
[root@gadmobe-balances-02 ~]
# less /etc/haproxy/haproxy.cfg
-
-
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
-
log 127.0.0.1 local3
-
option dontlognull
-
option http-server-close
-
option forwardfor except 127.0.0.0/8
-
option redispatch
-
retries 3
-
timeout http-request 10s
# 防止 Slowloris like attacks
-
timeout queue 1m
-
timeout connect 10s
-
timeout client 1m
-
timeout server 1m
-
timeout http-keep-alive 10s
-
timeout check 10s
-
maxconn 3000
-
-
frontend ha_server
-
bind 0.0.0.0:80
-
mode http
-
log global
-
option httpclose
-
option forwardfor
-
default_backend rel_server
-
-
-
backend rel_server
-
mode http
-
option httpchk GET /check_ha.php
-
balance roundrobin
-
server web2 10.130.36.96:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3
-
server web3 10.130.74.106:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3
-
server web4 10.130.40.98:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3
测试
通过 telnet 登录验证结果,登陆连接后超过10秒就会自动被拒绝断掉
-
[root@li857-78 ~]
# telnet 159.65.15.11 80
-
Trying 159.65.15.11...
-
Connected to 159.65.15.11.
-
Escape character is
'^]'.
-
HTTP/1.0 408 Request Time-out
-
Cache-Control: no-cache
-
Connection: close
-
Content-Type: text/html
-
-
<html><body><h1>408 Request Time-out</h1>
-
Your browser didn
't send a complete request in time.
-
</body></html>
-
Connection closed by foreign host.
-
Limiting the number of connections per users
以网站为例,普通用户访问网站,或者从网站下载东西时,浏览器一般会建立 5-7 个 TCP 链接。当一个恶意打开了大量 TCP 链接时,耗费服务器大量资源,影响其它用户的访问,因此我们需要根据实际情况,限制同一个用户的链接数。
-
[root@gadmobe-balances
-02 ~]# less /etc/haproxy/haproxy.cfg
-
-
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
-
log
127.0
.0
.1 local3
-
option dontlognull
-
option http-server-close
-
option forwardfor except
127.0
.0
.0/
8
-
option redispatch
-
retries
3
-
timeout http-request
10s # 防止 Slowloris like attacks
-
timeout queue
1m
-
timeout connect
10s
-
timeout client
1m
-
timeout server
1m
-
timeout http-keep-alive
10s
-
timeout check
10s
-
maxconn
3000
-
-
frontend ha_server
-
bind
0.0
.0
.0:
80
-
mode http
-
log global
-
option httpclose
-
option forwardfor
-
default_backend rel_server
-
-
# Table definition
-
stick-table type ip size
100k expire
30s store conn_cur
-
# Allow clean known IPs to bypass the filter
-
tcp-request connection accept
if { src -f /etc/haproxy/whitelist.lst }
-
# Shut the
new connection
as long
as the client has already
10 opened
-
tcp-request connection reject
if { src_conn_cur ge
10 }
-
tcp-request connection track-sc1 src
-
-
backend rel_server
-
mode http
-
option httpchk GET /check_ha.php
-
balance roundrobin
-
server web2
10.130
.36
.96:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
-
server web3
10.130
.74
.106:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
-
server web4
10.130
.40
.98:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
- type 定义了这个table的key的类型,可以是 ip,ipv6,integer,string,binary之一
"type ip" 用于存储IPv4类型的IP地址,每个entry约占用50 bytes内存空间,主要用途是存放客户端源IP。
"type ipv6" 用于存储IPv6类型的IP地址,每个entry约占用60 bytes内存空间,主要用途是存放客户端源IP。
"type integer" 用于存储32位整数
"type string [len ]" 用于存储字符串,如果设置了len,则匹配设置的长度,多的字符会被截断,如不指定len,则默认长度是32个字符。
"type binary [len ]" 用于存储二进制块,如果设置了len,则最大存储指定长度,如果数据少于len,则使用0填充。默认长度是32 bytes。 - size 定义了这个table可以存储的entry最大数量.
- store ] 用于存储其他额外信息,这些信息可以用于ACL.用于控制各种与客户端活动相关的标准。多种data type可以用逗号分隔,写在store后边。除了"server_id"是系统自动启用和检测以外,其他data type必须明确声明。如果一个ACL引用了一个未声明的data type,则ACL会直接返回不匹配。
- - conn_cur : 当前connection数,一个正32位整数,当一新connection匹配指定的entry的时候,这个数值增加,当connection结束的时候,这个数值减少。通过这个值可以了解一个entry上任意时间点的准确的连接数。
- - conn_rate() : connection的连接频率 ,指定时间范围内(毫秒为单位)建立connection的频率。
- http://blog.sina.com.cn/s/blog_704836f40102w243.html ---》相关参数可以参考此篇文章
下载httpd
yum install httpd -y
利用 apache ab测试工具做验证,和服务器一直保持建立 10 个链接。
[root@li857-78 ~]# ab -n 50000000 -c 10 http://159.65.15.11:80/
用 telnet 打开第 11 个链接,服务器拒绝该链接。
-
[root@li857
-78 ~]# telnet
159.65
.15
.11
80
-
Trying
159.65
.15
.1...
-
Connected to
159.65
.15
.11.
-
Escape character is
'^]'.
-
Connection closed by foreign host.
Limiting the connection rate per user
仅仅限制单个用户的并发链接数并意味着万事大吉,如果用户在短时间内向服务器不断的发送建立和关闭链接请求,也会耗费服务器资源,影响服务器端的性能,因此需要控制单个用户建立连接的访问速率/频率。
通常情况下,考虑到用户通过浏览器一般会建立 5-7 条 TCP 链接,我们可以认为普通用户在 3 秒内不应该建立超过 20 条链接。
-
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
-
log
127.0
.0
.1 local3
-
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
3000
-
-
frontend ha_server
-
bind
0.0
.0
.0:
80
-
mode http
-
log global
-
option httpclose
-
option forwardfor
-
default_backend rel_server
-
-
# Table definition
-
stick-table type ip size
100k expire
30s store conn_cur,conn_rate(
3s) #
3秒内的连接次数限制到
20次
-
# Allow clean known IPs to bypass the filter
-
tcp-request connection accept
if { src -f /etc/haproxy/whitelist.lst }
-
# Shut the
new connection
as long
as the client has already
10 opened or rate more than
20
-
tcp-request connection reject
if { src_conn_cur ge
10 } || { src_conn_rate ge
20 }
-
tcp-request connection track-sc1 src
-
-
backend rel_server
-
mode http
-
option httpchk GET /check_ha.php
-
balance roundrobin
-
server web2
10.130
.36
.96:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
-
server web3
10.130
.74
.106:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
-
server web4
10.130
.40
.98:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
注:若某些用户在同一个私有网段通过 NAT 访问网站,这样的配置存在不合理之处,最好把 NAT 处的公网地址添加到 whitelist.lst 文件中
ab -n 20 -c 1 -r http://127.0.0.1:8080/
再用 telnet 打开第 21 个链接,服务器拒绝该请求
</div>
</div>
转载于:https://my.oschina.net/AnnaWu/blog/1621644
配置 Haproxy 防范 DDOS 攻击
作为 load balancer, Happroxy 常常作为服务器的前端,向外界用户提供服务的入口,如果能在入口处处理安全相关问题,将极大简化后端的设计。事实上,Haproxy 不仅仅是一款开源出色的 load balancer(四层和七层),而且在安全上也相当出色。它配合内核 IP/TCP 协议栈,能够较好的抵抗 DOS, DDOS 攻击,还能通过限制单个 IP 的连接数和请求速率等,防止用户的恶意行为。
TCP syn flood attacks
通过向服务器发送大量的 TCP syn 分组,恶意用户实现了了 TCP syn flood 攻击,幸运的是,简单的配置内核网络参数即可防止这种攻击。
#vim /etc/sysctl.conf 然后 sysctl -p
-
[root@kaka-games-balancers
-02 ~]# vim /etc/sysctl.conf
-
-
.....................
-
.....................
-
.....................
-
-
# Protection SYN flood
-
net.ipv4.tcp_syncookies =
1
-
net.ipv4.conf.all.rp_filter =
1
-
net.ipv4.tcp_max_syn_backlog =
1024
-
-
-
[root@kaka-games-balancers
-02 ~]# sysctl -p
Slowloris like attacks
一个 Http 请求通常包括头部、url、methods 等,服务器需要接收整个 Http 请求后会做出响应。恶意用户发送缓慢的 Http 请求,比如一个字节一个字节的发送头部,服务器将一直处于 wating 状态,从而耗费服务器的资源。Haproxy 通过配置 timeout http-request 参数,当一个用户的请求时间超过设定值时,Haproxy 断开与该用户的连接。
参数: timeout http-request
-
[root@gadmobe-balances-02 ~]
# less /etc/haproxy/haproxy.cfg
-
-
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
-
log 127.0.0.1 local3
-
option dontlognull
-
option http-server-close
-
option forwardfor except 127.0.0.0/8
-
option redispatch
-
retries 3
-
timeout http-request 10s
# 防止 Slowloris like attacks
-
timeout queue 1m
-
timeout connect 10s
-
timeout client 1m
-
timeout server 1m
-
timeout http-keep-alive 10s
-
timeout check 10s
-
maxconn 3000
-
-
frontend ha_server
-
bind 0.0.0.0:80
-
mode http
-
log global
-
option httpclose
-
option forwardfor
-
default_backend rel_server
-
-
-
backend rel_server
-
mode http
-
option httpchk GET /check_ha.php
-
balance roundrobin
-
server web2 10.130.36.96:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3
-
server web3 10.130.74.106:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3
-
server web4 10.130.40.98:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3
测试
通过 telnet 登录验证结果,登陆连接后超过10秒就会自动被拒绝断掉
-
[root@li857-78 ~]
# telnet 159.65.15.11 80
-
Trying 159.65.15.11...
-
Connected to 159.65.15.11.
-
Escape character is
'^]'.
-
HTTP/1.0 408 Request Time-out
-
Cache-Control: no-cache
-
Connection: close
-
Content-Type: text/html
-
-
<html><body><h1>408 Request Time-out</h1>
-
Your browser didn
't send a complete request in time.
-
</body></html>
-
Connection closed by foreign host.
-
Limiting the number of connections per users
以网站为例,普通用户访问网站,或者从网站下载东西时,浏览器一般会建立 5-7 个 TCP 链接。当一个恶意打开了大量 TCP 链接时,耗费服务器大量资源,影响其它用户的访问,因此我们需要根据实际情况,限制同一个用户的链接数。
-
[root@gadmobe-balances
-02 ~]# less /etc/haproxy/haproxy.cfg
-
-
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
-
log
127.0
.0
.1 local3
-
option dontlognull
-
option http-server-close
-
option forwardfor except
127.0
.0
.0/
8
-
option redispatch
-
retries
3
-
timeout http-request
10s # 防止 Slowloris like attacks
-
timeout queue
1m
-
timeout connect
10s
-
timeout client
1m
-
timeout server
1m
-
timeout http-keep-alive
10s
-
timeout check
10s
-
maxconn
3000
-
-
frontend ha_server
-
bind
0.0
.0
.0:
80
-
mode http
-
log global
-
option httpclose
-
option forwardfor
-
default_backend rel_server
-
-
# Table definition
-
stick-table type ip size
100k expire
30s store conn_cur
-
# Allow clean known IPs to bypass the filter
-
tcp-request connection accept
if { src -f /etc/haproxy/whitelist.lst }
-
# Shut the
new connection
as long
as the client has already
10 opened
-
tcp-request connection reject
if { src_conn_cur ge
10 }
-
tcp-request connection track-sc1 src
-
-
backend rel_server
-
mode http
-
option httpchk GET /check_ha.php
-
balance roundrobin
-
server web2
10.130
.36
.96:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
-
server web3
10.130
.74
.106:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
-
server web4
10.130
.40
.98:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
- type 定义了这个table的key的类型,可以是 ip,ipv6,integer,string,binary之一
"type ip" 用于存储IPv4类型的IP地址,每个entry约占用50 bytes内存空间,主要用途是存放客户端源IP。
"type ipv6" 用于存储IPv6类型的IP地址,每个entry约占用60 bytes内存空间,主要用途是存放客户端源IP。
"type integer" 用于存储32位整数
"type string [len ]" 用于存储字符串,如果设置了len,则匹配设置的长度,多的字符会被截断,如不指定len,则默认长度是32个字符。
"type binary [len ]" 用于存储二进制块,如果设置了len,则最大存储指定长度,如果数据少于len,则使用0填充。默认长度是32 bytes。 - size 定义了这个table可以存储的entry最大数量.
- store ] 用于存储其他额外信息,这些信息可以用于ACL.用于控制各种与客户端活动相关的标准。多种data type可以用逗号分隔,写在store后边。除了"server_id"是系统自动启用和检测以外,其他data type必须明确声明。如果一个ACL引用了一个未声明的data type,则ACL会直接返回不匹配。
- - conn_cur : 当前connection数,一个正32位整数,当一新connection匹配指定的entry的时候,这个数值增加,当connection结束的时候,这个数值减少。通过这个值可以了解一个entry上任意时间点的准确的连接数。
- - conn_rate() : connection的连接频率 ,指定时间范围内(毫秒为单位)建立connection的频率。
- http://blog.sina.com.cn/s/blog_704836f40102w243.html ---》相关参数可以参考此篇文章
下载httpd
yum install httpd -y
利用 apache ab测试工具做验证,和服务器一直保持建立 10 个链接。
[root@li857-78 ~]# ab -n 50000000 -c 10 http://159.65.15.11:80/
用 telnet 打开第 11 个链接,服务器拒绝该链接。
-
[root@li857
-78 ~]# telnet
159.65
.15
.11
80
-
Trying
159.65
.15
.1...
-
Connected to
159.65
.15
.11.
-
Escape character is
'^]'.
-
Connection closed by foreign host.
Limiting the connection rate per user
仅仅限制单个用户的并发链接数并意味着万事大吉,如果用户在短时间内向服务器不断的发送建立和关闭链接请求,也会耗费服务器资源,影响服务器端的性能,因此需要控制单个用户建立连接的访问速率/频率。
通常情况下,考虑到用户通过浏览器一般会建立 5-7 条 TCP 链接,我们可以认为普通用户在 3 秒内不应该建立超过 20 条链接。
-
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
-
log
127.0
.0
.1 local3
-
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
3000
-
-
frontend ha_server
-
bind
0.0
.0
.0:
80
-
mode http
-
log global
-
option httpclose
-
option forwardfor
-
default_backend rel_server
-
-
# Table definition
-
stick-table type ip size
100k expire
30s store conn_cur,conn_rate(
3s) #
3秒内的连接次数限制到
20次
-
# Allow clean known IPs to bypass the filter
-
tcp-request connection accept
if { src -f /etc/haproxy/whitelist.lst }
-
# Shut the
new connection
as long
as the client has already
10 opened or rate more than
20
-
tcp-request connection reject
if { src_conn_cur ge
10 } || { src_conn_rate ge
20 }
-
tcp-request connection track-sc1 src
-
-
backend rel_server
-
mode http
-
option httpchk GET /check_ha.php
-
balance roundrobin
-
server web2
10.130
.36
.96:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
-
server web3
10.130
.74
.106:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
-
server web4
10.130
.40
.98:
80 cookie
1 weight
5 check inter
2000 rise
2 fall
3
注:若某些用户在同一个私有网段通过 NAT 访问网站,这样的配置存在不合理之处,最好把 NAT 处的公网地址添加到 whitelist.lst 文件中
ab -n 20 -c 1 -r http://127.0.0.1:8080/
再用 telnet 打开第 21 个链接,服务器拒绝该请求
</div>
</div>