pymumu / smartdns

A local DNS server to obtain the fastest website IP for the best Internet experience, support DoT, DoH. 一个本地DNS服务器,获取最快的网站IP,获得最佳上网体验,支持DoH,DoT。
https://pymumu.github.io/smartdns/
GNU General Public License v3.0
8.31k stars 1.06k forks source link

[Feature request] SOCKS5 proxy support #1205

Closed phantomcraft closed 1 year ago

phantomcraft commented 1 year ago

It would be a good idea to implement SOCKS5 proxy support, as the DNS queries could be made over Tor, Vmess/Vless, Shadowsocks, SSH proxies or any other kind of internet circumvention tool.

Could you please implement it?

PikuZheng commented 1 year ago

Duplicate with #928 I stick to smartdns as a pure dns server, the proxy thing is resolved by the network connection software

pymumu commented 1 year ago

This feature has been planned and is expected to be supported in the first quarter of next year.

phantomcraft commented 1 year ago

@pymumu

Good, I'm looking forward for that: =)

Permanent caching + SOCKS5 support = OVERKILL in censored regions.

SOCKS5 proxies support UDP depending on the sub-protocol used, it should work with UDP queries along with TCP ones.

/\ Maybe you should already have seen this project: https://github.com/AdguardTeam/dnsproxy

It implements support for HTTP/3 (QUIC) in DoH servers that uses these protocols, it turns the DNS query very fast and as SOCKS5 proxies support UDP, a good suggestion is to implement support for HTTP/3 in SmartDNS DoH.

You could also implement support for HTTP proxies, it would be interesting to use with DoH and also, HTTP proxies can listen on UDP sockets and receive QUICK connections (HTTP/3) from SmartDNS.

pymumu commented 1 year ago

develop a simple version on branch proxy-test to support socks5 and http proxy, it's in alpha state, may crash or not working correctly. but you can test.

not support udp proxy, and the configuration option may change in future version.

usage:

proxy-https ip[:port] -name [proxy name]
proxy-socks ip[:port] -name [proxy name]

server-tls x.x.x.x -proxy [proxy name]
phantomcraft commented 1 year ago

@pymumu

I tested your commit, but it only works if the addresses are IPv4, not IPv6:

bind 127.0.0.1:10053 -group blah
proxy-socks [::1]:1080 -name ssh
force-qtype-SOA 65
speed-check-mode none
cache-size 524288
server-https https://cloudflare-dns.com/dns-query -spki-pin MnLdGiqUGYhtyinlrGTC4FZdDyDXv4NOWFGnXW3ur14= -tls-host-verify cloudflare-dns.com -group blah -proxy ssh

^X^Cuser@localhost:~$ /dev/shm/smartdns -f -x -p - -c Desktop/dnsd.conf 
unpriviledged ping is disabled, please enable by setting net.ipv4.ping_group_range
[2022-12-21 19:38:34,658][ERROR][     dns_client.c:1915] connect 104.16.248.249 failed, Address family not supported by protocol
open log file /var/log/smartdns/smartdns.log failed, Permission denied
[2022-12-21 19:38:34,658][ERROR][     dns_client.c:1915] connect 104.16.248.249 failed, Address family not supported by protocol
bind 127.0.0.1:10053 -group blah
proxy-socks 127.0.0.1:1080 -name ssh
force-qtype-SOA 65
speed-check-mode none
cache-size 524288
server-tcp [2620:119:53::53]:443 -group blah -proxy ssh

user@localhost:~$ /dev/shm/smartdns -f -x -p - -c Desktop/dnsd.conf 
unpriviledged ping is disabled, please enable by setting net.ipv4.ping_group_range
[2022-12-21 19:40:04,580][ERROR][     dns_client.c:1802] connect 2620:119:53::53 failed, Invalid argument
open log file /var/log/smartdns/smartdns.log failed, Permission denied
[2022-12-21 19:40:04,580][ERROR][     dns_client.c:1802] connect 2620:119:53::53 failed, Invalid argument
pymumu commented 1 year ago

known issue, the feature still has a lot of work to do, please be patient.

phantomcraft commented 1 year ago

@pymumu

No pressure, no problems.

