Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SIP009] Handling remote DNS in ss-server in a backwards compatible way #156

Open
Mygod opened this issue Feb 20, 2020 · 23 comments
Open

[SIP009] Handling remote DNS in ss-server in a backwards compatible way #156

Mygod opened this issue Feb 20, 2020 · 23 comments

Comments

@Mygod
Copy link
Contributor

Mygod commented Feb 20, 2020

I propose that if shadowsocks server receives a (TCP/UDP) connection to 0.0.0.0:53 or [::]:53, it should redirect the connection to current default DNS resolver (on Linux, this might be handled by res_query). This is useful for socksifier VPNs as well as resolving ACL rules.

This is a backwards compatible change and should not break anything. (maybe this is an SIP?)

@ghost
Copy link

ghost commented Feb 20, 2020

0.0.0.0:53

Literally 0.0.0.0 (0.0.0.0/32) or just any IP address (0.0.0.0/0)?

@riobard
Copy link
Contributor

riobard commented Feb 20, 2020

SOCKS6 draft RFC section 12 has some idea I think we should probably borrow. However this should be made optional since it has security implications.

@Mygod
Copy link
Contributor Author

Mygod commented Feb 20, 2020

@studentmain 32.

@riobard Damn it someone already had that idea before me. But yeah we might want to look into SOCKS6 more.

@riobard
Copy link
Contributor

riobard commented Feb 20, 2020

I'm modeling v2 protocol upon SOCKS6 but it's still draft so changes are to be expected.

@ghost
Copy link

ghost commented Feb 20, 2020

