背景
之前服务器上部署的 dns 解锁失效了,尝试在hk机器上分流 gpt 流量,通过sg的doh dns进行解析。链路大体如下:
IOS(ChatGPT APP)->Router(Dnsmasq dns分流海外流量)->HK Server(Dnsmasq dns分流GPT流量)->HK Server(dnscryt-proxy)->SG DOH DNS
不过事实上是 OPENAI 更改了地区检测策略,通过访问服务的 ip 进行地区判断,提高了绕过地区检测的门槛,dns 解锁不再可行,所以本次实践从解锁这个目标来看是失败的。
但 DNS解锁 依然是其他 APP 的主流解锁方案,依然有记录的意义。
步骤
- 在 https://github.com/DNSCrypt/dnscrypt-proxy/releases 下载最新版本, eg: dnscrypt-proxy-linux_x86_64-2.1.12.tar.gz
 - 创建配置文件
 
server_names = ['my-doh-server']
listen_addresses = ['0.0.0.0:5353']
doh_servers = true
[static]
  [static.'my-doh-server']
  stamp = 'sdns://xxxxxxx'
- 计算 stamp
 
stamp的计算是个坑,基本google所有搜索结果都指向 https://dnscrypt.info/stamps/ 这个网站,但是我试过很多方法都打不开,除了dnscrypt.info也没有任何网站介绍 dns stamp 的计算方式。我实在不理解配置文件里为何不能明文存储这些信息,为何要搞这么麻烦。
在 github 上找到一个项目 https://github.com/jedisct1/go-dnsstamps ,是按照dnscrypt.info的规范实现的,修改gotest测试用例计算 stamp。
func TestDNSOverHTTP_NoHashes(t *testing.T) {
    const expected = `sdns://AgcAAAAAAAAACTEyNy4wLjAuMSDDhGvyS56TymQnTA7GfB7MXgJP_KzS10AZNQ6B_lRq5AtleGFtcGxlLmNvbQovZG5zLXF1ZXJ5`
    var stamp ServerStamp
    stamp.Props |= ServerInformalPropertyDNSSEC
    stamp.Props |= ServerInformalPropertyNoLog
    stamp.Props |= ServerInformalPropertyNoFilter
    stamp.ServerAddrStr = ""
    stamp.Proto = StampProtoTypeDoH
    stamp.ProviderName = "https://xxxx.com"
    stamp.Hashes = [][]uint8{}
    stamp.Path = "/dns-query"
    stampStr := stamp.String()
    if stampStr != expected {
        t.Errorf("expected stamp %q but got instead %q", expected, stampStr)
    }
    parsedStamp, err := NewServerStampFromString(stampStr)
    if err != nil {
        t.Fatal(err)
    }
    ps := parsedStamp.String()
    if ps != stampStr {
        t.Errorf("re-parsed stamp string is %q, but %q expected", ps, stampStr)
    }
}
- 部署
 
nohup ./dnscrypt-proxy -config dnscrypt-proxy.toml >/dev/null 2>&1 &