Skip to content

Instantly share code, notes, and snippets.

@stephenlb
Last active January 4, 2017 22:26
Show Gist options
  • Select an option

  • Save stephenlb/1b13616e1e5c45d2fe15292846e7c1e9 to your computer and use it in GitHub Desktop.

Select an option

Save stephenlb/1b13616e1e5c45d2fe15292846e7c1e9 to your computer and use it in GitHub Desktop.
Do you use Dyn DNS? Do you think your Domain is being Blocked? - Nameserver Scanner for ISPs in Regions of the World - Net Neutrality! Why don't you scan the internet's known Nameservers (DNS Servers) to find out. The Python Scanner will test two control domains before testing your target domain. If both control domains pass, and your target dom…
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Libs
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
import multiprocessing
import subprocess
import librato
import json
import sys
import os
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Configuration
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
settings = {
'concurrency' : 200 ## Queries at the same time
, 'time' : 5 ## Seconds before timeout
, 'retry' : 3 ## Retry this many times after timeout
, 'domain' : 'pubnub.com' ## Domain to Scan on Internet
, 'controls' : 'google.com' ## Control Domain to Compare
, 'nameservers' : sys.argv[-1] ## CSV of Nameservers
, 'lock' : multiprocessing.Lock()
, 'librato_user' : os.environ['LIBRATO_USER']
, 'librato_pass' : os.environ['LIBRATO_PASS']
}
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Metrics
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
metrics = {
"country" : {}
}
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## CSV Format
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
csv_format = [
'ip'
, 'name'
, 'country_id'
, 'city'
, 'version'
, 'error'
, 'dnssec'
, 'reliability'
, 'checked_at'
, 'created_at'
]
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Main
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def main():
## Open Nameservers CSV
nameservers = []
namesfile = open( settings['nameservers'], 'r' )
for ns in namesfile: nameservers.append(ns)
namesfile.close()
## Sprinkle in Concurrency
pool = multiprocessing.Pool(settings['concurrency'])
pool.map( find_blocked_domain, nameservers )
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Find Blocked Domain
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def find_blocked_domain(nameserver):
## Parse The Nameserver CSV Line
ns = parse_nameserver_csv(nameserver)
## Ignore CSV Header
if ns['ip'] == 'ip': return True
## Test our Domain, if it fails also check Control
target = lookup(
nameserver=ns['ip']
, domain=settings['domain']
)
## If target passes then Return IPs
if target: return target
## Check the Control Domains
control = True
for control_domain in settings['controls'].split(','):
if control: control = control and lookup(
nameserver=ns['ip']
, domain=control_domain
)
## If the control failed too then the Nameserver is bad.
## We can ignore bad nameservers.
if not control: return True
## Print Suspected Blocklist Candidate
with settings['lock']:
print(json.dumps(ns))
sys.stdout.flush()
track_metric( 'country', ns['country_id'] )
return False
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Parse CSV Line
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def parse_nameserver_csv(nameserver):
ns_result = {}
ns_parse = nameserver.split(',')
ns_parse_pos = 0
for param in csv_format:
ns_result[param] = ns_parse[ns_parse_pos].replace( '"', '' )
ns_parse_pos += 1
return ns_result
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Track Metric
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def track_metric( metric, key ):
if not metric in metrics: metrics[metric] = {}
if not key in metrics[metric]: metrics[metric][key] = 0
metrics[metric][key] += 1
## send to librato
record(
key.lower()
, metrics[metric][key]
, description="DNS Query Failure"
)
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Easy Librato Guage Recording
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def record( metric, value, description="DNS Query Failure" ):
if not settings['librato_user']: return
libratoapi = librato.connect(
settings['librato_user']
, settings['librato_pass']
)
libratoapi.submit(
metric
, value
, description=description
)
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Query Lookup
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def lookup(**kwargs):
try: return subprocess.check_output([
"dig"
, kwargs.get( 'domain', 'google.com' )
, "@%s" % kwargs.get( 'nameserver', 'localhost' )
, "+time=%s" % kwargs.get( 'time', settings['time'] )
, "+retry=%s" % kwargs.get( 'retry', settings['retry'] )
, "+noall"
, "+tcp"
, "+question"
, "+short"
, "+answer"
]).strip()
except: return False
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
## Run Main if Main
## =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
if __name__ == '__main__':
try : main()
except ( KeyboardInterrupt ) : sys.exit(0)
## Get Nameservers
## http://public-dns.info/
## Grep Region
REGION='LB'
grep ",$REGION," nameservers.csv | sed 's/^\([^,]*\).*$/\1/g' > region-nameservers.txt
## Domains to Query
DOMAINS='google.com pubnub.com';
## Scan Region Results
while read ns;
do echo -e "\n\nQuerying Nameserver: '$ns'";
for domain in $DOMAINS;
do echo $domain;
dig @$ns +time=2 +noall +question +answer $domain;
sleep 1;
done;
done < region-nameservers.txt
{'city': 'Denver', 'name': 'remote.secure64.com.', 'dnssec': 'true', 'ip': '64.92.221.186', 'created_at': '2014-12-30 01:48:05 +0100\n', 'checked_at': '2016-12-18 10:23:41 +0100', 'country_id': 'US', 'version': 'dnsmasq-2.45', 'error': '', 'reliability': '0.44'}
{'city': '', 'name': 'ns1.lyman.co.id.', 'dnssec': 'false', 'ip': '117.54.11.54', 'created_at': '2014-12-29 20:39:54 +0100\n', 'checked_at': '2016-12-18 09:50:12 +0100', 'country_id': 'ID', 'version': '9.2.1', 'error': '', 'reliability': '0.38'}
{'city': '', 'name': '173-14-40-85-Michigan.hfc.comcastbusiness.net.', 'dnssec': 'false', 'ip': '173.14.40.85', 'created_at': '2014-12-29 16:16:30 +0100\n', 'checked_at': '2016-12-18 09:10:45 +0100', 'country_id': 'US', 'version': 'dnsmasq-2.45', 'error': '', 'reliability': '0.74'}
{'city': '', 'name': '', 'dnssec': 'false', 'ip': '89.144.141.34', 'created_at': '2014-12-29 16:51:51 +0100\n', 'checked_at': '2016-12-18 09:19:40 +0100', 'country_id': 'IR', 'version': '', 'error': '', 'reliability': '0.74'}
{'city': 'Joa\xc3\xa7aba', 'name': '187-5-134-253.ccoce700.e.brasiltelecom.net.br.', 'dnssec': 'false', 'ip': '187.5.134.253', 'created_at': '2014-12-30 10:25:34 +0100\n', 'checked_at': '2016-12-18 10:31:29 +0100', 'country_id': 'BR', 'version': 'Microsoft DNS 6.0.6002 (17724C46)', 'error': '', 'reliability': '0.91'}
{'city': 'Kowloon', 'name': '', 'dnssec': 'false', 'ip': '123.1.150.121', 'created_at': '2014-12-29 15:27:32 +0100\n', 'checked_at': '2016-12-18 08:58:30 +0100', 'country_id': 'HK', 'version': 'dnsmasq-2.48', 'error': '', 'reliability': '0.82'}
{'city': 'Taipei', 'name': '60-250-55-43.HINET-IP.hinet.net.', 'dnssec': 'false', 'ip': '60.250.55.43', 'created_at': '2014-12-31 21:15:13 +0100\n', 'checked_at': '2016-12-18 11:57:29 +0100', 'country_id': 'TW', 'version': 'dnsmasq-2.48', 'error': '', 'reliability': '0.71'}
{'city': 'Moscow', 'name': 'mail.binagroup.ru.', 'dnssec': 'false', 'ip': '94.159.15.155', 'created_at': '2014-12-30 19:48:11 +0100\n', 'checked_at': '2016-12-18 11:45:59 +0100', 'country_id': 'RU', 'version': 'Microsoft DNS 6.1.7601 (1DB15B4F)', 'error': '', 'reliability': '0.88'}
{'city': 'Jannali', 'name': '14-200-42-169.static.tpgi.com.au.', 'dnssec': 'false', 'ip': '14.200.42.169', 'created_at': '2014-12-31 20:24:34 +0100\n', 'checked_at': '2016-12-18 11:55:30 +0100', 'country_id': 'AU', 'version': 'dnsmasq-2.52', 'error': '', 'reliability': '0.76'}
{'city': 'Singapore', 'name': '', 'dnssec': 'false', 'ip': '42.61.87.201', 'created_at': '2015-01-06 07:55:36 +0100\n', 'checked_at': '2016-12-18 12:40:57 +0100', 'country_id': 'SG', 'version': '9.8.2rc1-RedHat-9.8.2-0.30.rc1.el6_6.1', 'error': '', 'reliability': '0.59'}
{'city': '', 'name': '', 'dnssec': 'false', 'ip': '203.241.132.35', 'created_at': '2015-01-06 18:16:33 +0100\n', 'checked_at': '2016-12-18 13:11:55 +0100', 'country_id': 'KR', 'version': '', 'error': '', 'reliability': '0.59'}
{'city': '', 'name': '213-208-203.netrun.cytanet.com.cy.', 'dnssec': 'false', 'ip': '213.7.208.203', 'created_at': '2015-01-06 19:40:35 +0100\n', 'checked_at': '2016-12-18 13:16:13 +0100', 'country_id': 'CY', 'version': '', 'error': '', 'reliability': '0.62'}
{'city': '', 'name': '', 'dnssec': 'false', 'ip': '213.55.96.166', 'created_at': '2014-09-26 20:56:12 +0200\n', 'checked_at': '2016-12-18 08:22:35 +0100', 'country_id': 'ET', 'version': '9.3.6-P1-RedHat-9.3.6-4.P1.el5_4.2', 'error': '', 'reliability': '0.74'}
{'city': '', 'name': '213-208-192.netrun.cytanet.com.cy.', 'dnssec': 'false', 'ip': '213.7.208.192', 'created_at': '2015-01-06 19:48:57 +0100\n', 'checked_at': '2016-12-18 13:16:44 +0100', 'country_id': 'CY', 'version': '', 'error': '', 'reliability': '0.68'}
{'city': 'Jakarta', 'name': '', 'dnssec': 'false', 'ip': '103.7.230.30', 'created_at': '2015-01-07 04:15:02 +0100\n', 'checked_at': '2016-12-18 13:38:47 +0100', 'country_id': 'ID', 'version': '', 'error': '', 'reliability': '0.59'}
{'city': 'Yogyakarta', 'name': '97.sub146.pika.net.id.', 'dnssec': 'false', 'ip': '110.76.146.97', 'created_at': '2015-01-06 08:47:42 +0100\n', 'checked_at': '2016-12-18 12:43:05 +0100', 'country_id': 'ID', 'version': '', 'error': '', 'reliability': '0.53'}
{'city': "Kamensk-Ural'skiy", 'name': '22-55-255-130.kamensktel.ru.', 'dnssec': 'true', 'ip': '130.255.55.22', 'created_at': '2015-01-08 00:14:24 +0100\n', 'checked_at': '2016-12-18 14:32:15 +0100', 'country_id': 'RU', 'version': 'dnsmasq-2.52', 'error': '', 'reliability': '0.62'}
{'city': 'Johannesburg', 'name': '', 'dnssec': 'false', 'ip': '41.76.32.214', 'created_at': '2015-01-07 19:18:56 +0100\n', 'checked_at': '2016-12-18 14:17:31 +0100', 'country_id': 'ZA', 'version': '', 'error': '', 'reliability': '0.82'}
{'city': '', 'name': 'LStLambert-658-1-79-45.w193-253.abo.wanadoo.fr.', 'dnssec': 'false', 'ip': '193.253.218.45', 'created_at': '2015-01-07 18:30:50 +0100\n', 'checked_at': '2016-12-18 14:15:15 +0100', 'country_id': 'FR', 'version': 'ZyWALL DNS', 'error': '', 'reliability': '0.71'}
{'city': 'Excelsior Springs', 'name': 'kcweb-68-171-29-249.static.ptr.kcweb.net.', 'dnssec': 'false', 'ip': '68.171.29.249', 'created_at': '2015-01-07 01:46:02 +0100\n', 'checked_at': '2016-12-18 13:32:32 +0100', 'country_id': 'US', 'version': 'Microsoft DNS 6.1.7601 (1DB14A66)', 'error': '', 'reliability': '0.74'}
{'city': '', 'name': 'ip-113-196.unikom.net.', 'dnssec': 'false', 'ip': '103.20.196.113', 'created_at': '2015-01-08 06:11:25 +0100\n', 'checked_at': '2016-12-18 14:51:07 +0100', 'country_id': 'ID', 'version': '', 'error': '', 'reliability': '0.26'}
{'city': '', 'name': 'static-209.248.160.115-tataidc.co.in.', 'dnssec': 'false', 'ip': '115.160.248.209', 'created_at': '2015-01-09 21:07:31 +0100\n', 'checked_at': '2016-12-18 16:27:08 +0100', 'country_id': 'IN', 'version': '', 'error': '', 'reliability': '0.59'}
{'city': 'Jakarta', 'name': 'ip123-3-6.tgg.net.id.', 'dnssec': 'false', 'ip': '27.123.3.6', 'created_at': '2015-01-08 00:35:56 +0100\n', 'checked_at': '2016-12-18 14:33:14 +0100', 'country_id': 'ID', 'version': '', 'error': '', 'reliability': '0.53'}
{'city': '', 'name': 'un-155-140.static.sitel.net.pl.', 'dnssec': 'false', 'ip': '89.107.155.140', 'created_at': '2015-01-08 19:11:35 +0100\n', 'checked_at': '2016-12-18 15:19:37 +0100', 'country_id': 'PL', 'version': '8.4.7-REL-NOESW', 'error': '', 'reliability': '0.62'}
{'city': '', 'name': 'www.mirero.co.kr.', 'dnssec': 'false', 'ip': '203.239.173.1', 'created_at': '2015-01-09 21:55:25 +0100\n', 'checked_at': '2016-12-18 16:29:17 +0100', 'country_id': 'KR', 'version': '', 'error': '', 'reliability': '0.53'}
{'city': 'Santiago', 'name': 'as5300-2-193.cnt.entelchile.net.', 'dnssec': 'false', 'ip': '164.77.43.203', 'created_at': '2015-01-08 18:24:34 +0100\n', 'checked_at': '2016-12-18 15:17:28 +0100', 'country_id': 'CL', 'version': '', 'error': '', 'reliability': '0.79'}
{'city': '', 'name': '', 'dnssec': 'false', 'ip': '212.84.172.4', 'created_at': '2015-01-07 11:34:35 +0100\n', 'checked_at': '2016-12-18 13:57:08 +0100', 'country_id': 'GB', 'version': '9.3.1', 'error': '', 'reliability': '0.62'}
{'city': 'Maputo', 'name': '', 'dnssec': 'false', 'ip': '196.3.98.142', 'created_at': '2015-01-10 10:47:47 +0100\n', 'checked_at': '2016-12-18 17:00:45 +0100', 'country_id': 'MZ', 'version': '', 'error': '', 'reliability': '0.56'}
{'city': 'Bekasi', 'name': 'host53-5.home-users.cyberplus.net.id.', 'dnssec': 'false', 'ip': '114.141.53.5', 'created_at': '2015-01-10 18:29:47 +0100\n', 'checked_at': '2016-12-18 17:22:07 +0100', 'country_id': 'ID', 'version': '', 'error': '', 'reliability': '0.74'}
{'city': 'Jakarta', 'name': 'ip123-4-201.tgg.net.id.', 'dnssec': 'false', 'ip': '27.123.4.201', 'created_at': '2015-01-07 22:09:40 +0100\n', 'checked_at': '2016-12-18 14:25:36 +0100', 'country_id': 'ID', 'version': '', 'error': '', 'reliability': '0.88'}
{'city': 'La Paz', 'name': '', 'dnssec': 'false', 'ip': '190.129.48.3', 'created_at': '2015-01-10 03:33:56 +0100\n', 'checked_at': '2016-12-18 16:43:13 +0100', 'country_id': 'BO', 'version': 'Microsoft DNS 6.1.7601 (1DB15B4F)', 'error': '', 'reliability': '0.82'}
{'city': 'Bekasi', 'name': 'host53-7.home-users.cyberplus.net.id.', 'dnssec': 'false', 'ip': '114.141.53.7', 'created_at': '2015-01-10 18:32:06 +0100\n', 'checked_at': '2016-12-18 17:22:12 +0100', 'country_id': 'ID', 'version': '', 'error': '', 'reliability': '0.79'}
{'city': '', 'name': 'planet4x4.com.ua.', 'dnssec': 'false', 'ip': '217.12.219.21', 'created_at': '2015-01-11 21:17:33 +0100\n', 'checked_at': '2016-12-18 18:26:37 +0100', 'country_id': 'UA', 'version': '9.3.6-P1-RedHat-9.3.6-16.P1.el5_7.1', 'error': '', 'reliability': '0.71'}
@stephenlb

stephenlb commented Dec 20, 2016

Copy link
Copy Markdown
Author

Nameserver Scanner for ISPs in Regions of the World

Do you think your Domain is being Blocked?

Net Neutrality! Why don't you scan the internet's known Nameservers (DNS Servers) to find out. The Python Scanner will test two control domains before testing your target domain. If both control domains pass, and your target domain fails, then the nameserver is probably blocking your domain. All suspected nameservers are printed to standard output.

Download nameservers.csv from http://public-dns.info/

Run the script with Librato

LIBRATO_USER=librato_user@pubnub.com \
LIBRATO_PASS=librato_secret \
python internet-dns-scanner.py nameservers.csv

Run the script without Librato

python internet-dns-scanner.py nameservers.csv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment