我也是很头疼,我这个小破网站竟然有人攻击。还特么的连续攻击。原本吧小网站我以为就是本身写写博客,而后你们给我评论下。互帮互助,团结友爱。结果吧,我被教育了。挺惨痛的回忆。前端
而后就是我的站长的流量问题。java
这个很重要,就是,必定要服务端渲染。node
没有别的缘由,你的网站若是是面向搜索引擎的你必须是服务端渲染。否则是无法被很好的搜索,提高排名的。redis
我我的网站比较隐私,就没搞那些东西了。不过我下一次必需要尝试下服务端渲染,否则目前为止经验尚浅啊。数据库
这里说的流量问题和搜索之类没有什么关系,就是单纯的记住,别把图片放上去。太吃流量了。你只是个小破站,就别搞那么多了。后端
我为了图片访问速度和服务器资源节省,把图片放在了oss存储上面,可是我想说。仍是很贵的。api
我给你们算一笔账浏览器
目前服务器(1核1G1M)是aliyun的,三年300,很便宜是吧,可是这是搞特价,正常一年须要一千。缓存
若是你的网站开发的时候优化作的还能够,那么首屏流量能控制在1M左右。这样其实很快。bash
可是主要是图片这块。你若是把图片放本身服务器,那么带宽就不能很低,否则卡死。
若是放oss,那么流量是按访问量计算的。具体好像是1G2毛,总之挺贵的。你要是图片不少,注意,随便页面切换,刷新单人就能给你刷走上百流量。人数稍微多点……,以前知道一个公司。半年,流量费用20万(主要用于视频监控)。
因此我的博主们,本身的小破站图片少放。
图片最好是作好防盗链。否则流量也会很痛苦。
这里我先copy下阿里在eggjs方面的防护,主要你们就是遇到这些了。
我此次遇到的攻击是CSRF方面的攻击。
后端:记录下每一个接口每次调用的的记录。
前端:记录下每一个路由的变化以后的访问记录
这两个是很简单的记录方式,可是能让你最直观的感觉到,网站访问的量是多少。还有就是监控你的网站是否恶意调用接口,恶意访问等等。很直观,很用好。
自己我是没有增长该项功能的。可是通过惨痛教训以后,我痛定思痛。增长了对应的记录。
经过接口调用的分析,得出对方是软件刷新页面不断恶意给我发送评论
这里我贴下我中间件的代码,上面的说实在没什么意义,随便写一下中间件,数据库记录下数据便可。很简单。
这里我增长了redis,若是用数据库性能不合适,而且不须要这么笨重。缓存比较不错。至于为何不存在全局变量。这个我得和你们科普下,不论是nodejs仍是java等后端。是存在多线程或者多进程的。那么一旦负载的时候,系统切换另外一个进程,那么就访问不到数据了。
下面是限制访问的中间件代码。
'use strict';
module.exports = (options, app) => {
return async function(ctx, next) {
try {
const ip = ctx.request.header['x-forwarded-for'];
const req_url = ctx.request.url;
// 获得最终url地址
const url = req_url.indexOf('?') === -1 ?
req_url :
req_url.substring(0, req_url.indexOf('?'));
// 存储当前接口访问信息,后续有统计
ctx.service.interface.apiVisit.add({
ip,
url,
});
// 当前时间
const time = new Date().getTime();
// 获取这个用户该接口上次调用时间
const usr_api = await app.redis.get(ip + url);
// 拦截的接口
const intercept_api = options.api[url];
// 参数获取完毕,设置最新参数
// 设置接口最新调用时间
await app.redis.set(ip + url, new Date().getTime());
if (intercept_api) {
if (time - usr_api > 5000) {
await next();
} else {
ctx.body = ctx.helper.result('', -1, '限制访问' + intercept_api / 1000 + '秒', 0);
}
} else {
await next();
}
} catch (e) {
ctx.logger.warn(e);
}
};
};复制代码
配置部分config.js
// 给'interfaceRestriction'传入参数
config.interfaceRestriction = {
// api封禁
api: {
'/dream-admin/noauth/blog/discuss/add': 1000 * 8,
},
// ip封禁,
ip: [
// '127.0.0.1',
],
};复制代码
上面的ip封禁没有写。暂时用不到
功能还能够拓展,好比限制ip,限制某个接口的访问频率等等。
上面失败的主要缘由在于,ip其实是能够伪造的。并且ip伪形成本很低。因此,你经过ip来限制对方这种爬虫的恶意攻击效果并很差,这只能防止那些恶意灌水的人罢了。爬虫分分钟几十上百万给你攻击过来,效果很差。
后来我在想怎么才合适。
自己攻击属于csrf,可是经过csrf的方式来防护对方没有用。由于csrf自己是一种基于口令的方式。经过爬虫工具,很容易能够窃取你的口令。
最后我就想着实在没什么好办法就增长验证码了。
最后,用了 svg-captcha包。
下面是使用方式,比较简单:
controller代码:
const { ctx, app } = this;
try {
// 生成算数验证码
const verify = svgCaptcha.createMathExpr({
size: 4,
ignoreChars: '0o1i',
noise: 5,
color: true,
background: '#7E7D78',
});
// 以ip为单位存储验证码
const ip = ctx.request.header['x-forwarded-for'];
await app.redis.set(ip, verify.text);
ctx.response.type = 'image/svg+xml'; // 知道你个返回的类型
ctx.body = verify.data;
} catch (e) {
ctx.body = ctx.helper.result('', -1, e);
}复制代码
最后在建立评论的地方,增长验证便可。
一、全部的一切都是为了增长对方破译的难度
二、不要对外开放建立数据的接口(万恶之源)
三、作好数据监控,防范于未然。而且让你能尽快的发现问题
四、若是你对外开放接口了,那么请作好防小人的准备。(验证码真的是一个好东西)
五、全部验证码不如手机验证码来的可靠。
其实最后下来仍是比较老套的一些东西。只是吧,好不容易胜利了。得发发动态。