Compare commits

...

18 commits

Author SHA1 Message Date
canewsin
d7759673bc v0.8.5(4625) 2023-02-22 22:19:22 +05:30
Seto
a6f0ece23c Fix openssl error in windows. 2023-02-22 22:19:22 +05:30
canewsin
bada2bdb5d Use default theme-class for corrupt users.json file
where settings key is missing etc
Fixes Ui.UiServer Error 500: UiWSGIHandler error
2023-02-22 22:19:22 +05:30
canewsin
523951f85c Update Stats Plugin 2023-02-22 22:19:22 +05:30
canewsin
588442e20e v0.8.4(4620) 2023-02-22 22:19:22 +05:30
canewsin
4bb00d8d0e Increase Def Min Site Size to 25MB 2023-02-22 22:19:22 +05:30
canewsin
0fe65b2dbc v0.8.3(4611) 2023-02-22 22:19:22 +05:30
canewsin
edd7675226 ContentManager.py Improve Logging of Valid Signers 2023-02-22 22:19:22 +05:30
canewsin
dba0f7d9c8 SiteStrorage.py -> Fix accessing unassigned varible 2023-02-22 22:19:22 +05:30
canewsin
02d7305004 ContentManager -> Support for multiSig 2023-02-22 22:19:22 +05:30
canewsin
8fe92df625 main.py -> Fix accessing unassigned varible 2023-02-22 22:19:22 +05:30
canewsin
112718ffe4 v0.8.2(4610) 2023-02-22 22:19:22 +05:30
canewsin
62970de60b Config:: Skip loading missing tracker files 2023-02-22 22:19:22 +05:30
canewsin
57e840b6ad Move trackers to seperate file & Add more trackers 2023-02-22 22:19:22 +05:30
canewsin
3121aad206 Fix Startup Error when plugins dir missing 2023-02-22 22:19:21 +05:30
Ganesh Chowdary Nune
3fdcef7e46 Added documentation for getRandomPort fn 2023-02-22 22:19:21 +05:30
canewsin
400f2c2fe5 UserManager:: Add Rust Code Impl tracking 2022-10-16 03:40:02 +05:30
canewsin
9455af0cdb User:: Add Rust Code Impl tracking 2022-10-16 03:36:42 +05:30
14 changed files with 236 additions and 57 deletions

View file

