697°

CDN

一、CDN简介

内容分发网络CDN(Content Delivery Network)将源站内容分发至遍布全国的加速节点,缩短用户查看内容的延迟,提高用户访问网站的响应速度与网站的可用性,解决网络带宽小、用户访问量大、网点分布不均等问题。

CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。

1、百度云CDN加速原理:

如上图所示,CDN加速详细步骤如下:

1.网站用户查询 my.com 的地址

2.请求权威DNS

3.返回配置的CNAME: my.com.a.bdydns.com

4.请求my.com.a.bdydns.com对应的IP

5.根据智能调度返回离用户最近的接入点IP

6.LocalDNS返回my.com的IP地址并缓存

7.向CDN节点发起HTTP/HTTPS请求,访问my.com的内容

8.CDN 通过百度云加速链路,将请求转发至多线中心节点

9.中心节点向源站发起回源请求

10.源站向中心节点返回响应

11、12.中心节点、边缘节点将响应返回用户,并缓存响应内容

2、用户是如何接入CDN节点的

1)通过控制台接入

2)通过open-api接入

opendn-api提供和控制台几乎相同的功能,用户使用自己的ak、sk,调用api进行域名创建、配置管理的操作。

二、 调度系统

从一个domain请求访问开始,到获得相关服务节点IP为止。dns调度、302调度,业务调度,opencdn调度。

2.1. dns调度

由jomo dns服务器直接解析出节点IP地址。

2.2 302调度

302中心将http请求的url进行封装,将请求302到服务节点

DNS调度和302调度的优劣及使用场景

2.3 httpDNS调度

2.4 openCDN 调度

三、CDN节点结构

每个CDN节点一般都会从运营商那里分一个公网的C段,如SHUN为112.65.203.0/24,总共有254个可用的公网IP。

a. BGW

在流量入口处一般会部署5、6、10、14个BGW,其个数不固定,其公网IP段一般从112.65.203.(10~23),作为管理口使用; 内网IP段为172.18.x.254,其中x段是bgw与后端jorcol机健康检查网段,

每台jorcol机上会有策略路由来保证对应bgw上的请求回到这个BGW;

b. Relay机

控制机Relay一般会部署四台,IP段为112.65.203.(4~7);

Relay机主要是进行控制命令的下发,日志的回传等功能。目前很多功能都是在4、6两台上启用,5、7做为冷备。

c. Jorcol机

Jorcol机由于需要回源,所以都会分配公网IP,其一般为112.65.203.(50~149)|(150~249),一般有一组或两组,分别为100个节点。

每台jorcol机上混布 Nginx + Cache(Olivehc)的结构

d. VIP

最后给业务使用的VIP一般在30~49,现在OpenCDN业务使用了35,即VIP为112.65.203.35,其BGW上对应的80与443分别与jorcol机的7015与7023对应,通过BGW实现LB。

四、配置参数说明

所有的配置都会在jnx/lua/com/parser.lua中解析,因此在parse.lua中可以看到现在所有支持的配置情况,下面是一些重要的配置和它们的介绍(按照解析顺序):

1、referer相关

referers

referer白名单

"referers":[".yyy.com",".xxx.com"]

referersBlackList

referer黑名单

"referersBlackList":["*.xxy.com","xyyx.com"]

emptyRefererEnabled

是否允许空referer

"emptyRefererEnabled":"ON"

regexRefererEnabled

是否允许正则referer

"regexRefererEnabled":"OFF"

如果referer中携带了协议,那么协议必须要同时匹配才算匹配。如果未开启正则,那么支持匹配,但是只支持最前面和最后面的,例如 .baidu.com,实时上就是去掉两头的进行字符串查找,中间的无法匹配。

2、IP黑白名单

ipWhiteList

客户端IP白名单

"ipWhiteList":["1.1.1.1","3.3.3.3","1.1.1.0/24","2.2.2.0/24"]

ipBlackList

客户端IP黑名单

"ipBlackList":["2.2.2.2","4.4.4.4","2.2.2.0/24","4.4.4.0/24"]

同时支持IP和NET(网段),根据IP和网段进行过滤。

