4.1 根据扩展名限制程序和文件访问
- Web2.0时代,绝大多数网站都是以用户为中心多的,例如:bbs,blog,sns产品,这几个产品都有一个共同特点,就是不但允许用户发布内容到服务器,还允许用户发图片甚至上传附件到服务器上,由于为用户开了上传功能,因此给服务器带来了很大的安全风险。虽然很多程序在上传前会着一定的控制,例如:文件大小,类型等,但是,一不小心就会被黑客钻了控制,上传了木马程序。
- 下面将利用Nginx配置禁止访问上传资源目录下的PHP,Shell,Perl,Python程序文件,这样用户即使上传了木马文件也没法执行,从而加强了网站的安全。
范例1:配置Nginx,禁止解析指定目录下的指定程序。
范例2:Nginx下配置禁止访问*.txt和*.doc文件。
实际配置信息如下:
4.2 禁止访问指定目录下的所有文件和目录
范例1:配置禁止访问指定的单个或多个目录
范例2:禁止访问目录并返回指定的HTTP状态码,命令如下:
作用:禁止访问目录下的指定文件1,或者禁止访问指定目录下的所有内容。最佳应用场景:对于集群的共享存储,一般是存放静态资源文件,所以,可禁止执行指定扩展名的程序,例:.php,.sh,.pl,.py
4.3 限制网站来源IP访问
下面介绍如何使用ngx_http_access_module限制网站来源IP访问
案例环境:phpmyadmin数据库的Web客户端,内部开发人员用的。
范例1:禁止某目录让外界访问,但允许某IP访问该目录,且支持PHP解析,命令如下:
范例2:限制指定IP或IP段访问,命令如下:
参考资料:http://nginx.org/en/docs/http/ngx_http_access_module.html
企业问题案例: Nginx做反向代理的时候可以限制客户端IP吗?
答:可以,具体方法如下:
方法一:使用if来控制,命令如下:
方法二:利用deny和allow只允许IP访问,命令如下:
方法三:只拒绝某些IP访问,命令如下:
注意事项:
- deny一定要加一个IP,否则会直接跳转到403,不再往下执行了,如果403默认页是在同一域名下,会造成死循环访问。
- 对于allow的IP段,从允许访问的段位从小到大排列,如127.0.0.0/24的下面才能是10.10.0.0/16,其中:
- 24表示子网掩码:255.255.255.0
- 16表示子网掩码:255.255.0.0
- 8表示子网掩码:255.0.0.0
- 以deny all:结尾,表示除了上面允许的,其他的都禁止。如:
4.4 配置Nginx,禁止非法域名解析访问企业网站
问题:Nginx如何防止用户IP访问网站(恶意域名解析,也相当于是直接IP访问企业网站)
方法一:让使用IP访问网站的用户,或者恶意解析域名的用过户,收到501错误,命令如下:
方法二:通过301跳转到主页,命令如下:
方法三:发现某域名恶意解析到公司的服务器IP,在server标签里添加以下代码即可,若有多个server则要多处添加。
5.1 什么是资源盗链
简单的说,就是某些不法网站未经允许,通过在其自身网站程序里非法调用其他网站的资源,然后在自己的网站上显示这些调用的资源,达到填充自身网站的效果。这一举动不仅浪费了调用资源网站的网络流量,还造成其他网站的带宽及服务压力吃紧,甚至宕机。
下面通过示意图阐述资源被盗链原理,如下图所示:
5.2 网站资源被盗链带来的问题
若网站图片及相关资源被盗链,最直接的影响就是网络带宽占用加大了,带宽费用多了,网络流量也可能忽高忽低,Nagios/Zabbix等报警服务频繁报警,类似下图所示:
最严重的情况就是网站的资源被非法使用,使网站带宽成本加大和服务器压力加大,这有可能导致数万元的损失,且网站的正常用户访问也会受到影响。
5.3 企业真实案例:网站资源被盗链,出现严重问题
某日,接到从事运维工作的朋友的紧急求助,其公司的CDN源站,源站的流量没有变动,但CDN加速那边的流量无故超了好几个GB,不知道怎么处理。该故障的影响:由于是购买的CDN网站加速服务,因此虽然流量多了几个GB,但是业务未受影响。只是,这么大的异常流量,持续下去可直接导致公司无故损失数万元。解决这个问题可体现运维的价值。
那么,这样的问题如何及时发现,又如何处理呢?
第一:对IDC及CDN带宽做监控报警第二:作为高级运维或运维经理,每天上班的重要任务,就是经常查看网站流量图,关注流量变化,关注异常流量。第三:对访问日志做分析,迅速定位异常流量,并且和公司市场推广等保持较好的沟通,以便调度带宽和服务器资源,确保网站正常的访问体验。
5.4 常见防盗链解决方案的基本原理
(1)根据HTTP referer实现防盗链
- 在HTTP协议中,有一个表头字段叫referer,使用URL格式来表示是哪里的链接用了当前网页的资源。通过referer可以检测访问的来源网页,如果是资源文件,可以跟踪到显示它的网页地址,一旦检测出来源不是本站,马上进行阻止或返回指定的页面。
- HTTP referer是header的一部分,当浏览器向Web服务器发送请求时,一般会带上referer,告诉服务器我是从哪个页面链接过来的,服务器借此获得一些信息用于处理。Apache,Nginx,Lighttpd三者都支持根据HTTP referer实现防盗链,referer是目前网站图片,附件,html等最常用的防盗链手段。下图是referer防盗链的基本原理图。
(2)根据cookie防盗链
- 对于一些特殊的业务数据,例如流媒体应用通过ActiveX显示的内容(例如,Flash,Windows Media视频,流媒体的RTSP协议等),因为他们不向服务器提供referer header,所以若采用上述的referer的防盗链手段,就达不到想要的效果。
- 对于Flash,Windows Media视频这种占用流量较大的业务数据,防盗链是比较困难的,此时可以采用cookie技术,解决Flash,Windows Media视频等的防盗链问题。
例如:ActiveX插件不传递referer,但会传递cookie,可以在显示ActiveX的页面的标签内嵌入一段Javascript代码,设置“cookie:Cache=av”如下:
然后就可以通过各种手段来判断这个cookie的存在,以及验证其值的操作了。根据cookie来防盗链的技术比较复杂,我们不在这里涉及,同学们如果感兴趣,或者企业确实需要,可通过网络来了解相关方法。
(3)通过加密变换访问路径实现防盗链
此种方法比较适合视频及下载类业务数据的网站。例如:Lighttpd有类似的插件mod_secdownload来实现此功能。先在服务器端配置此模块,设置一个固定用于加密的字符串,比如yunjisuan,然后设置一个url前缀,比如/mp4/,再设置一个过期时间,比如1小时,然后写一段PHP代码,利用加密字符串和系统时间等通过md5算法生成一个加密字符串。最终获取到的文件的URL链接中会带有一个时间戳和一个加密字符的MD5数值,在访问时系统会对这两个数据进行验证。如果时间不在预期的时间段内(如1小时内)则失效;如果时间戳符合条件,但是加密的字符串不符合条件也会失效,从而达到防盗链的效果。
5.5 Nginx Web服务实现防盗链实战
在默认情况下,只需要进行简单的配置,即可实现防盗链处理。请看下面的实例。
(1)利用referer,并且针对扩展名rewrite重定向
(2)利用referer,并且针对站点目录过滤返回错误码
针对目录的方法如下:
在上面这段防盗链设置中,分别针对不同文件类型和不同的目录进行了设置,同学们可以根据自己需求进行类似设定。下面是上述代码的说明:
5.6 NginxHttpAccessKeyModule实现防盗链介绍
- 如果不怕麻烦,有条件实现的话,推荐使用NginxHttpAccessKeyModule。
- 其运行方式是:如download目录下有一个file.zip文件。对应的URI是http://www.abc.com/download/file.zip,使用ngx_http_accesskey_module 模块后就成了http://www.bac.com/download/file.zipkey=09093abeac094,只有正确地给定了key值,才能下载download目录下的file.zip,而且key值是与用户的IP相关的,这样就可以避免被盗链了。据说,现在NginxHttpAccessKeyModule连迅雷都可以防了,同学们执行尝试一下。
5.7 在产品设计上解决盗链方案
产品设计时,处理盗链问题可将计就计,为网站上传的图片增加水印。例如:下图就是为网站上传的图片增加的水印。
为图片添加版权水印是很有效的方法。网站直接转载图片一般是为了快捷,但是对于有水印的图片,很多站长是不愿意转载的。
6.1 生产环境常见的HTTP状态码列表
6.2 为什么要配置错误页面优雅显示
在网站的运行过程中,可能因为页面不存在或系统过载等原因,导致网站无法正常响应用户的请求,此时Web服务会返回系统默认的错误码,或者很不友好的页面,如下图所示:
我们可以将404,403等的错误信息页面重定向到网站首页或其他事先指定的页面,提升网站的用户访问体验。
范例1:对错误代码403实行本地页面跳转,命令如下:
范例2:对错误代码404实行本地页面优雅显示,命令如下:
范例3: 50x页面放到本地单独目录下,进行优雅显示
范例4: 错误状态码URL重定向,命令如下:
范例5: 将错误状态码重定向到一个location,命令如下:
6.3 阿里门户网站天猫的Nginx优雅显示配置案例如下:
7.1 单机LNMP环境目录权限严格控制措施
为了保证网站不遭受木马入侵,所有站点目录的用户和组都应该为root,所有的目录权限是755;所有的文件权限是644.设置如下:
- 以上的权限设置可以防止黑客上传木马,以及修改站点文件,但是,合理的网站用户上传的内容也会被拒之门外。那么如何让合法的用户可以上传文件,而又不至于被黑客利用攻击呢?
- 如果是单机的LNMP环境,站点目录和文件属性设置如下。
- 先把所有的目录权限设置为755,所有的文件权限设置为644,所用的目录,以及文件用户和组都是root;然后把用户上传资源的目录权限设置为755,将用户和组设置为Nginx服务的用户;最后针对上传资源的目录做资源访问限制。
- 部分公司所采用的授权方式不是很安全,常见的有如下两种:
- 上述两种授权方法虽然不能说错误,但是没有做到授权最小化,会给网站带来非常大的安全隐患,特别是木马入侵的时候。
- 在比较好的网站业务架构中,应把资源文件,包括用户上传的图片,附件等服务和程序服务分离,最好把上传程序服务也分离出来,这样就可以从容地按照之前所述进行安全授权了。
7.2 Nginx企业网站集群超级安全设置
结合Linux权限体系及Nginx大型集群架构进行配置,严格控制针对Nginx目录的访问才能降低网站被入侵的风险。比如,可根据下图中的企业集群架构逻辑图和不同角色提供的不同服务来严格控制不同服务器的Nginx目录权限。
下图为集群架构中不同于前面Web业务的权限管理细化。
做到上述的设置后,网站服务在系统层面被入侵的风险就大大降低了。
8.1 robots.txt机器人协议常识
- Robots协议(也称为爬虫协议,机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。
- 我理解的是robots.txt是通过代码控制搜索引擎蜘蛛索引的一个手段,以便减轻网站服务器的带宽使用率,从而让网站的空间更稳定,同时也可以提高网站其他页面的索引效率,提高网站收录。
- 我们只需要创建一个robots.txt文本文件,然后在文档内设置好代码,告诉搜索引擎我网站的哪些文件你不能访问。然后上传到网站根目录下面,因为当搜索引擎蜘蛛在索引一个网站时,会先爬行查看网站根目录下是否有robots.txt文件。
8.2 机器人协议起源
- 2011年10月25日,京东商城正式将一淘网的搜索爬虫屏蔽,以防止一淘网对其内容进行抓取。
京东的robots.txt设置如下:https://www.jd.com/robots.txt
- 2008年9月8日,淘宝网宣布封杀百度爬虫,百度忍痛遵守爬虫协议。因为一旦破坏协议,用户的隐私和利益就无法得到保障,搜索网站就谈不上人性关怀。
淘宝的robots.txt设置如下:https://www.taobao.com/robots.txt
- 2012年8月,360综合搜索被指违反robots协议。
360的robots.txt设置如下:http://www.360.cn/robots.txt
8.3 Nginx防爬虫优化配置
我们可以根据客户端的user-agents信息,轻松地阻止指定的爬虫爬取我们的网站。下面来看几个案例。
范例1:阻止下载协议代理,命令如下:
这里根据$http_user_agent获取客户端agent,然后判断是否允许或返回指定错误码。
范例2:添加内容防止N多爬虫代理访问网站,命令如下:
范例3:测试禁止不同的浏览器软件访问
示例代码如下:
在之前的HTTP协议原理一节中,讲解了很多HTTP方法,其中最常用的HTTP方法为GET,POST,我们可以通过Nginx限制HTTP请求的方法来达到提升服务器安全的目的,例如,让HTTP只能使用GET,HEAD和POST方法的配置如下:
当上传服务器上传数据到存储服务器时,用户上传写入的目录就不得不给Nginx对应的用户相关权限,这样一旦程序有漏洞,木马就有可能被上传到服务器挂载的对应存储服务器的目录里,虽然我们也做了禁止PHP,SH,PL,PY等扩展名的解析限制,但还是会遗漏一些想不到的可执行文件。对于这样情况,该怎么办呢?事实上,还可以通过限制上传服务器的Web服务(可以具体到文件)使用GET方法,防止用户通过上传服务器访问存储内容,让访问存储渠道只能从静态或图片服务器入口进入。例如,在上传服务器上限制HTTP的GET方法的配置如下:
实际效果如下图所示:
10.1 什么是CDN
- CDN的全称是Content Delivery Network,中文意思是内容分发网络。简单地讲,通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的Cache服务器内,通过智能DNS负载均衡技术,判断用户的来源,让用户就近使用与服务器相同线路的带宽访问Cache服务器,取得所需的内容。例如:天津网通用户访问天津网通Cache服务器上的内容,北京电信访问北京电信Cache服务器上的内容。这样可以有效减少数据在网络上传输的时间,提高访问速度。
- CDN是一套全国或全球的1分布式缓存集群,其实质是通过智能DNS判断用户的来源地域及上网线路,为用户选择一个最接近用户地域,以及和用户上网线路相同的服务器节点,因为地域近,且线路相同,所以,可以大幅提升用户浏览网站的体验。
- CDN产生背景之一:BGP机房虽然可以提升用户体验,但是价格昂贵,对于用户来说,CDN的诞生可以提供比BGP机房更好的体验(让同一地区,同一线路的用户访问和当地同一线路的网站),BGP机房和普通机房有将近5~10倍的价格差。CDN多使用单线的机房,根据用户的线路及位置,为用户选择靠近用户的位置,以及相同的运营商线路,不但提升了用户体验,价格也降下来了。
- [x] CDN的价值:
- 为架设网站的企业省钱
- 提升企业网站的用户访问体验(相同线路,相同地域,内存访问)
- 可以阻挡大部分流量攻击,例如:DDOS攻击
10.2 CDN的特点
- [x] CDN就是一个具备根据用户区域和线路智能调度的分布式内存缓存集群。其特点如下:
- 通过服务器内存缓存网站数据,提高了企业站点(尤其含有大量图片,视频等的站点)的访问速度,并大大提高企业站点的稳定性(省钱且提升用户体验)。
- 用户根据智能DNS技术自动选择最适合的Cache服务器,降低了不同运营商之间互联瓶颈造成的影响,实现了跨运营商的网络加速,保证不同网络中的用户都能得到良好的访问质量。
- 加快了访问速度,减少了原站点的带宽
- 用户访问时从服务器的内存中读取数据,分担了网络流量,同时减轻了原站点负载压力等。
- 使用CDN可以分担源站的网络流量,同时可以减轻原站点的负载压力,并降低黑客入侵及各种DDOS攻击对网站的影响,保证网站有较好的服务质量。
下面是通过curl命令访问163网站的header信息,可以看到163网站的首页就使用了CDN进行加速。
上面的“(CdnCacheServerV2.0)”表示163首页使用了CDN加速。
10.3 企业使用CDN的基本要求
首先要说的是,不是所有的网站都可以一上来就能用CDN的。要加速的业务数据应该存在独立的域名,例如:img1-4.yunjisuan.com/video1-4.yunjisuan.com,业务内容图片,附件,JS,CSS等静态元素,这样的静态网站域名才可以使用CDN。
下面来看一个DNS解析范例。DNS服务器加速前的A记录如下:
提示:这个img.yunjisuan.com.cachecn.com.地址必须是事先由CDN公司配置好的CDN公司的域名。国内较大的CDN提供商为网宿,蓝讯,快网。
解耦是开发人员中流行的一个名词,简单地说就是把一堆程序代码按照业务用途分开,然后提供服务,例如:注册登录,上传,下载,浏览列表,商品内容页面,订单支付等都应该是独立的程序服务,只不过在客户端看来是一个整体而已。如果中小公司做不到上述细致的解耦,起码也要让下面的几个程序模块独立。
- 网页页面服务。(静态,动态页面)
- 图片附件及下载服务。(upload)
- 上传图片服务。(static)
- 上述三者的功能尽量分离。分离的最佳方式是分别使用独立的服务器(需要改动程序),如果程序实在不易更改,次选方案是在前端负载均衡器Haproxy/Nginx上,根据URI(例如目录或扩展名)过滤请求,然后抛给后面对应的服务器。
- 例如:根据扩展名分发,请求http://www.yunjisuan.com/a/b.jpg就应抛给图片服务器(独立的静态服务器最适合使用CDN);根据URL路径分发,请求http://www.yunjisuan.com/upload/index.php就应抛给上传服务器。不符合上面两个要求的,默认抛给Web服务器。
说明:可以部署3台服务器,人为分布请求服务器。当然了,这适合并发比较高,服务器较多的情况。程序架构分离了,效率,安全性都会提高很多。
12.1 为什么要让Nginx服务使用普通用户
默认情况下,Nginx的Master进程使用的是root用户,worker进程使用的是Nginx指定的普通用过户,使用root用户跑Nginx的Master进程有两个最大的问题:
- 管理权限必须是root,这就使得最小化分配权限原则遇到难题。
- 使用root跑Nginx服务,一旦网站出现漏洞,用户就可以很容易地获得服务器的root权限。
因此,如果能有一种不用给开发人员,甚至普通运维人员管理员权限,就可以很好地管理Nginx服务的方法,具体内容将在下节为大家讲解。
12.2 给Nginx服务降权的解决方案
解决方案如下:
- 给Nginx服务降权,用inca用户跑Nginx服务,给开发及运维设置普通账号,只要与inca同组即可管理Nginx,该方案解决了Nginx管理问题,防止root分配权限过大。
- 开发人员使用普通账户即可管理Nginx服务及站点下的程序和日志。
- 采取项目负责制度,即谁负责项目维护,出了问题就是谁负责。
很多公司开发和运维为root权限争得不可开交,甚至大打出手。参考资料:到底要不要给开发人员管理服务器的权限?(http://down.51cto.com/data/844517).
12.3 给Nginx服务降权实战
本优化属架构优化(同样适合其他软件),通过Nginx启动命令的-c参数指定不同的Nginx配置文件,可以同时启动多个实例,并使用普通的用户运行服务。Nginx安装后的启动命令路径为“/usr/local/nginx/sbin/nginx”,可以通过加-h参数查看相关参数的用法,命令及结果如下:
较常用的方法是使服务跑在指定用户的家目录下面,这样相对比较安全,同时有利于批量业务部署和上线。
配置普通用户启动Nginx的过程如下:
1)添加用户并创建相关目录和文件,操作如下:
2)配置Nginx配置文件。配置后的查看命令如下:
说明如下:
- 所有参数的值,带路径的都要改成/home/yunjisuan.
- 特权用户root使用的80端口,改为普通用过户使用的端口,在1024以上,这里为8080.
3)启动Nginx,命令如下:
特别提示:此处启动nginx,如果不定向到空会显示一些提示,不是错误,可以通过&>/dev/null 定向到空,从而忽略不见。
4)配置好解析后,浏览器带端口访问结果如下图所示:
5)解决普通端口非80提供服务的问题
用负载均衡器解决Web服务非80端口的转换问题,负载均衡器可为Haproxy,Nginx,F5等。
本解决方案的优点如下:
- 给Nginx服务降权,让网站更安全。
- 按用户设置站点权限,使站点更独立(无需虚拟化隔离)
- 开发不需要用root即可完整管理服务及站点。
- 可实现责任划分,即网络问题属于运维的责任,网站打不开就是开发的责任,或者两者共同承担。
- ngx_http_limit_conn_module这个模块用于限制每个定义的key值的连接数(Nginx默认已经被编译),特别是单IP的连接数。
- 不是所有的连接数都会被计数。一个符合计数要求的连接是整个请求头已经被读取的连接。
控制Nginx并发连接数量参数的说明如下:
1)limit_conn_zone参数:
2)limit_conn参数:
13.1 限制单IP并发连接数
Nginx的配置文件如下:
测试1:利用Webbench进行并发连接测试(模拟一个客户端)
我们查看Web服务器的access.log日志如下:
从上边的日志我们可以看到,当并发数为1时(就一个客户端),nginx正常记录用户的访问情况,http返回状态码为200
测试2:利用Webbench进行多客户端并发测试(模拟2个客户端)
我们查看Web服务器的access.log日志如下:
从上边的日志我们可以看出,当我们用单IP地址模拟两个并发客户端进行连接时,日志以1:1比例交替出现了503错误。即Nginx已经做了并发连接限制,对超过限制的请求返回503.
测试3:利用Webbench进行多客户端并发测试(模拟3个客户端)
我们查看Web服务器的access.log日志如下:
经过测试,可以看得出,200与503基本出现次数为1:2,即Nginx已经做了并发连接限制,对超过限制的请求返回503.
以上功能的应用场景之一是用于服务器下载,命令如下:
上面的命令限制访问download下载目录的连接数,该连接数1.
13.2 限制虚拟主机总连接数
不仅可以限制单IP的并发连接数,还可以限制虚拟主机总连接数,甚至可以对两者同时限制。
Nginx的配置文件如下:
测试:
我们查看Web服务器的access.log日志如下:
结论:200和503出现的次数近似2:1至此,Nginx限制连接数的应用实践就讲解完毕了。更多资料可参考:http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
ngx_http_limit_req_module模块用于限制每个IP访问每个定义key的请求速率。
- 这里运用了令牌桶原理,burst=num,一共有num块令牌,令牌发完后,多出来的那些请求就会返回503。
- 换句话说,一个银行,只有一个营业员,银行很小,等候室只有5个人的位置。因此,营业员一个时刻只能为一个人提供服务,剩下的不超过5个人可以在银行内等待,超出的人不提供服务,直接返回503。
- nodelay默认在不超过burst值的前提下会排队等待处理,如果使用此参数,就会处理完num + 1次请求,剩余的请求都视为超时,返回503。
用于测试的Nginx配置文件如下:
利用Webbench进行测试
我们查看Web服务器的access.log日志如下:
- 通过过滤排重日志,可以看到第一个请求返回200,为正常处理,剩余2582次+9858次超过了限制的在1秒内执行完成,但是都返回了503
- 具体过程原理为:Nginx在第1秒先处理第一个请求,同时接下来的5个请求等待排队,剩下的(2582+9858)请求返回503。接着第2秒到第6秒处理等待的5个请求。