[Tutorial] Set up Ghost as a Tor Onion Service

Since there is another guide that made an attempt onionize Ghost CMS but didn’t work, I made one that works.

This guide assumes you have installed Ghost with ghost-cli, if not just adjust accordingly, there won’t be too much difference.

Install Tor:

Creating onion service
On /etc/tor/torrc append below config to the bottom of the file.

HiddenServiceDir /var/lib/tor/{sitename}/
HiddenServicePort 80 127.0.0.1:80

Restart the Tor process, sudo systemctl restart tor. After that, let’s see the generated Onion Service address by running sudo cat /var/lib/tor/{sitename}/hostname.

NGINX
The Onion Service address is ready. Now let’s configure it so Nginx sent the information about the onion address to the client by using Onion-Location.

Upon /etc/nginx/sites-available/{sitename}-ssl.conf, add the config just before location / { line.

add_header Onion-Location http://{generated-onion-address}.onion$request_uri;

After that, add a new server block in the bottom of the file.

server {
    listen 80;

    server_name {generated-onion-address}.onion;

    location / {
        proxy_set_header X-Forwarded-Proto https;
        proxy_pass http://127.0.0.1:2368;
    }
}

Check if the config is all good and restart Nginx.

sudo nginx -t
sudo systemctl restart nginx

The whole config should look like this.

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name manasiwibi.com www.manasiwibi.com;
    root /var/www/ghost/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

    ssl_certificate /etc/letsencrypt/manasiwibi.com/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/manasiwibi.com/manasiwibi.com.key;
    include /etc/nginx/snippets/ssl-params.conf;

    add_header Onion-Location http://{generated-onion-address}.onion$request_uri;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 1g;
}


server {
    listen 80;

    server_name {generated-onion-address}.onion;

    location / {
        proxy_set_header X-Forwarded-Proto https;
        proxy_pass http://127.0.0.1:2368;
    }
}

The reason why I set X-Forwarded-Proto to https is since ghost setting are making an internal http to https redirection by default, so we need to override that via the web server, by assuming/overriding the connection on the local reverse proxy is https.

Checking It Out
Run wget --server-response --spider your.domain to see whether Nginx already sent out the onion information. The output should indicate it exists.

onion-location: http://{generated-onion-address}.onion/

Or simply just open up Tor Browser and directly visit your clearnet domain. It should automatically be redirected into the configured Onion Service address.

As a caveat; if you want your onion service/server to be kept private. I suggest you follow the recommended guidelines based on Tor project websites and other consideration/guidelines recommendations.

Note: this guide is reposted from my blog at Configure Ghost as an Onion Service.