I've raised this problem a long while ago privately but considering it hasn't changed, I'm assuming it has been forgotten, hence opening this ticket.
Outline shouldn't hard-code DNS resolver in the client. Especially when using OpenDNS. Ideally, this should be an option that is set by the outline manager. Otherwise outline should route the DNS through outline-server. This has a few reasons:
OpenDNS is known to interfere with traffic and arbitrary filter, block or drop some requests. They always block Tor, sometimes they block Signal. And that's what a lot journalists need these days to communicate with each other and their sources. That is, if you want to continue to brand outline as a tool for safer journalism.
I use outline to help people bypass censorship in various repressive countries. Bypassing one censor to hit another doesn't seem like an ideal situation.
This interferes with the principles of open and decentralized web, which I believe are the underlying principles of having any services run self hosted.
System administrators should have control over where their users' traffic is routing through.
This has a great impact on the privacy of the users.
This leads to people following nonstandard workarounds and potentially shooting themselves in the foot if they don't know what they're doing.
I totally agree with this request, Here in I.R.Iran i can't use Outline on my Android because government censored hard-coded DNS Servers inside outline client, I don't know how they do that but months ago DNS stopped working for mobile phones which run Outline. (means if I turn on Outline, apps which use DNS to resolve their server's IP address will stop working, but some apps like Telegram works because they have IP address of their servers hard-coded inside them)
By the way I'm currently using Simple DNSCrypt + Shadowsocks client on my Laptop and it works perfectly.
Thank you for your feedback. We are open to considering this feature request.
Since the client could easily override the DNS server set by the server admin (many apps use custom DNS resolvers), we are thinking of making a configurable option in the client. Perhaps the admin could set the default resolver in the invite.
@alalamav Thanks for the response. I'd argue that those "many apps" you mentioned aren't probably routing the entire traffic of the device.
To be perfectly clear... I think it's ideal if it's configurable in "outline manager" and optionally possible to override by "outline client" if the users wishes to. Otherwise, considering most end users might not even know what DNS is, and that they already have trusted admin with their traffic, it might make sense to let the admin decide where the DNS requests should go.
@mrphs, your proposal sounds reasonable to me.
The point I was trying to make is that there is no guarantee that a given app will use the system resolver set by Outline. They can always make DNS requests to the resolver of their choice and indeed many apps do.
Hi, this has become quite urgent as of today. I'm operating four servers in three different countries, and OpenDNS has stopped responding to all of them.
@alalamav
I don't think Shadowsocks has a mechanism for setting the DNS servers, as it seems to be only a transparent proxy. The client needs to somehow understand which DNS servers to use. The Outline developers have made the simplest possible choice: the DNS servers are hardcoded into the Outline client. If these servers don't work for you, you're out of luck.
The simplest solution I can see is to make the DNS IP addresses changeable through extra URL arguments such as "?dns1=9.9.9.9&dns2=1.1.1.1". This looks sensible to me and is also backwards-compatible.
There could also be a UI element or a json/xml/plist file for users to manually change the DNS servers on the client side. You could also add to the server Docker image a simple httpd daemon that returns a dnsconfig.json file that the client can parse. And if I've understood SS properly (possibly not) you could also set up dnsmasq on the server Docker image, and hardcode the client to use this instead.
This is mostly a problem on the Mac where overriding Outline's default DNS servers is a tough exercise. I'd rather fix the problem properly than write scripts to work around it.
Just make a script called “routedns.sh” in your root directory using sudo nano /root/routedns.sh And paste in the following
#!/bin/bash
/sbin/iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to “outline-server-external-ipv4”:53;
/sbin/iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to “outline-server-external-ipv4”:53;
/sbin/iptables -t nat -A POSTROUTING -j MASQUERADE;
/sbin/ip6tables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to [“outline-server-external-IPv6”]:53;
/sbin/ip6tables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to [“outline-server-external-IPv6”]:53;
/sbin/ip6tables -t nat -A POSTROUTING -j MASQUERADE
exit 0
And then type sudo chmod +x /root/routedns.sh
Then type sudo nano /etc/rc.local And paste in this
#!/bin/bash
bash /root/routedns.sh
exit 0
Finally, type sudo chmod +x /etc/rc.local And enable rc-local by typing sudo systemctl enable rc-local
This will route all dns traffic to the outline server. I tested this on a DigitalOcean Ubuntu 18.04 droplet. This might not work on other vps providers and distros.
@mvonweis The README on outline-server says
This repository has all the code needed to create and manage Outline servers on DigitalOcean. An Outline server runs instances of Shadowsocks proxies and provides an API used by the Outline Manager application.
Outline server install script installs 2 containers - the API for outline manager and the shadowsocks server.
The outline manager API can be extended to also allow defining a default set of nameservers that could be served to all the outline clients.
@Omoeba Thanks for the shell script but I don't think it fits neatly in the way outline-server, outline-manager and outline-client has been designed. Plus the script is not portable to windows and mac.
@modib what do you mean by not portable?
@modib Correct, but this requires modifying three components instead of one. The Manager app is so limited that out only works for trivial setups.
@omoeba The iptables script only works on Linux. Porting it to Mac or Windows requires rewriting the whole script.
The script is meant to be run on the server, not the client.
Just make a script called “routedns.sh” in your root directory using
sudo nano /root/routedns.shAnd paste in the following#!/bin/bash /sbin/iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to “outline-server-external-ipv4”:53; /sbin/iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to “outline-server-external-ipv4”:53; /sbin/iptables -t nat -A POSTROUTING -j MASQUERADE; /sbin/ip6tables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to [“outline-server-external-IPv6”]:53; /sbin/ip6tables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to [“outline-server-external-IPv6”]:53; /sbin/ip6tables -t nat -A POSTROUTING -j MASQUERADE exit 0And then type
sudo chmod +x /root/routedns.shThen type
sudo nano /etc/rc.localAnd paste in this#!/bin/bash bash /root/routedns.sh exit 0Finally, type
sudo chmod +x /etc/rc.localAnd enable rc-local by typingsudo systemctl enable rc-localThis will route all dns traffic to the outline server. I tested this on a DigitalOcean Ubuntu 18.04 droplet. This might not work on other vps providers and distros.
@Omoeba I'm sorry but I'm not good at iptables... so could you write some example codes with example ip for me?
@ASTERISK-Git this will route all dns to cloudflare’s DNS at https://1.1.1.1/dns/
#!/bin/bash
/sbin/iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to 1.1.1.1:53;
/sbin/iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to 1.1.1.1:53;
/sbin/iptables -t nat -A POSTROUTING -j MASQUERADE;
/sbin/ip6tables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to [2606:4700:4700::1111]:53;
/sbin/ip6tables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to [2606:4700:4700::1111]:53;
/sbin/ip6tables -t nat -A POSTROUTING -j MASQUERADE
exit 0
I hear the need to specify the DNS resolver to be used. That should be specified by the managers, as general users don't know how to do that.
I like the idea of the server running its own resolver. Then the client could be changed to try
What should this server resolver look like? I see at least two options:
Thoughts?
cc: @bemasc
Clarifying some implementation options.
A) Run a stub resolver on the Client's localhost that forwards the queries to dns.local (or some other pre-defined domain) via a Shadowsocks proxy connection. The server would intercept dns.local and forward to the designated resolver. Configure the VPN to use the localhost address as the DNS resolver.
B) Configure the VPN to use
C) Fetch some DNS config with the address of the designated resolver from the server on connection and configure the VPN with that.
D) Hardcode the designated DNS resolver on the invite. Can't be changed later.
In A-C the Client needs to check if the resolver supports DNS resolution. For backward compatibility, we can check that in the connectivity test and fallback to the existing behavior on failure. Similar to how we fallback DNS to TCP if UDP is blocked.
(D) is probably the easiest, but cannot be changed.
(C) is probably a good compromise of simplicity and flexibility
A-B is compatible with third-party Shadowsocks clients that allow specifying the IP of the resolver.
There are a few options for the designated resolver:
A) Run own recursive resolver
B) Use the host's system resolver
C) Use a third-party resolver, specified somehow by the admin. This is similar to (B), since the admin can change the system resolver.
One interesting consideration here is that, if the VPN advertises the IP of a good third-party resolver, Android DoT and Chrome DoH might be able to upgrade to encrypted DNS. This improves the user's privacy with respect to the proxy server, and also has nontrivial performance and reliability implications (perhaps good, perhaps bad).
I think the best balance of simplicity and flexibility might be to place the proxy's recommended DNS server in a shadowsocks online-config JSON blob, and avoid changing the behavior of ss:// access keys (which would continue to use client-hardcoded resolvers).
One tricky thing here is that Chrome DoH needs to see the third-party IP as the configured DNS server, so we would need to reconfigure the VPN interface after receiving the latest shadowsocks config.
Most helpful comment
@alalamav Thanks for the response. I'd argue that those "many apps" you mentioned aren't probably routing the entire traffic of the device.
To be perfectly clear... I think it's ideal if it's configurable in "outline manager" and optionally possible to override by "outline client" if the users wishes to. Otherwise, considering most end users might not even know what DNS is, and that they already have trusted admin with their traffic, it might make sense to let the admin decide where the DNS requests should go.