记一次DNS污染应对
静态站的waline评论插件服务的二级域名被ISP DNS做了污染封禁导致评论插件和访问计数不可用。记录一下我排查和解决问题的过程与思考。
现象
特定条件下,从客户端访问我的静态站时,客户端请求我的自建waline服务失败,看响应头发现remote ip是(::1),ipv6回环地址。
ping对应域名证实DNS结果确实为(::1)。
为了明确问题,我用不同网络环境做了测试:
网络 | 代理 | DNS | 结果 |
---|---|---|---|
中国移动蜂巢5G | 关闭 | 自动 | fail |
中国移动蜂巢5G | 全局 | 等同于8.8.8.8 | success |
中国移动蜂巢5G | 关闭 | 114.114.114.114 | success |
中国移动光纤宽带 | 关闭 | 自动 | fail |
中国移动光纤宽带 | 全局 | 等同于8.8.8.8 | success |
中国移动光纤宽带 | 关闭 | 114.114.114.114 | success |
我手头只有移动的5G网络和宽带网络,还不好排除ISP本身状态的影响,但绕过中国移动网络的ISP DNS,就能成功。
初步判断是DNS的问题。上DNSChecker验证一下非ISP DNS,用当前的中国移动ISP+各种全球非ISP DNS做测试,结果是域名解析全部正确。那么看起来真的很可能是ISP DNS主动做了污染。
搜搜有前科吗?有的,国内ISP偶现用回环地址做DNS污染来针对性封禁域名的情况。
捞个本地的移动ISP DNS试试,dig @211.137.64.163 <domain>
:
1 |
|
真的给我解成了回环地址。
上班时也试了下电信的ISP DNS,dig @202.103.24.68 <domain>
:
1 |
|
看来还不止被一个ISP做了DNS污染,都给我解成回环地址。
DNS劫持与DNS污染
对比维度 | DNS劫持 | DNS污染 |
---|---|---|
攻击方式 | 篡改DNS解析结果 | 伪造DNS响应数据 |
影响范围 | 个体或小范围 | 大范围或区域 |
目的 | 诱导用户访问恶意网站 | 干扰用户访问特定服务 |
典型场景 | 钓鱼、恶意软件传播 | 网络封锁、广告注入 |
DNS劫持通常在客户端完成,DNS污染通常在网关或DNS服务上操作。
分析原因
- 捞了下waline服务的日志,发现有不少”/robots.txt not found”,还在80、443口都来了一遍。有搜索引擎爬虫或者模拟搜索引擎的爬虫试图抓取我waline服务端的响应内容,那么可能有人在收录或分析我的waline服务。其实应该也分析不出什么,这服务没过鉴权的情况下响应体里甚至不包含文字。
- 其实也可能是二级域名本身的关键词命中了什么政策类的域名筛选规则,大家给二级域名起名也要谨慎点。
应对
除了用于展示内容的静态站域名,其他功能性二级域名都用nginx配置加上禁爬声明先:
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
36
37
38
39
40
41
42
43
44# HTTP server block
server {
listen 80;
server_name example.com;
# 禁止爬虫访问所有内容
location = /robots.txt {
return 200 "User-agent: *\"\nDisallow: /";
add_header Content-Type text/plain;
add_header Cache-Control "public, max-age=3600";
if ($request_method !~ ^(GET|HEAD)$ ) {
return 405;
}
}
# 其他请求重定向到 HTTPS
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS server block
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/privkey.pem;
# 禁止爬虫访问所有内容
location = /robots.txt {
return 200 "User-agent: *\"\nDisallow: /";
add_header Content-Type text/plain;
add_header Cache-Control "public, max-age=3600";
if ($request_method !~ ^(GET|HEAD)$ ) {
return 405;
}
}
# 其他请求处理(如 root、proxy_pass 等)
location / {
# 你的其他配置,如 proxy_pass 或 root
}
}再给二级域名换成个更烂大街的抽象名称躲封禁规则,配好对应DNS记录和nginx路由。
用certbot更新下SSL证书:
1
certbot certonly ----cert-name <cert_name> --manual --preferred-challenges http --webroot-path /root/Dropbox/<homepage_dir> -m me@bipedalbit.net -d <domain1> -d <domain2> -d <domain3>
我不爱用
certbot run
自动改nginx配置文件更新SSL证书,会把我写好的nginx配置格式搞乱。用certbot certonly
命令需要按命令行提示在指定域名下指定位置放个指定内容的文本文件证明你是指定域名内容的控制方,然后回车下一步。麻烦点,但低频操作,不自动化也负担不大。改改waline服务的部署配置,把里面的服务二级域名更新下,重启服务。
OK这下通了,观察一天看看,还是通的,大概是妥了。