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)
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)
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)
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("Сервер остановлен")
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)