3、cacheTtl

cacheTtl

缓存规则

"cacheTtl": [

{"type": "suffix", "value": ".jpg", "ttl":36000, "weight": 30,"override_origin":False,},

{"type": "suffix", "value": ".mp4", "ttl":36000, "weight": 30,"regex":True|False},

{"type": "path", "value": "/", "ttl":1800, "weight": 5,"key_query":True|False}

]

节点上配置会根据权重进行排序,权重高的在前,匹配时会使用第一条匹配到的规则,因此高权重的更容易匹配到。

源站优先时传给cache的头为ohc-max-age-default,否则为ohc-max-age。支持正则匹配和指定是否携带query_string(对路径设置带url缓存)。

4、waf

wafEnabled

waf放攻击策略

"wafEnabled":"ON"

5、302 防攻击

sourceGuardEnabled

302放攻击

"sourceGuardEnabled":"OFF"

源站响应5XX过多时认为是攻击,当判断为攻击时,给用户发送302,url中携带baidu-cdnid-redirect=cdnid_encode,如果用户携带此code follow302,则说明为正常请求,否则返回403。

7、isBan

isBan

封禁某一个域名

"isBan": "NO"

如果isBan为yes,节点直接返回403。

8、originVerifyEnabled cache follow源站302

originVerifyEnabled

cache是否follow源站的302

"originVerifyEnabled":"OFF"

通过Ohc-Origin-Verify-Disable:on或者off,来判断是否需要cache follow302。

9、视频相关配置

flv

flv视频相关配置

"flv": {

    "fileSuffix": ["flv"],

    "startArgName": "start",

    "endArgName": "end",

    "dragMode": "secondScript"

}

mp4

mp4视频相关配置

"mp4": {

    "fileSuffix": ["mp4"],

    "startArgName": "start",

    "endArgName": "end",

    "dragMode": "second"

}

视频拖动设置,通过在url参数中携带start、end参数来进行视频拖动,mp4的start end是秒数,flv的start end是字节。

注意,如果要配置视频拖动,需要首先配置后缀为flv和mp4格式的视频内容的缓存,否则将无法进行拖动(这个问题cache正在修复开发,预计很快可以上线)。

10、keyIncludeQuery带参数缓存

keyIncludeQuery

是否带参数缓存

"keyIncludeQuery":"ON"

通过Ohc-KeyIncludeQuery-Whitelist:*来开启cache的带参数缓存,如果不配置,默认是带参数缓存。

11、designateHostToOrigin

designateHostToOrigin

自定义回源host

"designateHostToOrigin": "xxxxxx.com"

通过ohc-upstream-host来开启cache自定义回源的host。目前内部节点之间还是使用加速域名(如果使用自定义host会403)

12、acceptRangesNone

acceptRangesNone

指定是否通过last-modified和etag校验

"acceptRangesNone":"ON"

on的时候强制不使用分片回源。

13、bos_key

bos_key

bos_key防盗链

"bos_key" : "******"

用户配置bos_key,根据url中的expires和bos_key计算密钥(sha256),当密钥和url中携带的token值相等时请求,否则返回403。

14、secretKey,antiHotlinkType

secretKey

防盗链加密密钥

"secretKey":"xxxxxxxxx"

antiHotlinkType

防盗链加密类型

"antiHotlinkType":""

通过防盗链加密类型,选择加密算法,使用加密密钥进行加密,例如打antiHotlinkType为tieba时,使用的a类防盗链。目前antiHotlinkType基本都是用户定制的防盗链,可以进行扩展和添加。

以tieba防盗链为例,防盗链计算方法如下:首先比对now与timestamp,然后计算ngx.md5(ngx.var.uri-timestamp -rand-uid-sercureID)与url中所带的md5hash值做对比。

15、wildDomainEnabled,shareCacheEnabled

wildDomainEnabled

泛域名

"wildDomainEnabled":"ON"

shareCacheEnabled

共享缓存

"shareCacheEnabled":"ON"

泛域名开启共享缓存,修改ohc-key,使用匹配的泛域名作为cache缓存的key

16、httpsEnabled

httpsEnabled

