def _draw_address_column(subwindow, x, y, line, attr): src = tor_controller().get_info('address', line.connection.local_address) if line.line_type == LineType.CONNECTION: src = '%s:%s' % (src, line.connection.local_port) if line.line_type == LineType.CIRCUIT_HEADER and line.circuit.status != 'BUILT': dst = 'Building...' else: dst = '<scrubbed>' if line.entry.is_private( ) else line.connection.remote_address dst += ':%s' % line.connection.remote_port if line.entry.get_type() == Category.EXIT: purpose = connection.port_usage(line.connection.remote_port) if purpose: dst += ' (%s)' % str_tools.crop(purpose, 26 - len(dst) - 3) elif not tor_controller().is_geoip_unavailable( ) and not line.entry.is_private(): dst += ' (%s)' % (line.locale if line.locale else '??') src = '%-21s' % src dst = '%-21s' % dst if tor_controller().is_geoip_unavailable( ) else '%-26s' % dst if line.entry.get_type() in (Category.INBOUND, Category.SOCKS, Category.CONTROL): dst, src = src, dst if line.line_type == LineType.CIRCUIT: return subwindow.addstr(x, y, dst, *attr) else: return subwindow.addstr(x, y, '%s --> %s' % (src, dst), *attr)
def _draw_address_column(subwindow, x, y, line, attr): src = tor_controller().get_info('address', line.connection.local_address) src += ':%s' % line.connection.local_port if line.line_type == LineType.CONNECTION else '' if line.line_type == LineType.CIRCUIT_HEADER and line.circuit.status != 'BUILT': dst = 'Building...' else: dst = '<scrubbed>' if line.entry.is_private() else line.connection.remote_address dst += ':%s' % line.connection.remote_port if line.entry.get_type() == Category.EXIT: purpose = connection.port_usage(line.connection.remote_port) if purpose: dst += ' (%s)' % str_tools.crop(purpose, 26 - len(dst) - 3) elif not tor_controller().is_geoip_unavailable() and not line.entry.is_private(): dst += ' (%s)' % (line.locale if line.locale else '??') if line.entry.get_type() in (Category.INBOUND, Category.SOCKS, Category.CONTROL): dst, src = src, dst if line.line_type == LineType.CIRCUIT: subwindow.addstr(x, y, dst, *attr) else: subwindow.addstr(x, y, '%-21s --> %-26s' % (src, dst), *attr)
def connections(): global controller args = StaticInfo.args control_port = StaticInfo.control_port controller = StaticInfo.controller if not (controller.is_alive()): return desc = controller.get_network_status(default = None) pid = StaticInfo.pid policy = controller.get_exit_policy() relays = {} # address => [orports...] for desc in controller.get_network_statuses(): relays.setdefault(desc.address, []).append(desc.or_port) exit_connections = {} # port => [connections] for conn in get_connections(resolver = args.resolver, process_pid = pid): global categories if conn.protocol == 'udp': continue if conn.local_port in controller.get_ports(Listener.OR, []): categories['INBOUND_OR'].append(conn) elif conn.local_port in controller.get_ports(Listener.DIR, []): categories['INBOUND_DIR'].append(conn) elif conn.local_port in controller.get_ports(Listener.CONTROL, []): categories['INBOUND_CONTROL'].append(conn) elif conn.remote_port in relays.get(conn.remote_address, []): categories['OUTBOUND'].append(conn) elif policy.can_exit_to(conn.remote_address, conn.remote_port): categories['EXIT'].append(conn) exit_connections.setdefault(conn.remote_port, []).append(conn) else: categories['OUTBOUND'].append(conn) circ = controller.get_circuits([]) for conn in circ: categories['CIRCUIT'].append(conn) if exit_connections: total_ipv4, total_ipv6 = 0, 0 for port in sorted(exit_connections): connections = exit_connections[port] ipv4_count = len([conn for conn in connections if is_valid_ipv4_address(conn.remote_address)]) ipv6_count = len(connections) - ipv4_count total_count = len(connections) total_ipv4, total_ipv6 = total_ipv4 + ipv4_count, total_ipv6 + ipv6_count usage = port_usage(port) label = '%s (%s)' % (port, usage) if usage else port
def _show_exiting_port_usage(): counts = {} key_width = max(map(len, self._exit_port_usage.keys())) for k, v in self._exit_port_usage.items(): usage = connection.port_usage(k) if usage: k = k.ljust(key_width + 3) + usage.ljust(EXIT_USAGE_WIDTH) counts[k] = v nyx.popups.show_counts('Exiting Port Usage', counts)
def handle_key(self, key): user_traffic_allowed = tor_controller().is_user_traffic_allowed() if key.is_scroll(): page_height = self.get_preferred_size()[0] - 1 if self._show_details: page_height -= (DETAILS_HEIGHT + 1) lines = list(itertools.chain.from_iterable([entry.get_lines() for entry in self._entries])) is_changed = self._scroller.handle_key(key, lines, page_height) if is_changed: self.redraw(True) elif key.is_selection(): self._show_details = not self._show_details self.redraw(True) elif key.match('s'): self.show_sort_dialog() elif key.match('r'): connection_tracker = nyx.util.tracker.get_connection_tracker() options = ['auto'] + list(connection.Resolver) resolver = connection_tracker.get_custom_resolver() selected_index = 0 if resolver is None else options.index(resolver) selection = nyx.popups.show_menu('Connection Resolver:', options, selected_index) if selection != -1: connection_tracker.set_custom_resolver(None if selection == 0 else options[selection]) elif key.match('d'): self.set_title_visible(False) self.redraw(True) entries = self._entries while True: lines = list(itertools.chain.from_iterable([entry.get_lines() for entry in entries])) selection = self._scroller.get_cursor_selection(lines) if not selection: break color = CONFIG['attr.connection.category_color'].get(selection.entry.get_type(), 'white') is_close_key = lambda key: key.is_selection() or key.match('d') or key.match('left') or key.match('right') key = nyx.popups.show_descriptor_popup(selection.fingerprint, color, self.max_x, is_close_key) if not key or key.is_selection() or key.match('d'): break # closes popup elif key.match('left'): self.handle_key(panel.KeyInput(curses.KEY_UP)) elif key.match('right'): self.handle_key(panel.KeyInput(curses.KEY_DOWN)) self.set_title_visible(True) self.redraw(True) elif key.match('c') and user_traffic_allowed.inbound: nyx.popups.show_count_dialog('Client Locales', self._client_locale_usage) elif key.match('e') and user_traffic_allowed.outbound: counts = {} key_width = max(map(len, self._exit_port_usage.keys())) for k, v in self._exit_port_usage.items(): usage = connection.port_usage(k) if usage: k = k.ljust(key_width + 3) + usage.ljust(EXIT_USAGE_WIDTH) counts[k] = v nyx.popups.show_count_dialog('Exiting Port Usage', counts) else: return False return True
def main(): ctrlport = 9051 resolver = 'proc' parser = argparse.ArgumentParser() parser.add_argument("--ctrlport", help="default: " + str(ctrlport)) parser.add_argument("--resolver", help="default: " + resolver) args = parser.parse_args() if args.ctrlport: ctrlport = int(args.ctrlport) if args.resolver: resolver= str(args.resolver) with Controller.from_port(port=ctrlport) as controller: controller.authenticate() try: ControlPort = int(controller.get_conf("ControlPort")) ORPort = None ORPort6 = None DirPort = None DirPort6 = None for address, port in controller.get_listeners(Listener.OR): if is_valid_ipv4_address(address): ORPort = port else: ORPort6 = port for address, port in controller.get_listeners(Listener.DIR): if is_valid_ipv4_address(address): DirPort = port else: DirPort6 = port except Exception as Exc: print ("Woops, control ports aren't configured") print (Exc) return # we will ignore changes of relays during the runtime of this script # relays = {} for s in controller.get_network_statuses(): relays.setdefault(s.address, []).append(s.or_port) MaxOpened = {} # hold the maximum amount of opened ports MaxClosed = {} # hold the maximum amount of closed ports MaxAll = {} # hold the maximum amount of overall ports Curr = {} # the current network connections of Tor # avoid useless calculation of mean immediately after start # first = 1 while True: # read in all allowed exit ports # exit_ports = [] for filename in glob.glob("/etc/tor/torrc.d/*") + (glob.glob("/etc/tor/*")): if os.path.isfile(filename): inputfile = open(filename) lines = inputfile.readlines() inputfile.close() for line in lines: if line.startswith("ExitPolicy accept "): for word in line.split(): if '*:' in word: # do consider classX ports port = int (word.split(':')[1]) exit_ports.append(port) try: t1 = time.time() Prev = Curr.copy() Curr.clear() pid = controller.get_info("process/pid") connections = get_connections(resolver=resolver, process_pid=pid,process_name='tor') t2 = time.time() policy = controller.get_exit_policy() for conn in connections: laddr, raddr = conn.local_address, conn.remote_address lport, rport = conn.local_port, conn.remote_port # ignore incoming connections # if (lport == ORPort and laddr == '5.9.158.75') or (lport == ORPort6 and laddr == '2a01:4f8:190:514a::2'): continue if (lport == DirPort and laddr == '5.9.158.75') or (lport == DirPort6 and laddr == '2a01:4f8:190:514a::2'): continue if raddr in relays: if rport in relays[raddr]: continue if not policy.can_exit_to(raddr, rport): continue # store the connections itself instead just counting them here # b/c we have to calculate the diff of 2 sets later # Curr.setdefault(rport, []).append(str(lport)+':'+raddr) if first == 1: Prev = Curr.copy() dt = t2-t1 os.system('clear') print (" port # opened closed max ( %s:%s, %i conns %.2f sec ) " % (resolver, ctrlport, len(connections), dt)) lines = 0; ports = set(list(Curr.keys()) + list(Prev.keys()) + list(MaxAll.keys())) for port in sorted(ports): if port in Prev: p = set(Prev[port]) else: p = set({}) if port in Curr: c = set(Curr[port]) else: c = set({}) n_curr = len(c) n_opened = len(c-p) n_closed = len(p-c) MaxAll.setdefault(port, 0) MaxOpened.setdefault(port, 0) MaxClosed.setdefault(port, 0) if first == 0: if MaxAll[port] < n_curr: MaxAll[port] = n_curr if MaxOpened[port] < n_opened: MaxOpened[port] = n_opened if MaxClosed[port] < n_closed: MaxClosed[port] = n_closed stri = " %5i %5i %6i %6i %6i %6i %6i (%s)" % (port, n_curr, n_opened, n_closed, MaxAll[port], MaxOpened[port], MaxClosed[port], port_usage(port)) print (stri.replace(' 0', ' ')) lines += 1 if lines % 5 == 0: print first = 0 except KeyboardInterrupt: break
def main(args=None): parser = argparse.ArgumentParser() parser.add_argument('--ctrlport', help='default: 9051 or 9151') parser.add_argument('--resolver', help='default: autodetected') args = parser.parse_args(args) control_port = int(args.ctrlport) if args.ctrlport else 'default' controller = stem.connection.connect(control_port=('127.0.0.1', control_port)) if not controller: return desc = controller.get_network_status(default=None) pid = controller.get_pid() print( HEADER_LINE.format( version=str(controller.get_version()).split()[0], uptime=stem.util.str_tools.short_time_label( time.time() - stem.util.system.start_time(pid)), flags=', '.join(desc.flags if desc else ['none']), )) policy = controller.get_exit_policy() relays = {} # address => [orports...] for desc in controller.get_network_statuses(): relays.setdefault(desc.address, []).append(desc.or_port) # categorize our connections categories = collections.OrderedDict(( (INBOUND_ORPORT, []), (INBOUND_DIRPORT, []), (INBOUND_CONTROLPORT, []), (OUTBOUND_ORPORT, []), (OUTBOUND_EXIT, []), (OUTBOUND_UNKNOWN, []), )) exit_connections = {} # port => [connections] for conn in get_connections(resolver=args.resolver, process_pid=pid): if conn.protocol == 'udp': continue if conn.local_port in controller.get_ports(Listener.OR, []): categories[INBOUND_ORPORT].append(conn) elif conn.local_port in controller.get_ports(Listener.DIR, []): categories[INBOUND_DIRPORT].append(conn) elif conn.local_port in controller.get_ports(Listener.CONTROL, []): categories[INBOUND_CONTROLPORT].append(conn) elif conn.remote_port in relays.get(conn.remote_address, []): categories[OUTBOUND_ORPORT].append(conn) elif policy.can_exit_to(conn.remote_address, conn.remote_port): categories[OUTBOUND_EXIT].append(conn) exit_connections.setdefault(conn.remote_port, []).append(conn) else: categories[OUTBOUND_UNKNOWN].append(conn) print(DIV) print(COLUMN % ('Type', 'IPv4', 'IPv6')) print(DIV) total_ipv4, total_ipv6 = 0, 0 for label, connections in categories.items(): if len(connections) == 0: continue ipv4_count = len([ conn for conn in connections if is_valid_ipv4_address(conn.remote_address) ]) ipv6_count = len(connections) - ipv4_count total_ipv4, total_ipv6 = total_ipv4 + ipv4_count, total_ipv6 + ipv6_count print(COLUMN % (label, ipv4_count, ipv6_count)) print(DIV) print(COLUMN % ('Total', total_ipv4, total_ipv6)) print(DIV) print('') if exit_connections: print(DIV) print(COLUMN % ('Exit Port', 'IPv4', 'IPv6')) print(DIV) total_ipv4, total_ipv6 = 0, 0 for port in sorted(exit_connections): connections = exit_connections[port] ipv4_count = len([ conn for conn in connections if is_valid_ipv4_address(conn.remote_address) ]) ipv6_count = len(connections) - ipv4_count total_ipv4, total_ipv6 = total_ipv4 + ipv4_count, total_ipv6 + ipv6_count usage = port_usage(port) label = '%s (%s)' % (port, usage) if usage else port print(COLUMN % (label, ipv4_count, ipv6_count)) print(DIV) print(COLUMN % ('Total', total_ipv4, total_ipv6)) print(DIV) print('')
def main(): parser = argparse.ArgumentParser() parser.add_argument('--ctrlport', type=int, help='default: 9051', default=9051) parser.add_argument('--resolver', help='default: autodetect', default='') args = parser.parse_args() with Controller.from_port(port=args.ctrlport) as controller: controller.authenticate() try: ORPort = None ORPort6 = None for address, port in controller.get_listeners(Listener.OR): if is_valid_ipv4_address(address): ORPort = port else: ORPort6 = port except Exception as Exc: print('Woops, control ports aren\'t configured') print(Exc) return relays = {} # address => [orports...] relays = parse_consensus(relays, '/var/lib/tor/data/cached-consensus') relays = parse_consensus(relays, '/var/lib/tor/data2/cached-consensus') MaxOpened = {} # hold the maximum amount of opened ports MaxClosed = {} # hold the maximum amount of closed ports MaxAll = {} # hold the maximum amount of overall ports Curr = {} # the current network connections of Tor # avoid useless calculation of mean immediately after start # first = True while True: # read in all allowed exit ports # exit_ports = [] for filename in glob.glob('/etc/tor/torrc.d/*') + ( glob.glob('/etc/tor/*')): if os.path.isfile(filename): inputfile = open(filename) lines = inputfile.readlines() inputfile.close() for line in lines: if line.startswith('ExitPolicy *accept '): accept = line.split()[2] if ':' in accept: port = accept.split(':')[1] if '-' in port: min = port.split('-')[0] max = port.split('-')[1] for port in range(int(min), int(max)): exit_ports.append(port) else: exit_ports.append(port) try: t1 = time.time() pid = controller.get_info('process/pid') connections = get_connections(resolver=args.resolver, process_pid=pid, process_name='tor') t2 = time.time() policy = controller.get_exit_policy() if not first: Prev = Curr.copy() Curr.clear() my_ipv4 = '5.9.158.75' my_ipv6 = ipaddress.IPv6Address( '2a01:4f8:190:514a::2').exploded for conn in connections: laddr, raddr = conn.local_address, conn.remote_address lport, rport = conn.local_port, conn.remote_port # ignore incoming connections # if conn.is_ipv6: if lport == ORPort6: if laddr == my_ipv6: continue else: if lport == ORPort: if laddr == my_ipv4: continue if raddr in relays: if rport in relays[raddr]: continue if not policy.can_exit_to(raddr, rport): continue # store the connections itself instead just counting them here # b/c we have to calculate the diff of 2 sets later too # Curr.setdefault(rport, []).append(str(lport) + ':' + raddr) dt = t2 - t1 os.system('clear') print( ' port # opened closed max ( %s:%s, %i conns %.2f sec )' % (args.resolver, args.ctrlport, len(connections), dt)) if first: Prev = Curr.copy() ports = sorted( set( list(Curr.keys()) + list(Prev.keys()) + list(MaxAll.keys()))) for port in ports: c = set({}) p = set({}) if port in Prev: p = set(Prev[port]) if port in Curr: c = set(Curr[port]) n_curr = len(c) n_opened = len(c - p) n_closed = len(p - c) MaxAll.setdefault(port, 0) MaxOpened.setdefault(port, 0) MaxClosed.setdefault(port, 0) if not first: if MaxAll[port] < n_curr: MaxAll[port] = n_curr if MaxOpened[port] < n_opened: MaxOpened[port] = n_opened if MaxClosed[port] < n_closed: MaxClosed[port] = n_closed stri = ' %5i %5i %6i %6i %6i %6i %6i (%s)' % ( port, n_curr, n_opened, n_closed, MaxAll[port], MaxOpened[port], MaxClosed[port], port_usage(port)) print(stri.replace(' 0', ' ')) first = False except KeyboardInterrupt: break except Exception: continue
def main(): ctrlport = 9051 resolver = 'proc' #handler = logging.FileHandler('/tmp/stem_debug') #handler.setFormatter(logging.Formatter( #fmt = '%(asctime)s [%(levelname)s] %(message)s', #datefmt = '%m/%d/%Y %H:%M:%S', #)) #log = stem.util.log.get_logger() #log.setLevel(logging.DEBUG) #log.addHandler(handler) #stem.util.connection.LOG_CONNECTION_RESOLUTION = True parser = argparse.ArgumentParser() parser.add_argument("--ctrlport", help="default: " + str(ctrlport)) parser.add_argument("--resolver", help="default: " + resolver) args = parser.parse_args() if args.ctrlport: ctrlport = int(args.ctrlport) if args.resolver: resolver= str(args.resolver) with Controller.from_port(port=ctrlport) as controller: controller.authenticate() try: ControlPort = int(controller.get_conf("ControlPort")) ORPort = None ORPort6 = None DirPort = None DirPort6 = None for address, port in controller.get_listeners(Listener.OR): if is_valid_ipv4_address(address): ORPort = port else: ORPort6 = port for address, port in controller.get_listeners(Listener.DIR): if is_valid_ipv4_address(address): DirPort = port else: DirPort6 = port except Exception as Exc: print ("Woops, control ports aren't configured") return # our version, uptime and flags # version = str(controller.get_version()).split()[0] uptime = 0 flags = '' try: descriptor = controller.get_server_descriptor() uptime = descriptor.uptime flags = controller.get_network_status(relay=descriptor.fingerprint).flags except Exception as Exc: print (Exc) print (" %s %s %s" % (version, datetime.timedelta(seconds=uptime), " ".join(flags))) policy = controller.get_exit_policy() pid = controller.get_info("process/pid") connections = get_connections(resolver=resolver,process_pid=pid,process_name='tor') print (" resolver=%s pid=%s conns=%i" % (resolver, pid, len(connections))) relaysOr = {} relaysDir = {} for s in controller.get_network_statuses(): relaysOr.setdefault(s.address, []).append(s.or_port) relaysDir.setdefault(s.address, []).append(s.dir_port) # classify network connections by port and relationship to the Tor relay # ports_int = {} ports_ext = {} def inc_ports (ports, t): v4, v6 = ports.get(t,(0,0)) if conn.is_ipv6: ports[t] = (v4, v6+1) else: ports[t] = (v4+1, v6) def inc_ports_int (description): t = (description) inc_ports (ports_int, t) def inc_ports_ext (description): t = (description, rport) inc_ports (ports_ext, t) # classify each connection # for conn in connections: if conn.protocol == 'udp': continue laddr, raddr = conn.local_address, conn.remote_address lport, rport = conn.local_port, conn.remote_port if raddr in relaysOr: if (lport == ORPort and not conn.is_ipv6) or (lport == ORPort6 and conn.is_ipv6): inc_ports_int('ORPort <= relay') elif (lport == DirPort and not conn.is_ipv6) or (lport == DirPort6 and conn.is_ipv6): inc_ports_int('DirPort <= relay') elif rport in relaysOr[raddr]: inc_ports_int('=> relay ORPort') elif rport in relaysDir[raddr]: inc_ports_int('=> relay DirPort') else: # a system hosts beside a Tor relay another service too # inc_ports_ext ('=> relay port') elif policy.can_exit_to(raddr, rport): inc_ports_ext ('=> exit') else: if (lport == ORPort and not conn.is_ipv6) or (lport == ORPort6 and conn.is_ipv6): inc_ports_int('ORPort <= outer') elif (lport == DirPort and not conn.is_ipv6) or (lport == DirPort6 and conn.is_ipv6): inc_ports_int('DirPort <= outer') elif lport == ControlPort: inc_ports_int('CtrlPort <= local') else: inc_ports_ext ('=> non exit port') print () print (' description port ipv4 ipv6 servicename') print (' ----------------- ----- ---- ---- -------------') sum4 = 0 sum6 = 0 for t in sorted(ports_int): description = t v4, v6 = ports_int[t] sum4 += v4 sum6 += v6 print (" %-17s %5s %5s %5s" % (description, '', str(v4) if v4 > 0 else '', str(v6) if v6 > 0 else '')) print ("") exit4 = 0 exit6 = 0 for t in sorted(ports_ext): description, port = t v4, v6 = ports_ext[t] sum4 += v4 sum6 += v6 if description == '=> exit': exit4 += v4 exit6 += v6 print (" %-17s %5i %5s %5s %s" % (description, port, str(v4) if v4 > 0 else '', str(v6) if v6 > 0 else '', port_usage(port))) print ("") print (" %17s %5s %5i %5i" % ('sum', '', sum4, sum6)) print (" %17s %5s %5i %5i" % ('exits among them', '', exit4, exit6))