[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r8440: Resolve bug 330: detect ISPs that want to hijack failing DNS (in tor/trunk: . doc src/or)
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] r8440: Resolve bug 330: detect ISPs that want to hijack failing DNS (in tor/trunk: . doc src/or)
- From: nickm@xxxxxxxx
- Date: Thu, 21 Sep 2006 17:48:29 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Thu, 21 Sep 2006 17:48:37 -0400
- Reply-to: or-talk@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
Author: nickm
Date: 2006-09-21 17:48:22 -0400 (Thu, 21 Sep 2006)
New Revision: 8440
Modified:
tor/trunk/
tor/trunk/ChangeLog
tor/trunk/doc/TODO
tor/trunk/doc/tor.1.in
tor/trunk/src/or/config.c
tor/trunk/src/or/dns.c
tor/trunk/src/or/main.c
tor/trunk/src/or/or.h
Log:
r8875@Kushana: nickm | 2006-09-21 16:46:28 -0400
Resolve bug 330: detect ISPs that want to hijack failing DNS requests and basically domain-squat the entire internet.
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/branches/eventdns [r8875] on c95137ef-5f19-0410-b913-86e773d04f59
Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog 2006-09-21 21:48:16 UTC (rev 8439)
+++ tor/trunk/ChangeLog 2006-09-21 21:48:22 UTC (rev 8440)
@@ -1,6 +1,5 @@
Changes in version 0.1.2.2-alpha - 2006-??-??
o Major features:
-
- Add server-side support for "reverse" DNS lookups (using PTR
records so clients can determine the canonical hostname for a given
IPv4 address). This has been specified for a long time, but was
@@ -8,6 +7,11 @@
servers now announce in their descriptors whether they support
eventdns.
+ o Minor features:
+ - Check for name servers (like Earthlink's) that hijack failing DNS
+ requests and replace the 'no such server' answer with a "helpful"
+ redirect to an advertising-driven search portal. [Resolves bug 330.]
+
o Security Fixes, minor
- If a client asked for a server by name, and we didn't have a
descriptor for a named server with that name, we might return an old
Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO 2006-09-21 21:48:16 UTC (rev 8439)
+++ tor/trunk/doc/TODO 2006-09-21 21:48:22 UTC (rev 8440)
@@ -87,9 +87,9 @@
- Write-limit directory responses (need to research)
N - DNS improvements
- - Option to deal with broken DNS of the "ggoogle.com? Ah, you meant
+ o Option to deal with broken DNS of the "ggoogle.com? Ah, you meant
ads.me.com!" variety.
-d - Autodetect whether DNS is broken in this way.
+ o Autodetect whether DNS is broken in this way.
- Don't ask reject *:* nodes for DNS unless client wants you to.
. Asynchronous DNS
o Document and rename SearchDomains, ResolvConf options
Modified: tor/trunk/doc/tor.1.in
===================================================================
--- tor/trunk/doc/tor.1.in 2006-09-21 21:48:16 UTC (rev 8439)
+++ tor/trunk/doc/tor.1.in 2006-09-21 21:48:22 UTC (rev 8440)
@@ -647,6 +647,15 @@
connected to "www.example.com".
This option only effects name lookup for addresses requested by clients.
(Defaults to "0".)
+.LP
+.TP
+\fBServerDNSDetectHijacking \fR\fB0\fR|\fB1\fR\fP
+When this option is set to 1, we will test periodically to determine whether
+our local nameservers have been configured to hijack failing DNS requests
+(usually to an advertising site). If they are, we will attempt to correct
+this. This option only effects name lookup for addresses requested by
+clients; and only takes effect if Tor was built with eventdns support.
+(Defaults to "1".)
.SH DIRECTORY SERVER OPTIONS
.PP
Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c 2006-09-21 21:48:16 UTC (rev 8439)
+++ tor/trunk/src/or/config.c 2006-09-21 21:48:22 UTC (rev 8440)
@@ -222,6 +222,7 @@
VAR("RunTesting", BOOL, RunTesting, "0"),
VAR("SafeLogging", BOOL, SafeLogging, "1"),
VAR("SafeSocks", BOOL, SafeSocks, "0"),
+ VAR("ServerDNSDetectHijacking",BOOL, ServerDNSDetectHijacking,"1"),
VAR("ServerDNSResolvConfFile", STRING, ServerDNSResolvConfFile, NULL),
VAR("ServerDNSSearchDomains", BOOL, ServerDNSSearchDomains, "0"),
VAR("ShutdownWaitLength", INTERVAL, ShutdownWaitLength, "30 seconds"),
Modified: tor/trunk/src/or/dns.c
===================================================================
--- tor/trunk/src/or/dns.c 2006-09-21 21:48:16 UTC (rev 8439)
+++ tor/trunk/src/or/dns.c 2006-09-21 21:48:22 UTC (rev 8440)
@@ -122,6 +122,7 @@
static int spawn_enough_dnsworkers(void);
#else
static int configure_nameservers(int force);
+static int answer_is_wildcarded(const char *ip);
#endif
#ifdef DEBUG_DNS_CACHE
static void _assert_cache_ok(void);
@@ -1330,6 +1331,11 @@
return 0;
}
+
+void
+dns_launch_wildcard_checks(void)
+{
+}
#else /* !USE_EVENTDNS */
/** Eventdns helper: return true iff the eventdns result <b>err</b> is
@@ -1470,9 +1476,19 @@
status = DNS_RESOLVE_SUCCEEDED;
tor_inet_ntoa(&in, answer_buf, sizeof(answer_buf));
escaped_address = esc_for_log(string_address);
- log_debug(LD_EXIT, "eventdns said that %s resolves to %s",
- safe_str(escaped_address),
- escaped_safe_str(answer_buf));
+
+ if (answer_is_wildcarded(answer_buf)) {
+ log_debug(LD_EXIT, "eventdns said that %s resolves to ISP-hijacked "
+ "address %s; treating as a failure.",
+ safe_str(escaped_address),
+ escaped_safe_str(answer_buf));
+ addr = 0;
+ status = DNS_RESOLVE_FAILED_PERMANENT;
+ } else {
+ log_debug(LD_EXIT, "eventdns said that %s resolves to %s",
+ safe_str(escaped_address),
+ escaped_safe_str(answer_buf));
+ }
tor_free(escaped_address);
} else if (type == DNS_PTR && count) {
char *escaped_address;
@@ -1546,6 +1562,94 @@
}
return r ? -1 : 0;
}
+
+/** If present, a list of dotted-quad IP addresses that our nameserver
+ * apparently wants to return in response to requests for nonexistent domains.
+ */
+static smartlist_t *dns_wildcard_list = NULL;
+
+/** Callback function when we get an answer (possibly failing) for a request
+ * for a (hopefully) nonexistent domain. */
+static void
+eventdns_wildcard_check_callback(int result, char type, int count, int ttl,
+ void *addresses, void *arg)
+{
+ static int notice_given = 0;
+ if (result == DNS_ERR_NONE && type == DNS_IPv4_A && count) {
+ uint32_t *addrs = addresses;
+ int i;
+ char *string_address = arg;
+ if (!dns_wildcard_list) dns_wildcard_list = smartlist_create();
+ for (i = 0; i < count; ++i) {
+ char answer_buf[INET_NTOA_BUF_LEN+1];
+ struct in_addr in;
+ in.s_addr = addrs[i];
+ tor_inet_ntoa(&in, answer_buf, sizeof(answer_buf));
+ if (!smartlist_string_isin(dns_wildcard_list, answer_buf))
+ smartlist_add(dns_wildcard_list, tor_strdup(answer_buf));
+ }
+ log(notice_given ? LOG_INFO : LOG_NOTICE, LD_EXIT,
+ "Your DNS provider gave an answer for \"%s\", which "
+ "is not supposed to exist. Apparently they are hijacking "
+ "DNS failures. Trying to correct for this. We've noticed %d bad "
+ "addresses so far.", string_address, smartlist_len(dns_wildcard_list));
+ notice_given = 1;
+ }
+ tor_free(arg);
+}
+
+/** Launch a single request for a nonexistent hostname consisting of
+ * <b>len</b> random (plausible) characters followed by <b>suffix</b> */
+static void
+launch_wildcard_check(int len, const char *suffix)
+{
+ char random_bytes[16], name[64], *addr;
+ size_t n = (len+1)/2;
+ int r;
+
+ tor_assert(n <= sizeof(random_bytes));
+
+ if (crypto_rand(random_bytes, n) < 0)
+ return;
+ base32_encode(name, sizeof(name), random_bytes, n);
+ name[len] = '\0';
+ strlcat(name, suffix, sizeof(name));
+
+ addr = tor_strdup(name);
+ r = eventdns_resolve_ipv4(name, DNS_QUERY_NO_SEARCH,
+ eventdns_wildcard_check_callback, addr);
+ if (r)
+ tor_free(addr);
+}
+
+#define N_WILDCARD_CHECKS 2
+
+/** Launch DNS requests for a few nonexistent hostnames, and see if we can
+ * catch our nameserver trying to hijack them and map them to a stupid "I
+ * couldn't find ggoogle.com but maybe you'd like to buy these lovely
+ * encyclopedias" page. */
+void
+dns_launch_wildcard_checks(void)
+{
+ int i;
+ if (!get_options()->ServerDNSDetectHijacking)
+ return;
+ log_info(LD_EXIT, "Launching checks to see whether our nameservers like "
+ "to hijack DNS failures.");
+ for (i = 0; i < N_WILDCARD_CHECKS; ++i) {
+ /* RFC2606 reserves these */
+ launch_wildcard_check(8, ".invalid");
+ launch_wildcard_check(8, ".test");
+ }
+}
+
+/** Return true iff we have noticed that the dotted-quad <b>ip</b> has been
+ * returned in response to a request for a nonexistent hostname. */
+static int
+answer_is_wildcarded(const char *ip)
+{
+ return dns_wildcard_list && smartlist_string_isin(dns_wildcard_list, ip);
+}
#endif /* USE_EVENTDNS */
/** Exit with an assertion if <b>resolve</b> is corrupt. */
Modified: tor/trunk/src/or/main.c
===================================================================
--- tor/trunk/src/or/main.c 2006-09-21 21:48:16 UTC (rev 8439)
+++ tor/trunk/src/or/main.c 2006-09-21 21:48:22 UTC (rev 8440)
@@ -722,6 +722,7 @@
static time_t time_to_try_getting_descriptors = 0;
static time_t time_to_reset_descriptor_failures = 0;
static time_t time_to_add_entropy = 0;
+ static time_t time_to_check_for_wildcarded_dns = 0;
or_options_t *options = get_options();
int i;
int have_dir_info;
@@ -923,6 +924,20 @@
* we'll pass it to poll/select and bad things will happen.
*/
close_closeable_connections();
+
+ /** 9. and if we're a server, check whether our DNS is telling stories to
+ * us. */
+ if (server_mode(options) && time_to_check_for_wildcarded_dns < now) {
+ if (!time_to_check_for_wildcarded_dns) {
+ time_to_check_for_wildcarded_dns = now + 60 + crypto_rand_int(120);
+ } else {
+ dns_launch_wildcard_checks();
+ time_to_check_for_wildcarded_dns = now + 12*3600 +
+ crypto_rand_int(12*3600);
+ }
+ }
+
+
}
static struct event *timeout_event = NULL;
Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h 2006-09-21 21:48:16 UTC (rev 8439)
+++ tor/trunk/src/or/or.h 2006-09-21 21:48:22 UTC (rev 8440)
@@ -1574,6 +1574,8 @@
int ServerDNSSearchDomains; /**< Boolean: If set, we don't force exit
* addresses to be FQDNs, but rather search for them in
* the local domains. */
+ int ServerDNSDetectHijacking; /**< Boolean: If true, check for DNS failure
+ * hijacking */
char *ServerDNSResolvConfFile; /**< If provided, we configure our internal
* resolver from the file here rather than from
* /etc/resolv.conf (unix) or the registry (windows) */
@@ -2158,6 +2160,7 @@
void assert_all_pending_dns_resolves_ok(void);
void dns_cancel_pending_resolve(const char *question);
int dns_resolve(edge_connection_t *exitconn);
+void dns_launch_wildcard_checks(void);
/********************************* hibernate.c **********************/