зеркало из https://github.com/mozilla/stoneridge.git
100 строки
2.9 KiB
Python
100 строки
2.9 KiB
Python
import argparse
|
|
import daemonize
|
|
import logging
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
import traceback
|
|
|
|
from dnsproxy import DnsProxyServer, UdpDnsHandler, DnsProxyException
|
|
from replay import configure_logging
|
|
|
|
import stoneridge
|
|
|
|
|
|
listen_ip = None
|
|
|
|
|
|
class NeckoDnsProxyServer(DnsProxyServer):
|
|
def necko_get_ip(self, client):
|
|
try:
|
|
return self.necko_ips[client]
|
|
except (AttributeError, KeyError):
|
|
iproute = subprocess.Popen(['ip', 'route', 'get', client],
|
|
stdout=subprocess.PIPE)
|
|
res = iproute.stdout.read()
|
|
iproute.wait()
|
|
bits = res.split()
|
|
ip = None
|
|
for i, bit in enumerate(bits):
|
|
if bit == 'src':
|
|
ip = bits[i + 1]
|
|
break
|
|
if ip is None:
|
|
# Hail mary, full of something...
|
|
return '127.0.0.1'
|
|
try:
|
|
self.necko_ips[client] = ip
|
|
except AttributeError:
|
|
self.necko_ips = {}
|
|
self.necko_ips[client] = ip
|
|
return self.necko_ips[client]
|
|
|
|
|
|
class NeckoDnsHandler(UdpDnsHandler):
|
|
def handle(self):
|
|
self.data = self.rfile.read()
|
|
self.transaction_id = self.data[0]
|
|
self.flags = self.data[1]
|
|
self.qa_counts = self.data[4:6]
|
|
self.domain = ''
|
|
operation_code = (ord(self.data[2]) >> 3) & 15
|
|
if operation_code == self.STANDARD_QUERY_OPERATION_CODE:
|
|
self.wire_domain = self.data[12:]
|
|
self.domain = self._domain(self.wire_domain)
|
|
else:
|
|
logging.debug("DNS request with non-zero operation code: %s",
|
|
operation_code)
|
|
real_ip = self.server.passthrough_filter(self.domain)
|
|
if real_ip:
|
|
message = 'passthrough'
|
|
ip = real_ip
|
|
else:
|
|
message = 'handle'
|
|
ip = self.server.necko_get_ip(self.client_address[0])
|
|
# TODO - make the above work again
|
|
ip = listen_ip
|
|
logging.debug('dnsproxy: %s(%s) -> %s', message, self.domain, ip)
|
|
self.reply(self.get_dns_reply(ip))
|
|
|
|
|
|
def daemon():
|
|
configure_logging('debug', None)
|
|
try:
|
|
with(NeckoDnsProxyServer(False, handler=NeckoDnsHandler)):
|
|
while True:
|
|
time.sleep(1)
|
|
except KeyboardInterrupt:
|
|
logging.info('Shutting down.')
|
|
except DnsProxyException as e:
|
|
logging.critical(e)
|
|
sys.exit(1)
|
|
except:
|
|
print traceback.format_exc()
|
|
sys.exit(2)
|
|
sys.exit(0)
|
|
|
|
|
|
@stoneridge.main
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--listen', dest='listen', required=True)
|
|
parser.add_argument('--pidfile', dest='pidfile', required=True)
|
|
parser.add_argument('--log', dest='log', required=True)
|
|
args = parser.parse_args()
|
|
|
|
global listen_ip
|
|
listen_ip = args.listen
|
|
|
|
daemonize.start(daemon, args.pidfile, args.log)
|