shadowsocks android pdnsd settings
5 min read

shadowsocks android pdnsd settings

The pdnsd FAQ

pdnsd可以作为简单的dns服务器使用,自定义各种记录,退出时会缓存到文件,所以可以保证下次启动时立即可以查询到,避免程序卡死。

很多dns resolver会在收到被裁减的udp回应包(超过512字节的,有些域名会有很多records)时,自动尝试使用tcp连接。

In some cases pdnsd will not consider the answer of the local name server authoritative enough, and will try to get answers from the name servers listed in the authority section of the reply message 使用proxy_only=on 或者 query_method=tcp_only 来避免。问题是,in what cases?

pdnsd Documentation

proxy_only=(on|off);
When this option is set to on, answers given by the servers are always
accepted, and no other servers (as, for example, specified in the NS records of
the query domain) are queried. If you do not turn this option on, pdnsd will do
such queries in some cases (in particular when processing ANY queries).
This option is useful when you do not want pdnsd to make connections to outside
servers for some reasons (e.g. when a firewall is blocking such queries).
I recommend that you turn on lean_query when using this option.
Default is off.

reject=string;
New in version 1.2.6: This option can be used to make pdnsd reject replies that
contain certain IP addresses. You can specify a single IP address, which will
be matched exactly, or a range of addresses using an address/mask pair.

reject_policy=(fail|negate);
New in version 1.2.6: This option determines what pdnsd does when an address in
the reply from a name server matches the reject list (see above). If this
option is set to fail, pdnsd will try another server, or, if there no more
servers to try, return the answer SERVFAIL. If this option is set to negate,
pdnsd will immediately return the answer NXDOMAIN (unknown domain) without
querying additional servers. The fail setting is useful if you don't always
trust the servers in this section, but do trust the servers in the following
section. The negate setting can be used to completely censor certain IP
addresses. In this case you should put the same reject list in every server
section, and also set the reject_recursively option (see below) to true.
The default is fail.

policy=(included|excluded|simple_only|fqdn_only);
pdnsd supports inclusion/exclusion lists for server sections: with include= and
exclude= (see below) you can specify domain names for which this server will be
used or will not be used. The first match counts (i.e., the first include or
exclude rule in a server section that matches a domain name is applied, and the
search for other rules is terminated). If no rule matched a given domain name,
the policy= option determines whether this server is used for the lookup for
that domain name; when included is given, the server will be asked, and when
excluded is given, it will not. #直白的说,就是默认策略呗?

include=string;
This option adds an entry to the exclusion/inclusion list. If a domain matches
the name given as string, the server is queried if this was the first matching
rule (see also the entry for policy).

exclude=string;
This option adds an entry to the exclusion/inclusion list. If a domain matches
the name given as string, the server is not queried if this was the first
matching rule (see also the entry for policy).

Each server section specifies a set of name servers that pdnsd should try to
get resource records or authoritative name server information from. The servers
are queried in the order of their appearance (or parallel to a limited extend).
If one fails, the next one is taken and so on.

上游服务器会依次查询,因此排在前面的会优先

以下是shadowsock的pdnsd配置

有三种模式

  1. 全部通过隧道查询8.8.8.8
  2. 指定白名单走国内dns,其余走隧道查询8.8.8.8
  3. 指定黑名单走隧道查询8.8.8.8,其余走国内dns(优先查询)。后者返回的结果如果符合reject ip列表,则拒绝接受,继续下一个查询。

目前,代码里第二种没有生效,只有第一种和第三种模式。 相比chinadns,这里需要维护一个黑名单和reject ip列表。

对上游服务器的查询,均走的是tcp协议。这个方便了隧道实现,但是速度会慢一点。

以下是配置详情

val PDNSD_LOCAL = #不做域名过滤
"""
|global {
| perm_cache = 2048;
| cache_dir = "%s";
| server_ip = %s; #127.0.01
| server_port = %d; #8153
| query_method = tcp_only;
| run_ipv4 = on;
| min_ttl = 15m;
| max_ttl = 1w;
| timeout = 10;
| daemon = off;
|}
|
|server { # 通过隧道查询8.8.8.8:53
| label = "local";
| ip = 127.0.0.1;
| port = %d; #本地端口8163
| %s
| reject_policy = negate; #立即失败
| reject_recursively = on;
| timeout = 5;
|}
|
|rr {
| name=localhost;
| reverse=on;
| a=127.0.0.1;
| owner=localhost;
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|}
""".stripMargin

val PDNSD_BYPASS = #白名单过滤
"""
|global {
| perm_cache = 2048;
| cache_dir = "%s";
| server_ip = %s;
| server_port = %d;
| query_method = tcp_only;
| run_ipv4 = on;
| min_ttl = 15m;
| max_ttl = 1w;
| timeout = 10;
| daemon = off;
|}
|
|server { #国内dns服务器
| label = "china-servers";
| ip = 114.114.114.114, 223.5.5.5;
| uptest = none;
| preset = on;
| include = %s; #这些域名将被包括,可以内网域名和已知未墙的域名
| policy = excluded; #默认全部排除,请走隧道查询
| timeout = 2;
|}
|
|server { # 通过隧道查询8.8.8.8:53
| label = "local-server";
| ip = 127.0.0.1;
| uptest = none;
| preset = on;
| port = %d;
| timeout = 5;
|}
|
|rr {
| name=localhost;
| reverse=on;
| a=127.0.0.1;
| owner=localhost;
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|}
""".stripMargin

val PDNSD_DIRECT = #黑名单过滤
"""
|global {
| perm_cache = 2048;
| cache_dir = "%s";
| server_ip = %s;
| server_port = %d;
| query_method = tcp_only;
| run_ipv4 = on;
| min_ttl = 15m;
| max_ttl = 1w;
| timeout = 10;
| daemon = off;
|}
|
|server { #国内dns服务器
| label = "china-servers";
| ip = 114.114.114.114, 112.124.47.27;
| timeout = 4;
| reject = %s; # ip在这个范围的,就reject
| reject_policy = fail; # 尝试下一个
| reject_recursively = on;
| exclude = %s; #这些域名将被排除,gfwlist放这里比较合适
| policy = included; #默认查询(只要不在exclude里)
| uptest = none;
| preset = on;
|}
|
|server { # 通过隧道查询8.8.8.8:53
| label = "local-server";
| ip = 127.0.0.1;
| port = %d;
| %s
| reject_policy = negate;
| reject_recursively = on;
|}
|
|rr {
| name=localhost;
| reverse=on;
| a=127.0.0.1;
| owner=localhost;
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|}
""".stripMargin

原文时间:2016.4