Ejemplo n.º 1
0
    def start(self):
        self._setup()

        try:
            self._logger.info('Starting DNS Server')
            self._logger.debug(
                'made DnsServer with blacklist {}, process count {}, dns server ip {}'
                .format(list(self._blacklist), self._process_count,
                        self._dns_server_ip))
            dns = DNSServer(blacklist_dns=self._blacklist,
                            process_count=self._process_count,
                            dns_server_ip=self._dns_server_ip)

            threading.Thread(target=self._logger_thread,
                             args=(dns.get_log_reader(), )).start()
            threading.Thread(target=self._reload_blacklist).start()

            self._logger.debug('made dnsserver instance')
            try:
                dns.start_dns_server()
            except OSError:
                self._logger.fatal('Something happen', exc_info=True)
            finally:
                self._logger.info('Ended DNS Server')
        except Exception:
            self._logger.error('error!', exc_info=True)
Ejemplo n.º 2
0
 def __init__(self):
     LOGGER.debug("MainControl init")
     self.tuntap = None
     self.client = None
     self.tap_control = None
     self.sys_hper = SysHelper()
     self.running = False
     # callbacks
     self.connect_cb = None
     self.tuntapset_cb = None
     self.tapcontrolset_cb = None
     self.stop_cb = None
     # traffic init
     traffic = load_traffic()
     if traffic:
         self.rx_total_init = traffic.get('rx', 0)
         self.tx_total_init = traffic.get('tx', 0)
     else:
         self.rx_total_init = 0
         self.tx_total_init = 0
     # filter
     self.filter = FilterRule(self.sys_hper)
     # direct dns
     self.dns_server = DNSServer(self.filter, self.dns_recv_callback)
Ejemplo n.º 3
0
    if request.method == 'PUT':
        if host not in challenges:
            challenges[host] = {}
        value = request.data
        log('Defining challenge file for {0}'.format(host), '/.well-known/acme-challenge/{0} => {1}'.format(filename, value))
        challenges[host][filename] = value
        return 'ok'
    else:
        if host not in challenges or filename not in challenges[host]:
            return 'not found', 404
        log('Removing challenge file for {0}'.format(host), '/.well-known/acme-challenge/{0}'.format(filename))
        del challenges[host][filename]
        return 'ok'


dns_server = DNSServer(port=53, log_callback=partial(log, program='DNS Server'))


@app.route('/dns/<string:record>', methods=['PUT', 'DELETE'])
def dns_challenge(record):
    if request.method == 'PUT':
        values = request.get_json(force=True)
        log('Adding TXT records for {0}'.format(record), values)
        dns_server.set_txt_records(record, values)
    else:
        log('Removing TXT records for {0}'.format(record))
        dns_server.clear_txt_records(record)
    return 'ok'


tls_alpn_server = ALPNChallengeServer(port=5001, log_callback=log)
Ejemplo n.º 4
0
def _create_parser():
    parser = argparse.ArgumentParser(description="Кэширующий DNS сервер.")
    parser.add_argument("asked_server", nargs="?", default="77.88.8.8")
    parser.add_argument("-c",
                        "--clear_cache",
                        action="store_true",
                        help="Отчищает кэш")
    return parser.parse_args()


if __name__ == '__main__':
    parser = _create_parser()
    if os.getuid() != 0:
        try:
            subprocess.call(["sudo", "python3", *sys.argv])
        except PermissionError:
            pass
        finally:
            sys.exit(0)
    if parser.clear_cache:
        DNSServer.clear_cache()
        sys.exit(0)
    try:
        print("Сервер запущен")
        DNSServer("localhost", 53, parser.asked_server).run()
    except KeyboardInterrupt:
        pass
    finally:
        print("Сервер остановлен")
