抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

本教程用到的资源全部都是免费且可持续使用的。NS1.com这个权威DNS服务器能根据ASN、国家或省份、DNS轮询(可加权)等方式解析域名,并且提供了API去控制某个解析(answer)是否响应。监控宝能实时监控网站(通过HTTP、PING、DNS方式等)并输出警告(webhook、Email、短信等),最高监控频率为2分钟。亚马逊的AWS Lambda是一个FaaS平台(serverless),可以作为连接NS1.com和监控宝之间的桥梁,当监控宝检测到网站速度变慢的时候发送信息到AWS Lambda,AWS Lambda得到信息后再传递给NS1.com,速度恢复的时候也是同样的操作。为什么要夹在一个AWS Lambda呢?这是因为监控宝发送的格式是固定的,并不能直接接入到NS1.com。

前言

需要用到的工具和技能有:

工具和技能

  • NS1.com。免费一个Filter Chain。Filter Chain就是根据不同条件进行响应的工具。

  • 监控宝国际版。国际版可以用中国大陆和海外的手机号注册,同样可以用国内电信、移动、联通、教育网的监控节点。免费5个网站监控。

  • AWS Lambda。注册使用可能需要visa银行卡或其他银行卡验证。每月一百万次调用。

  • 一点点耐心。

  • 一点点点python技术。

NS1.com使用教程

Filter Chain的使用

顾名思义就是不断地过滤不符合条件的answer,直到链(Chain)的结尾就是要返回给用户的解析结果。

因此每个过滤器的顺序十分重要(这一点官方文档写到比较隐晦,但是十分重要)

一般而言,以Up开头,Select First N结尾。前者代表是否开启该answer,我们使用监控包如果发现网站速度过慢则可以设置为Up: False;后者表示假如链(Chain)的结尾有多个answer,则返回前N个answer,默认N为1。可以通过调整Priority调整优先级。

这是我的设置

建议勾选对应的复选框。因为每个人的设置不一样,请仔细阅读说明决定是否勾选!

之后我们要根据不同的运营商或者国家地区来返回DNS解析结果。因为NS1没有提供国内运营商的分类,但是提供了ASN来分类。我写了个爬虫小脚本,爬取不同运营商的ASN,使用以下这个项目获取,然后填入到对应区域。

我是创建了answer group来分类不同的运营商的。

你也可以使用自动化工具来定时更新ASN。使用到的工具有aws lambda(下文有介绍)和aws cloud bridge的定时器(需自行配置),例如每隔10更新一次。

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
# key为你的ns1 feed label;value为下载asn列表用到的url的一部分,一般情况下不需要修改
asn_dict = {
'dianxin':'chinanet',
'yidong':'cmcc',
'liantong':'unicom'
}

ns1_api_key = ''
source_id = ''
ns1_req_url = f'https://api.nsone.net/v1/feed/{source_id}'
headers = {
"X-NSONE-Key":f"{ns1_api_key}"
}

for ns1_asn_label, gh_asn in asn_dict.items():
url_to_down = f'https://raw.githubusercontent.com/xingpingcn/china-mainland-asn/main/asn_txt/{gh_asn}.txt'
response = requests.get(url_to_down).text
asn_list_from_gh = response.split('\n')[1].split(',')
data = {
f"{ns1_asn_label}":{"asn":asn_list_from_gh}
}
res = requests.post(ns1_req_url,headers=headers,json=data)
print(res.status_code)

之后可以选择countryCNanswer作为未命中规则的备选。之后再填写一个只有Upanswer作为除中国之外全球的DNS解析结果。

强烈建议

如果你使用renderrailwaycfcycliczeabur等托管你的网站,除中国之外全球的DNS解析结果是必须配置的,此设置用于ssl证书的申请。建议设置为加权的DNS轮询(此方法似乎对于netlify有点水土不服,因为只要DNS没解析到netlify就暂停ssl证书。其他的只要认证了网站就可以用一段时间,一般是3个月,下一个3个月会重新申请,认证一次不过会自动重试几次;成功一次就可以继续用3个月)

建议国内少用country,因为不太准

NS1 API的使用

设置DNS

根据图的指引创建data sourcedata feed。详细看官方文档。

可以看到上面的图,在answer里已经设置好了关联的data feed了(绿色箭头表示开启,红色表示关闭);先关联,之后我们会通过AWS Lambda来控制的。关联的data feed详细操作看官方文档。

