大佬教程收集整理的这篇文章主要介绍了防盗链(一)资料整理,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
防盗链,其本质就是用户对于自己的资源设置的访问控制,控制“谁”可以在“什么时间”访问到“什么资源”。不做防盗链,用户的许多资源都为其他人做了嫁衣,也会给自己的服务器增加不必要的访问压力和带宽消耗。
不同的用户,由于网站的性质不同(游戏/新闻/游戏),需求也是不尽相同的,所以需要在我们的portal系统中添加访问控制的功能,满足用户的需要。
表示在什么情况下需要进行防盗链逻辑。比如我们需要对 xxx.com/image/ 下面的URL进行防盗链处理,而对 xxx.com/js/ 则不需要防盗链。
是否进行防盗链,一般通过2种方式进行匹配:
URL匹配是指,符合某些前缀或者正则表达式的URL进行防盗链,见上例; 类型匹配,就是对某些特定类型的资源进行防盗链,例如jpg、mp3。
IP黑白名单
只允许或者阻止某些IP访问资源,一般都是IP黑名单的形式。
用户可以在界面中输入单个IP、IP区间、或者IP通配符,例如:
1.2.3.4 192.168.199.1 ~ 192.168.199.100 192.168.1.*
个人理解是我们通过分析以往的访问日志,得出某些IP的访问可能有异常,之后将其加入黑名单。IP黑名单的限制范围既可以是全局范围(我们CDN服务提供商配置),也可以是域名范围(CDN服务使用方配置)。
Referer黑白名单
最常用的防盗链手段,通过对http请求中的referer header进行判断,以决定用户是否可以访问该资源。一般都是referer白名单的形式。
需要支持单个域名以及泛域名的形式,例如:
ent.cankaoxiaoxi.com *.cankaoxiaoxi.com
public void doGet(httpServletrequest request, httpServletResponse responsE) throws servletexception, IOException { // 获取请求是从哪里来的 String referer = request.getHeader("referer"); // 如果是直接输入的地址,或者不是从本网站访问的重定向到本网站的首页 if (referer == null || !referer.startsWith("http://localhost")) { response.sendRedirect("/day06/index.jsp"); // 然后return,不要输出后面的内容了 return; } String date = "日记"; response.getWriter().write(datE); } public void dopost(httpServletrequest request, httpServletResponse responsE) throws servletexception, IOException { doGet(request, responsE); }
个人认为使用场景并不多。
UA白名单
http请求header中的User Agent字段,是一段浏览器或者设备标识自己的字符串。对于网站主来说,有时需要让一些资源只能在某些浏览器或者设备上才能访问。
UA 防盗链通常用在手机 APP 或者一些可自定义 User Agent 的应用,比如播放器。设置UA白名单,也和其他情况类似,支持字符串通配符。
Java通过浏览器请求头(User-Agent)获取 浏览器类型,操作系统类型,手机机型 User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、cpu 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。 一些网站常常通过判断 UA 来给不同的操作系统、不同的浏览器发送不同的页面,因此可能造成某些页面无法在某个浏览器中正常显示,但通过伪装 UA 可以绕过检测。 一:获得浏览器请求头中的User-Agent String ua = request.getHeader("User-Agent") 二:获得浏览器类型,操作系统类型:(注意,UserAgent类在UserAgentUtils.jar中,自行下载) UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); browser browser = userAgent.getbrowser(); OperaTingSystem os = userAgent.getoperaTingSystem(); 三:获得手机类型: 方案一:正则表达式 通过观察规律,得出以下表达式: ;\s?([^;]+?)\s?(Build)?/ Java代码: Pattern pattern = Pattern.compile(";\\s?(\\S*?\\s?\\S*?)\\s?(Build)?/"); Matcher matcher = pattern.matcher(userAgent); String model = null; if (matcher.find()) { model = matcher.group(1).trim(); log.debug("通过userAgent解析出机型:" + model); } 以下为部分UserAgent,供测试,可以直接在EditPlus里验证。
通过验证,成功率95%以上。
方案二:开源类库WURFL
地址:https://wurfl.sourceforge.net/apis.php
在线测试地址:https://tools.scientiamobile.com/
token一般会在请求参数或者cookie中,没有带 token 的外链,或者超过了有效期的token链接都会返回403,达到防盗链的目的。
Token 加密串这种方案,一般用于文件下载的场景比较多,静态图片的场景则较少。
在系统中,用户需要有界面能够上传自定义的盗链提示图,甚至是不同的http返回码可以设置不同的盗链提示图。
Nginx本身已经提供了丰富的功能,通过获取http请求中的各个字段,判断请求是否合法,可以实现以上提到的URL匹配、类型匹配、IP黑白名单等功能。
比如,可以获取client ip,来决定是否请求upstream,以此达到IP黑白名单的目的,样例:
## If IP is 1.2.3.4 send BACkend to apachereadwrite ## if ( $remote_addr ~* 1.2.3.4 ) { proxy_pass http://cdn_BACkend; }
也可以判断server_name,来达到域名黑白名单的效果,样例:
# conf/Nginx.conf server { listen 80; include /home/uaq/local/static_dynamic_proxy/Nginx/conf/static_server_names.conf; #charset koi8-r; #access_log logs/host.access.log main; LOCATIOn ~ { proxy_pass http://static_accelerate; } # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; LOCATIOn = /50x.html { root html; } }
# conf/static_server_names.conf; server_name a.com b.com ;
ngx_http_referer_module,可以专门用于判断referer是否合法、或者是否是空的referer,样例:
LOCATIOn ~* \.(gif|jpg|png|bmp)$ { valid_referers none blocked *.mmtrix.com server_names ~\.google\. ~\.baidu\.; if ($invalid_referer) { return 403; } }
ngx_http_secure_link_module,用于检测访问资源者的授权,以及资源的有效时间,可以用于Token加密串的防盗链,样例:
server { listen 80; server_name cdn.aaa.com; access_log /data/logs/Nginx/access.log main; index index.html index.php index.html; LOCATIOn / { secure_link $arg_st,$arg_e; secure_link_md5 some_private_key$uri$arg_e; if ($secure_link = "") { return 403; } if ($secure_link = "0") { return 403; } } }
虽然Nginx的功能已经比较强大,但是不够灵活,而且在conf中有过多的配置,也会占用较多内存、影响Nginx处理请求的时间。我们既然作为CDN服务提供商,除了全局的配置,还需要为每个用户的每个域名进行自定义的配置,因为将所有条件写入Nginx conf是不现实的。另外,lua还提供更多强大功能,例如请求时访问redis、memcached,和其他实例共享状态等等功能。因此,Nginx + lua可能是一个不错的解决方案。
网上的cookie token加密串的样例:
-- Some variable declarations. local cookie = ngx.var.cookie_myToken local hmac = "" local timestamp = "" -- check that the cookie exists. if cookie ~= nil and cookie:find(":") ~= nil then -- If there's a cookie, split off the HMAC signature -- and timestamp. local divider = cookie:find(":") hmac = cookie:sub(divider+1) timestamp = cookie:sub(0, divider-1) -- Verify that the signature is valid. if hmac_sha1("some very secret String", timestamp) == hmac and tonumber(timestamp) >= os.time() then return end end -- Internally rewrite the URL so that we serve -- /auth/ if there's no valid token. ngx.exec("/auth/")
网上查找到的各种与Nginx+lua相关的方案,基本上都还是单机版本的解决方案。考虑到我们分布式环境,以及业务复杂的情况,还需要用到分布式存储、缓存、任务分发等技术。
以上是大佬教程为你收集整理的防盗链(一)资料整理全部内容,希望文章能够帮你解决防盗链(一)资料整理所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。