Configure Ghost as an Onion Service

As you have may notice, my blog is built over Ghost. I’m a keen supporter of the Tor network as a whole. So why wouldn’t I onionized my own website.
I’m gonna skip the ghost installation part but straight into configuring the onion service.

As a prerequisite, I configured Ghost using Ubuntu manual installation with Nginx and SSL set up. And of course, you should have installed Tor.

Assuming we have a similar configuration, we will find the SSL Nginx
configuration file at /etc/nginx/sites-available/{sitename}-ssl.conf.

We just simply need to add the Onion-Location header and Onion service address inside our Nginx config. But before we go over that part let's start with starting up the onion service

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.