en

Database Security for Tor Hidden Services

The database is the most sensitive component of most hidden service applications. Protecting it requires network isolation, access control, encryption, and backup strategies appropriate to the threat model of operating a Tor hidden service. This guide covers PostgreSQL and MySQL hardening for onion site backends.

Need this done for your project?

We implement, you ship. Async, documented, done in days.

Start a Brief

Network Isolation: Database Should Never Face the Internet

A hidden service's database must never be exposed to the internet. Bind PostgreSQL or MySQL to localhost only: in postgresql.conf, set listen_addresses = 'localhost' or listen_addresses = '127.0.0.1'. MySQL: bind-address = 127.0.0.1. For multi-server setups, bind to the internal Docker network IP only (not 0.0.0.0). Use Docker network isolation: create an internal Docker network (--internal flag) for database containers that has no external connectivity, only application containers can reach the database container through this network. Test isolation: after binding to localhost, attempt to connect from an external IP - the connection should fail with 'connection refused'.

Database User and Permission Hardening

Create a dedicated database user for your hidden service application with minimal permissions. Do not use the postgres/root superuser for application connections. PostgreSQL: CREATE USER hsapp WITH PASSWORD 'strongpassword'; GRANT CONNECT ON DATABASE hiddensite TO hsapp; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO hsapp. Do not grant: CREATEDB, SUPERUSER, CREATEROLE. MySQL: CREATE USER 'hsapp'@'localhost' IDENTIFIED BY 'strongpassword'; GRANT SELECT, INSERT, UPDATE, DELETE ON hiddendb.* TO 'hsapp'@'localhost'. Revoke dangerous default grants: REVOKE ALL ON *.* FROM 'anonymous'@''; Separate read-only user for reporting/analytics reduces risk if read-only paths are compromised.

Encryption at Rest for Database Files

Full disk encryption (LUKS on Linux) protects database files if the physical server is seized. This is particularly relevant for dedicated server deployments where someone with physical access could remove the disk. LUKS configuration: encrypt the entire database partition or use encrypted logical volumes (LVM + LUKS). Automatic decryption on boot requires the LUKS key to be available at boot time (stored on the server), so full disk encryption protects against disk removal but not against server seizure while running. PostgreSQL's Transparent Data Encryption (TDE) - available in PostgreSQL 15+ with pg_tde extension - encrypts individual table data without requiring full disk encryption. Application-level encryption (encrypting sensitive fields before writing to DB) provides protection even if DB files are copied.

Backup Strategy for Hidden Service Databases

Database backups for hidden services require careful handling to avoid creating plaintext copies that reduce security. Backup approach: encrypt backups before storing anywhere. PostgreSQL: pg_dump hiddendb | gzip | gpg --encrypt --recipient backup-key@operator.example > /backup/hiddendb-$(date +%Y%m%d).sql.gz.gpg. Store encrypted backups off-server (different VPS, different jurisdiction if possible) but note that the backup destination also becomes a point of risk. Test restores periodically: restore from backup to a test environment and verify application functionality. Backup frequency should match the RPO (recovery point objective): daily backups accept up to 24 hours of data loss on disaster; hourly backups with WAL archiving approach near-zero data loss. Balance security (more copies = more exposure surface) with recovery capability.

Audit Logging for Hidden Service Databases

Database audit logging records who accessed what data and when. This is valuable for detecting intrusions but also creates a log of user activity that has privacy implications. For hidden services handling sensitive user data, audit logging is a double-edged tool. PostgreSQL audit logging via pgaudit extension: logs all DML (SELECT, INSERT, UPDATE, DELETE) with user and timestamp. This log shows exactly what data was accessed. Operators must consider: where are audit logs stored, who has access, how long are they retained, and under what circumstances would they be produced in response to legal demands. If audit logs create unacceptable risk, consider application-level event logging (only log actions, not data content) rather than database-level row access logging.

Why Anubiz Host

100% async — no calls, no meetings
Delivered in days, not weeks
Full documentation included
Production-grade from day one
Security-first approach
Post-delivery support included

Ready to get started?

Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.

Anubiz Chat AI

Online