开启https服务

"httpsEnabled":"ON

开启https服务,边缘节点使用https。如果未开启此选项并且使用了https,会产生500错误。

17、httpToHttpsEnabled

httpToHttpsEnabled

302跳转到https

"httpToHttpsEnabled":"ON"

用户使用http访问,会302跳转到https访问。

18、originProtocol

originProtocol

回源协议

"originProtocol":"https"

选择回源协议,默认为http协议。会传给cache两个头,"Use-Https", "yes","Ohc-SSL-Version", orig_ssl_ver。会传递ssl版本,指定cache使用用户指定ssl版本回源。

19、sslVersion

sslVersion

选择ssl版本

"sslVersion":"TLSV1"

用户自定义回源ssl版本,共有四个版本可选:SSLV3(1),TLSV1(2),TLSV11(3),TLSV12(4)。默认TLSV1

20、disableHttpsSpider

disableHttpsSpider

根据用户设置UA实现http到https跳转

"disableHttpsSpider": "xxxxxx"

禁止某些ua对于http到https的跳转

21、needModifyHeader、modifyHeaderMap

needModifyHeader

是否更改到用户端的相应头

"needModifyHeader" : " * "

modifyHeaderMap

响应头的具体内容和更改方式

"modifyHeaderMap": [

    {

        "add": [

            {

                "apk$": {

                    "content-type": "a"

                }

            },

            {

                "apk$": {

                    "content-type": "b"

                }

            }

        ]

    }

用于修改到用户端的响应头,支持正则匹配。共有update,add,delete三种action。只有needModifyHeader为*时才会进行更改。

22、antiAttack

antiAttack

对IP地址进行访问限制

"antiAttack":[{"limit":2,"duration":10,"block":20,"ip":["220.220.0.0/24","10.94.43.58"],"path":"/index/a"}]

限制用户在一定时间之内对于CDN节点的访问。如果超出访问限制,则返回503。使用ngx.var.remote_addr .. path .. math.floor(ngx.time() / duration)作为key来进行共享内存查找。

主要有下面几个配置项:

limit:指定时间范围内的请求次数限制

duration:时间范围,单位秒

block:超出请求次数限制后封禁的时长,单位秒

ip:Ip段列表,支持CIDR格式表示的IP段,不设置则对所有客户端生效

path:访问路径,不设置则对所有路径生效,根据uri进行最长前缀匹配

23、urlRedirect

urlRedirect

支持根据ua进行url重定向

"urlRedirect":[

    {

        "from":"http://www.mydrivers.com(/|/index\\.(.+))(\\?.*)?",

        "to": "http://www.mydrivers.com/wap/nav.htm",

        "user-agent":"mqqbrowser;android",

        "exclude":["http://www.mydrivers.com/zhuanti/.*"]

"regex" : true //可选

    }

]

根据ua进行url的重定向,先匹配ua,当ua匹配时,如果url匹配from,那么使用to中的url进行重定向(返回302响应,只在边缘节点生效)。

如果配置了regex,那么将使用to中的内容,替换匹配到的from中的内容然后进行重定向。

例如:针对移动终端访问官网http://www.drivergenius.com跳转到移动版本的网页 http://www.drivergenius.com/default_m.asp

24、originRequest

originRequest

回源时需要添加的头部信息

"originRequest": { //回源时需要添加(修改)域删除某些header

    "addHeaders": {"x-bce-date":"2016-10-22T22:11:22Z","x-bce-authorization":"baidu-cdn-origin"}, 

    "addHeadersNotes": {"x-bce-date":"comments for x-bce-date header", "x-bce-authorization":"BCE签名Header"},

    "addHeadersDynamic":{"x-requset-url":"ngx.var.scheme .. '://' .. ngx.var.host .. ngx.var.uri"},

    "addHeadersDynamicNotes":{"x-requset-url":"pass real url"},

    "removeHeaders": {"myself-Test":"test","xxx":""},

    "removeHeadersNotes":{"myself-Test":"测试Header","xxx":""},

    "inheritHeaders":true|false  

}

在rewrite阶段进行处理,修改传给源站的请求头。addHeadersDynamic通过嵌入一小段lua代码来设定请求头。inheritHeaders通过设定是否仅在二级三级节点生效。默认只在边缘节点生效。

25、clientResponse

clientResponse

添加删除用户响应header

"clientResponse":{ //用户请求响应时,添加或删除某此header

    "addHeaders": {"x-bce-authorization":"baidu-cdn-origin"}, //如果此头已存在,则会重写些头,即达到修改的效果

    "addHeadersNotes": {"x-bce-date":"comments for x-bce-date header", "x-bce-authorization":"BCE签名Header"},

    "removeHeaders": {"Age":"","xxx":""},

    "removeHeadersNotes":{"Age":"删除 Age Header","xxx":"remove xxxx"}

},

添加删除给用户的响应中的header,可以认为是needModifyHeader的简化版,不支持正则表达式。

26、cache

cache

根据不同的参数筛选回源地址

"cache":{

    "keyIncludeHeaders":["origin","allow"], 

    "mapOrigin":[

        {"path":"/a/b/", "origin":["1.2.3.3","1.2.3.4"]},

        {"path":"/c/d","origin":["1.2.2.2"]}, 

        {"header":{"user-agent":"android"}, "origin":["1.2.3.4"]}, 

        {"args":{"mt":4},"origin":["59.56.21.220"]} 

    ]

}

keyIncludeHeaders,指定参与计算key的头。mapOrigin,根据不同的目录,header,args指定不同的回源地址。

当path有相同的前缀时,越精确的匹配优先级越高,例如/a/b和/a/b/c同时进行配置,以/a/b/c的配置为准。

path的优先级高于header,args的优先级。另外对于header和args,只要参数key匹配就可以,不需要值一起匹配。此处会关闭cache的长连接:Ohc-Upstream-Keepalive-Timeout:0。cache会通过host作为key计算长连接的fd,如果开启长连接,没法实时根据mapOrigin来更换源站地址。

27、forbiddenUA

forbiddenUA

禁止某些ua的访问

"forbiddenUA":"chrome"

对ua进行模糊匹配,如果能匹配上,直接给出403。ua限制为最小5个字符(api限制)。

28、antiHotLink

antiHotLink

防盗链类型,配合secretKey使用,nginx通过该字段判断采用哪种校验规则

"antiHotLink":{

    "antiType": "typeA",         

    "secretKey": "bdcloud1234",

    "newsecretKey": "opencdn1234", 

    "secureFile": "/test.txt",     

    "auth_arg": "auth_key",     

    "delAuthKey":"on | off",  

    "timeout": 1800,    

    "sign_arg_key":"sign",   

    "time_arg_key":"t"    

}

A类防盗链:url中auth_key=timestamp-rand-uid-md5hash,其中使用md5hash与md5( uri-timestamp-rand-uid-secret_key)进行比较,相等则通过,否则403.

B类防盗链:匹配url中的[[/(\d{12})/(\w{32})/]],其中12个数字为timestamp,32个字符为md5hash的值,使用new_secret_key .. tostring(timestamp) .. newuri计算md5值(其中newurl为去除匹配字符串之后的url),相等则通过,否则给出403。

C类防盗链:优先根据sign_arg_key和time_arg_key从url参数中获取md5hash值和时间戳信息,如果不存在,则从url中截取/32为字符/md5hash/timehex,使用new_secret_key .. newuri .. timehex计算md5值,其中,newuri是去除url匹配字符之后的新的uri。

29、httpsOnlyEnabled

httpsOnlyEnabled

只允许https请求

"httpsOnlyEnabled":"ON"

开启此选项,使用http访问给出403

30、shareCacheById

shareCacheById

设置与目的域名共享缓存,目的域名也需要这个配置

"shareCacheById":"keyid"

不同的域名,使用一个key来进行共享缓存。cache计算key时会忽略host,使用keyid作为算key的依据。

31、keyExcludeQuery

keyExcludeQuery

指定去参数缓存

"keyExcludeQuery":["^/ids/js/passport\.js\?"]

当匹配某些规则时,去参数缓存(比keyincludequery优先级高),当为空字符串时匹配所有url。

五、常见查问题的工具

1、查看节点用户配置

1.1 curl 127.1:7015/baidu-cdn-opencdn-detail | grep zpw.sys-qa.com

1.2.1 查看域名配置信息信息

http://opencdn.baidu.com/domain ####可以查询域名---源站信息——用户id

1.2.2 CDN节点信息+域名状态信息

http://cdn.baidu.com/oss/index.php?r=tools/jomoCha/index

2、节点查看日志:

日志查询步骤:

1.登录relay01机

2.ssh infwork@tc-sys-cdn-oc01.tc.baidu.com 密码:XXXXXX

3.根据web查看状态码是哪个节点返回的 同时查看下web上服务器的硬件状态

4.go 节点 (eg:go zzcm4 ###登录的是relay机可以机器名)

  1. r jorcol-number (eg:r 100)

6.根据状态码初步判断是哪个服务的问题查看日志(eg:503可能是nginx)

查看日志命令(在relay机进行执行)eg:go zzcm4 ###登录zzcm节点上的relay4机器

错误码查询:

1.nginx日志查询

logstats.py nginx.access.opencdn_perf -t 2017051013 -m "grep pic1cdn.cmbchina.com" | awk -F '\t' '$7==503'

2.查看olivehc日志

logstats.py olivehc.access.opencdn -m "grep pic1cdn.cmbchina.com" -t 2017051013

3.waf--403错误:

有些403错误是触发waf造成的,nginx和olivehc都查不到错误信息的,需要查询

nginx.waf.opencdn

4.https加速查询:

nginx.access.https_opencdn

olivehc.access.https_opencdn

5.统计客户端请求数

logstats.py nginx.access.opencdn_perf -t 2017051012 -m "grep cmbchina.com" |awk -F '\t' '$7==200'|awk '{print $1}' |awk '{a[$1]+=1;}END{for(i in a){print a[i]" "i;}}'|sort -nk1

3、节点抓包

例如,抓去回源时的请求:

/usr/sbin/tcpdump -i any dst host opencdn.origin.jomodns.com -w zpw.cap

在cap文件中查找相应的域名即可。

问题及答复:

域名被攻击该怎么办 如果CDN节点遇到DDOS类的攻击,会有几种情况:

1) 如果负载集中在一个边缘节点上,那么GSLB不会将其上的负载转移到其他地方去,由这一个节点承受攻击。

2) 如果负载分布在多个节点上,GSLB会启动负载均衡功能,有几个节点共同承载的方式化解攻击。

