一.核心安全配置
1.编译安装Nginx
(1)安装支持软件
Nginx的配置及运行需要pcre、zlib等软件包的支持,因此应预先安装这些软件的开发包(devel),以便提供相应的库和头文件,确保Nginx的安装顺利完成
命令:dnf install -y gcc make pcre-devel zlib-devel openssl-devel perl-ExtUtils-MakeMaker git wget tar
(2)创建运行用户、组和日志目录
命令:useradd -M -s /sbin/nologin nginx
mkdir -p /var/log/nginx
chown -R nginx:nginx /var/log/nginx
(3)编译安装Nginx
命令:tar zxf nginx-1.26.3.tar.gz
cd nginx-1.26.3
./configure --prefix=/usr/local/nginx --pid-path=/var/run/nginx.pid --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream
make && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin (为主程序nginx创建链接文件)
(4)添加Nginx系统服务
命令:vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target
[Service]
Type=forkingPIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/sbin/nginx -t
ExecStart=/usr/local/sbin/nginx
ExecReload=/usr/local/sbin/nginx-s reload
ExecStop=/bin/ki11 -S QUIT $MAINPID
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
User=root
Group=root
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start nginx
systemctl enable nginx
2.隐藏版本号
生产环境中,需要隐藏Nginx版本号,以避免Nginx的版本,使攻击者不能针对特定版本进行攻击。隐藏版本号之前,可以使用Fiddler工具抓取数据包查看Nginx版本,也可以在OpenEuler中使用curl -I 192.168.10.202查看
修改配置文件
命令:vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
......
server_tokens off; (隐藏版本号)
nginx -t
nginx -s reload
3.限制危险请求方法
不安全的请求方式,是潜在的安全风险,TRACE(易引发XST攻击)、PUT/DELETE(文件修改风险)、CONNECT(代理滥用),通过正则表达式匹配请求方法,非白名单方法返回444(无响应关闭连接)
修改配置文件
命令:vim /usr/local/nginx/conf/nginx.conf
sercer {
.......
if ($request_method ! ~ ^(GET|HEAD|POST)$) {
return 444;
}
.......
}
测试PUT/DELETE请求
命令:curl -XPUT -I 192.168.10.202
测试TRACE和CONNECT方法时,状态码不是444的原因:
a.CONNECT请求的目标不是代理服务器时,服务器必须返回400 Bad Request,Nginx核心层在请求解析阶段直接拦截,根本不进入后续的location处理流程
b.现代Nginx默认禁用TRACE方法,在ngx_http_core_module阶段直接返回405Not Allowed
4.请求限制(CC攻击防御)
CC攻击是一种常见的网络攻击方式,通过大量合法或伪造小流量请求来耗尽服务器资源,导致正常用户无法访问网站。要在Nginx中有效防止CC攻击,可以采用多种策略和方法
CC攻击,也称为连接数攻击或请求速率限制攻击,通过模拟大量用户访问来消耗服务器资源,从而使得正常用户无法正常访问网站。为了防止此类攻击,可以使用Nginx提供的模块来限制请求速率和并发连接数
(1)使用Nginx的limit_req模块限制请求速率
编辑配置文件
命令:vim /usr/local/nginx/conf/nginx.conf
http {
#定义限制区(10MB内存/每秒10请求)
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
#其他全局配置...
server {
location / {
root html;
index index.html index.php;
limit_req zone-req_limit burst=20 nodelay;
}
...
}
}
关键参数说明:
a.limit_req_zone定义共享内存区
b.$binary_remote_addr 是一个内置变量,用于表示客户端IP地址的二进制格式
c.zone=req_limit:10m 创建名为req_limit的共享内存区,大小10M,用来存储客户端Ip
d.rate=10r/s 限制并发数,每个IP每秒可以发起的请求次数
e.limit_req 实施速率限制
f.zone=req_limit 绑定到预定义的共享内存区
g.burst=20 类似与等候区,超出并发数的请求会到等候区,等候区占满后,多余的请求会立刻返回503
h.nodelay 立刻处理突发请求而不延迟,相当于立刻处理等候区的请求,多余的请求会立刻返回503
(2)压力测试验证
安装ab测试工具
ApacheBench(简称ab)是Apache HTTP服务器自带的一个轻量级,易用的HTTP服务器性能测试工具。主要用于评估服务器在并发访问下的性能表现,包括响应时间、吞吐量等关键指标。
命令:dnf install httpd-tools -y
发起测试请求
共发起300个请求,每次发起30个请求
命令:ab -n 300 -c 30 http://192.168.10.202/
查看access.log发现大量请求日志状态码503
命令:tail -300 /usr/local/nginx/logs/access.log | grep -c 503
5.防盗链
防盗链是一种重要的安全设置,旨在防止未经授权的用户盗用网站(静态)资源。盗链行为不仅侵犯了内容创作者的版权,还可能导致原网站带宽和资源的过度消耗,影响正常用户的访问速度和体验。
一般来说,用户浏览一个完整的页面并不是一次性全部传送到客户端的。如果所请求的页面带有图片或其他信息,那么第一个HTTP请求传送的是这个页面的文本,然后通过客户端的浏览器对这段文本进行解释执行。如果发现其中还有图片,那么客户端的浏览器会再次发送一条HTTP请求,当这个请求被处理后这个图片文件才会被传送到客户端,最后浏览器会将图片安放到页面的正确位置,就这样一个完整的页面要经过多次发送HTTP请求才能够被完整的显示。基于这样的机制,就会产生盗链问题:如果一个网站中没有其页面中所说图片信息,那么它完全可以链接到其他网站的图片信息上。这样,没有任何资源的网站利用了其他网站的资源来展示给浏览者,提高了自己的访问量,而大部分浏览者又不会很容易地发现。一些不良网站为了不增加成本而扩充自己站点内容,经常盗用其他网站的链接。一方面损害了原网站的合法利益,另一方面又加重了服务器的负期
操作系统 | 域名 | IP | 服务 |
OpenEuler | www.aaa.com | 192.168.10.202 | 源主机 |
OpenEuler | www.bbb.com | 192.168.10.201 | 盗链主机 |
(1)修改Windows的C:\Windows/System32\drivers\etc\hosts文件,设置域名和IP映射关系
192.168.10.202 www.aaa.com
192.168.10.201 www.bbb.com
(2)修改两台CentOS的hosts文件,设置域名和IP映射关系
192.168.10.202 www.aaa.com
192.168.10.201 www.bbb.com
(3)把图片logo.jpg放到源主机的工作目录下
命令:ls /usr/local/nginx/html
index.html kgc.png
(4)编辑源网站首页文件
命令:vim /usr/local/nginx/html/index.html
<html>
<body>
<h1>aaa It work!
<img src="kgc.png"/> (网页中显示图片的代码)
</h1>
</body>
</html>
(5)测试访问源网站
(6)编辑盗链网站首页文件
命令:vim /usr/local/nginx/html/index.html
<html>
<body>
<h1>bbb It work!
<img src="http://www.aaa.com/kgc.png"/> (网页中显示图片的代码)
</h1>
</body>
</html>
(7)测试访问盗链网站(盗链成功)
(8)配置Nginx防盗链
命令:vim /usr/local/nginx/conf/nginx.conf
location ~* \.(gif | jpg | jpeg |) png | bmp | swf | flv | mp4 | webp | ico) $ {
root html
valid_referers aaa.com *.aaa.com;
if ($invalid_referer ) {
return 403
}
}
nginx -t
nginx -s reload
~*\.(jpglgif|swf)$:这段正则表达式表示匹配不区分大小写,以jpg或.gif或.swf结尾的文件;
Valid referers:设置信任的网站,可以正常使用图片;2
后面的网址或者域名:referer中包含相关字符串的网址:
>If语句:如果链接的来源域名不在validreferers所列出的列表中$invalid_referer为1,则执行后面的操作,即进行重写或返回403页面
(8)测试访问盗链网站(盗链失败)
二.高级防护
1.动态黑名单
动态黑名单是Nginx中一种实时拦截恶意请求的安全机制,它允许在不重启服务的情况下,动态更新需要封禁的IP地址或网段。相比静态配置的allow/deny指令,动态黑名单更灵活高效,适用于高并发、多变的攻击防护场景。
(1)编辑黑名单配置文件
命令:vim /usr/local/nginx/conf/blockips.conf
192.168.1.0/24 1 ; #封禁整个网段
192.168.10.201 1 ;#封禁ip
IP地址后的数字含义
0 ""; # 允许
1 403; #完全封禁
2 444; #静默断开
3 503; #服务不可用
(3)编辑主配置文件
命令:vim /usr/local/nginx/conf/nginx.conf
http {
......
geo $block_ip {
default 0; #默认允许访问
include /usr/lcoal/nginx/conf/blockips.conf ; # 包含黑名单
}
......
server {
......
if ($block_ip) { #判断标记值
return 403 ; # 封禁动作
}
.......
}
}
nginx -t
nginx -s reload
geo:Nginx内置模块指令,专门用于处理ip地址相关的逻辑。基于客户端ip地址生成一个变量值,用于后续的访问控制判断
$block_ip:自定义的变量名,存储计算结果(通常为0或1)
default 0 :默认值,表示不在黑名单中的ip允许访问
if ($block_ip):当变量值为1时触发封禁逻辑
(3)使用封禁ip测试访问
命令:curl 192.168.10.202
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
(4)自动添加黑名单
自动封禁访问超过100次的ip
#!/bin/bash
#自动封禁访问超过100次的IP
awk’{print $l}’/var/log/nginx/access.logsort |uniq -c|sort -nrawk ’{if($1>100) print $2"1;"}’>/usr/local/nginx/conf/blockips. conf
每小时更新攻击ip
#!/bin/bash
#每小时更新攻击IP
awk'/攻击特征/(print $l}’/var/log/nginx/access.logsort|uniq >/usr/local/nginx/conf/blockips. conf
2.nginx https配置
HTTP由于是明文传输,主要存在三大风险:窃听风险、篡改风险、冒充风险
2.1安全通信的四大原则
不难猜到 HTTPS就是为了解决上述三个风险而生的,一般我们认为安全的通信需要包括以下四个原则:机密性、完整性,身份认证和不可否认。
机密性:即对数据加密,解决了窃听风险,因为即使被中间人窃听,由于数据是加密的,他也拿不到明文;
完整性:指数据在传输过程中没有被篡改,不多不少,保持原样,中途如果哪怕改了一个标点符号,接收方也能识别出来,从来判定接收报文不合法;
身份认证:确认对方的真实身份,即证明“你妈是你妈”的问题,这样就解决了冒充风险,用户不用担心访问的是某宝结果却在和钓鱼网站通信的问题:
不可否认:即不可否认已发生的行为,比如小明向小红借了1000元,但没打借条,或者打了借条但没有签名,就会造成小红的资金损失。
2.2通信原理简述
既然HTTP是明文传输的,那我们给报文加密不就行了,既然要加密,我们肯定需要通信双方协商好密钥吧。一种是通信双方使用同一把密钥,即对称加密的方式来给报文进行加解密。
但是这里有一个关键问题:对称加密的通信双方要使用同一把密钥,这个密钥是如何协商出来的?如果通过报文的方式直接传输密钥,之后的通信其实还是在裸奔,因为这个密钥会被中间人截获甚至替换掉,这样中间人就可以用截获的密钥解密报文,甚至替换掉密钥以达到篡改报文的目的。
有人说对这个密钥再次加密不就完了,但对方如果要解密这个密钥,那还是要传加密密钥给对方,依然还是会被中间人截获的,这么看来直接传输密钥无论怎样都无法摆脱俄罗斯套娃的难题,是不可行的。
直接传输密钥无论从哪一端传从上节分析来看是不行了,这里我们再看另
种加密方式:非对称加密。非对称加密即加解密双方使用不同的密钥,一把作为公钥,可以公开的,把作为私钥,不能公开,公钥加密的密文只有私钥可以解密,私钥签名的内容,也只有公钥可以验签。这样的话对serve来说,保管好私钥,发布公钥给其他client,其他client只要把对称加密的密钥(或用于生成对称加密密钥的信息)使用公钥加密后传给server 即可。如此一来由于公钥加密只有私钥能解密,而私钥只有server 有所以能保证client向server传输是安全的,server解密后即可拿到对称加密密钥,这样交换了密钥之后就可以用对称加密密钥通信了。
但是问题又来了,server 怎么把公钥安全地传输给client呢???????
如果直接传公钥,也会存在被中间人调包的风险,好像没完没了了一样.……..
数字证书,解决公钥传输信任问题
如何解决公钥传输问题呢?从现实生活中的场景找答案。员工入职时,企业般会要求提供学历证明,这个学历必须由第三方权威机构(CertificateAuthority证书颁发机构,简称CA)即教育部颁发。同理,server也可以向CA申请证书,在证书中附上公钥,然后将证书传给client。证书是由站点管理者向CA申请,申请的时候会提交域名、组织单位信息和公钥等数据(这些数据组成了 Certificate Signing,Reguest 证书签名请求,简称 CSR),CA会根据这些信息生成证书
这样当client拿到证书后,就可以获得证书上的公钥,再用此公钥加密对称加密密钥传给server即可。看起来确实很完美,不过在这里大家要考虑一个问题
想象一下上文中我们提到的学历,企业如何认定你提供的学历证书是真是假呢?答案是用学历编号,企业拿到证书后用学历编号在学信网上一查就知道证书真伪了,学历编号其实就是我们常说的证书的数字签名,可以防止证书造假。
证书的数字签名怎么来的?是使用的CA机构的私钥给CSR(确切来说是CSR生成的摘要信息)进行的签名,这样的话c1ient得用CA的公钥来给名解密才行,拿到的才是未经篡改合法的证书(私钥签名,公钥验签)
细心的你一定发现了问题,那CA 公钥又是如何安全地传输到client的?如果还是从server传输到client,依然无法解决公钥被调包的风险。实际上CA公钥是存在于CA证书上,而此证书(也称RootCA证书)被操作系统信任,内置在操作系统上的,无需传输,如果用的是windows的同学,可以通过:控制面板一>网络和Internet->Internet选项一>内容一>证书一>受信任的根证书颁发机构,可以看到很多内置的被信任的证书
https 总结:
server传输CA颁发的证书给client,client收到证书后使用系统内置的CA证书的公钥来验签,验签通过证明证书是受信任的,证书受信任那么证书中的公钥也就是受信任的,这样的话就解决了公钥传输过程中被调包的风险。
Client拿到server端的公钥后,使用公钥加密会话密钥(也就是对称加密的密钥),然后发送给服务端,服务端通过私钥解密获得会话密钥(对称加密的密钥),然后就可以安全愉快的进行数据传输了。
1.这里可能有同学会有疑问,为什么client拿到了server 给的公钥,不直接使用公钥进行加密通信,反而用公钥加密会话密钥,用会话密钥来加密通信,多此一举,这是因为会话密钥是对称加密,而对称加密的密钥管理简单且具有更高的加密和解密效率。所以https加密是混合模式,在握手阶段是非对称加密,在数据传输阶段是对称加密
2.还有个问题,中间人如果也去CA申请一个受信任的证书呢,把server发送的证书截取并替换成自己的行不行呢,答案是不行的,因为client除了要验证证书的合法性外,每个证书中包含的域名也是唯一的