From 0112d12693d91b83f6c3b33f5398055958a34501 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Wed, 23 Jan 2019 00:48:45 +0800 Subject: [PATCH] Add ignore-ip feature --- ReadMe.md | 1 + ReadMe_zh-CN.md | 1 + etc/smartdns/smartdns.conf | 3 +++ src/dns_conf.c | 12 ++++++++++++ src/dns_conf.h | 2 ++ src/dns_server.c | 20 +++++++++++++++++--- 6 files changed, 36 insertions(+), 3 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 2e1a9b8..29f1769 100755 --- a/ReadMe.md +++ b/ReadMe.md @@ -396,6 +396,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use |address|Domain IP address|None|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-` for ignore, `#` for return SOA, `4` for IPV4, `6` for IPV6| address /www.example.com/1.2.3.4 |ipset|Domain IPSet|None|ipset /domain/[ipset\|-], `-` for ignore|ipset /www.example.com/pass |bogus-nxdomain|bogus IP address|None|[IP/subnet], Repeatable| bogus-nxdomain 1.2.3.4/16 +|ignore-ip|ignore ip address|None|[ip/subnet], Repeatable| ignore-ip 1.2.3.4/16 |blacklist-ip|ip blacklist|None|[ip/subnet], Repeatable,When the filtering server responds IPs in the IP blacklist, The result will be discarded directly| blacklist-ip 1.2.3.4/16 |force-AAAA-SOA|force AAAA query return SOA|no|[yes\|no]|force-AAAA-SOA yes |dualstack-ip-selection|Dualstack ip selection|no|[yes\|no]|dualstack-ip-selection yes diff --git a/ReadMe_zh-CN.md b/ReadMe_zh-CN.md index d787950..3372d18 100644 --- a/ReadMe_zh-CN.md +++ b/ReadMe_zh-CN.md @@ -396,6 +396,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms |address|指定域名IP地址|无|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-`表示忽略, `#`表示返回SOA, `4`表示IPV4, `6`表示IPV6| address /www.example.com/1.2.3.4 |ipset|域名IPSET|None|ipset /domain/[ipset\|-], `-`表示忽略|ipset /www.example.com/pass |bogus-nxdomain|假冒IP地址过滤|无|[ip/subnet],可重复| bogus-nxdomain 1.2.3.4/16 +|ignore-ip|忽略IP地址|无|[ip/subnet],可重复| ignore-ip 1.2.3.4/16 |blacklist-ip|黑名单IP地址|无|[ip/subnet],可重复| blacklist-ip 1.2.3.4/16 |force-AAAA-SOA|强制AAAA地址返回SOA|no|[yes\|no]|force-AAAA-SOA yes |dualstack-ip-selection|双栈IP优选|no|[yes\|no]|dualstack-ip-selection yes diff --git a/etc/smartdns/smartdns.conf b/etc/smartdns/smartdns.conf index 106a101..5375dfb 100644 --- a/etc/smartdns/smartdns.conf +++ b/etc/smartdns/smartdns.conf @@ -36,6 +36,9 @@ cache-size 512 # List of IPs that will be filtered when nameserver is configured -blacklist-ip parameter # blacklist-ip [ip/subnet] +# List of IPs that will be ignored +# ignore-ip [ip/subnet] + # force AAAA query return SOA # force-AAAA-SOA [yes|no] diff --git a/src/dns_conf.c b/src/dns_conf.c index 4220530..e722851 100644 --- a/src/dns_conf.c +++ b/src/dns_conf.c @@ -579,6 +579,8 @@ int config_iplist_rule(char *subnet, enum address_rule rule) case ADDRESS_RULE_BOGUS: ip_rule->bogus = 1; break; + case ADDRESS_RULE_IP_IGNORE: + ip_rule->ip_ignore = 1; } return 0; @@ -602,6 +604,15 @@ int conf_bogus_nxdomain(void *data, int argc, char *argv[]) return config_iplist_rule(argv[1], ADDRESS_RULE_BOGUS); } +int conf_ip_ignore(void *data, int argc, char *argv[]) +{ + if (argc <= 1) { + return -1; + } + + return config_iplist_rule(argv[1], ADDRESS_RULE_IP_IGNORE); +} + int conf_edns_client_subnet(void *data, int argc, char *argv[]) { char *slash = NULL; @@ -689,6 +700,7 @@ struct config_item config_item[] = { CONF_YESNO("force-AAAA-SOA", &dns_conf_force_AAAA_SOA), CONF_CUSTOM("blacklist-ip", config_blacklist_ip, NULL), CONF_CUSTOM("bogus-nxdomain", conf_bogus_nxdomain, NULL), + CONF_CUSTOM("ignore-ip", conf_ip_ignore, NULL), CONF_CUSTOM("edns-client-subnet-ipv4", conf_edns_client_subnet, &dns_conf_ipv6_ecs), CONF_CUSTOM("edns-client-subnet-ipv6", conf_edns_client_subnet, &dns_conf_ipv6_ecs), CONF_CUSTOM("conf-file", config_addtional_file, NULL), diff --git a/src/dns_conf.h b/src/dns_conf.h index 3b01144..ef5b69f 100644 --- a/src/dns_conf.h +++ b/src/dns_conf.h @@ -84,11 +84,13 @@ struct dns_bogus_ip_address { enum address_rule { ADDRESS_RULE_BLACKLIST = 1, ADDRESS_RULE_BOGUS = 2, + ADDRESS_RULE_IP_IGNORE = 3, }; struct dns_ip_address_rule { unsigned int blacklist : 1; unsigned int bogus : 1; + unsigned int ip_ignore : 1; }; struct dns_edns_client_subnet { diff --git a/src/dns_server.c b/src/dns_server.c index d8f524f..27fef02 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -884,8 +884,13 @@ static int _dns_server_ip_rule_check(struct dns_request *request, unsigned char } } - return -1; + if (rule->ip_ignore) { + goto skip; + } + return -1; +skip: + return -2; match: if (request->rcode == DNS_RC_SERVFAIL) { request->rcode = DNS_RC_NXDOMAIN; @@ -904,6 +909,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain, struct dns_rrs *rrs = NULL; int ping_timeout = DNS_PING_TIMEOUT; unsigned long now = get_tick_count(); + int ip_check_result = 0; if (packet->head.rcode != DNS_RC_NOERROR && packet->head.rcode != DNS_RC_NXDOMAIN) { if (request->rcode == DNS_RC_SERVFAIL) { @@ -940,9 +946,13 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain, tlog(TLOG_DEBUG, "domain: %s TTL:%d IP: %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]); /* ip rule check */ - if (_dns_server_ip_rule_check(request, addr, 4, DNS_T_A, result_flag) == 0) { + ip_check_result = _dns_server_ip_rule_check(request, addr, 4, DNS_T_A, result_flag); + if (ip_check_result == 0) { _dns_server_request_release(request); break; + } else if (ip_check_result == -2) { + _dns_server_request_release(request); + continue; } if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(request->cname, name, DNS_MAX_CNAME_LEN) != 0) { @@ -991,9 +1001,13 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain, tlog(TLOG_DEBUG, "domain: %s TTL: %d IP: %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", name, ttl, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]); - if (_dns_server_ip_rule_check(request, addr, 16, DNS_T_AAAA, result_flag) == 0) { + ip_check_result = _dns_server_ip_rule_check(request, addr, 16, DNS_T_AAAA, result_flag); + if (ip_check_result == 0) { _dns_server_request_release(request); break; + } else if (ip_check_result == -2) { + _dns_server_request_release(request); + continue; } if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(request->cname, name, DNS_MAX_CNAME_LEN) != 0) {