这里写目录标题
核心安全配置
编译安装 Nginx
安装支持软件
Nginx 的配置及运行需要 pcre、zlib 等软件包的支持,因此应预先安装这些软件的开发包(devel),以便提供相应的库和头文件,确保Nginx的安装顺利完成
[root@bogon ~]# dnf install -y gcc make pcre-devel zlib-devel openssl-devel perl-ExtUtils-MakeMaker git wget tar
创建运行用户、组和日志目录
[root@localhost ~]# useradd -M-s /sbin/nologin nginx
[root@localhost ~]# mkdir -p /var/log/nginx
[root@localhost ~]# chown-R nginx:nginx /var/log/nginx
编译安装 Nginx
[root@localhost ~]# tar zxf nginx-l.26.3. tar. gz
[root@localhost ~]# cd nginx-1.26.3
[root@bogon nginx-1.26.3]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module
[root@bogon nginx-1.26.3]# make && make install
为主程序 nginx 创建链接文件
[root@localhost nginx-l.26.3]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin
添加Nginx 系统服务
[ root@localhost ~] # vi /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target
[Service]
Ttpe=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/sbin/nginx -t
ExecStart=/usr/local/sbin/nginx
ExecStop=/bin/kill -s QUIT $MAINPID
ExecReload=/usr/local/sbin/nginx -s reload
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
User=root
Group=root
[Install]
WantedBy=multi-user.target
隐藏版本号
在生产环境中,需要隐藏 Nginx 的版本号,以避免泄漏 Nginx 的版本,使攻击者不能针对特定版本进行攻击。在隐藏版本号之前,可以使用 Fiddler 工具抓取数据包,查看Nginx版本,也可以在0penEuler 中使用命令 curl -Ihttp://192.168.10.101/查看
限制危险请求方法
不安全的请求方式,是潜在的安全风险,TRACE(易引发XST攻击)、PUT/DELETE(文件修改风险)、CONNECT(代理滥用),通过正则表达式匹配请求方法,非白名单方法返回 444(无响应关闭连接)
PS:注意测试 TRACE 和 CONNECT 方法时,状态码不是 444(原因:1.CONNECT 请求的目标不是代理服务器时,服务器必须返回400Bad Request,Nginx 核心层在请求解析阶段直接拦截,根本不进入后续的 1ocation 处理流程 2.现代 Nginx默认禁用 TRACE 方法,在 ngx http core module 阶段直接返回 405 Not Allowed)
请求限制(CC攻击防御)
CC 攻击(Challenge Collapsar 攻击)是一种常见的网络攻击方式,通过大量合法或伪造的小流量请求来耗尽服务器资源,导致正常用户无法访问网站。要在 Nginx中有效防止 CC 攻击,可以采用多种策略和方法。CC攻击,也称为连接数攻击或请求速率限制攻击,通过模拟大量用户访问来消耗服务器资源,从而使得正常用户无法正常访问网站。为了防止此类攻击,可以使用 Nginx提供的模块来限制请求速率和并发连接数
使用 Nginx 的 limit reg 模块限制请求速率
- limit_req_zone 定义共享内存区
- $binary_remote_addr 是一个内置变量,用于表示客户端 IP 地址的二进制格式
- zone=req_limit:10m 创建名为 req limit 的共享内存区,大小 10M,用来存储客户端IP
- rate=10r/s 限制并发数,每个 IP 每秒可以发起的请求次数
- limit_req 实施速率限制
- zone=req 1imit 绑定到预定义的共享内存区
- burst=20 类似与等候区,超出并发数的请求会到等候区,等候区占满后,多余的请求会立刻返回 503
- 立即处理突发请求而不延迟,相当于立即处理等候区的请求,多余nodelay的请求会立刻返回 503
压力测试验证
安装 ab 测试工具
ApacheBench(简称ab)是 Apache HTTP 服务器自带的一个轻量级、易用的HTTP服务器性能测试工具。它主要用于评估服务器在并发访问下的性能表现,包括响应时间、吞吐量等关键指标
[root@bogon ~]# dnf install httpd-tools -y
OS 9.6 kB/s | 2.1 kB 00:00
everything 11 kB/s | 2.7 kB 00:00
EPOL 8.9 kB/s | 2.3 kB 00:00
debuginfo 10 kB/s | 2.2 kB 00:00
source 9.4 kB/s | 2.6 kB 00:00
update 12 kB/s | 2.7 kB 00:00
发起测试请求共发起 300个请求,每次发起30个请求
[root@bogon ~]# ab -n 300 -c 30 http://192.168.10.101/
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.10.101 (be patient)
防盗链
防盗链是一种重要的安全设置,旨在防止未经授权的用户盗用网站(静态)资源。盗链行为不仅侵犯了内容创作者的版权,还可能导致原网站带宽和资源的过度消耗,影响正常用户的访问速度和体验。一般来说,用户浏览一个完整的页面并不是一次性全部传送到客户端的。如果所请求的页面带有图片或其他信息,那么第一个 HTTP 请求传送的是这个页面的文本,然后通过客户端的浏览器对这段文本进行解释执行。如果发现其中还有图片,那么客户端的浏览器会再次发送一条HTTP请求,当这个请求被处理后这个图片文件才会被传送到客户端,最后浏览器会将图片安放到页面的正确位置,就这样一个完整的页面要经过多次发送 HTTP 请求才能够被完整的显示。基于这样的机制,就会产生盗链问题:如果一个网站中没有其页面中所说图片信息,那么它完全可以链接到其他网站的图片信息上。这样,没有任何资源的网站利用了其他网站的资源来展示给浏览者,提高了自己的访问量,而大部分浏览者又不会很容易地发现。一些不良网站为了不增加成本而扩充自己站点内容,经常盗用其他网站的链接。一方面损害了原网站的合法利益,另一方面又加重了服务器的负担
- *.(jpg|gif|swf)$:这段正则表达式表示匹配不区分大小写,以.jpg或.gif 或.swf 结尾的文件;
- Valid referers:设置信任的网站,可以正常使用图片;
- 后面的网址或者域名:referer中包含相关字符串的网址;
- If 语句:如果链接的来源域名不在 valid referers 所列出的列表中,$invalid referer 为1,则执行后面的操作,即进行重写或返回 403 页面
高级防护
动态黑名单
动态黑名单是 Nginx中一种实时拦截恶意请求的安全机制,它允许在不重启服务的情况下,动态更新需要封禁的 IP地址或网段。相比静态配置的 allow/deny指令,动态黑名单更灵活高效,适用于高并发、多变的攻击防护场景
编辑黑名单配置文件
[root@localhost ~]# vi /usr/local/nginx/conf/blockips.conf
192.168.1.0/24 1;#封禁整个网段
192.168.10.102 1;#封禁 ip
IP 地址后的数字含义:
0 ""; # 允许
1 403; #完全封禁
2 444; #静默断开
3 503; #服务不可用
- geo:Nginx 内置模块指令,专门用于处理IP地址相关的逻辑。基于客户端IP 地址生成一个变量值,用于后续的访问控制判断
- $block ip:自定义的变量名,存储计算结果(通常为0或1)。
- default 0:默认值,表示不在黑名单中的 IP 允许访问
- if($block_ip):当变量值为1时触发封禁逻辑
使用封禁 ip 测试访问
[root@localhost ~]# curl 192.168.10.101
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</hl></center><hr><center>nginx</center>
</body>
</html>
自动添加黑名单
uniq-c:统计连续出现的次数,并在行首显示次数sort -nr:按数值排序
nginx https 配置
https 概念
HTTPS,全称HyperText Transfer Protocol over Secure Socket Layer,设计初衷是为了保证数据传输安全。国内大型互联网巨头在 2016开始大力推行https,期间关于 https 的重大事件有:
众所周知,http(超文本传输协议)是客户端浏览器与web 服务器之间的通信协议,而 https 协议可以认为是 HTTP + SSL/TLS,在 http 之下 tcp 之上加了ss1 一层,用于对应用层数据的加解密
SSL:由 Netscape 公司开发,专门用于保护Web 通讯。SSL 协议位于 TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为SSL记录协议(SSL Record Protocol)和SSL握手协议(SSL Handshake Protocol)两层。SSL经历了多个版本的迭代,包括从未公开发布的SSL1.0、存在严重安全漏洞且现已废弃的 SSL2.0、在 2014 年因 PO0DLE 攻击漏洞而被逐步淘汰的 SSI3.0
TLS:是IETF(Internet Engineering Task Force,互联网工程任务组)制定的一种新的协议,它建立在 SSL3.0协议规范之上,是 SSL3.0的后续版本从历史上看,TLS对 SSL首先是继承关系,后来逐步发展并取代了SSL,成为当前主流的网络安全协议。TLS经历了多个版本的演进,包括TLS1.0(1999年发布,基于 SSL 3.0但进行了改进)、TLS 1.1(2006 年发布,增加了对 CBC 攻击的保护)、TLS 1.2(2008年发布,引入了更强大的加密算法,如 AES)和 TLS 1.3(2018年发布,进一步简化了握手过程,提高了性能和安全性)。值得注意的是,TS1.0和TS1.1也在 2021年被正
HTTP 为什么不安全
HTTP 由于是明文传输,主要存在三大风险:窃听风险、篡改风险、冒充风险
窃听风险
中间人可以获取到通信内容,由于内容是明文,所以获取明文后有安全风险
篡改风险
中间人可以篡改报文内容后再发送给对方,风险极大
冒充风险
比如你以为是在和某宝通信,但实际上是在和一个钓鱼网站通信
安全通信的四大原则
不难猜到 HTTPS 就是为了解决上述三个风险而生的,一般我们认为安全的通信需要包括以下四个原则: 机密性、完整性,身份认证和不可否认
- 机密性:即对数据加密,解决了窃听风险,因为即使被中间人窃听,由于数据是加密的,他也拿不到明文;
- 完整性:指数据在传输过程中没有被篡改,不多不少,保持原样,中途如果哪怕改了一个标点符号,接收方也能识别出来,从来判定接收报文不合法;
- 身份认证:确认对方的真实身份,即证明“你妈是你妈”的问题,这样就解决了冒充风险,用户不用担心访问的是某宝结果却在和钓鱼网站通信的问题;
- 不可否认:即不可否认已发生的行为,比如小明向小红借了1000元,但没打借条,或者打了借条但没有签名,就会造成小红的资金损失
https 总结:
server 传输 CA 颁发的证书给 client,client 收到证书后使用系统内置的CA 证书的公钥来验签,验签通过证明证书是受信任的,证书受信任那么证书中的公钥也就是受信任的,这样的话就解决了公钥传输过程中被调包的风险
Ps:1.这里可能有同学会有疑问,为什么 client 拿到了 server 给的公钥,不直接使用公钥进行加密通信,反而用公钥加密会话密钥,用会话密钥来加密通信,多此一举,这是因为会话密钥是对称加密,而对称加密的密钥管理简单且具有更高的加密和解密效率。所以 https 加密是混合模式,在握手阶段是非对称加密在数据传输阶段是对称加密
2.还有个问题,中间人如果也去 CA 申请一个受信任的证书呢,把 server 发送的证书截取并替换成自己的行不行呢,答案是不行的,因为client 除了要验证证书的合法性外,每个证书中包含的域名也是唯一的
使用openssl生成证书和私钥生成证书和私钥
-x509:生成自签名证书(而非CSR)
-nodes:不加密私钥(无密码保护)
-days 365:证书有效期1年
-keyout:私钥文件
-out:自签名文件
-newkey rsa:2048:生成 2048 位的 RSA 私钥
-subj:证书主题信息(按需修改字段)
Ps
CA 签名证书:
需要由受信任的第三方证书颁发机构(CA)签发流程如下:
1.用户生成私钥和CSR(证书签名请求)。
2.将 CSR 提交给 CA(如Let’s Encrypt、DigiCert 等)
3.CA 机构验证身份后,用CA的私钥对证书签名,生成最终证书
自签名证书:
证书的颁发者(Issuer)和主体(Subject)是同一个实体(即自己)
无需第三方 CA参与,直接用工具(如 0penSSL)生成私钥和证书
签名时使用自己的私钥,而不是 CA 的私钥
适用于测试、内部环境或无需公开信任的场景