Forward DNS requests to shadowsocks proxy for specific interface

Hello,

I am following this tutorial to setup a shadowsocks proxy client on the router that connects to a proxy server that runs locally:

Tutorial Shadowsocks

The connection works fine, however the DNS requests are not routed through the proxy. In the tutorial, they mention to change the dnsmasq options. However, this would change the DNS settings for all interfaces. The shadowsocks proxy tunnels the traffic on only one interface. I want to change the DNS server specifically for this interface to 127.0.0.1#8053(like in the tutorial), all other should remain the same. How can I do this?

From the link you provided:

This will forward all DNS queries to the local tunnel endpoint (on port 8053 of the localhost interface) and it will also prevent the router from using other upstream DNS servers, manually defined or obtained via DHCP. Dnsmasq will still listen on port 53 on all interfaces.

If you want to make sure that all devices on your LAN will be forced to use the service, you might consider using DNS hijacking.

I understood that from the tutorial. However, the problem is that this will route all DNS traffic through the proxy. I have a special case here:

I have multiple interfaces: Guest, IOT... and I want to only route the traffic of one of those, lets say for example IOT through the proxy. I need the DNS traffic from the IOT interface to go through the proxy and all other DNS requests from other interfaces to go to the normal DNS server. With the given setting, all DNS traffic goes through the proxy. How can I do this for a specific interface?

Okay, now I get it.
First you need to make the service listen on all interfaces.
Look in the shadowsocks configuration file for something like option local_address '127.0.0.1' (I am guessing here) and change the IP to 0.0.0.0.
Restart the service and check if the settings are applied by running netstat -nlp | grep 8053
You have to see somewhere 0.0.0.0:8053.
Then create a firewall rule like the one below by first editing the zone name and the IP subnet.

uci add firewall redirect
uci set firewall.@redirect[-1].name='IoT-DNS'
uci set firewall.@redirect[-1].target='DNAT'
uci set firewall.@redirect[-1].src='iot' # Correct zone name
uci set firewall.@redirect[-1].src_ip='192.168.101.0/24' # IoT IP subnet
uci add_list firewall.@redirect[-1].proto='udp'
uci add_list firewall.@redirect[-1].proto='tcp'
uci set firewall.@redirect[-1].src_dport='53'
uci set firewall.@redirect[-1].dest_port='8053'
uci commit firewall
/etc/init.d/firewall restart

First of all, thank you for your time! Yes, this seems to be what I want. I have added the port forwarding rule as you suggested, but unfortunately the DNS does not work at all after I use the rule. I am new to OpenWrt, so I do not fully understand how to debug the problem. Here are the steps that I took:

  1. The DNS request does not work from the IOT interface
  2. Using tcpdump, I can see the DNS requests sent from a device on the IOT interface on port 53.
  3. Using tcpdump, I cannot see any TCP/UDP packets on port 8053

Here is how the network looks like:

On 192.168.2.0/24, there is the shadowsocks proxy server. The IOT interface is the 192.168.10.0/24
network. The idea is to isolate the IOT interface and force all traffic through proxy. The IOT zone is isolated, so cannot forward to wan. The only option is over the proxy server on 192.168.2.0/24.

When I disable your rule and allow the IOT zone to forward to wan, DNS is working but I have the DNS leak problem. When I reenable the rule, the DNS is not working.

I also do not exactly understand, what the tunnel_address parameter of the tunnel is. It is set to 8.8.8.8:53, so I assume that it somehow forwards the DNS requests to the google DNS. I can see it in the logs of the shadowsocks server:

[shadowsocks] UDP proxying 192.168.2.1:33549 to 8.8.8.8:53
[shadowsocks] UDP proxying 192.168.2.1:48733 to 8.8.8.8:53

Do you know how I can find out, where the problem lies with the DNS?

You cannot capture packets using tcpdump if their destination is rewritten to a different port on a local interface.

It seems so, but I can't confirm it without installing and testing the service.

Check the output of

nslookup openwrt.org 127.0.0.1:8053; nslookup openwrt.org 192.168.2.1:8053; nslookup openwrt.org 192.168.10.1:8053

BTW (if you haven't seen it yet), It turns out that other users have similar problems even if they follow the guide strictly.

https://forum.openwrt.org/t/shadowsocks-client-on-router/141822