@ -1,3 +1,23 @@
### ZeroNet 0.8.5 (2023-02-12) Rev4625
- Fix(https://github.com/ZeroNetX/ZeroNet/pull/202) for SSL cert gen failed on Windows.
- default theme-class for missing value in `users.json`.
- Fetch Stats Plugin changes.
### ZeroNet 0.8.4 (2022-12-12) Rev4620
- Increase Minimum Site size to 25MB.
### ZeroNet 0.8.3 (2022-12-11) Rev4611
- main.py -> Fix accessing unassigned varible
- ContentManager -> Support for multiSig
- SiteStrorage.py -> Fix accessing unassigned varible
- ContentManager.py Improve Logging of Valid Signers
### ZeroNet 0.8.2 (2022-11-01) Rev4610
- Fix Startup Error when plugins dir missing
- Move trackers to seperate file & Add more trackers
- Config:: Skip loading missing tracker files
- Added documentation for getRandomPort fn
### ZeroNet 0.8.1 (2022-10-01) Rev4600 ### ZeroNet 0.8.1 (2022-10-01) Rev4600
- fix readdress loop (cherry-pick previously added commit from conservancy) - fix readdress loop (cherry-pick previously added commit from conservancy)
- Remove Patreon badge - Remove Patreon badge

@ -1 +1 @@
Subproject commit 859ffbf43335796e225525ff01257711485088d9 Subproject commit 412d37030beca51244741e138b5f6d97f8f1a652

View file

@ -13,8 +13,8 @@ import time
class Config(object): class Config(object):
def __init__(self, argv): def __init__(self, argv):
self.version = "0.8.1-patch" self.version = "0.8.5"
self.rev = 4601 self.rev = 4625
self.argv = argv self.argv = argv
self.action = None self.action = None
self.test_parser = None self.test_parser = None
@ -36,7 +36,7 @@ class Config(object):
self.openssl_lib_file = None self.openssl_lib_file = None
self.openssl_bin_file = None self.openssl_bin_file = None
self.trackers_file = ["{data_dir}/1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d/trackers.txt"] self.trackers_file = False
self.createParser() self.createParser()
self.createArguments() self.createArguments()
@ -81,34 +81,7 @@ class Config(object):
def createArguments(self): def createArguments(self):
from Crypt import CryptHash from Crypt import CryptHash
access_key_default = CryptHash.random(24, "base64") # Used to allow restrited plugins when multiuser plugin is enabled access_key_default = CryptHash.random(24, "base64") # Used to allow restrited plugins when multiuser plugin is enabled
trackers = [ trackers = []
"http://open.acgnxtracker.com:80/announce", # DE
"http://tracker.bt4g.com:2095/announce", # Cloudflare
"http://vps02.net.orel.ru:80/announce",
"http://tracker.files.fm:6969/announce",
"http://t.publictracker.xyz:6969/announce",
"https://tracker.lilithraws.cf:443/announce",
"https://tracker.babico.name.tr:443/announce",
"https://tr.abiir.top:443/announce",
"udp://abufinzio.monocul.us:6969/announce",
"udp://vibe.sleepyinternetfun.xyz:1738/announce",
"udp://www.torrent.eu.org:451/announce",
"udp://tracker.0x.tf:6969/announce",
"udp://tracker.zerobytes.xyz:1337/announce",
"udp://tracker.opentrackr.org:1337/announce",
"udp://tracker.birkenwald.de:6969/announce",
"udp://tracker.moeking.me:6969/announce",
"udp://ipv6.babico.name.tr:8000/announce",
"zero://145.239.95.38:15441",
"zero://188.116.183.41:26552",
"zero://45.77.23.92:15555",
"zero://k5w77dozo3hy5zualyhni6vrh73iwfkaofa64abbilwyhhd3wgenbjqd.onion:15441",
"zero://2kcb2fqesyaevc4lntogupa4mkdssth2ypfwczd2ov5a3zo6ytwwbayd.onion:15441",
"zero://gugt43coc5tkyrhrc3esf6t6aeycvcqzw7qafxrjpqbwt4ssz5czgzyd.onion:15441",
"zero://5vczpwawviukvd7grfhsfxp7a6huz77hlis4fstjkym5kmf4pu7i7myd.onion:15441",
"zero://ow7in4ftwsix5klcbdfqvfqjvimqshbm2o75rhtpdnsderrcbx74wbad.onion:15441",
"zero://qn65si4gtcwdiliq7vzrwu62qrweoxb6tx2cchwslaervj6szuje66qd.onion:26117",
]
# Platform specific # Platform specific
if sys.platform.startswith("win"): if sys.platform.startswith("win"):
coffeescript = "type %s | tools\\coffee\\coffee.cmd" coffeescript = "type %s | tools\\coffee\\coffee.cmd"
@ -271,7 +244,7 @@ class Config(object):
self.parser.add_argument('--access_key', help='Plugin access key default: Random key generated at startup', default=access_key_default, metavar='key') self.parser.add_argument('--access_key', help='Plugin access key default: Random key generated at startup', default=access_key_default, metavar='key')
self.parser.add_argument('--dist_type', help='Type of installed distribution', default='source') self.parser.add_argument('--dist_type', help='Type of installed distribution', default='source')
self.parser.add_argument('--size_limit', help='Default site size limit in MB', default=10, type=int, metavar='limit') self.parser.add_argument('--size_limit', help='Default site size limit in MB', default=25, type=int, metavar='limit')
self.parser.add_argument('--file_size_limit', help='Maximum per file size limit in MB', default=10, type=int, metavar='limit') self.parser.add_argument('--file_size_limit', help='Maximum per file size limit in MB', default=10, type=int, metavar='limit')
self.parser.add_argument('--connected_limit', help='Max connected peer per site', default=8, type=int, metavar='connected_limit') self.parser.add_argument('--connected_limit', help='Max connected peer per site', default=8, type=int, metavar='connected_limit')
self.parser.add_argument('--global_connected_limit', help='Max connections', default=512, type=int, metavar='global_connected_limit') self.parser.add_argument('--global_connected_limit', help='Max connections', default=512, type=int, metavar='global_connected_limit')
@ -339,8 +312,7 @@ class Config(object):
def loadTrackersFile(self): def loadTrackersFile(self):
if not self.trackers_file: if not self.trackers_file:
return None self.trackers_file = ["trackers.txt", "{data_dir}/1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d/trackers.txt"]
self.trackers = self.arguments.trackers[:] self.trackers = self.arguments.trackers[:]
for trackers_file in self.trackers_file: for trackers_file in self.trackers_file:
@ -352,6 +324,9 @@ class Config(object):
else: # Relative to zeronet.py else: # Relative to zeronet.py
trackers_file_path = self.start_dir + "/" + trackers_file trackers_file_path = self.start_dir + "/" + trackers_file
if not os.path.exists(trackers_file_path):
continue
for line in open(trackers_file_path): for line in open(trackers_file_path):
tracker = line.strip() tracker = line.strip()
if "://" in tracker and tracker not in self.trackers: if "://" in tracker and tracker not in self.trackers:

View file

@ -727,7 +727,6 @@ class ContentManager(object):
elif "files_optional" in new_content: elif "files_optional" in new_content:
del new_content["files_optional"] del new_content["files_optional"]
new_content["modified"] = int(time.time()) # Add timestamp
if inner_path == "content.json": if inner_path == "content.json":
new_content["zeronet_version"] = config.version new_content["zeronet_version"] = config.version
new_content["signs_required"] = content.get("signs_required", 1) new_content["signs_required"] = content.get("signs_required", 1)
@ -747,9 +746,11 @@ class ContentManager(object):
) )
self.log.info("Correct %s in valid signers: %s" % (privatekey_address, valid_signers)) self.log.info("Correct %s in valid signers: %s" % (privatekey_address, valid_signers))
signs_required = 1
if inner_path == "content.json" and privatekey_address == self.site.address: if inner_path == "content.json" and privatekey_address == self.site.address:
# If signing using the root key, then sign the valid signers # If signing using the root key, then sign the valid signers
signers_data = "%s:%s" % (new_content["signs_required"], ",".join(valid_signers)) signs_required = new_content["signs_required"]
signers_data = "%s:%s" % (signs_required, ",".join(valid_signers))
new_content["signers_sign"] = CryptBitcoin.sign(str(signers_data), privatekey) new_content["signers_sign"] = CryptBitcoin.sign(str(signers_data), privatekey)
if not new_content["signers_sign"]: if not new_content["signers_sign"]:
self.log.info("Old style address, signers_sign is none") self.log.info("Old style address, signers_sign is none")
@ -757,15 +758,32 @@ class ContentManager(object):
self.log.info("Signing %s..." % inner_path) self.log.info("Signing %s..." % inner_path)
if "signs" in new_content: if "signs" in new_content:
del(new_content["signs"]) # Delete old signs # del(new_content["signs"]) # Delete old signs
old_signs_content = new_content["signs"]
del(new_content["signs"])
else:
old_signs_content = None
if "sign" in new_content: if "sign" in new_content:
del(new_content["sign"]) # Delete old sign (backward compatibility) del(new_content["sign"]) # Delete old sign (backward compatibility)
sign_content = json.dumps(new_content, sort_keys=True) if signs_required > 1:
has_valid_sign = False
sign_content = json.dumps(new_content, sort_keys=True)
for signer in valid_signers:
res = CryptBitcoin.verify(sign_content,signer,old_signs_content[signer]);
print(res)
if res:
has_valid_sign = has_valid_sign or res
if has_valid_sign:
new_content["modified"] = content["modified"]
sign_content = json.dumps(new_content, sort_keys=True)
else:
new_content["modified"] = int(time.time()) # Add timestamp
sign_content = json.dumps(new_content, sort_keys=True)
sign = CryptBitcoin.sign(sign_content, privatekey) sign = CryptBitcoin.sign(sign_content, privatekey)
# new_content["signs"] = content.get("signs", {}) # TODO: Multisig # new_content["signs"] = content.get("signs", {}) # TODO: Multisig
if sign: # If signing is successful (not an old address) if sign: # If signing is successful (not an old address)
new_content["signs"] = {} new_content["signs"] = old_signs_content or {}
new_content["signs"][privatekey_address] = sign new_content["signs"][privatekey_address] = sign
self.verifyContent(inner_path, new_content) self.verifyContent(inner_path, new_content)
@ -800,7 +818,9 @@ class ContentManager(object):
# Return: The required number of valid signs for the content.json # Return: The required number of valid signs for the content.json
def getSignsRequired(self, inner_path, content=None): def getSignsRequired(self, inner_path, content=None):
return 1 # Todo: Multisig if not content:
return 1
return content.get("signs_required", 1)
def verifyCertSign(self, user_address, user_auth_type, user_name, issuer_address, sign): def verifyCertSign(self, user_address, user_auth_type, user_name, issuer_address, sign):
from Crypt import CryptBitcoin from Crypt import CryptBitcoin
@ -988,14 +1008,16 @@ class ContentManager(object):
if inner_path != "content.json" and not self.verifyCert(inner_path, new_content): # Check if cert valid if inner_path != "content.json" and not self.verifyCert(inner_path, new_content): # Check if cert valid
raise VerifyError("Invalid cert!") raise VerifyError("Invalid cert!")
valid_signs = 0 valid_signs = []
for address in valid_signers: for address in valid_signers:
if address in signs: if address in signs:
valid_signs += CryptBitcoin.verify(sign_content, address, signs[address]) result = CryptBitcoin.verify(sign_content, address, signs[address])
if valid_signs >= signs_required: if result:
valid_signs.append(address)
if len(valid_signs) >= signs_required:
break # Break if we has enough signs break # Break if we has enough signs
if valid_signs < signs_required: if len(valid_signs) < signs_required:
raise VerifyError("Valid signs: %s/%s" % (valid_signs, signs_required)) raise VerifyError("Valid signs: %s/%s, Valid Signers : %s" % (len(valid_signs), signs_required, valid_signs))
else: else:
return self.verifyContent(inner_path, new_content) return self.verifyContent(inner_path, new_content)
else: # Old style signing else: # Old style signing