I compiled SmartDNS to a standalone executable (as static executables don't work with LD_PRELOAD) and I'm using together with proxychains-ng, it has been working fine.

pymumu commented 1 year ago

ipv6 issue fixed, should work now.

phantomcraft commented 1 year ago

@pymumu

I tested, it work with addresses passed as domain names (for example, one.one.one.one:53) for both TCP and UDP.

It works with IPv6 TCP but not with IPv6 UDP:

bind 127.0.0.1:9951 -group blah
proxy-socks 127.0.0.1:1080 -name test
force-qtype-SOA 65
speed-check-mode none
cache-size 0
server [2606:4700:4700::1001]:53 -group blah -proxy test
user@localhost:/dev/shm/smartdns-proxy-test$ dig @127.0.0.1 -p 9951 kernel.org

; <<>> DiG 9.18.7-1-Debian <<>> @127.0.0.1 -p 9951 kernel.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 38994
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;kernel.org.            IN  A

;; Query time: 2002 msec
;; SERVER: 127.0.0.1#9951(127.0.0.1) (UDP)
;; WHEN: Thu Dec 22 16:39:04 EST 2022
;; MSG SIZE  rcvd: 28
user@localhost:~$ socks -l
221222213821.593 1080 00000 - 0.0.0.0:0 0.0.0.0:0 0 0 0 Accepting connections [324254/907843392]
221222213903.126 1080 00000 - 127.0.0.1:60192 2606:4700:4700::1001:53 195 0 0 UDPMAP 0.0.0.0:53
phantomcraft commented 1 year ago

Another issue, this commit doesn't work with Tor.

Easy to test:

bind 127.0.0.1:1111 -group blah
proxy-socks 127.0.0.1:9050 -name test
force-qtype-SOA 65
speed-check-mode none
cache-size 0
server-tcp 1.1.1.1:53 -group blah -proxy test
user@localhost:~$ dig @127.0.0.1 -p 1111 t.co

; <<>> DiG 9.18.7-1-Debian <<>> @127.0.0.1 -p 1111 t.co
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 20210
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;t.co.              IN  A

;; Query time: 2001 msec
;; SERVER: 127.0.0.1#1111(127.0.0.1) (UDP)
;; WHEN: Fri Dec 23 00:22:34 EST 2022
;; MSG SIZE  rcvd: 22
pymumu commented 1 year ago

@pymumu

I tested, it work with addresses passed as domain names (for example, one.one.one.one:53) for both TCP and UDP.

It works with IPv6 TCP but not with IPv6 UDP:

bind 127.0.0.1:9951 -group blah
proxy-socks 127.0.0.1:1080 -name test
force-qtype-SOA 65
speed-check-mode none
cache-size 0
server [2606:4700:4700::1001]:53 -group blah -proxy test
user@localhost:/dev/shm/smartdns-proxy-test$ dig @127.0.0.1 -p 9951 kernel.org

; <<>> DiG 9.18.7-1-Debian <<>> @127.0.0.1 -p 9951 kernel.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 38994
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;kernel.org.          IN  A

;; Query time: 2002 msec
;; SERVER: 127.0.0.1#9951(127.0.0.1) (UDP)
;; WHEN: Thu Dec 22 16:39:04 EST 2022
;; MSG SIZE  rcvd: 28
user@localhost:~$ socks -l
221222213821.593 1080 00000 - 0.0.0.0:0 0.0.0.0:0 0 0 0 Accepting connections [324254/907843392]
221222213903.126 1080 00000 - 127.0.0.1:60192 2606:4700:4700::1001:53 195 0 0 UDPMAP 0.0.0.0:53

Please make sure the remote server DOT on ipv6 can be connected

pymumu commented 1 year ago

@pymumu I tested, it work with addresses passed as domain names (for example, one.one.one.one:53) for both TCP and UDP. It works with IPv6 TCP but not with IPv6 UDP:

bind 127.0.0.1:9951 -group blah
proxy-socks 127.0.0.1:1080 -name test
force-qtype-SOA 65
speed-check-mode none
cache-size 0
server [2606:4700:4700::1001]:53 -group blah -proxy test
user@localhost:/dev/shm/smartdns-proxy-test$ dig @127.0.0.1 -p 9951 kernel.org

; <<>> DiG 9.18.7-1-Debian <<>> @127.0.0.1 -p 9951 kernel.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 38994
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;kernel.org.            IN  A

;; Query time: 2002 msec
;; SERVER: 127.0.0.1#9951(127.0.0.1) (UDP)
;; WHEN: Thu Dec 22 16:39:04 EST 2022
;; MSG SIZE  rcvd: 28
user@localhost:~$ socks -l
221222213821.593 1080 00000 - 0.0.0.0:0 0.0.0.0:0 0 0 0 Accepting connections [324254/907843392]
221222213903.126 1080 00000 - 127.0.0.1:60192 2606:4700:4700::1001:53 195 0 0 UDPMAP 0.0.0.0:53

Please make sure the remote server IPV6 DOT can be connected

attach debug log

phantomcraft commented 1 year ago
bind 127.0.0.1:1111 -group blah
proxy-socks 127.0.0.1:1083 -name test
force-qtype-SOA 65
speed-check-mode none
cache-size 0
server [2606:4700:4700::1001]:53 -group blah -proxy test
log-level debug
user@localhost:~$ /dev/shm/smartdns -x -f -p - -c Desktop/dnsd.conf 
unpriviledged ping is disabled, please enable by setting net.ipv4.ping_group_range
[2022-12-23 05:39:59,410][NOTICE][       smartdns.c:395 ] smartdns starting...(Copyright (C) Nick Peng <pymumu@gmail.com>, build: Dec 23 2022 05:35:16)
open log file /var/log/smartdns/smartdns.log failed, Permission denied
[2022-12-23 05:39:59,411][ INFO][     dns_server.c:4007] ICMP ping is disabled, no ipv6 icmp check feature
[2022-12-23 05:39:59,411][ INFO][     dns_server.c:5668] IPV6 is not ready, disable IPV6 features
[2022-12-23 05:39:59,411][ INFO][     dns_client.c:1114] add server 2606:4700:4700::1001:53, type: udp
[2022-12-23 05:40:03,113][DEBUG][     dns_server.c:4502] recv query packet from 127.0.0.1, len = 45, type = 0
[2022-12-23 05:40:03,113][DEBUG][            dns.c:1880] opt type 10
[2022-12-23 05:40:03,113][DEBUG][     dns_server.c:4514] request qdcount = 1, ancount = 0, nscount = 0, nrcount = 0, len = 45, id = 35297, tc = 0, rd = 1, ra = 0, rcode = 0
[2022-12-23 05:40:03,113][ INFO][     dns_server.c:4537] query server t.co from 127.0.0.1, qtype = 1
[2022-12-23 05:40:03,113][DEBUG][     dns_client.c:548 ] send query to group blah
[2022-12-23 05:40:03,113][DEBUG][     dns_client.c:3226] send query to server 2606:4700:4700::1001
[2022-12-23 05:40:03,113][ INFO][     dns_client.c:3522] send request t.co, qtype 1, id 1
[2022-12-23 05:40:03,113][ INFO][          proxy.c:380 ] Server select method is 0
[2022-12-23 05:40:03,113][DEBUG][          proxy.c:500 ] proxy dest: 127.0.0.1:43829
[2022-12-23 05:40:03,113][ INFO][          proxy.c:557 ] connected to socks proxy server.
[2022-12-23 05:40:03,613][ INFO][     dns_client.c:3781] retry query t.co, type: 1, id: 1
[2022-12-23 05:40:03,613][DEBUG][     dns_client.c:3226] send query to server 2606:4700:4700::1001
[2022-12-23 05:40:04,113][ INFO][     dns_client.c:3781] retry query t.co, type: 1, id: 1
[2022-12-23 05:40:04,113][DEBUG][     dns_client.c:3226] send query to server 2606:4700:4700::1001
[2022-12-23 05:40:04,613][ INFO][     dns_client.c:3781] retry query t.co, type: 1, id: 1
[2022-12-23 05:40:04,613][DEBUG][     dns_client.c:3226] send query to server 2606:4700:4700::1001
[2022-12-23 05:40:05,113][ INFO][     dns_client.c:3778] retry query t.co, type: 1, id: 1 failed
[2022-12-23 05:40:05,113][DEBUG][     dns_client.c:1417] result: t.co, qtype: 1, hasresult: 0, id 1
[2022-12-23 05:40:05,113][DEBUG][     dns_server.c:1538] reply t.co qtype: 1, rcode: 0, reply: 1
[2022-12-23 05:40:05,113][ INFO][     dns_server.c:808 ] result t.co, qtype: 1, rtcode: 2

===============================

Test for Tor:

bind 127.0.0.1:1111 -group blah
proxy-socks 127.0.0.1:9050 -name test
force-qtype-SOA 65
speed-check-mode none
cache-size 0
server-tcp 1.1.1.1:53 -group blah -proxy test
log-level debug
user@localhost:~$ /dev/shm/smartdns -x -f -p - -c /home/user/Desktop/dnsd.conf 
unpriviledged ping is disabled, please enable by setting net.ipv4.ping_group_range
[2022-12-23 05:52:04,122][NOTICE][       smartdns.c:395 ] smartdns starting...(Copyright (C) Nick Peng <pymumu@gmail.com>, build: Dec 23 2022 05:35:16)
open log file /var/log/smartdns/smartdns.log failed, Permission denied
[2022-12-23 05:52:04,123][ INFO][     dns_server.c:4007] ICMP ping is disabled, no ipv6 icmp check feature
[2022-12-23 05:52:04,124][ INFO][     dns_server.c:5668] IPV6 is not ready, disable IPV6 features
[2022-12-23 05:52:04,124][ INFO][     dns_client.c:1114] add server 1.1.1.1:53, type: tcp
[2022-12-23 05:52:11,802][DEBUG][     dns_server.c:4502] recv query packet from 127.0.0.1, len = 45, type = 0
[2022-12-23 05:52:11,802][DEBUG][            dns.c:1880] opt type 10
[2022-12-23 05:52:11,802][DEBUG][     dns_server.c:4514] request qdcount = 1, ancount = 0, nscount = 0, nrcount = 0, len = 45, id = 36955, tc = 0, rd = 1, ra = 0, rcode = 0
[2022-12-23 05:52:11,802][ INFO][     dns_server.c:4537] query server t.co from 127.0.0.1, qtype = 1
[2022-12-23 05:52:11,802][DEBUG][     dns_client.c:548 ] send query to group blah
[2022-12-23 05:52:11,802][DEBUG][     dns_client.c:3226] send query to server 1.1.1.1
[2022-12-23 05:52:11,802][DEBUG][     dns_client.c:1896] tcp server 1.1.1.1 connecting.
[2022-12-23 05:52:11,802][ INFO][     dns_client.c:3522] send request t.co, qtype 1, id 1
[2022-12-23 05:52:11,802][ INFO][          proxy.c:380 ] Server select method is 0
[2022-12-23 05:52:12,302][ INFO][     dns_client.c:3781] retry query t.co, type: 1, id: 1
[2022-12-23 05:52:12,302][DEBUG][     dns_client.c:3226] send query to server 1.1.1.1
[2022-12-23 05:52:12,302][DEBUG][     dns_client.c:1165] server 1.1.1.1 closed.
[2022-12-23 05:52:12,802][ INFO][     dns_client.c:3781] retry query t.co, type: 1, id: 1
[2022-12-23 05:52:12,802][DEBUG][     dns_client.c:3226] send query to server 1.1.1.1
[2022-12-23 05:52:12,802][DEBUG][     dns_client.c:1896] tcp server 1.1.1.1 connecting.
[2022-12-23 05:52:12,803][ INFO][          proxy.c:380 ] Server select method is 0
[2022-12-23 05:52:13,302][ INFO][     dns_client.c:3781] retry query t.co, type: 1, id: 1
[2022-12-23 05:52:13,302][DEBUG][     dns_client.c:3226] send query to server 1.1.1.1
[2022-12-23 05:52:13,302][DEBUG][     dns_client.c:1165] server 1.1.1.1 closed.
[2022-12-23 05:52:13,802][ INFO][     dns_client.c:3778] retry query t.co, type: 1, id: 1 failed
[2022-12-23 05:52:13,802][DEBUG][     dns_client.c:1417] result: t.co, qtype: 1, hasresult: 0, id 1
[2022-12-23 05:52:13,802][DEBUG][     dns_server.c:1538] reply t.co qtype: 1, rcode: 0, reply: 1
[2022-12-23 05:52:13,802][ INFO][     dns_server.c:808 ] result t.co, qtype: 1, rtcode: 2

===========================================

I'm using 3proxy andmy connection has IPv6 support.

I tested SmartDNS and another method to connect to a IPv6 address through UDP, here is the results:

user@localhost:~$ socks -p1083 -l
221223105632.289 1083 00000 - 0.0.0.0:1083 0.0.0.0:0 0 0 0 Accepting connections [2021024/3737102144]
221223105648.926 1083 00000 - 127.0.0.1:60473 2606:4700:4700::1001:53 45 97 0 UDPMAP 2606:4700:4700::1001:53
221223105651.644 1083 00000 - 127.0.0.1:42459 2606:4700:4700::1001:53 45 97 0 UDPMAP 2606:4700:4700::1001:53
221223105652.966 1083 00000 - 127.0.0.1:59405 2606:4700:4700::1001:53 45 49 0 UDPMAP 2606:4700:4700::1001:53
221223105656.707 1083 00000 - 127.0.0.1:37695 2606:4700:4700::1001:53 45 97 0 UDPMAP 2606:4700:4700::1001:53
221223105809.126 1083 00000 - 127.0.0.1:47542 2606:4700:4700::1001:53 165 0 0 UDPMAP 0.0.0.0:53
221223105816.966 1083 00000 - 127.0.0.1:59568 2606:4700:4700::1001:53 132 0 0 UDPMAP 0.0.0.0:53
221223105838.598 1083 00000 - 127.0.0.1:59570 2606:4700:4700::1001:53 264 0 0 UDPMAP 0.0.0.0:53

SmartDNS make the destination address be "0.0.0.0:53" while the other method (that works) send the right IPv6 address.