A microservice for checking whether an IP address belongs to the TOR network.
Live Demo: https://torchecker.trustcrypt.com
- Real-time TOR exit node IP verification
- Historical tracking of TOR node activity
- REST API for programmatic access
- Web interface for manual checks
- Automatic updates every 10 minutes via Celery
- PostgreSQL for persistent storage
- Docker Compose for easy deployment
# Clone the repository
git clone https://github.com/keklick1337/tor_checker.git
cd tor_checker
# Start all services
docker compose up -d
# Open web interface
open http://localhost:8000+------------------------------------------------------------------+
| TOR IP Checker |
+------------------------------------------------------------------+
| |
| +-------------+ +-------------+ +-------------+ |
| | Web UI |---->| Flask API |---->| PostgreSQL | |
| | (HTML/JS) | | Server | | Database | |
| +-------------+ +-------------+ +-------------+ |
| ^ ^ |
| | | |
| +-------------+ +------+------+ | |
| | TOR Exit |---->| Celery |------------+ |
| | Addresses | | Worker | |
| +-------------+ +-------------+ |
| | ^ |
| | +------+------+ |
| | | Celery | |
| +------------>| Beat | |
| (every 10 min) +-------------+ |
| | |
| +------+------+ |
| | Redis | |
| | Broker | |
| +-------------+ |
| |
+------------------------------------------------------------------+
# Query parameter
curl "http://localhost:8000/api/check?ip=185.220.101.1"
# Path parameter
curl "http://localhost:8000/api/check/185.220.101.1"Response:
{
"ip": "185.220.101.1",
"is_tor": true,
"is_active": true,
"last_seen": "2026-01-21T07:45:00",
"first_seen": "2025-12-01T10:30:00",
"nodes": [
{
"node_id": "ABC123DEF456...",
"published": "2026-01-21T05:00:00",
"last_status": "2026-01-21T07:00:00",
"exit_address_date": "2026-01-21T07:45:00",
"first_seen": "2025-12-01T10:30:00",
"last_seen": "2026-01-21T07:45:00",
"is_active": true
}
]
}curl "http://localhost:8000/api/stats"Response:
{
"total_nodes": 3500,
"active_nodes": 3200,
"unique_ips": 2800,
"active_ips": 2500,
"last_update": {
"time": "2026-01-21T07:50:00",
"nodes_count": 3200,
"new_nodes": 15,
"updated_nodes": 3100,
"deactivated_nodes": 85
}
}curl "http://localhost:8000/api/health"| Column | Type | Description |
|---|---|---|
| id | SERIAL | Primary key |
| node_id | VARCHAR(64) | TOR node fingerprint |
| exit_address | VARCHAR(45) | Exit node IP address |
| published | TIMESTAMP | Publication time |
| last_status | TIMESTAMP | Last status from TOR |
| exit_address_date | TIMESTAMP | Exit address timestamp |
| first_seen | TIMESTAMP | First observation time |
| last_seen | TIMESTAMP | Last observation time |
| is_active | BOOLEAN | Current activity status |
Stores history of database updates with statistics.
# Start services
docker compose up -d
# View logs
docker compose logs -f web
docker compose logs -f celery_worker
docker compose logs -f celery_beat
# Stop services
docker compose down
# Remove all data
docker compose down -v
# Rebuild and start
docker compose build --no-cache
docker compose up -dEnvironment variables:
| Variable | Default | Description |
|---|---|---|
| DATABASE_URL | postgresql://tor_user:tor_password@postgres:5432/tor_checker | Database connection URL |
| REDIS_URL | redis://redis:6379/0 | Redis connection URL |
| HOST | 0.0.0.0 | Server bind address |
| PORT | 8000 | Server port |
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r code/requirements.txt
# Start only PostgreSQL and Redis
docker compose up -d postgres redis
# Set environment variables
export DATABASE_URL=postgresql://tor_user:tor_password@localhost:5432/tor_checker
export REDIS_URL=redis://localhost:6379/0
# Start server
cd code
python server.py
# In another terminal - start worker
celery -A celery_app.celery worker --loglevel=info
# In third terminal - start beat scheduler
celery -A celery_app.celery beat --loglevel=infoTOR exit node data is fetched from the official TOR Project source: https://check.torproject.org/exit-addresses
File format:
ExitNode <fingerprint>
Published <YYYY-MM-DD HH:MM:SS>
LastStatus <YYYY-MM-DD HH:MM:SS>
ExitAddress <IP> <YYYY-MM-DD HH:MM:SS>
- Backend: Python, Flask, SQLAlchemy
- Database: PostgreSQL
- Task Queue: Celery, Redis
- Containerization: Docker, Docker Compose
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.