import subprocess import configparser import re import json import requests from ast import literal_eval OBFS_REGEX = re.compile(r'^ServerTransportPlugin (obfs\d+|scramblesuit)') FTEPROXY_REGEX = re.compile(r'^ServerTransportPlugin fte') FLASHPROXY_REGEX = re.compile(r'^ServerTransportPlugin websocket') MEEKPROXY_REGEX = re.compile(r'^ServerTransportPlugin meek') IP_REGEX = re.compile(r'^(OutboundBindAddress)\ (\d{1,3}\.\d{1,3}\.\d{1,3}\.' r'\d{1,3})') def read_tor_config(configfile='/etc/tor/torrc'): with open(configfile) as fb: lines = {line[:-1] for line in fb if not line.startswith('#')} lines = {line for line in filter(None, lines)} return lines def get_tor_status(name='tor'): try: pids = subprocess.check_output(['pidof', 'tor']).decode('utf-8')[:-1] pids = pids.split(' ') pid_file = '.'.join([name, 'pid']) pid = open('/'.join(['/var', 'run', 'tor', pid_file])).readline()[:-1] if str(pid) in pids: return 'Online' else: return 'Offline' except subprocess.CalledProcessError: return 'Offline' def get_tor_fingerprint(name='tor'): fingerprint_file = '/'.join(['/var', 'lib', name, 'fingerprint']) with open(fingerprint_file) as fb: line = fb.readline()[:-1] hostname, fingerprint = line.split(' ') return hostname, fingerprint def get_server_type(tor_config): if 'BridgeRelay 1' in tor_config: return 'Bridge' elif 'ExitPolicy reject *:*' in tor_config: return 'Relay', None else: return 'Exit', None def get_obfs_proxy(tor_config): return any(OBFS_REGEX.match(i) for i in tor_config) def get_fte_proxy(tor_config): return any(FTEPROXY_REGEX.match(i) for i in tor_config) def get_flash_proxy(tor_config): return any(FLASHPROXY_REGEX.match(i) for i in tor_config) def get_meek_proxy(tor_config): return any(MEEKPROXY_REGEX.match(i) for i in tor_config) def get_ip(tor_config): for i in tor_config: match = IP_REGEX.match(i) if match is not None: return match.groups()[1] return None def get_config(): config = configparser.ConfigParser() config.read('/etc/ennstatus_updater.conf') return config def create_server_json(tor_configfile='/etc/tor/torrc', name='tor'): tor_config = read_tor_config(tor_configfile) server_type = get_server_type(tor_config) hostname, fingerprint = get_tor_fingerprint(name) tor_status = get_tor_status(name) ip = get_ip(tor_config) obfs = None fte = None flash = None meek = None if server_type == 'Bridge': obfs = get_obfs_proxy(tor_config) fte = get_fte_proxy(tor_config) flash = get_flash_proxy(tor_config) meek = get_meek_proxy(tor_config) dictionary = {'server_type': server_type, 'server_name': hostname, 'tor_status': tor_status, 'fingerprint': fingerprint} if ip is not None: dictionary['ip'] = ip if obfs is not None: dictionary['obfs'] = obfs if fte is not None: dictionary['fteproxy'] = fte if flash is not None: dictionary['flashproxy'] = flash if meek is not None: dictionary['meek'] = meek return dictionary def update_server(server_json, url): headers = {'Content-type': 'application/json', 'Accept': 'text/plain'} response = requests.post(url + '/api/update', data=json.dumps(server_json), headers=headers) return response.text def main(): config = get_config() ennstatus_url = config['main']['ennstatus_url'] if 'servers' in config['main']: for server in literal_eval(config['main']['servers']): server_json = create_server_json(config[server]['configfile'], server) response = update_server(server_json, ennstatus_url) print(response, end='') else: server_json = create_server_json() response = update_server(server_json, ennstatus_url) print(response, end='') if __name__ == '__main__': main()