Ejemplo n.º 5
0
class MainControl:
    def __init__(self):
        LOGGER.debug("MainControl init")
        self.tuntap = None
        self.client = None
        self.tap_control = None
        self.sys_hper = SysHelper()
        self.running = False
        # callbacks
        self.connect_cb = None
        self.tuntapset_cb = None
        self.tapcontrolset_cb = None
        self.stop_cb = None
        # traffic init
        traffic = load_traffic()
        if traffic:
            self.rx_total_init = traffic.get('rx', 0)
            self.tx_total_init = traffic.get('tx', 0)
        else:
            self.rx_total_init = 0
            self.tx_total_init = 0
        # filter
        self.filter = FilterRule(self.sys_hper)
        # direct dns
        self.dns_server = DNSServer(self.filter, self.dns_recv_callback)

    def set_connect_cb(self, callback):
        self.connect_cb = callback

    def set_tuntapset_cb(self, callback):
        self.tuntapset_cb = callback

    def set_tapcontrolset_cb(self, callback):
        self.tapcontrolset_cb = callback

    def set_stop_cb(self, callback):
        self.stop_cb = callback

    def get_rx_rate(self):
        if self.client:
            return self.client.rx_rate
        else:
            return 0

    def get_tx_rate(self):
        if self.client:
            return self.client.tx_rate
        else:
            return 0

    def get_rx_total(self):
        if self.client:
            self.rx_total_init = self.client.rx_total
            return self.client.rx_total
        else:
            return self.rx_total_init

    def get_tx_total(self):
        if self.client:
            self.tx_total_init = self.client.tx_total
            return self.client.tx_total
        else:
            return self.tx_total_init

    def clear_traffic(self):
        if self.client:
            self.client.clear_traffic()
        else:
            traffic = {}
            traffic['rx'] = 0
            traffic['tx'] = 0
            save_traffic(traffic)
        self.rx_total_init = 0
        self.tx_total_init = 0

    def query_traffic_remain(self, server_ip, server_port, username, secret):
        secret = secret.encode('utf-8')
        cipher = Chacha20Cipher(secret)
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        identification_raw = username.encode('utf-8')
        identification = hashlib.sha256(identification_raw).digest()
        send_data = b'\x02' + identification
        sock.sendto(cipher.encrypt(send_data), (server_ip, server_port))
        try:
            sock.settimeout(5)
            data, _ = sock.recvfrom(2048)
            data = cipher.decrypt(data)
            traffic_remain = int.from_bytes(data[1:5], 'big')
            return traffic_remain
        except Exception:
            return None

    def run(self, server_ip, server_port, username, secret):
        LOGGER.debug("MainControl run")
        self.server_ip = server_ip
        self.server_port = server_port
        identification_raw = username.encode('utf-8')
        self.identification = hashlib.sha256(identification_raw).digest()
        self.secret = secret.encode('utf-8')
        self.running = True
        self.main_thread = threading.Thread(target=self.handle_start)
        self.main_thread.start()

    def stop(self):
        LOGGER.debug("MainControl stop")
        self.stop_thread = threading.Thread(target=self.handle_stop)
        self.stop_thread.start()

    def handle_start(self):
        LOGGER.debug("MainControl handle_start")
        LOGGER.info("MainControl start connecting")
        self.client = Client(self.server_ip, self.server_port, self.identification, self.secret, self.client_recv_cb, self.client_handshake_cb)
        self.client.run()

        # waiting for client connecting to server
        while not self.tuntap:
            time.sleep(0.1)
            if not self.running:
                return
        if self.tuntapset_cb is not None:
            self.tuntapset_cb()

        # dns
        self.dns_server.run()

        self.tap_control = TAPControl(self.tuntap)
        self.tap_control.read_callback = self.tap_read_cb
        self.tap_control.run()
        if self.tapcontrolset_cb is not None:
            self.tapcontrolset_cb()

    def handle_stop(self):
        LOGGER.debug("MainControl handle_stop")
        LOGGER.info("MainControl stop")
        self.running = False
        if self.tap_control is not None:
            self.tap_control.close()
        if self.client is not None:
            self.client.stop()
        if self.tuntap is not None:
            close_tun_tap(self.tuntap)
        if self.dns_server is not None:
            self.dns_server.stop()
        self.filter.uninit_filter()
        self.tap_control = None
        self.tuntap = None
        self.client = None
        self.sys_hper.uninit_network(self.server_ip)
        LOGGER.info("MainControl stopped")
        if self.stop_cb is not None:
            self.stop_cb()

    def client_handshake_cb(self, gateway_ip, interface_ip):
        LOGGER.debug("MainControl client_handshake_cb")
        if self.connect_cb is not None:
            self.connect_cb()
        ipv4_addr = list(interface_ip)
        ipv4_gateway = list(gateway_ip)
        ipv4_network = [10, 0, 0, 0]
        ipv4_netmask = [255, 255, 255, 0]
        LOGGER.info("MainControl handshake success with interface ip: %s, gateway ip: %s" % (ipv4_addr, ipv4_gateway))
        self.sys_hper.init_network(self.server_ip, ipv4_addr, ipv4_gateway, ipv4_network, ipv4_netmask)
        self.tuntap = open_tun_tap(ipv4_addr, ipv4_network, ipv4_netmask)

        # filter
        ffilter = load_filter()
        filter_type = FILTER_BLACK
        filter_domains = []
        filter_ips = []
        if ffilter is not None:
            ftype = ffilter.get('type')
            domains = ffilter.get('domains')
            ips = ffilter.get('ips')
            if ftype == 'Blacklist':
                filter_type = FILTER_BLACK
            elif ftype == 'Whitelist':
                filter_type = FILTER_WHITE
            filter_domains = domains.strip().split('\n')
            filter_ips = ips.strip().split('\n')
        LOGGER.info("MainControl filter domains:\n%s\nfilter ips:\n%s" % (filter_domains, filter_ips))
        self.filter.init_filter(filter_type, filter_domains, filter_ips)

    def client_recv_cb(self, data):
        LOGGER.debug("MainControl client_recv_cb")
        self.tap_control.write(data)

    def tap_read_cb(self, data):
        LOGGER.debug("MainControl tap_read_cb")

        # dns filter
        if is_dns_packet(data):
            LOGGER.debug("MainControl read dns packet")
            qnames = get_dns_qnames(data)
            for qname in qnames:
                if self.filter.match_domain(qname.decode()):
                    LOGGER.info("DNSServer domain matched: %s" % qname)
                    self.dns_server.resolve(data)
                    return

        self.client.send(data)

    def dns_recv_callback(self, data):
        LOGGER.debug("MainControl dns_recv_callback")
        self.tap_control.write(data)