一、安全防护与HTTPS概念
一、安全防护与HTTPS概念
为什么要隐藏版本号?
当访问网站时,能从响应标头查看到server的信息,这里面就包含了是什么web应用及其版本为你提供的服务。如果不隐藏server的版本,会导致别有用心的人知晓服务的版本号,从而针对该版本进行攻击。
PS:浏览器中按F12,选择网络,在最上面点击你访问的网页(例如百度,会显示www.baidu.com)找到这个并点击它,选择标头-响应标头,这里面有一行为server,会跟上web应用程序及版本。
限制不安全的请求方式,能更好保护nginx服务器。常见的危险请求方法包括TRACE(易引发XST攻击)、PUT/DELETE(文件修改风险)、CONNECT(代理滥用)。通过在配置文件中添加正则表达式来匹配请求方法即可拒绝不安全的请求方式。
CC攻击介绍
CC攻击(Challenge Collapsar攻击)是一种常见的网络攻击方式,通过大量合法或伪造的小流量请求来耗尽服务器资源,导致正常用户无法访问网站。也称为连接数攻击或请求速率限制攻击。
面对CC攻击的处理方式
使用nginx的limit_req模块来限制请求速率
压力测试介绍
压力测试是指通过快速大量的访问来评估服务器在并发访问下的性能表现,包括响应时间、吞吐量等关键指标。
盗链介绍
简单解释:
网站B盗用网站A的静态资源,通过网站A来解析网站B盗走内容用户的请求,网站B无需付出静态资源以及性能上的消耗。
详细解释:
一般来说,用户浏览一个完整的页面并不是一次性全部传送到客户端的。如果所请求的页面带有图片或其他信息,那么第一个HTTP请求传送的是这个页面的文本,然后通过客户端的浏览器对这段文本进行解释执行。如果发现其中还有图片,那么客户端的浏览器会再次发送一条HTTP请求,当这个请求被处理后这个图片文件才会被传送到客户端,最后浏览器会将图片安放到页面的正确位置,就这样一个完整的页面要经过多次发送HTTP请求才能够被完整的显示。基于这样的机制,就会产生盗链问题:如果一个网站中没有其页面中所说图片信息,那么它完全可以链接到其他网站的图片信息上。这样,没有任何资源的网站利用了其他网站的资源来展示给浏览者,提高了自己的访问量,而大部分浏览者又不会很容易地发现。一些不良网站为了不增加成本而扩充自己站点内容,经常盗用其他网站的链接。一方面损害了原网站的合法利益,另一方面又加重了服务器的负担。
防盗链介绍
防盗链是用于防止未经授权的用户盗用网站(静态)资源。
动态黑名单介绍
动态黑名单是nginx中一种实时拦截恶意请求的安全机制,它允许在不重启服务的情况下,动态更新需要封禁的IP地址或网段。动态黑名单更灵活高效,适用于高并发、多变的攻击防护场景。
https介绍
HTTPS,全称HyperText Transfer Protocol over Secure Socket Layer,设计初衷是为了保证数据传输安全。
http是客户端浏览器与web服务器之间的通信协议,而https协议可以认为是HTTP+SSL/TLS,在http之下tcp之上加了ssl一层,用于对应用层数据的加解密。
如图
HTTP
SSL/TSL
TCP
IP
SSL:由Netscape公司开发,专门用于保护web通讯。SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为SSL记录协议(SSL Record Protocol)和SSL握手协议(SSL Handshake Protocol)两层。
TLS:是IETF(Internet Engineering Task Force,互联网工程任务组)制定的一种新的协议,它建立在SSL3.0协议规范之上,是SSL3.0的后续版本。TLS是当前主流的网络安全协议。
http为什么不安全?
http是明文传输,主要存在三大风险:窃听风险、篡改风险、冒充风险。
窃听风险:
中间人可以获取到通信内容,由于内容是明文,所以获取明文后有安全风险。
客户机 -> 中间人(窃听,不修改) -> 服务器
篡改风险:
中间人可以篡改报文内容后再发送给对方,风险极大。
客户机 -> 中间人(窃听且修改) -> 服务器
冒充风险:
比如你以为是在和某宝通信,但实际上是在和一个钓鱼网站通信。
客户机 -> <- 中间人(直接冒充服务器,让客户机以为自己在和服务器通信) 服务器
HTTPS是为了解决以上三大风险而存在的。
安全的通信需包含四个原则:机密性、完整性、身份认证和不可否认。
机密性:对数据加密,解决了窃听风险,因为即使被中间人窃听,由于数据是加密的,他也拿不到明文。
完整性:数据在传输过程中没有被篡改,不多不少,保持原样,中途如果哪怕改了一个标点符号,接收方也能识别出来,从来判定接收报文不合法。
身份认证:确认对方的真实身份,即证明我是我的问题,这样就解决了冒充风险,用户不用担心访问的是某宝结果却在和钓鱼网站通信的问题。
不可否认:不可否认已发生的行为,比如小明向小红借了100元,但没有打借条,或者打了借条但没有签名,就会造成小红的资金损失。
HTTPS通信原理简述
HTTPS使用对称加密和非对称加密以及数字证书。对称加密是指加解密的密钥相同,非对称加密是指有公钥和私钥,公钥加密的只有私钥能解开,私钥加密的只有公钥能验证。使用非对称加密来对对称加密的密钥进行加密,这时候传递非对称加密的密钥需要借助数字证书来传递。在数字证书中添加上公钥即可。到这里,公钥和对称加密的密钥都有了,就可以开始传输了。
PS:非对称加密,公加私解用于信息加密 私加公解用于身份验证。
nginx配置文件解释
worker_processes 1; # 工作进程数,与cpu内核数有关。进程拆分为线程供cpu的核>心来处理,一个内核一次处理一个线程。
events {
worker_connections 1024; # 每个工作进程能处理的最大连接数。
}
二、nginx配置演示
隐藏版本号
浏览器中按F12,选择网络,在最上面点击你访问的网页(例如百度,会显示www.baidu.com)找到这个并点击它,选择标头-响应标头,这里面有一行为server,会跟上web应用程序及版本。
vim nginx.conf
server_tokens off; # 表示关闭nginx的版本号,在http响应头中看不到nginx的版本。
此时查看server发现没有版本号了。
隐藏危险请求方法
if ($request_method !~ ^(GET|HEAD|POST)$) { # 如果请求方式不是GET|HEAD|POST,会返回666状态码。
return 666;
}
验证:
curl -XPUT -I 192.168.10.101
curl:(52) Empty reply from server
查看日志
192.168.10.102 - - [11/Mar/2025:11:30:11 +0800] "PUT /HTTP/1.1" 666 0 "-" "curl/8.4.0"
请求限制(CC攻击防御)
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; # $binray_remote_addr 获取二进制的客户端ip地址,remote_addr表示远程IP,在http里代表>
客户端地址。 req_limit:10m 表示10兆,用于存储客户端的ip和连接。 rate=10r/s 表示每个IP可以发起的请求次数。
limit_req zone=req_limit burst=20 nodelay; # zone=req_limit 绑定到预
定义的共享内存区 burst=20 类似于等候区,超出并发数的请求会到等候区,等候区占
满后,多余的请求会立即返回503 nodelay表示立即处理突发请求而不延迟,相当于立即
处理等候区的请求,多余的请求会立刻返回503
客户机:
for i in $(seq 150);do curl 192.168.10.101; done
服务器:
cat access.log发现有大量503的回应。
防盗链
客户机(101):
cat aaa.html
<html>
<body>
<h1> aaa
<img src="http://192.168.10.101/kgc.png"/> 盗取192.168.10.101的图片,ip可换域名
</h1>
</body>
</html>
浏览器访问192.168.10.102会显示192.168.10.101的图片。
服务器(101):
location ~* \.(jpg|jpeg|png|bmp|swf|flv|mp4|webp|ico)$ { # ~* \.(jpg|gif|swf)$ 表示匹配不区分大小写,以.jpg或.gif或.swf结尾的文件;
root html;
valid_referers ooos.com *.ooos.com; # 访问网址为ooos.com的
访问网址为*(所有的开头).ooos.com的
if ($invalid_referer) { # 如果链接的来源域名不在valid_refe
rers所列出的列表中,$invalid_referer为1,则执行后面的操作,即进行重写或返回99
9。
return 999;
}
客户机:
vim /etc/hosts
192.168.10.101 www.ooos.com
浏览器访问192.168.10.102不显示图片,状态码为404。输入192.168.10.101也不显示图片,状态码为404。访问www.ooos.com会显示图片。(开头也可以是aaa、bbb、ccc等等)
动态黑名单
[root@localhost conf]# cat blockips.conf
192.168.1.0/24 1;
192.168.10.102 1;
[root@localhost conf]# vim nginx.conf
geo $block_ip { # Nginx内置模块指令,专门用于处理ip地址相关的逻辑,基
于客户端ip地址生成一个变量值,用于后续的访问控制判断。 $block_ip是自定义的变>量名,存储计算结果(通常为0或1) default 0 是默认值,表示不在黑名单中的ip允许
访问。
default 0; # 默认允许访问
include /usr/local/nginx/conf/blockips.conf; # 包含黑名单
}
server {
listen 80;
server_name localhost;
if ($block_ip) { # 判断标记值,变量值为1时触发封禁逻辑
return 666; # 封禁动作
}
客户端验证
[root@localhost html]# curl -I 192.168.10.101
HTTP/1.1 666
Server: nginx/1.26.3
Date: Tue, 29 Apr 2025 02:41:35 GMT
Content-Length: 0
Connection: keep-alive
脚本实现动态黑名单
[root@localhost conf]# vim /root/a.sh # 将此脚本加入定时任务中,可实现定时防护。
#!/bin/bash
awk '{print $1}' /usr/local/nginx/logs/access.log | sort | uniq -c | sort -nr
| awk '{if ($1 > 100) print $2 " 1;" }' > /usr/local/nginx/conf/blockips.con
f
# sort 用于排序 sort -nr n表示依照数值大小来排序,数值小的在上。 r表示以相反>的顺序来排序。 uniq -c用于在每列旁边显示该行重复出现的次数。
# 如果$1出现次数大于100,那么将它打印出来并加上1; 表示拒绝该ip,将结果重定向>覆盖输出到blockips.conf文件中
[root@localhost conf]# for i in $(seq 166); do curl 192.168.10.101;done # 大量访问以触发条件$1>100
这里就简单的运行一次来验证脚本。
[root@localhost ~]# bash a.sh
[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# cat blockips.conf
192.168.10.101 1;
[root@localhost conf]# curl 192.168.10.101
<html>
<body>
<h1>ooos!
<img src="kgc.png"/>
</h1>
</body>
</html>
[root@localhost conf]# nginx - s reload # 可将此步加到脚本中。
[root@localhost conf]# curl -I 192.168.10.101
HTTP/1.1 666
Server: nginx/1.26.3
Date: Tue, 29 Apr 2025 03:17:37 GMT
Content-Length: 0
Connection: keep-alive
https配置
[root@localhost conf]# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx-selfsigned.key -out /etc/nginx/ssl/nginx-selfsigned.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=localhost" # 生成证书
req表示请求。
-x509表示生成自签名证书(x509是证书类型)
-nodes表示不加密私钥(无密码保护)。
-days 365表示证书有效期一年。
-newkey rsa:2048 表示生成2048位的RSA密钥。
-keyout 表示将私钥输出到指定位置。
-out 表示将证书文件输出到指定位置
-subj 表示证书主题信息,C=CN是指国家为中国,ST=Beijing表示省份 L=Beijing表示市 O=Myorg表示证书机构(这里是自定义的名字) CN=localhost是主机名。
[root@localhost conf]# vim nginx.conf
server {
listen 443 ssl; # 监听HTTPS端口
server_name localhost; # 域名或IP
# 指定证书和私钥路径
ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt;
ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key;
# SSL协议和加密套件配置(可选,提升安全性)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
# 将HTTP请求重定向到HTTPS
server {
listen 80;
server_name localhost;
return 301 https://$host$request_uri;
}
[root@localhost conf]# firewall-cmd --add-service=https
success
浏览器访问https://192.168.10.101 提示证书不安全,选择高级-继续前往或信任该证书-访问成功。
访问http://192.168.10.101 会跳转到https://192.168.10.101,因为之前信任了证书,所以未提示证书不安全。