commit 8a3c6dbbfe6b47f97b4a053be4dd1029ec2e49d8
Author: aagbsn <aagbsn(a)extc.org>
Date: Thu Sep 12 13:21:36 2013 +0200
Do not submit probe_ip by default
---
data/ooniprobe.conf.sample | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/data/ooniprobe.conf.sample b/data/ooniprobe.conf.sample
index b86ff69..d651bbd 100644
--- a/data/ooniprobe.conf.sample
+++ b/data/ooniprobe.conf.sample
@@ -7,7 +7,7 @@ basic:
logfile: /var/log/ooniprobe.log
privacy:
# …
[View More]Should we include the IP address of the probe in the report?
- includeip: true
+ includeip: false
# Should we include the ASN of the probe in the report?
includeasn: true
# Should we include the country as reported by GeoIP in the report?
[View Less]
commit e4f5b47d2eaf278adc1cd47505afa73b23b79f27
Merge: 40f5789 ee3911f
Author: Arturo Filastò <art(a)fuffa.org>
Date: Thu Sep 12 12:47:17 2013 +0200
Merge branch 'master' into feature/move_nettests
* master:
Enforce str on IP address of backend.
Change the default ports used by Tor.
data/ooniprobe.conf.sample | 4 ++--
ooni/nettests/blocking/dnsconsistency.py | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --cc ooni/nettests/…
[View More]blocking/dnsconsistency.py
index 3c88cd2,0000000..d883434
mode 100644,000000..100644
--- a/ooni/nettests/blocking/dnsconsistency.py
+++ b/ooni/nettests/blocking/dnsconsistency.py
@@@ -1,175 -1,0 +1,175 @@@
+# -*- encoding: utf-8 -*-
+#
+# dnsconsistency
+# **************
+#
+# The test reports censorship if the cardinality of the intersection of
+# the query result set from the control server and the query result set
+# from the experimental server is zero, which is to say, if the two sets
+# have no matching results whatsoever.
+#
+# NOTE: This test frequently results in false positives due to GeoIP-based
+# load balancing on major global sites such as google, facebook, and
+# youtube, etc.
+#
+# :authors: Arturo Filastò, Isis Lovecruft
+# :licence: see LICENSE
+
+import pdb
+
+from twisted.python import usage
+from twisted.internet import defer
+
+from ooni.templates import dnst
+
+from ooni import nettest
+from ooni.utils import log
+
+class UsageOptions(usage.Options):
+ optParameters = [['backend', 'b', '8.8.8.8:53',
+ 'The OONI backend that runs the DNS resolver'],
+ ['testresolvers', 'T', None,
+ 'File containing list of DNS resolvers to test against'],
+ ['testresolver', 't', None,
+ 'Specify a single test resolver to use for testing']
+ ]
+
+class DNSConsistencyTest(dnst.DNSTest):
+
+ name = "DNS Consistency"
+ description = "DNS censorship detection test"
+ version = "0.6"
+ authors = "Arturo Filastò, Isis Lovecruft"
+ requirements = None
+
+ inputFile = ['file', 'f', None,
+ 'Input file of list of hostnames to attempt to resolve']
+
+ requiredTestHelpers = {'backend': 'dns'}
+
+ usageOptions = UsageOptions
+ requiredOptions = ['backend', 'file']
+
+ def setUp(self):
+ if (not self.localOptions['testresolvers'] and \
+ not self.localOptions['testresolver']):
+ raise usage.UsageError("You did not specify a testresolver")
+
+ elif self.localOptions['testresolvers']:
+ test_resolvers_file = self.localOptions['testresolvers']
+
+ elif self.localOptions['testresolver']:
+ self.test_resolvers = [self.localOptions['testresolver']]
+
+ try:
+ with open(test_resolvers_file) as f:
+ self.test_resolvers = [x.split('#')[0].strip() for x in f.readlines()]
+ self.report['test_resolvers'] = self.test_resolvers
+ f.close()
+
+ except IOError, e:
+ log.exception(e)
+ raise usage.UsageError("Invalid test resolvers file")
+
+ except NameError:
+ log.debug("No test resolver file configured")
+
+ dns_ip, dns_port = self.localOptions['backend'].split(':')
- self.control_dns_server = (dns_ip, int(dns_port))
++ self.control_dns_server = (str(dns_ip), int(dns_port))
+
+ self.report['control_resolver'] = self.control_dns_server
+
+ @defer.inlineCallbacks
+ def test_a_lookup(self):
+ """
+ We perform an A lookup on the DNS test servers for the domains to be
+ tested and an A lookup on the known good DNS server.
+
+ We then compare the results from test_resolvers and that from
+ control_resolver and see if the match up.
+ If they match up then no censorship is happening (tampering: false).
+
+ If they do not we do a reverse lookup (PTR) on the test_resolvers and
+ the control resolver for every IP address we got back and check to see
+ if anyone of them matches the control ones.
+
+ If they do then we take not of the fact that censorship is probably not
+ happening (tampering: reverse-match).
+
+ If they do not match then censorship is probably going on (tampering:
+ true).
+ """
+ log.msg("Doing the test lookups on %s" % self.input)
+ list_of_ds = []
+ hostname = self.input
+
+ self.report['tampering'] = {}
+
+ control_answers = yield self.performALookup(hostname, self.control_dns_server)
+ if not control_answers:
+ log.err("Got no response from control DNS server %s," \
+ " perhaps the DNS resolver is down?" % self.control_dns_server[0])
+ self.report['tampering'][self.control_dns_server] = 'no_answer'
+ return
+
+ for test_resolver in self.test_resolvers:
+ log.msg("Testing resolver: %s" % test_resolver)
+ test_dns_server = (test_resolver, 53)
+
+ try:
+ experiment_answers = yield self.performALookup(hostname, test_dns_server)
+ except Exception, e:
+ log.err("Problem performing the DNS lookup")
+ log.exception(e)
+ self.report['tampering'][test_resolver] = 'dns_lookup_error'
+ continue
+
+ if not experiment_answers:
+ log.err("Got no response, perhaps the DNS resolver is down?")
+ self.report['tampering'][test_resolver] = 'no_answer'
+ continue
+ else:
+ log.debug("Got the following A lookup answers %s from %s" % (experiment_answers, test_resolver))
+
+ def lookup_details():
+ """
+ A closure useful for printing test details.
+ """
+ log.msg("test resolver: %s" % test_resolver)
+ log.msg("experiment answers: %s" % experiment_answers)
+ log.msg("control answers: %s" % control_answers)
+
+ log.debug("Comparing %s with %s" % (experiment_answers, control_answers))
+ if set(experiment_answers) & set(control_answers):
+ lookup_details()
+ log.msg("tampering: false")
+ self.report['tampering'][test_resolver] = False
+ else:
+ log.msg("Trying to do reverse lookup")
+
+ experiment_reverse = yield self.performPTRLookup(experiment_answers[0], test_dns_server)
+ control_reverse = yield self.performPTRLookup(control_answers[0], self.control_dns_server)
+
+ if experiment_reverse == control_reverse:
+ log.msg("Further testing has eliminated false positives")
+ lookup_details()
+ log.msg("tampering: reverse_match")
+ self.report['tampering'][test_resolver] = 'reverse_match'
+ else:
+ log.msg("Reverse lookups do not match")
+ lookup_details()
+ log.msg("tampering: true")
+ self.report['tampering'][test_resolver] = True
+
+ def inputProcessor(self, filename=None):
+ """
+ This inputProcessor extracts domain names from urls
+ """
+ log.debug("Running dnsconsistency default processor")
+ if filename:
+ fp = open(filename)
+ for x in fp.readlines():
+ yield x.strip().split('//')[-1].split('/')[0]
+ fp.close()
+ else:
+ pass
[View Less]
commit 1c8485b81c57d8613c17de2a1a1b69125db92d74
Author: aagbsn <aagbsn(a)extc.org>
Date: Thu Sep 12 15:04:48 2013 +0200
Drops the hierarchy by reportFormatVersion
See also: https://github.com/TheTorProject/ooni-backend/issues/20
This was not implemented in ooni-probe or ooni-backend, and is
redundant to the report, though if we decide to change the report
header in the future we may need to handle this case in parsers.
Adding new fields should …
[View More]generally not be a problem, though
ooni-backend presently expects a fixed length report header.
---
docs/source/reports.rst | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/docs/source/reports.rst b/docs/source/reports.rst
index 77d8cf6..ad97411 100644
--- a/docs/source/reports.rst
+++ b/docs/source/reports.rst
@@ -2,7 +2,7 @@ Reports
=======
The reports collected by ooniprobe are stored on
-https://ooni.torproject.org/reports/ ``reportFormatVersion`` / ``CC`` /
+https://ooni.torproject.org/reports/ ``CC`` /
Where ``CC`` is the two letter country code as specified by `ISO 31666-2
<http://en.wikipedia.org/wiki/ISO_3166-2>`_.
@@ -50,11 +50,9 @@ some malicious report poisoning attack in progress.
Report format version changelog
===============================
-In here shall go details about he major changes to the reporting format.
+In here shall go details about the major changes to the reporting format.
version 0.1
-----------
Initial format version.
-
-
[View Less]
commit 23567662bea818287c26a448c88b43fe8d6c641c
Author: Arturo Filastò <art(a)fuffa.org>
Date: Thu Sep 12 15:00:07 2013 +0200
Only lookup and set collectors when it is needed.
---
ooni/deck.py | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/ooni/deck.py b/ooni/deck.py
index 22ae066..98d90e0 100644
--- a/ooni/deck.py
+++ b/ooni/deck.py
@@ -140,27 +140,34 @@ class Deck(InputFile):
if self.bouncer:
log.msg("Looking up …
[View More]test helpers...")
yield self.lookupTestHelpers()
-
+
@defer.inlineCallbacks
def lookupTestHelpers(self):
from ooni.oonibclient import OONIBClient
oonibclient = OONIBClient(self.bouncer)
required_test_helpers = []
+ requires_collector = []
for net_test_loader in self.netTestLoaders:
+ if not net_test_loader.collector:
+ requires_collector.append(net_test_loader)
+
for th in net_test_loader.requiredTestHelpers:
+ # {'name':'', 'option':'', 'test_class':''}
if th['test_class'].localOptions[th['option']]:
continue
- # {'name':'', 'option':'', 'test_class':''}
required_test_helpers.append(th['name'])
-
- if not required_test_helpers:
+
+ if not required_test_helpers and not requires_collector:
defer.returnValue(None)
response = yield oonibclient.lookupTestHelpers(required_test_helpers)
for net_test_loader in self.netTestLoaders:
log.msg("Setting collector and test helpers for %s" % net_test_loader.testDetails['test_name'])
- if not net_test_loader.requiredTestHelpers:
+
+ # Only set the collector if the no collector has been specified
+ # from the command line or via the test deck.
+ if not net_test_loader.requiredTestHelpers and net_test_loader in requires_collector:
log.msg("Using the default collector: %s" % response['default']['collector'])
net_test_loader.collector = response['default']['collector'].encode('utf-8')
@@ -168,7 +175,8 @@ class Deck(InputFile):
test_helper = response[th['name']]
log.msg("Using this helper: %s" % test_helper)
th['test_class'].localOptions[th['option']] = test_helper['address']
- net_test_loader.collector = test_helper['collector'].encode('utf-8')
+ if net_test_loader in requires_collector:
+ net_test_loader.collector = test_helper['collector'].encode('utf-8')
@defer.inlineCallbacks
def fetchAndVerifyNetTestInput(self, net_test_loader):
[View Less]