├── .idea
├── dictionaries
│ └── wangchao.xml
├── modules.xml
├── pddns.iml
├── php.xml
├── vcs.xml
└── workspace.xml
├── FakeDNSQuery.php
├── README.md
├── cliDaemon.php
├── data.txt
└── index.php
/.idea/dictionaries/wangchao.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | wangchao
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/pddns.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/php.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
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 |
31 |
34 |
37 |
38 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | echo
111 | FakeDNSQuery
112 | $stop
113 | $this->fakeDnsIpMap
114 | $reloadTime
115 | reloadFakeDnsIpMap
116 | $fakeDnsKeywords
117 | fakeDnsKeywords
118 |
119 |
120 |
121 |
122 |
123 |
124 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 | 1527143906195
186 |
187 |
188 | 1527143906195
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
--------------------------------------------------------------------------------
/FakeDNSQuery.php:
--------------------------------------------------------------------------------
1 | data = $data;
28 | $this->fakeDnsIpMap = $fakeDnsIpMap;
29 | $this->fakeDnsKeywords = $fakeDnsKeywords;
30 | $this->dominio = "";
31 | $tipo = (ord($data{2}) >> 3) & 15;
32 | if ($tipo == 0) {
33 | $ini = 12;
34 | $lon = ord($data{$ini});
35 | while ($lon != 0) {
36 | $subDominio = substr($data, $ini + 1, $lon);
37 | $this->dominio .= $subDominio . '.';
38 | $ini += ($lon + 1);
39 | $lon = ord($data{$ini});
40 | }
41 | }
42 | echo "get domain $this->dominio" . PHP_EOL;
43 | }
44 |
45 | public function respuesta()
46 | {
47 | $domainName = substr($this->dominio, 0, -1);
48 |
49 | foreach ($this->fakeDnsKeywords as $fakeDnsKeyword) {
50 | if (strpos($domainName, $fakeDnsKeyword) !== false) {
51 | $this->fakeDnsIpMap[$domainName] = "0.0.0.0";
52 | }
53 | }
54 |
55 | $isExistFakeDomainInMap = isset($this->fakeDnsIpMap[$domainName]);
56 |
57 | echo "try to fake $this->dominio ($domainName) \n";
58 | $packet = '';
59 | if ($isExistFakeDomainInMap) {
60 | $fakeDnsIp = $this->fakeDnsIpMap[$domainName];
61 | echo "find fake $domainName map to $fakeDnsIp \n";
62 | } else {
63 | echo "no fake $domainName \n";
64 | var_dump($this->fakeDnsIpMap);
65 | return $packet;
66 | }
67 | if ($this->dominio && isset($this->fakeDnsIpMap[$domainName])) {
68 | $fakeDnsIp = $this->fakeDnsIpMap[$domainName];
69 | echo ">>>>>>>>>>>>>>> start to fake domain $this->dominio to $fakeDnsIp " . PHP_EOL;
70 | $subStr = substr($this->data, 0, 2);
71 | $packet .= $subStr . "\x81\x80";
72 | $subStr = substr($this->data, 4, 2);
73 | $packet .= $subStr . $subStr . "\x00\x00\x00\x00";
74 | $subStr = substr($this->data, 12);
75 | $packet .= $subStr;
76 | $packet .= "\xc0\x0c";
77 | $packet .= "\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04";
78 | $ipSubStr = "";
79 | foreach (explode(".", $fakeDnsIp) as $perIpSeg) {
80 | $ipSubStr .= chr(intval($perIpSeg));
81 | }
82 | $packet .= $ipSubStr;
83 | }
84 | return $packet;
85 | }
86 |
87 |
88 | /**
89 | * @param null|string $hostIp 本dns服务器的公网ip地址
90 | */
91 | public static function serve($hostIp = null)
92 | {
93 | $udpSocket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
94 | if (!$hostIp) {
95 | $hostIp = '192.168.1.122';
96 | }
97 |
98 | socket_bind($udpSocket, $hostIp, 53);
99 |
100 | $fakeDnsKeywords = ["weibo", "sina"];
101 | $fakeDnsIpMap = [];
102 | // $fakeDnsIpMap 用于动态欺骗自定义域名与ip的绑定数组
103 | // $fakeDnsIpMap = [
104 | // //..
105 | // "www.fakewang22.com" => '14.215.177.38',
106 | // //..
107 | // ];
108 |
109 | $dataFile = __DIR__ . '/data.txt';
110 | while (1) {
111 | if (file_exists($dataFile)) {
112 | $data = file_get_contents($dataFile);
113 | if ($data) {
114 | $fakeDnsIpMap = unserialize($data);
115 | }
116 | }
117 |
118 | echo sprintf("Server ip: %s for fakeDnsIpMap %s \n", $hostIp, json_encode($fakeDnsIpMap));
119 |
120 | $fromIp = '';
121 | $fromPort = null;
122 | //这里会阻塞
123 | socket_recvfrom($udpSocket, $dnsQueryData, 1024, 0, $fromIp, $fromPort);
124 | echo "received udp data\n";
125 | //echo "from remote address $fromIp and remote port $fromPort" . PHP_EOL;
126 | $dq = new self($dnsQueryData, $fakeDnsIpMap, $fakeDnsKeywords);
127 | $respuestaData = $dq->respuesta();
128 | if ($respuestaData) {
129 | socket_sendto($udpSocket, $respuestaData, strlen($respuestaData), 0, $fromIp, $fromPort);
130 | }
131 | $dq = null;
132 | }
133 | }
134 |
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # pddns
3 |
4 | 由于家里路由器公网ip老是变动,
5 | 于是有了这个想法,
6 | 通过有公网ip的服务器作为dns服务器,
7 | 把域名解析到家里的电脑ip
8 |
9 |
10 | > 这只是穷B不买域名只改设备dns自嗨的一种方式
11 |
12 |
13 | 目前跑脚本系统最好用Linux,Windows我没测过
14 |
15 | 安卓手机改DNS时需要在wifi里把ip设置为静态(小米手机好恶心,我改了dns对小米广告域名的ip映射,还是有广告。。。)
16 |
17 | ```
18 |
19 | 1. 命令行 cli 运行 `sudo php cliDaemon.php` 守护进程来作为dns服务器
20 |
21 | 2. 家里的电脑浏览器访问`<公网dns服务器的ip>/index.php?fakeDomain=my-home-domain.com&ip=118.89.204.190`
22 | 来更新我自己的假域名与家里变动ip的对应映射关系
23 |
24 | 3. 手机等想访问家里电脑的设备的dns地址添加这个dns服务器ip
25 |
26 | ```
--------------------------------------------------------------------------------
/cliDaemon.php:
--------------------------------------------------------------------------------
1 | $ip
19 | ];
20 |
21 | //var_dump($fakeDnsIpMap);
22 |
23 |
24 | $data = serialize($fakeDnsIpMap);
25 | if (file_put_contents(__DIR__ . '/data.txt', $data)) {
26 | echo "OK";
27 | } else {
28 | echo "Fail";
29 | }
30 |
--------------------------------------------------------------------------------