View file

@ -127,6 +127,10 @@ class CryptConnectionManager:
"/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA" "/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA"
] ]
self.openssl_env['CN'] = random.choice(self.fakedomains) self.openssl_env['CN'] = random.choice(self.fakedomains)
environ = os.environ
environ['OPENSSL_CONF'] = self.openssl_env['OPENSSL_CONF']
environ['RANDFILE'] = self.openssl_env['RANDFILE']
environ['CN'] = self.openssl_env['CN']
if os.path.isfile(self.cert_pem) and os.path.isfile(self.key_pem): if os.path.isfile(self.cert_pem) and os.path.isfile(self.key_pem):
self.createSslContexts() self.createSslContexts()
@ -152,7 +156,7 @@ class CryptConnectionManager:
self.log.debug("Running: %s" % cmd) self.log.debug("Running: %s" % cmd)
proc = subprocess.Popen( proc = subprocess.Popen(
cmd, shell=True, stderr=subprocess.STDOUT, cmd, shell=True, stderr=subprocess.STDOUT,
stdout=subprocess.PIPE, env=self.openssl_env stdout=subprocess.PIPE, env=environ
) )
back = proc.stdout.read().strip().decode(errors="replace").replace("\r", "") back = proc.stdout.read().strip().decode(errors="replace").replace("\r", "")
proc.wait() proc.wait()
@ -175,7 +179,7 @@ class CryptConnectionManager:
self.log.debug("Generating certificate key and signing request...") self.log.debug("Generating certificate key and signing request...")
proc = subprocess.Popen( proc = subprocess.Popen(
cmd, shell=True, stderr=subprocess.STDOUT, cmd, shell=True, stderr=subprocess.STDOUT,
stdout=subprocess.PIPE, env=self.openssl_env stdout=subprocess.PIPE, env=environ
) )
back = proc.stdout.read().strip().decode(errors="replace").replace("\r", "") back = proc.stdout.read().strip().decode(errors="replace").replace("\r", "")
proc.wait() proc.wait()
@ -194,7 +198,7 @@ class CryptConnectionManager:
self.log.debug("Generating RSA cert...") self.log.debug("Generating RSA cert...")
proc = subprocess.Popen( proc = subprocess.Popen(
cmd, shell=True, stderr=subprocess.STDOUT, cmd, shell=True, stderr=subprocess.STDOUT,
stdout=subprocess.PIPE, env=self.openssl_env stdout=subprocess.PIPE, env=environ
) )
back = proc.stdout.read().strip().decode(errors="replace").replace("\r", "") back = proc.stdout.read().strip().decode(errors="replace").replace("\r", "")
proc.wait() proc.wait()

