把格式为 1.2.4.8.somename.com 的域名解析成 ip 1.2.4.8

230 天前
 zhng920823
哪有类似的这种服务, 需要用自己的域名
否能自己搭建这种 nameserver 呢
谢谢
1446 次点击
所在节点    问与答
10 条回复
ltkun
230 天前
要发布到公网那得自建 dns 服务器 如果自己用就修改一下 hosts
leonshaw
230 天前
https://v2ex.com/t/1007532
这种动态解析权威 DNS 代码要自己写了
baobao1270
230 天前
PowerDNS + Python backend
如果追求性能,看一下 rust 写的 trustdns
Lentin
230 天前
https://nip.io/

后端开源的说是
zhng920823
230 天前
@Lentin #4 多谢, 我看看这个
Puteulanus
230 天前
zhng920823
230 天前
@Puteulanus 确实强大
Rehtt
229 天前
holinhot
228 天前
python 几分钟就能写一个不过性能很差只有 2000qps; 用 go 写性能好 100 倍
ahu
227 天前
@Puteulanus #6 不错的示范 😄

于是我照猫画虎,经过约 5 轮的对话,免费的 GPT 3.5 为我写了个能 work 的 PHP 版本:

```
<?php
// 指定域名
$targetDomain = 'somename.com';

// 响应 IP 地址
$responseIP = '1.2.4.8';

// 启动 DNS 服务器
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '127.0.0.1', 5345);

echo "DNS 服务器已启动...\n";

while (true) {
socket_recvfrom($socket, $data, 512, 0, $from, $port);

// 解析 DNS 请求
$dnsRequest = dns_parse_message($data);

// 打印收到的 DNS 请求
echo "收到 DNS 请求:\n";
print_r($dnsRequest);

// 检查请求是否为 A 记录且为目标域名的子域名
if ($dnsRequest && isset($dnsRequest['question'][0]['qtype']) && $dnsRequest['question'][0]['qtype'] == 0 && endsWith($dnsRequest['question'][0]['qname'], ".$targetDomain")) {
// 构建响应数据
$dnsResponse = dns_build_response($dnsRequest, $responseIP);

// 打印响应数据
echo "准备发送的 DNS 响应:\n";
print_r($dnsResponse);

// 发送响应
$bytesSent = socket_sendto($socket, $dnsResponse, strlen($dnsResponse), 0, $from, $port);
if ($bytesSent === false) {
echo "发送 DNS 响应失败\n";
} else {
echo "已发送 $bytesSent 字节的 DNS 响应\n";
}

echo "已响应 DNS 请求:{$dnsRequest['question'][0]['qname']} -> $responseIP\n";
}
}

// 解析 DNS 请求
function dns_parse_message($data)
{
$dnsHeader = unpack('nid/nflags/nqdcount/nancount/nnscount/narcount', substr($data, 0, 12));
$question = [];
$offset = 12;
for ($i = 0; $i < $dnsHeader['qdcount']; $i++) {
$questionName = '';
$nameFound = false;
while (true) {
$labelLength = ord($data[$offset]);
if ($labelLength == 0) {
$offset++;
break;
}
if (($labelLength & 0xC0) == 0xC0) {
$offset += 2; // 跳过指针
break;
}
$questionName .= substr($data, $offset + 1, $labelLength) . '.';
$offset += $labelLength + 1;
}
$offset += 4;
$question[] = [
'qname' => rtrim($questionName, '.'),
'qtype' => isset(unpack('ntype', substr($data, $offset, 2))['type']) ? unpack('ntype', substr($data, $offset, 2))['type'] : '',
];
$offset += 4;
}

return [
'header' => $dnsHeader,
'question' => $question,
];
}

// 构建 DNS 响应
function dns_build_response($request, $ip)
{
$header = pack('nnnnnn', $request['header']['id'], 0x8180, 1, 1, 0, 0);
$question = '';
foreach ($request['question'] as $q) {
$question .= dns_compress_name($q['qname']) . pack('nn', 1, 1);
}
$answer = dns_compress_name($request['question'][0]['qname']) . pack('n*', 1, 1, 0, 1, 0, 4); // 响应类型为 A 记录,TTL 为 0 ,数据长度为 4
$answer .= inet_pton($ip); // 将 IP 地址转换为二进制格式

return $header . $question . $answer;
}

// 辅助函数,检查字符串结尾
function endsWith($haystack, $needle)
{
return substr($haystack, -strlen($needle)) === $needle;
}

// 辅助函数,压缩 DNS 消息中的域名
function dns_compress_name($name)
{
$parts = explode('.', $name);
$compressedName = '';
foreach ($parts as $part) {
$compressedName .= chr(strlen($part)) . $part;
}
return $compressedName . "\x00";
}
?>

```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1029670

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX