目录
防盗链
http协议中的referrer
防盗联的基本的原理。
防盗联本质:
执行这步动作操作的是谁来执行的呢?
非法的访问也就是倒连是什么意思呢?
什么情况下使用防盗联
nginx防盗链配置
测试一:访问出错
测试二:直接打开图片 错误
测试三:有referers 的情况下,在没有referers 的情况下直接访问 错误
想让不带referers 可以直接访问
使用浏览器或curl检测
简单命令
使用curl测试
带引用
企业中如何使用
返回错误页面
方式一
方式二:
测试:
整合rewrite返回报错图片
测试:
高可用 high availability 简称 HA
高可用场景及解决方案
图解:
安装Keepalived
编译安装
下载地址
如遇报错提示
安装依赖
yum安装
配置
keepalived.conf 文件全部内容
keepalived.conf 配置文件详解
实例:
192.168.116.155 keepalived.conf
查看一下
192.168.116.128 keepalived.conf
测试在外网:ping 192.168.116.200
Keepalived高级应用
问题:nginx 出现问题 keepalived 没有问题 是检测不到的解决方式:通过脚本
总结:
脚本方式:
主服务器
keepalived.conf
在/usr/local/src 添加检测脚本nginx_check.sh 检测脚本
从服务器
keepalived.conf
nginx_check.sh 检测脚本 【不变】
防盗联本质:
就是存在我们自己服务下这些资源,只能由我们自己服务器来访问。其他引用不能访问。
大概道理:当我们的请求用户打到我们这台机器上,这台机器会给她去寻找,她所访问的一些资源,首先假设他请求的是个静态的 HTML 页面(index.html),这个页面里我们引用了一些其他的资源,这些资源都是在 HTML 的骨架里再次被访问的。
比如说我们在访问到这个 HTML 的时候,它会给我们返回 HTML 页面 里面的静态数据。这些数据返回来之后有很多的引用,比如说 css 、 js 他还会再次去请求,甚至多次去请求我们当前这个站点。当再次请求的时候,他在发起请求的时候,会在请求的这个 header 里,在这个 request header 里边加上这么一个参数,叫 referrer 这是 HTTP 协议所规定的,由浏览器来遵守的。这个 referrer在我们第二次访问的时候才有。在第一次访问的时候它是没有的。就是我们内联的这些资源再次访问请求。我们服务器这时候会在这个协议头上加上 referrer 表示我引用了你之前的这个页面,是从这个页面过来的。
举例理解:
比如说我问你你从哪来的,我是从河北来的,第二次来的时候我会问你从哪来?因为第一次来你之前你也没去过什么地儿对吧?这是问他第二次的来源是哪儿。当它带上这 referrer 的时候,我就能判定它是不是我当前那台主机了。如果他是我当前这台主机,我肯定是要让他访问我这个服务器里资源的对吧?这里边有 logo.png index.html 这里边需要一个 logo.png 这是第二次在访问的。第二次访问的时候,这里边 HTTP 请求头里加上这个 referrer 了。加上 referrer 之后它表示它是从某一个页面来的,就是刚才我访问的这个 index 面。当然它会把这个整个完整的被访问的这个域名给加上
执行这步动作操作的是谁来执行的呢?
不是我们用户来执行的,我们用户也没法去操作这一步操作。尤其是在浏览器里,浏览器想要让它保证绝对的安全的话,你这些 HTTP 协议就得让浏览器来帮我们去填充,我们现在是没法操控这个浏览器里边这个 referrer 是啥的,所以这是浏览器帮我们来完成的。也就是用户只要使用一个正当的浏览器,普通用户使用普通比较正常正规的合法的浏览器,他就一定会带上这个 referrer 在请求我们的系统,那这种情况下这是正常的访问
非法的访问也就是倒连是什么意思呢?
那当前这个地址站点是我们这个 101 我访问的这是 101 这个站点,我自己引用我自己你肯定可以引用对不对?再搞一个站点出来 102 ,通过 proxy_pass 或者是和 HTML 里的引用,比如说我里边直接引用 images src 拟另外一个站点。那么我们在访问这个资源的时候,不管是 proxy_pass 也好,还是这个 images src 它都属于第二次访问了。
如果我打开了第二个站点,它的首页这里边又内联了一些 image 、JS、CSS什么的,它也一定会加上这个 referrer 那么就可以通过 referrer 来判定这个站点和 原始的站点 是不是一个站点。如果不是的话,那我就判断它是非法请求。
有一个这个网站非法的去引用了我的资源,我本来也不想让他引用,那一定是这样的,如果想让他引用,你也不需要配置这个了对吧,这是这个防盗联的基本的原理。
正常情况下,我们一般来说,除非你是资源消耗量比较大,或者是这个资源比较稀缺,你就期望用户到你的站点上他能看的这种情况,我们才让他去配置一下这个防盗帘。
有的我们的网站上边放了一些资源什么的,我还特别希望让这个更多的站点去引用,然后能增加曝光量对吧。
valid_referers none | blocked | server_names | strings ....;
- none, 检测 Referer 头域不存在的情况。
- blocked,检测 Referer 头域的值被防火墙或者代理服务器删除或伪装的情况。这种情况该头域的值不以“http://” 或 “https://” 开头。 【不常用】
- server_names ,设置一个或多个 URL ,检测 Referer 头域的值是否是这些 URL 中的某一个。【域名、不是ip】 ip可能不好用
# 在需要防盗链的location中配置
valid_referers 192.168.44.101;
if ($invalid_referer) {
return 403;
}
在新标签也打开图片
不止引用非法、禁止访问、直接引用也非法
我们可以增加这个配置叫 none 在我们检测这个 referers 的时候,如果你在这配置一个 none 那也说 referers 如果没有的话,那我就让你访问。有错了不行,也是一些站点倒连方式。
应用场景:
你得访问他一个页面,这个页面里头可能会加载我的一些图片或者一些其他的资源,包括浏览器在点击下载按钮的时候,他去下载某一个压缩包,他也会带这个 referers 那么如果不带这个 referers 比如说我把这个我页面里边有一个下载地址,那我给它复制下来,拿其他的一些下载工具去下载。
valid_referers none 192.168.44.101; if ($invalid_referer) { return 403; }
[root@centos01 ~]# yum install -y curl
curl 比这个浏览器好用,尤其是在做一些测试的时候更纯粹更简单一些。因为浏览器为了让我们加速访问一些网站,它会给我们在多个地给我们设置缓存,让你刷新的时候有可能刷不到最新的页面,用 curl 就会非常有效地解决这个问题。
简单命令
使用curl测试
curl -I http://192.168.44.101/img/logo.png
I 这是大写的 I 是比较常用的这个请求,不会把这个内容给我们展示出来,只是给我们返回响应的一些头信息。
带引用
curl -e "http://baidu.com" -I http://192.168.44.101/img/logo.png
测试带引用种请求的话可以 -e 然后把我们需要引用地址 就是这referers 他给带上,填上引用地址
需要 keepalive 技术 ,这个 keepalive 的不需要额外再加一台机器。所有机器都有 keepalive 其实就是一个小小的软件。
作用:
互相的通讯,两台机器上的 keeplive 互相的通讯,来互相检测对方有没有挂掉两台机器同时对外提供服务,怎么提供服务?
ip 地址不能重复 假设两个 ip 111 、112 以谁为主要的入口 ?
假设以111,为主入口,但是此时111机器宕机,keepalive 之间建立了通信 能不能把 112 改成 111 换ip问题就解决了? 真的解决了?
如何判断这台机器是真的宕机,还是假死的状态?或者 说当时这个交换机过热,出了一些短时的通讯故障,或者出现了网络分区故障。
什么叫网略分区?
每一个机柜下边都会有一个这个小的交换机,那么交换机和交换机之间通讯一旦产生了故障,那么这会就出现网络分区故障的情况。
分成了两个区:
1、内网互相访问没有问题,但这根网线如果断了,两个机柜之间互相访问就访问不到了
2、如果要是说短时的这种交换机过热,这会可能真的突然访问不到了
把111的ip地址直接挪到112上 ,把112 的 ip (112) 给清除掉,或者在网卡上额外的增加一个ip,但是此时,如果再次启动 就会 ip(111)冲突
直接交换 ip 的方式不可行。逻辑上是可以行得通的。但实际使用的时候这里不是有很大问题换个思路 :
虚拟出来一个ip200 ,叫 virtual ip 这个 IP 地址在局域网里边是虚拟存在的 【其实也不能说是完全虚拟存在,只是说在局域网里边没有任何一台机器占用了这个 IP 地址】
keepalive 的,不再去换他的真实的 IP 地址,而是把这个虚拟的 IP 地址来回漂移
作用:
用户访问的时候,入口是这个虚拟的 IP 地址,这个 IP 地址究竟在哪台机器上?它不固定问题解决
下载地址
https://www.keepalived.org/download.html# 使用 ./configure 编译安装
如遇报错提示
configure: error: !!! OpenSSL is not properly installed on your system. !!! !!! Can not include OpenSSL headers files. !!!
安装依赖
yum install openssl-devel
yum install keepalived -y
配置
使用yum安装后配置文件所在位置 /etc/keepalived/keepalived.conf
keepalived.conf 文件全部内容
冗余文件多
! Configuration File for keepalived global_defs { notification_email { [email protected] [email protected] [email protected] } notification_email_from [email protected] smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.200.16 192.168.200.17 192.168.200.18 } } virtual_server 192.168.200.100 443 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.201.100 443 { weight 1 SSL_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc } url { path /mrtg/ digest 9b3a0c85a887a256d6939da88aabd8cd } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } } virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP sorry_server 192.168.200.200 1358 real_server 192.168.200.2 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.200.3 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } } virtual_server 10.10.10.3 1358 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.200.4 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.200.5 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
keepalived.conf 配置文件详解
//global_defs 全局配置 global_defs { notification_email { [email protected] [email protected] [email protected] } notification_email_from [email protected] smtp_server 192.168.200.1 smtp_connect_timeout 30 // router路由 LVS_DEVEL 访问到主机 vi /etc/hosts 中添加主机的名字 router_id LVS_DEVEL vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } //检测脚本和权重的参数 script 脚本文件 Evrrp_script chk_http_port { script "/usr/local/src/nginx_check.sh" #(检测脚本执行的间隔) 路径 interval 2 weight 2 } //虚拟ip的配置 vrrp_instance VI_1 { # 在内网当中通讯的协议 VI_1 实例名称 state MASTER # 备份服务器上 将 MASTER 改为 BACKUP interface eth0 // 网卡 查看网卡 ifconfig virtual_router_id 51 # 主、备机 的 virtual_router_id 必须相同 priority 100 # 主、备机去不同的优先级 主机值大,备份机值小 advert_int 1 # 间隔检测的时间 authentication { # keepalived 认证配置 同一组保持一致 auth_type PASS auth_pass 1111 } virtual_ipaddress { # 虚拟的 ip 地址 可以填写多个 192.168.200.16 // VRRP H 虚拟地址 192.168.200.17 192.168.200.18 } }
! Configuration File for keepalived
global_defs {
router_id lb155
}
vrrp_instance VI_1 { # 在内网当中通讯的协议 VI_1 实例名称
state MASTER
interface ens33 # interface 这个要和网卡的名字 对应 ip addr 查看机器上网卡
virtual_router_id 51
priority 100 # 优先级 数值越高 优先级越高
advert_int 1 # 间隔检测的时间
authentication { # keepalived 认证配置 同一组保持一致
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { # 虚拟的 ip 地址 可以填写多个
192.168.116.200
}
}
keepalive是比较简单的一个软件,它主要是靠检测 keepalive 的这个进程,它是否存活。如果存活着,它就能互相的发送数据包,它就能够互相通讯,一旦要无法通讯了那接下来,我就把这 IP 给它飘走了
keepalived ,除了网络无法到达的情况,我们还可以通过这种一些更灵活的方式
写个脚本我去检测这个我当前需要监听的这个进程,keepalived,没有配置的情况下,只是在监听我们 keeplive 的进程
问题:nginx 出现问题 keepalived 没有问题 是检测不到的
解决方式:通过脚本脚本在本机跑着,和keepalived 是分开的 三者(keepalived、nginx、脚本)之间没有什么关联。脚本不断地去检测 NGINX 当前是否报错了,包括后边要用 Redis 的话也可以这么做。用个脚本去检测 NGINX 当前的访问请求,它是不是正常的200。我每秒访问一次,如果要是出了问题,接下来把这个脚本就把, keepalived 的进程他给 kill 掉。一旦这个进程被 kill 掉了,IP 就飘走了。
总结:
keepalived 不只是能够用到 nginx 上,它是对于 主机级别的检测或者说它是进程级别检测,它只是检测了我这台机器的 keepalived 有没有存活,所以它可以检测一切,比如说两台MySQL 、两台这个Redis ,两台消息中间件,两个后端的应用服务器,都可以提供这个脚本,然后去检测他的这个状态,然后通过 keepalived 的去杀死自己的进程。这就是keepalived
(1) 修改 /etc/ keepalived /keepalived.conf 配置文件
(2)在/user / local / src 添加检测脚本
(3)启动nginx 和 keepalived
./nginx 关闭 ./nginx -s stop
systemctl start keepalived.service
查看是否启动成功 ps- ef | grep keepalived
//global_defs 全局配置
global_defs {
notification_email {
[email protected]
[email protected]
[email protected]
}
notification_email_from [email protected]
smtp_server 192.168.200.1
smtp_connect_timeout 30
// router路由 LVS_DEVEL 访问到主机 vi /etc/hosts 中添加主机的名字
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
//检测脚本和权重的参数 script 脚本文件
Evrrp_script chk_http_port {
script "/usr/local/src/nginx_check.sh" #(检测脚本执行的间隔) 路径
interval 2
weight 2
}
//虚拟ip的配置
vrrp_instance VI_1 {
state MASTER # 备份服务器上 将 MASTER 改为 BACKUP
interface eth0 // 网卡 查看网卡 ifconfig
virtual_router_id 51 # 主、备机 的 virtual_router_id 必须相同
priority 100 # 主、备机去不同的优先级 主机值大,备份机值小
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.200.16 // VRRP H 虚拟地址
192.168.200.17
192.168.200.18
}
}
#!/bin/bash2
A='ps -C nginx -no-header |wc -1'
if [ $A -eq 0 ];then
/usr/1ocal/nginx/sbin/nginx
sleep 2
if [ 'ps -C nginx --no-header |wc -1' -eq 0 ];then
killall keepalived
fi
fi
global_defs {
notification_email {
[email protected]
[email protected]
[email protected]
}
notification_email_from [email protected]
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
//检测脚本和权重的参数
Evrrp_script chk_http_port {
script "/usr/local/src/nginx_check.sh" #(检测脚本执行的间隔) 路径
interval 2
weight 2
}
vrrp_instance VI_1 {
state BACKUP # 备份服务器上 将 MASTER 改为 BACKUP
interface eth0 // 网卡 查看网卡 ifconfig
virtual_router_id 51 # 主、备机 的 virtual_router_id 必须相同
priority 90 # 主、备机去不同的优先级 主机值大,备份机值小
advert_int 1 # 心跳 1s
authentication {
auth_type PASS //校验方式 密码 1111
auth_pass 1111
}
virtual_ipaddress {
192.168.200.16 // VRRP H 虚拟地址
192.168.200.17
192.168.200.18
}
}
#!/bin/bash2
A='ps -C nginx -no-header |wc -1'
if [ $A -eq 0 ];then
/usr/1ocal/nginx/sbin/nginx //nginx 启动脚本的位置
sleep 2
if [ 'ps -C nginx --no-header |wc -1' -eq 0 ];then
killall keepalived // 所有的都杀掉 主 挂 从 上
fi
fi