View file

@ -72,6 +72,12 @@ class FileServer(ConnectionServer):
self.ui_server = None self.ui_server = None
def getRandomPort(self, ip, port_range_from, port_range_to): def getRandomPort(self, ip, port_range_from, port_range_to):
"""Generates Random Port from given range
Args:
ip: IP Address
port_range_from: From Range
port_range_to: to Range
"""
self.log.info("Getting random port in range %s-%s..." % (port_range_from, port_range_to)) self.log.info("Getting random port in range %s-%s..." % (port_range_from, port_range_to))
tried = [] tried = []
for bind_retry in range(100): for bind_retry in range(100):

View file

@ -16,7 +16,9 @@ import plugins
class PluginManager: class PluginManager:
def __init__(self): def __init__(self):
self.log = logging.getLogger("PluginManager") self.log = logging.getLogger("PluginManager")
self.path_plugins = os.path.abspath(os.path.dirname(plugins.__file__)) self.path_plugins = None
if plugins.__file__:
self.path_plugins = os.path.dirname(os.path.abspath(plugins.__file__));
self.path_installed_plugins = config.data_dir + "/__plugins__" self.path_installed_plugins = config.data_dir + "/__plugins__"
self.plugins = defaultdict(list) # Registered plugins (key: class name, value: list of plugins for class) self.plugins = defaultdict(list) # Registered plugins (key: class name, value: list of plugins for class)
self.subclass_order = {} # Record the load order of the plugins, to keep it after reload self.subclass_order = {} # Record the load order of the plugins, to keep it after reload
@ -32,7 +34,8 @@ class PluginManager:
self.config.setdefault("builtin", {}) self.config.setdefault("builtin", {})
sys.path.append(os.path.join(os.getcwd(), self.path_plugins)) if self.path_plugins:
sys.path.append(os.path.join(os.getcwd(), self.path_plugins))
self.migratePlugins() self.migratePlugins()
if config.debug: # Auto reload Plugins on file change if config.debug: # Auto reload Plugins on file change
@ -127,6 +130,8 @@ class PluginManager:
def loadPlugins(self): def loadPlugins(self):
all_loaded = True all_loaded = True
s = time.time() s = time.time()
if self.path_plugins is None:
return
for plugin in self.listPlugins(): for plugin in self.listPlugins():
self.log.debug("Loading plugin: %s (%s)" % (plugin["name"], plugin["source"])) self.log.debug("Loading plugin: %s (%s)" % (plugin["name"], plugin["source"]))
if plugin["source"] != "builtin": if plugin["source"] != "builtin":

View file

@ -143,7 +143,7 @@ class Site(object):
# Next size limit based on current size # Next size limit based on current size
def getNextSizeLimit(self): def getNextSizeLimit(self):
size_limits = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000] size_limits = [25, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000]
size = self.settings.get("size", 0) size = self.settings.get("size", 0)
for size_limit in size_limits: for size_limit in size_limits:
if size * 1.2 < size_limit * 1024 * 1024: if size * 1.2 < size_limit * 1024 * 1024:

View file

@ -463,7 +463,8 @@ class SiteStorage(object):
else: else:
try: try:
ok = self.site.content_manager.verifyFile(file_inner_path, open(file_path, "rb")) ok = self.site.content_manager.verifyFile(file_inner_path, open(file_path, "rb"))
except Exception as err: except Exception as _err:
err = _err
ok = False ok = False
if not ok: if not ok:

View file

@ -749,7 +749,10 @@ class UiRequest(object):
def replaceHtmlVariables(self, block, path_parts): def replaceHtmlVariables(self, block, path_parts):
user = self.getCurrentUser() user = self.getCurrentUser()
themeclass = "theme-%-6s" % re.sub("[^a-z]", "", user.settings.get("theme", "light")) if user and user.settings:
themeclass = "theme-%-6s" % re.sub("[^a-z]", "", user.settings.get("theme", "light"))
else:
themeclass = "theme-light"
block = block.replace(b"{themeclass}", themeclass.encode("utf8")) block = block.replace(b"{themeclass}", themeclass.encode("utf8"))
if path_parts: if path_parts:

View file

@ -12,7 +12,7 @@ from Config import config
from util import helper from util import helper
from Debug import Debug from Debug import Debug
# Fully Implemented in zeronet-rs::src::core::user.rs
@PluginManager.acceptPlugins @PluginManager.acceptPlugins
class User(object): class User(object):
def __init__(self, master_address=None, master_seed=None, data={}): def __init__(self, master_address=None, master_seed=None, data={}):

View file

@ -8,7 +8,7 @@ from .User import User
from Plugin import PluginManager from Plugin import PluginManager
from Config import config from Config import config
# Fully Implemented in zeronet-rs::src::io::utils.rs & zeronet-rs::src::io::user.rs
@PluginManager.acceptPlugins @PluginManager.acceptPlugins
class UserManager(object): class UserManager(object):
def __init__(self): def __init__(self):

View file

@ -254,8 +254,9 @@ class Actions(object):
file_correct = site.content_manager.verifyFile( file_correct = site.content_manager.verifyFile(
content_inner_path, site.storage.open(content_inner_path, "rb"), ignore_same=False content_inner_path, site.storage.open(content_inner_path, "rb"), ignore_same=False
) )
except Exception as err: except Exception as exp:
file_correct = False file_correct = False
err = exp
if file_correct is True: if file_correct is True:
logging.info("[OK] %s (Done in %.3fs)" % (content_inner_path, time.time() - s)) logging.info("[OK] %s (Done in %.3fs)" % (content_inner_path, time.time() - s))

142
trackers.txt Normal file
View file

@ -0,0 +1,142 @@
udp://tracker.opentrackr.org:1337/announce
udp://explodie.org:6969/announce
udp://open.stealth.si:80/announce
http://tracker.ipv6tracker.ru:80/announce
udp://tracker.birkenwald.de:6969/announce
udp://tracker.moeking.me:6969/announce
http://tracker.bt4g.com:2095/announce
https://tracker.nanoha.org:443/announce
http://tracker.files.fm:6969/announce
http://open.acgnxtracker.com:80/announce
udp://tracker.army:6969/announce
udp://fe.dealclub.de:6969/announce
udp://tracker.leech.ie:1337/announce
udp://tracker.altrosky.nl:6969/announce
https://tracker.cyber-hub.net:443/announce
https://tracker.lilithraws.cf:443/announce
http://bt.okmp3.ru:2710/announce
udp://vibe.sleepyinternetfun.xyz:1738/announce
udp://open.publictracker.xyz:6969/announce
udp://tracker.bitsearch.to:1337/announce
udp://tracker.pomf.se:80/announce
https://tr.burnabyhighstar.com:443/announce
https://tr.abiir.top:443/announce
udp://open.free-tracker.ga:6969/announce
http://i-p-v-6.tk:6969/announce
http://open-v6.demonoid.ch:6969/announce
udp://aarsen.me:6969/announce
udp://htz3.noho.st:6969/announce
udp://uploads.gamecoast.net:6969/announce
udp://mail.zasaonsk.ga:6969/announce
udp://tracker.joybomb.tw:6969/announce
udp://tracker.jonaslsa.com:6969/announce
udp://leefafa.tk:6969/announce
udp://carr.codes:6969/announce
https://tr.fuckbitcoin.xyz:443/announce
udp://tracker.cubonegro.xyz:6969/announce
udp://tracker.skynetcloud.site:6969/announce
http://tracker4.itzmx.com:2710/announce
https://tracker.lilithraws.org:443/announce
udp://tracker.novaopcj.eu.org:6969/announce
udp://exodus.desync.com:6969/announce
http://t.acg.rip:6699/announce
udp://tracker2.dler.com:80/announce
udp://6ahddutb1ucc3cp.ru:6969/announce
udp://tracker.blacksparrowmedia.net:6969/announce
http://fxtt.ru:80/announce
udp://tracker.auctor.tv:6969/announce
udp://torrentclub.space:6969/announce
udp://zecircle.xyz:6969/announce
udp://psyco.fr:6969/announce
udp://fh2.cmp-gaming.com:6969/announce
udp://new-line.net:6969/announce
udp://torrents.artixlinux.org:6969/announce
udp://bt.ktrackers.com:6666/announce
udp://static.54.161.216.95.clients.your-server.de:6969/announce
udp://cpe-104-34-3-152.socal.res.rr.com:6969/announce
http://t.overflow.biz:6969/announce
udp://tracker1.myporn.club:9337/announce
udp://moonburrow.club:6969/announce
udp://tracker.artixlinux.org:6969/announce
https://t1.hloli.org:443/announce
udp://bt1.archive.org:6969/announce
udp://tracker.theoks.net:6969/announce
udp://tracker.4.babico.name.tr:3131/announce
udp://buddyfly.top:6969/announce
udp://ipv6.tracker.harry.lu:80/announce
udp://public.publictracker.xyz:6969/announce
udp://mail.artixlinux.org:6969/announce
udp://v1046920.hosted-by-vdsina.ru:6969/announce
udp://tracker.cyberia.is:6969/announce
udp://tracker.beeimg.com:6969/announce
udp://creative.7o7.cx:6969/announce
udp://open.dstud.io:6969/announce
udp://laze.cc:6969/announce
udp://download.nerocloud.me:6969/announce
udp://cutscloud.duckdns.org:6969/announce
https://tracker.jiesen.life:8443/announce
udp://jutone.com:6969/announce
udp://wepzone.net:6969/announce
udp://ipv4.tracker.harry.lu:80/announce
udp://tracker.tcp.exchange:6969/announce
udp://f1sh.de:6969/announce
udp://movies.zsw.ca:6969/announce
https://tracker1.ctix.cn:443/announce
udp://sanincode.com:6969/announce
udp://www.torrent.eu.org:451/announce
udp://open.4ever.tk:6969/announce
https://tracker2.ctix.cn:443/announce
udp://bt2.archive.org:6969/announce
http://t.nyaatracker.com:80/announce
udp://yahor.ftp.sh:6969/announce
udp://tracker.openbtba.com:6969/announce
udp://tracker.dler.com:6969/announce
udp://tracker-udp.gbitt.info:80/announce
udp://tracker.srv00.com:6969/announce
udp://tracker.pimpmyworld.to:6969/announce
http://tracker.gbitt.info:80/announce
udp://tracker6.lelux.fi:6969/announce
http://tracker.vrpnet.org:6969/announce
http://00.xxtor.com:443/announce
http://vps02.net.orel.ru:80/announce
udp://tracker.yangxiaoguozi.cn:6969/announce
udp://rep-art.ynh.fr:6969/announce
https://tracker.imgoingto.icu:443/announce
udp://mirror.aptus.co.tz:6969/announce
udp://tracker.lelux.fi:6969/announce
udp://tracker.torrent.eu.org:451/announce
udp://admin.52ywp.com:6969/announce
udp://thouvenin.cloud:6969/announce
http://vps-dd0a0715.vps.ovh.net:6969/announce
udp://bubu.mapfactor.com:6969/announce
udp://94-227-232-84.access.telenet.be:6969/announce
udp://epider.me:6969/announce
udp://camera.lei001.com:6969/announce
udp://tamas3.ynh.fr:6969/announce
https://tracker.tamersunion.org:443/announce
udp://ftp.pet:2710/announce
udp://p4p.arenabg.com:1337/announce
http://tracker.mywaifu.best:6969/announce
udp://tracker.monitorit4.me:6969/announce
udp://ipv6.tracker.monitorit4.me:6969/announce
zero://k5w77dozo3hy5zualyhni6vrh73iwfkaofa64abbilwyhhd3wgenbjqd.onion:15441
zero://2kcb2fqesyaevc4lntogupa4mkdssth2ypfwczd2ov5a3zo6ytwwbayd.onion:15441
zero://5vczpwawviukvd7grfhsfxp7a6huz77hlis4fstjkym5kmf4pu7i7myd.onion:15441
zero://pn4q2zzt2pw4nk7yidxvsxmydko7dfibuzxdswi6gu6ninjpofvqs2id.onion:15441
zero://6i54dd5th73oelv636ivix6sjnwfgk2qsltnyvswagwphub375t3xcad.onion:15441
zero://tl74auz4tyqv4bieeclmyoe4uwtoc2dj7fdqv4nc4gl5j2bwg2r26bqd.onion:15441
zero://wlxav3szbrdhest4j7dib2vgbrd7uj7u7rnuzg22cxbih7yxyg2hsmid.onion:15441
zero://zy7wttvjtsijt5uwmlar4yguvjc2gppzbdj4v6bujng6xwjmkdg7uvqd.onion:15441
zero://rlcjomszyitxpwv7kzopmqgzk3bdpsxeull4c3s6goszkk6h2sotfoad.onion:15441
zero://gugt43coc5tkyrhrc3esf6t6aeycvcqzw7qafxrjpqbwt4ssz5czgzyd.onion:15441
zero://ow7in4ftwsix5klcbdfqvfqjvimqshbm2o75rhtpdnsderrcbx74wbad.onion:15441
zero://57hzgtu62yzxqgbvgxs7g3lfck3za4zrda7qkskar3tlak5recxcebyd.onion:15445
zero://hb6ozikfiaafeuqvgseiik4r46szbpjfu66l67wjinnyv6dtopuwhtqd.onion:15445
zero://qn65si4gtcwdiliq7vzrwu62qrweoxb6tx2cchwslaervj6szuje66qd.onion:26117
zero://s3j2s5pjdfesbsmaqx6alsumaxxdxibmhv4eukmqpv3vqj6f627qx5yd.onion:15441
zero://agufghdtniyfwty3wk55drxxwj2zxgzzo7dbrtje73gmvcpxy4ngs4ad.onion:15441
zero://kgsvasoakvj4gnjiy7zemu34l3hq46dn5eauqkn76jpowmilci5t2vqd.onion:15445
zero://dslesoe72bdfwfu4cfqa2wpd4hr3fhlu4zv6mfsjju5xlpmssouv36qd.onion:15441
zero://f2hnjbggc3c2u2apvxdugirnk6bral54ibdoul3hhvu7pd4fso5fq3yd.onion:15441
zero://skdeywpgm5xncpxbbr4cuiip6ey4dkambpanog6nruvmef4f3e7o47qd.onion:15441
zero://tqmo2nffqo4qc5jgmz3me5eri3zpgf3v2zciufzmhnvznjve5c3argad.onion:15441