编写feed更改请求-python

我们可以编写python以请求API来更改UP的状态。之后我们会把代码放到AWS Lambda来控制的。

注意填写必要的信息。

参数设置

  • statusTrue是开启,False是关闭。
  • source_idlabel就是上面图中提到要记住的内容。
  • ns1_api_key需要自己到设置里申请。建议只开启必要的权限。

    设置`KEY`

    点击右上角的settings里的users&teams

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests

status = True

source_id = ''
label=''
ns1_api_key = ''
url = f'https://api.nsone.net/v1/feed/{source_id}'
headers = {
"X-NSONE-Key":f"{ns1_api_key}"
}
data = {
f"{label}":{"up":status}
}
res = requests.post(url,headers=headers,json=data)

使用AWS Lambda

AWS Lambda支持python且可以通过各种条件来触发,现在我们用监控平台(本教程用的监控宝)的webhook来触发,发送POST请求到NS1来更新answer状态。

创建函数

点击创建函数——填写信息——点击高级设置

授权类型选NONE,勾选配置跨源资源共享(CORS)

如果里选择使用监控宝,那么填入以下代码 ↓

参数设置

url_token填写监控宝里回调url里的回调token。如果没有监控宝还没有设置,不要紧回来再弄。
其他参数请看这里
其中status会根据监控宝的状态自动设置。

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
import base64
import hashlib
import json

source_id = ''
label=''
status = True
ns1_api_key = ''

url_token = '' #回调token

def g_md5(content):
md5hash = hashlib.md5(content)
md5 = md5hash.hexdigest()
return md5

def lambda_handler(event, context):
json_data = json.loads(event['body'])
verify = str(json_data['msg_id'])+str(json_data['task_id'])+str(json_data['fault_time'])+url_token
md5 = g_md5(verify.encode('utf-8'))
if md5==json_data['token']:
if json_data['message_status'] == 1 or json_data['message_status'] == '1':
status = False
elif json_data['message_status'] == 2 or json_data['message_status'] == '2':
status = True
url = f'https://api.nsone.net/v1/feed/{source_id}'
headers = {
"X-NSONE-Key":f"{ns1_api_key}"
}
data = {
f"{label}":{"up":status}
}
res = requests.post(url,headers=headers,json=data)
print(res.text,f'[status] \'up\': {status}')

这里不得不吐槽一句监控宝,回调url设置中的测试发送的json和实际应用中发送的json不一样的,如果发现测试报错请使用正常监控方式来测试

记得点击deploy

设置层(layers)

因为AWS Lambda默认不能使用第三方库,因为用到了requests库,所以要自己上传requests库。或者你也可以自己用python原生库重写。

requests.zip可以根据官方文档自己生成,也可以上传我制作的requests.zip

之后设置函数的(layers),选择我们上传的requests.zip包。

使用监控平台

类似的平台还有观测云,免费版最高30分钟的检测频率,20万次访问每天好像是,节点11个,3网都有。

或者可以破解一些免费测速网站的js。

warning

监控宝似乎在14天试用期之后直接封我号了,发两份邮件也不回,建议改用观测云,配置都是差不多的。

监控宝

点击查看,但是不建议

监控宝可以使用回调url(webhook)来传递信息,设置如下图。

回调url就填写AWS Lambda提供的url

之后创建监控任务,记得在Webhook通知那里选择你的回调url。

观测云

aws lambda填入以下代码

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import json
import requests

source_id = ''
ns1_api_key = ''

def lambda_handler(event, context):
# print(event,type(event))
json_data = json.loads(event['body'])
if json_data['isp'] == 'telecom':
label = 'dianxin' # ns1的feed label,下同
elif json_data['isp'] == 'unicom':
label = 'liantong'
elif json_data['isp'] == 'cmcc':
label = 'yidong'
if json_data['df_status'] == 'critical':
status = False
else:
status = True
url = f'https://api.nsone.net/v1/feed/{source_id}'
headers = {
"X-NSONE-Key":f"{ns1_api_key}"
}
data = {
f"{label}":{"up":status}
}
res = requests.post(url,headers=headers,json=data)
print(res.text,f'[status] {label} -> \'up\': {status}')

观测云平台配置

评论