I think this is an SIP. Client built in DNS proxy (we can't send to 0.0.0.0 on socket) will required to use this feature.

@riobard
Copy link
Contributor

riobard commented Feb 20, 2020

If there's a dns resolver running on the server (e.g. dnsmasq), wouldn't the client be able to use it just by connecting to 127.0.0.1:53?

@Mygod Mygod changed the title Handling remote DNS in ss-server in a backwards compatible way [SIP] Handling remote DNS in ss-server in a backwards compatible way Feb 20, 2020
@Mygod
Copy link
Contributor Author

Mygod commented Feb 20, 2020

Added [SIP] to title as per discussions.

@riobard I made a pass through the socks6 draft. I think we can extend shadowsocks to v2 to accommodate socks6 when the rfc goes stable.

@riobard
Copy link
Contributor

riobard commented Feb 20, 2020

Right, that's why I'm modeling the v2 on SOCKS6 now.

@fortuna
Copy link
Contributor

fortuna commented Feb 20, 2020

The Outline team has also discussed some ideas on how to make the server define the DNS resolver to be used.

Alternative 1: use a special domain name (e.g. dns.local.)
One alternative we discussed was to have a special hostname. For example, dns.local, and then make sure we use the hostname address (not IP) in the SS header.

Alternative 2: use <server_ip>:53 as the DNS resolver
An alternative is for the client to assume <server_ip>:53 is a DNS resolver. We can run a forwarder resolver there and set the firewall so that it doesn't accept external connections.

In any of those cases, the client needs to check if the functionality is available first.

One thing that bothers me with 0.0.0.0, is that it's usually interpreted as any IP on an interface. So we're mixing up the semantics

cc: @alalamav @bemasc

@Mygod
Copy link
Contributor Author

Mygod commented Feb 20, 2020

@fortuna 0 address is also used in socks6 draft and we really do mean any address so I think it's fine. Of course this behavior will only be used for TCP/UDP connect.

EDIT: I think in the case of Outline where the server is entirely managed, I think the alternatives you propose would work fine. In general, we want a shadowsocks server to coexist with other thing and we don't want to take out bind :53 (systemd-resolved is absolutely disgusting) nor a hostname.

@bemasc
Copy link

bemasc commented Feb 21, 2020

The SOCKS 6 draft, and especially this DNS support proposal, are still early in the IETF review process. Ultimately, I trust the IETF to choose whether this is an acceptable use of 0.0.0.0 or not. If not, it could be implemented using a new IANA-reserved domain like socks-server.arpa, or using a new (fourth) address type (not IPv4, IPv6, or domain).

@Mygod
Copy link
Contributor Author

Mygod commented Feb 21, 2020

@bemasc Using a 4th address type is a good idea actually...

@Mygod
Copy link
Contributor Author

Mygod commented Feb 23, 2020

@bemasc On second thought, I think the issue is that we want to support both DNS over TCP and UDP, so this actually ends up using two more address types (DNS over TCP, DNS over UDP). Also maybe the IP address could also serve as a hint (meaning not requirement) for server to either use an IPv4/IPv6 DNS?

@ghost
Copy link

ghost commented Feb 23, 2020

DNS over TCP and UDP

SS client act as a DNS proxy here, so I think only support DNS over TCP is ok.

@fortuna
Copy link
Contributor

fortuna commented Feb 25, 2020

I wonder if a better option is to define a new SOCKS command. Why overload the existing commands (CONNECT), and make their implementations more complicated, if you can have a new command that can isolate complexity (e.g. RESOLVE)?

Connecting and resolving are different operations, so you can expect different parameters. A new command would allow that, rather than overloading and abusing the existing CONNECT parameters, which will make the protocol harder to understand and maintain.

@ghost
Copy link

ghost commented Feb 25, 2020

I wonder if a better option is to define a new SOCKS command. Why overload the existing commands (CONNECT), and make their implementations more complicated, if you can have a new command that can isolate complexity (e.g. RESOLVE)?

Connecting and resolving are different operations, so you can expect different parameters. A new command would allow that, rather than overloading and abusing the existing CONNECT parameters, which will make the protocol harder to understand and maintain.

Current SS protocol has no SOCKS command field...

But it's good idea for SOCKS6 protocol (maybe SS v2 protocol too).

@Mygod
Copy link
Contributor Author

Mygod commented May 17, 2020

@fortuna I think there are some advantages for using the zero address. In practice, connecting to zero address is equivalent to connecting to localhost, so even if the socks server is not implemented correctly (or simply not updated to support this), it is easily fixable by setting up another DNS relay/server at localhost:53.

@madeye If it looks good, shall we assign it a number and start implementing it? (e.g. shadowsocks/shadowsocks-android@3a7ab22)

@madeye
Copy link
Contributor

madeye commented May 17, 2020

I think we can first implement it in shadowsocks-rust as an experimental feature.

@Mygod Mygod changed the title [SIP] Handling remote DNS in ss-server in a backwards compatible way [SIP009] Handling remote DNS in ss-server in a backwards compatible way May 17, 2020
@kimw
Copy link
Contributor

kimw commented Oct 24, 2020

I wonder if a better option is to define a new SOCKS command. Why overload the existing commands (CONNECT), and make their implementations more complicated, if you can have a new command that can isolate complexity (e.g. RESOLVE)?

A non-standard SOCKS command may expose the shadowsocks. I mean, for example, any bad APP can try the command (e.g. RESOLVE).

@ghost
Copy link

ghost commented Oct 24, 2020

I wonder if a better option is to define a new SOCKS command. Why overload the existing commands (CONNECT), and make their implementations more complicated, if you can have a new command that can isolate complexity (e.g. RESOLVE)?

A non-standard SOCKS command may expose the shadowsocks. I mean, for example, any bad APP can try the command (e.g. RESOLVE).

If an app can try SOCKS command, it already know the server password.

@kimw
Copy link
Contributor

kimw commented Oct 24, 2020

If an app can try SOCKS command, it already know the server password.

@studentmain Not at all. The APP, which trying to make connections thru SOCKS, only knows about: there's a SOCKS proxy service, a common IT infrastructure.

@ghost
Copy link

ghost commented Oct 24, 2020

If an app can try SOCKS command, it already know the server password.

@studentmain Not at all. The APP, which trying to make connections thru SOCKS, only knows about: there's a SOCKS proxy service, a common IT infrastructure.

Then it exposed shadowsocks client (again, but with a hard way), not server. And current shadowsocks protocol itself has no SOCKS command field.

@kimw
Copy link
Contributor

kimw commented Oct 25, 2020

Then it exposed shadowsocks client (again, but with a hard way), not server. And current shadowsocks protocol itself has no SOCKS command field.

Yes, it is. The ss-server, ss-tunnel, and ss-redir will never exposed, but only ss-local do (if ss-local implements custom SOCKS command).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants