Torrust-Actix Tracker is a lightweight but incredibly powerful and feature-rich BitTorrent Tracker made using Rust.
Currently, it's being actively used at https://www.gbitt.info/.
This project originated from Torrust-Tracker code originally developed by Mick van Dijke, further developed by Power2All as alternative for OpenTracker and other tracker code available on GitHub.
- Block array for TCP tracking (HTTP/HTTPS), UDP tracking and API (HTTP/HTTPS)
- Full IPv4 and IPv6 support
- Persistence saving supported using SQLite3, MySQL or PostgresSQL database
- Customize table and database structure in the configuration
- Whitelist system for private tracking
- Blacklist system for blocking unwelcome hashes
- Torrent key support for locking access to announcement through keys as info_hash with a timeout
- User account support, configurable for also database support
- Swagger UI built-in in the API (toggleable), useful both for testing API and documentation for API
- Sentry SaaS and self-hosted support
- Full Stand-Alone/Master/Slave cluster mode
- Optional Redis/Memcache Caching for peers data (can be used to show on a website for instance, to less burden SQL)
- Cloudflare's "Simple Proxy Protocol" support added (https://developers.cloudflare.com/spectrum/how-to/enable-proxy-protocol/#enable-simple-proxy-protocol-for-udp)
- RtcTorrent implementation (as alternative/replacement for WebTorrent)
- Configurable LZ4/Zstd compression for RTC SDP data (lz4 default, enabled by default)
- BEP 3: The BitTorrent Protocol
- BEP 7: IPv6 Support
- BEP 15: UDP Tracker Protocol for BitTorrent
- BEP 23: Tracker Returns Compact Peer Lists
- BEP 41: UDP Tracker Protocol Extensions
- BEP 48: Tracker Protocol Extension: Scrape
You can get the latest binaries from releases or follow the install from scratch instructions below.
- Clone the repository:
git clone https://github.com/Power2All/torrust-actix.git
cd torrust-actix- Build the source code using Rust (make sure you have installed rustup with stable branch)
cargo build --releaseNote:
lib/torrust-client(the optional desktop GUI) is excluded from the default build. It requires thefontconfigsystem library and a graphical environment (Slint UI framework). See lib/torrust-client — Optional GUI below for details.
lib/torrust-client is a desktop GUI front-end built with the Slint UI framework.
It is a workspace member but is not compiled by default (default-members excludes it).
# Debian / Ubuntu
sudo apt-get install libfontconfig1-dev
# Fedora / RHEL
sudo dnf install fontconfig-devel
# Arch
sudo pacman -S fontconfig# Build only the GUI client
cargo build --release -p torrust-client
# Or build the entire workspace including the GUI
cargo build --release --workspaceRun the code using --help argument for using in your enironment:
./target/release/torrust-actix --helpBefore you can run the server, you need to either have persistence turned off, and when enabled, make sure your database is created and working. See the help argument above how to fix your setup as you wish.
Swagger UI is introduced, and when enabled in the configuration, is accessible through the API via /swagger-ui/.
Sentry.io support is introduced, you can enable it in the configuration and the URL where to push the data to.
To run this application in Docker, we provided a Docker Compose file that you can use to run it locally or remotely.
You can find it in the "docker" folder called "docker-compose.yml", and in order to deploy it, use the following commands:
docker compose build .
docker compose start
Use environment variables to override the configuration settings.
LOG_LEVEL <off | trace | debug | info | warn | error>
LOG_CONSOLE_INTERVAL <UINT64>
TRACKER__API_KEY <STRING>
TRACKER__WHITELIST_ENABLED <true | false>
TRACKER__BLACKLIST_ENABLED <true | false>
TRACKER__KEYS_ENABLED <true | false>
TRACKER__USERS_ENABLED <true | false>
TRACKER__SWAGGER <true | false>
TRACKER__KEYS_CLEANUP_INTERVAL <UINT64>
TRACKER__REQUEST_INTERVAL <UINT64>
TRACKER__REQUEST_INTERVAL_MINIMUM <UINT64>
TRACKER__PEERS_TIMEOUT <UINT64>
TRACKER__PEERS_CLEANUP_INTERVAL <UINT64>
TRACKER__PEERS_CLEANUP_THREADS <UINT64>
TRACKER__PROMETHEUS_ID <STRING>
TRACKER__RTC_INTERVAL <UINT64>
TRACKER__RTC_PEERS_TIMEOUT <UINT64>
TRACKER__TOTAL_DOWNLOADS <UINT64>
TRACKER__RTC_COMPRESSION_ENABLED <true | false>
TRACKER__RTC_COMPRESSION_ALGORITHM <lz4 | zstd>
TRACKER__RTC_COMPRESSION_LEVEL <UINT64>
TRACKER__CLUSTER <standalone | master | slave>
TRACKER__CLUSTER_ENCODING <binary | json | msgpack>
TRACKER__CLUSTER_TOKEN <STRING>
TRACKER__CLUSTER_BIND_ADDRESS <STRING>
TRACKER__CLUSTER_MASTER_ADDRESS <STRING>
TRACKER__CLUSTER_KEEP_ALIVE <UINT64>
TRACKER__CLUSTER_REQUEST_TIMEOUT <UINT64>
TRACKER__CLUSTER_DISCONNECT_TIMEOUT <UINT64>
TRACKER__CLUSTER_RECONNECT_INTERVAL <UINT64>
TRACKER__CLUSTER_MAX_CONNECTIONS <UINT64>
TRACKER__CLUSTER_THREADS <UINT64>
TRACKER__CLUSTER_SSL <true | false>
TRACKER__CLUSTER_SSL_KEY <STRING>
TRACKER__CLUSTER_SSL_CERT <STRING>
TRACKER__CLUSTER_TLS_CONNECTION_RATE <UINT64>
CACHE__ENABLED <true | false>
CACHE__ENGINE <redis | memcache>
CACHE__ADDRESS <STRING>
CACHE__PREFIX <STRING>
CACHE__TTL <UINT64>
SENTRY__ENABLED <true | false>
SENTRY__DEBUG <true | false>
SENTRY__ATTACH_STACKTRACE <true | false>
SENTRY__SEND_DEFAULT_PII <true | false>
SENTRY__DSN <STRING>
SENTRY__MAX_BREADCRUMBS <UINT64>
SENTRY__SAMPLE_RATE <F32>
SENTRY__TRACES_SAMPLE_RATE <F32>
DATABASE__PERSISTENT <true | false>
DATABASE__INSERT_VACANT <true | false>
DATABASE__REMOVE_ACTION <true | false>
DATABASE__UPDATE_COMPLETED <true | false>
DATABASE__UPDATE_PEERS <true | false>
DATABASE__PATH <STRING>
DATABASE__ENGINE <sqlite3 | mysql | pgsql>
DATABASE__PERSISTENT_INTERVAL <UINT64>
DATABASE_STRUCTURE__TORRENTS__BIN_TYPE_INFOHASH <true | false>
DATABASE_STRUCTURE__TORRENTS__TABLE_NAME <STRING>
DATABASE_STRUCTURE__TORRENTS__COLUMN_INFOHASH <STRING>
DATABASE_STRUCTURE__TORRENTS__COLUMN_SEEDS <STRING>
DATABASE_STRUCTURE__TORRENTS__COLUMN_PEERS <STRING>
DATABASE_STRUCTURE__TORRENTS__COLUMN_COMPLETED <STRING>
DATABASE_STRUCTURE__WHITELIST__BIN_TYPE_INFOHASH <true | false>
DATABASE_STRUCTURE__WHITELIST__TABLE_NAME <STRING>
DATABASE_STRUCTURE__WHITELIST__COLUMN_INFOHASH <STRING>
DATABASE_STRUCTURE__BLACKLIST__BIN_TYPE_INFOHASH <true | false>
DATABASE_STRUCTURE__BLACKLIST__TABLE_NAME <STRING>
DATABASE_STRUCTURE__BLACKLIST__COLUMN_INFOHASH <STRING>
DATABASE_STRUCTURE__KEYS__BIN_TYPE_HASH <true | false>
DATABASE_STRUCTURE__KEYS__TABLE_NAME <STRING>
DATABASE_STRUCTURE__KEYS__COLUMN_HASH <STRING>
DATABASE_STRUCTURE__KEYS__COLUMN_TIMEOUT <STRING>
DATABASE_STRUCTURE__USERS__ID_UUID <true | false>
DATABASE_STRUCTURE__USERS__BIN_TYPE_KEY <true | false>
DATABASE_STRUCTURE__USERS__TABLE_NAME <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_UUID <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_ID <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_ACTIVE <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_KEY <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_UPLOADED <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_DOWNLOADED <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_COMPLETED <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_UPDATED <STRING>
API_0_ENABLED <true | false>
API_0_SSL <true | false>
API_0_BIND_ADDRESS <STRING>
API_0_REAL_IP <STRING>
API_0_SSL_KEY <STRING>
API_0_SSL_CERT <STRING>
API_0_KEEP_ALIVE <UINT64>
API_0_REQUEST_TIMEOUT <UINT64>
API_0_DISCONNECT_TIMEOUT <UINT64>
API_0_MAX_CONNECTIONS <UINT64>
API_0_THREADS <UINT64>
API_0_TLS_CONNECTION_RATE <UINT64>
HTTP_0_ENABLED <true | false>
HTTP_0_SSL <true | false>
HTTP_0_BIND_ADDRESS <STRING>
HTTP_0_REAL_IP <STRING>
HTTP_0_SSL_KEY <STRING>
HTTP_0_SSL_CERT <STRING>
HTTP_0_KEEP_ALIVE <UINT64>
HTTP_0_REQUEST_TIMEOUT <UINT64>
HTTP_0_DISCONNECT_TIMEOUT <UINT64>
HTTP_0_MAX_CONNECTIONS <UINT64>
HTTP_0_THREADS <UINT64>
HTTP_0_TLS_CONNECTION_RATE <UINT64>
HTTP_0_RTCTORRENT = <true | false>
UDP_0_ENABLED <true | false>
UDP_0_BIND_ADDRESS <STRING>
UDP_0_UDP_THREADS <UINT64>
UDP_0_WORKER_THREADS <UINT64>
UDP_0_RECEIVE_BUFFER_SIZE <UINT64>
UDP_0_SEND_BUFFER_SIZE <UINT64>
UDP_0_REUSE_ADDRESS <true | false>
UDP_0_USE_PAYLOAD_IP <true | false>
UDP_0_SIMPLE_PROXY_PROTOCOL <true | false>
RtcTorrent is the built-in WebRTC peer-to-peer library that lets a browser (or Node.js process) act as a BitTorrent seeder or leecher without any browser plugin or native binary. It uses the standard HTTP announce endpoint with additional query parameters for WebRTC signalling.
A full protocol white paper is available in RtcTorrent.md.
Browser (leecher) ──announce + rtctorrent=1──► Tracker (Torrust-Actix)
◄── SDP offer from seeder ──
Browser ──answer + rtcanswerfor=<peer_id>────► Tracker
Seeder ──poll (announce) ───────────────────► Tracker
◄── SDP answer ──
WebRTC Data Channel established directly between Browser ↔ Seeder
cd lib/rtctorrent
npm install
npm run build # produces dist/rtctorrent.browser.js (minified)
npm run dev # watch mode for developmentThe build outputs two bundles:
| File | Target | Use |
|---|---|---|
dist/rtctorrent.browser.js |
Browser (<script>) |
Website player/downloader |
dist/rtctorrent.node.js |
Node.js (require) |
CLI seeder, server-side |
Copy dist/rtctorrent.browser.js to your web server's static assets, then include it in your HTML:
<script src="/assets/rtctorrent.browser.js"></script><!DOCTYPE html>
<html>
<head><title>RtcTorrent Demo</title></head>
<body>
<video id="player" controls autoplay style="width:100%"></video>
<script src="/assets/rtctorrent.browser.js"></script>
<script>
const client = new RtcTorrent({
trackerUrl: 'http://your-tracker.example.com/announce',
// Optional: override ICE/STUN servers
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' }
]
});
// Download via .torrent URL, magnet URI, or parsed torrent object
client.download('magnet:?xt=urn:btih:INFOHASH&dn=MyVideo&tr=http://your-tracker.example.com/announce')
.then(torrent => {
console.log('Started downloading:', torrent.name);
});
// Stream a video file directly into a <video> element
client.streamVideo('INFOHASH_HEX', 0, document.getElementById('player'));
</script>
</body>
</html><input type="file" id="filePicker">
<script src="/assets/rtctorrent.browser.js"></script>
<script>
const client = new RtcTorrent({
trackerUrl: 'http://your-tracker.example.com/announce'
});
document.getElementById('filePicker').addEventListener('change', async (e) => {
const file = e.target.files[0];
// Create a torrent from the selected file
const { torrent, magnetUri, infoHash } = await client.create([file], {
version: 'v1', // or 'v2' / 'hybrid'
name: file.name
});
console.log('Magnet URI:', magnetUri);
console.log('Info Hash:', infoHash);
// Start seeding — the tracker handles WebRTC signalling
await client.seed(torrent, [file]);
});
</script>| Option | Default | Description |
|---|---|---|
trackerUrl |
'' |
HTTP announce URL of the Torrust-Actix tracker |
announceInterval |
30000 |
Re-announce interval in milliseconds |
rtcInterval |
10000 |
WebRTC signalling poll interval in milliseconds |
maxPeers |
50 |
Maximum simultaneous WebRTC peers |
iceServers |
Google STUN | Array of ICE server objects |
| Method | Description |
|---|---|
create(files, options) |
Create a torrent from File objects (browser) or file paths (Node) |
download(torrentData) |
Download via magnet URI, .torrent URL, or parsed torrent object |
seed(torrentData, files) |
Seed an existing torrent |
streamVideo(infoHash, fileIndex, videoEl) |
Stream a video piece-by-piece into a <video> element |
stop() |
Stop all torrents and close connections |
parseMagnet(uri) |
Parse a magnet URI into a torrent object |
parseTorrentFile(buffer) |
Parse a .torrent file buffer |
calculateInfoHash(info) |
Calculate the SHA-1 info hash of a torrent info dictionary |
Enable RtcTorrent support on the HTTP listener in config.toml:
[[http_trackers]]
enabled = true
bind_address = "0.0.0.0:6969"
rtctorrent = true # Enable WebRTC signalling endpointOr via environment variable:
HTTP_0_RTCTORRENT=true
The bin/seed.js script seeds files from the command line:
# Install dependencies
cd lib/rtctorrent && npm install
# Single file
node bin/seed.js --tracker http://your-tracker.example.com/announce \
--name "My Movie" \
--out movie.torrent \
/path/to/movie.mp4
# Re-seed from an existing .torrent (no re-hashing)
node bin/seed.js --torrent-file movie.torrent /path/to/movie.mp4
# Seed from a magnet URI
node bin/seed.js --magnet "magnet:?xt=urn:btih:..." /path/to/movie.mp4
# Multi-torrent mode via YAML config
node bin/seed.js --torrents torrents.yamlYAML multi-torrent config example:
torrents:
- name: "My Movie"
file:
- "/data/movie.mp4"
trackers:
- "http://your-tracker.example.com/announce"
out: "/data/movie.torrent"
version: v1 # v1 | v2 | hybrid
webseed:
- "https://cdn.example.com/movie.mp4"Reload the YAML config without restarting by sending SIGHUP (Linux/macOS) or simply saving the file (polled every 2 seconds on all platforms).
Run the built-in demo server to test locally:
cd lib/rtctorrent
npm install && npm run build
npm run serve # serves demo at http://localhost:8080/demo/- Changed some informative data
- Bug-fix needed for the peer/torrent cleanup thread
- Fixing versioning, added back healthcheck for Docker and fixed some other small bugs
- Added
//////!doc comments throughout the codebase for docs.rs / crates.io publishing - Made a large set of
[tracker_config],[sentry_config], and[database_structure.*]keys optional inconfig.toml— sensible defaults are applied automatically when the keys are absent- Optional tracker fields:
whitelist_enabled,blacklist_enabled,keys_enabled,keys_cleanup_interval,users_enabled,swagger,prometheus_id, allcluster_*fields, and allrtc_*fields - The entire
[sentry_config]section can now be omitted (defaults to disabled) - All
[database_structure.*]sub-sections can be omitted (default table/column names are used)
- Optional tracker fields:
--create-confignow annotates every optional key with an inline# Optional: defaults to …comment so new users can see at a glance what can be left out- Refactored
impl RtcDataout of the struct file intosrc/tracker/impls/rtc_data.rs, consistent with the rest of the project structure
- Adding LZ4/ZSTD compression for memory objects for the RtcTorrent peer data, enabled by default, disablable through config
- Memory optimization for the peer data
- Some small bug fixes
- Refactoring the whole project structure
- Adding security and anti-malicious validation and checks
- Adding RtcTorrent library and support to the tracker, for web streaming and downloading of BitTorrent. This is a major change from v4.1.0. It uses the default HTTP BitTorrent announce endpoint, with additional parameters
- Added hot reloading of SSL certificates for renewal
- API has an extra endpoint to run the hot reloading
- Some more code optimizations
- Added a full Cluster first version through WebSockets
- Option to run the app in Stand-Alone (which is default, as single server), or using the cluster mode
- When set to Master, it still functions as if being Stand-Alone, but with WebSocket support for clustering
- When set to Slave, it will forward all the requests to the Master server to be handled
- Added configurations to be applied in config.toml and the environment variables
- Added statistics, also showing cluster statistics next to the rest. Slave will only show active requests
- WebSocket data can be sent in 3 different ways, but Master server is the leading what way to talk
- This is a very early version of the WebSocket cluster implementation, and needs thorough testing
- Moved the more database engines additions to another version (and MeiliSearch/ElasticSearch support for v4.2)
- Refactored the database engine to be less massive, more logical and less redundancy
- Implemented a Redis and Memcache cache optionally to push peer data to, for usage on websites (without burdening SQL)
- Added UDP support for Cloudflare's "Simple Proxy Protocol" (https://developers.cloudflare.com/spectrum/how-to/enable-proxy-protocol/#enable-simple-proxy-protocol-for-udp)
- Another little overhaul, changing some memory tools for enhancement and performance
- Less CPU cycles applied when requests are handled
- Preparing for v4.1 to add some more database engines to the mix apart from SQLx
- Small debug and hotfixes
- Fixed the unit test that somehow failed
- Updated this readme file
- More code optimizations thanks to AI scanning further
- UDP performance tweaks (some new config options added)
- Added an initial unit testing for checking if all functions and features work as expected
- Code optimizations thanks to AI scanning
- Huge memory and CPU consumption improvement for UDP, using offloading
- Added further UDP improvement by adding customization, also added to the config:
- Receive Buffer Size
- Send Buffer Size
- Reuse of Address
- Updating libraries and cleanup code
- Updating libraries
- Adding healthcheck for Docker through Python check script
- Updating libraries
- Adding full environment support to override configurations (Thanks tachyon3000 for the idea)
- Updating libraries (Actix 4.9 to 4.10)
- Some critical exploit in ZIP fixed
- Some faulty v4.0.8 deployments fixed with GitHub
- Updating libraries
- Fixing threading for UDP
- Removed a feature from Parking Lot, cause of an unfixed vulnerability
- Update Swagger UI to version v4.0.0 and OpenAPI version v3.1.1
- Cleanup was still broken, did a big rewrite, after testing it works now as expected
- Did some tokio threading correctly for core threads
- Added a new configuration key, to set the threads, default for each shard (256), but can be changed
- Fixed some clippy issues
- Found a performance issue on peers cleanup
- Switched peers cleanup from Tokio spawn to Thread spawn for speedup
- Bumped version of Tokio
- Library bump
- Further implementation of Sentry (trace logging)
- Fixing announce and scrape paths, since it is the wrong way.
- Fixing various smaller bugs that isn't app-breaking, but should be handled better.
- Added support for Sentry.io SaaS and self-hosted setup.
- Preparing work for version v4.1.0, which will introduce LUA support for middleware.
- Added option that the system will remove data from database.
- Added updates variables for the white/black list and keys tables.
- Renaming the "database" naming which should be "tables".
- A lot of fixes and bugs I stumbled upon.
- Completely rebuilt of the tracker code, for readability.
- Moved to Actix v4, thus versioning this software to v4.0.0 as well.
- Rebuilt and remade the way configuration file is created (you need to give the command as argument for it).
- Redone the whole database system, is tested with the latest versions available at this time.
- API has gone through a lot of work and tested.
- Introduced Swagger UI as testing and documentation.
- A lot of improvements in speed and performance applied further.
- Import and Export function added, will dump or import from JSON files, handy for when making a backup from your existing database, or when migrating to an other database engine.
- Removed WebGUI, was outdated and not really useful.
- Bumped library versions significantly, including security patches.
- Fixed changes in libraries to work properly.
- Tuned the non-persistence code to use less memory.
- Bumped library versions, including security patches.
- Fixed a bug in the PostgreSQL handler.
- Some forgotten naming from Torrust-Axum to Torrust-Actix.
- Bumped library versions.
- Modified the way scheduling was done through threads, it could lock up and slow down public trackers with heavy activity.
- Tweaking the SQLite3 database usage and database space consumption.
- Full overhaul on how torrents and peers are used in memory. Using crossbeam skipmap for thread safe non-locking memory sharing.
- Some various improvement on coding performance, readability and linting the files.
- Replaced Tokio Axum web framework for Actix, reason: Missing critical things like a timeout on connect, disconnect, read and write, and support was lackluster.
- Renamed the GitHub repository from torrust-axum to torrust-actix.
- Adding user tracking support with an extra key.
- Bumped library versions.
- Added a Code of Conduct file, as some open source projects need this.
- Added a Maintenance toggle function to API and WebGUI.
- Configuration file is not generated when it doesn't exist, or has invalid data, unless forced with a '--create-config' argument.
- Fixed various small bugs.
- Bumped library versions.
- Database for SQLite3, MySQL and PostgreSQL now works properly with all the tables, and will be used if enabled.
- UDP had a problem in IPv4, fixed the code for correctly parsing byte array.
- Cleanup and refactoring of some redundant code.
- Added some small checks where needed to prevent errors.
- Whitelist System: You can enable this to only allow torrent hashes to be used you specify in the database, or add them through the API.
- Blacklist System: You can enable this to disallow torrent hashes to be used you specify in the database, or add them through the API.
- Keys System: You can enable this to only allow tracking when an activated "key" hash (same as an info_hash, 20 bytes or 40 characters hex) is given. Keys with a timeout of zero "0" will be permanent and won't be purged by the cleanup.
- WebGUI: The API has an available web interface, which can be accessed through https://your.api:8080/webgui/ and giving the correct API Key, which you configure in the configuration file.
- Customizable database structure can be given in the configuration file.
- The system is also now available through Docker Hub at https://hub.docker.com/r/power2all/torrust-axum
- Bugfixes
- SQLite3 support added
- MySQL support added
- PostgresSQL support added
Initial version of Torrust-Axum.
This Torrust-Tracker was a joint effort by Nautilus Cyberneering GmbH, Dutch Bits and Power2All. Also thanks to Naim A. and greatest-ape for some parts in the Torrust-Tracker code. This project (Torrust-Actix) is built from scratch by Power2All.