3) 如果负载已经压满整个区域的节点,则CDN不再提供服务。

2.CDN的优势

CDN将源站内容分发至遍布全国的加速节点,缩短用户查看内容的延迟,提高用户访问网站的响应速度与网站的可用性,解决网络带宽小、用户访问量大、网点分布不均等问题。

CDN本质上是依赖于一组代理服务器来提供高可用和高性能服务的网络架构。

3.http的各种状态码的意义

总结一下状态码的含义:

2XX 表示成功

3XX 表示重定向

4XX 表示客户端错误

    403 ForbiddenThe request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource, or may need an account of some sort. 

   404 Not FoundThe requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible.

5XX 表示服务端错误

    502 Bad GatewayThe server was acting as a gateway or proxy and received an invalid response from the upstream server.

503 Service UnavailableThe server is currently unavailable (because it is overloaded or down for maintenance). Generally, this is a temporary state.

具体状态码信息可以参考以下链接:

https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors

4.用公共DNS会造成调度问题吗

这个问题还是不太明白

5.接入cdn域名如何解析

Client在访问网站时,将会去local DNS去解析网站域名,localDNS在没有缓存的情况下,会去权威DNS查询到域名对应的CNAME,然后llocal DNS会拿着CNAME去百度云DNS去获取边缘节点的VIP。GSLB会根据算法确认最适合客户的边缘节点的VIP,然后发给local DNS,然后local DNS再发给client

本文由【-___-】发布于开源中国,原文链接:https://my.oschina.net/tanghaoo/blog/2997404

全部评论: 0

    我有话说: