How to Run a WordPress Site on Both .onion and a Public Domain (Dark Net & Clear Net)

Want your blog reachable by anyone – both Tor users and regular browsers – without running two separate installations?
The trick is one code-base, two reverse proxies, and a single database. Below is a quick 400-500 word guide for Ubuntu/Debian that shows the minimal steps.

1. Prep the Server

Start with a clean VPS or local virtul server:

sudo apt update && sudo apt upgrade -y
sudo apt install tor nginx mariadb-server php-fpm php-mysql php-curl php-gd php-xml php-zip -y

Why? A clean server keeps the attack surface small and makes troubleshooting easier.

2. Install WordPress

Download the latest WordPress release:

cd /var/www
sudo wget https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz
sudo mv wordpress wp_site
sudo chown -R www-data:www-data wp_site

Create a DB:

sudo mysql -u root -p <<'SQL'
CREATE DATABASE wp;
GRANT ALL PRIVILEGES ON wp.* TO 'wp_user'@'localhost' IDENTIFIED BY 'StrongPass!23';
FLUSH PRIVILEGES;
EXIT;
SQL

Edit wp-config.php with the DB details.

3. Set Up Tor Hidden Service

sudo nano /etc/tor/torrc

Add:

HiddenServiceDir /var/lib/tor/wp/
HiddenServicePort 80 127.0.0.1:8080

Restart Tor and grab the address:

sudo systemctl restart tor
sudo cat /var/lib/tor/wp/hostname   # e.g., abcdefghijklmnop.onion

Secure the directory:

sudo chown -R debian-tor:debian-tor /var/lib/tor/wp
sudo chmod 700 /var/lib/tor/wp

4. Configure Nginx for Two Front-Ends

Create a single server block that listens on both ports:

server {
    listen 127.0.0.1:8080;
    listen 80;           # clear-net HTTP
    listen [::]:80;

    server_name example.org www.example.org;   # replace with your domain

    root /var/www/wp_site;
    index index.php index.html;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }

    location ~ /\.ht { deny all; }
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/wp_site /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Why? The same WordPress install is served from two addresses:

  • http://example.org (clear-net) and
  • http://<onion>.onion (Tor).

5. Secure the Site

  • Keep WordPress, plugins, and themes up to date (wp-cli core update, etc.).
  • Enable two-factor authentication on the admin panel.
  • Add in wp-config.php:
define('DISALLOW_FILE_EDIT', true);
  • Consider a security plugin (Wordfence, iThemes Security) for extra hardening.

6. Verify

  1. Clear-net – Open https://example.org.
    If you want HTTPS, set up Let’s Encrypt with Certbot.
  2. Tor – In the Tor Browser, enter http://<onion>.onion.
    The same content should appear.

Final Checklist

  • [ ] Tor hidden service running (check /var/lib/tor/wp/hostname).
  • [ ] Nginx listening on both 127.0.0.1:8080 and your public port.
  • [ ] WordPress installed once, shared between fronts.
  • [ ] Security hardening applied.
  • [ ] Backup database and the hidden-service key (/var/lib/tor/wp).

That’s it! You now have a single WordPress site that anyone can reach—whether they’re on the Tor network or the open web.

Happy blogging, both in the shadows and out in the light!

Leave a comment