Kushal Das

FOSS and life. Kushal Das talks here.


Using onion services over unix sockets and nginx

I have explained before about how to create Onion services, this provides an easy solution to expose any service from inside of your home network to the Internet, in a secured manner (authorized services). But, in all of those examples I used an IP/port combination to expose/talk to the internal service. Instead you can also use unix sockets to do the same.

To do so, use the following style in your torrc file, this example is from my blog.

HiddenServiceDir /var/lib/tor/hidden/
HiddenServiceVersion 3
HiddenServicePort 80 unix:/var/run/tor-hs-kushal.sock
HiddenServicePort 443 unix:/var/run/tor-hs-kushal-https.sock

And the corresponding nginx configuration parts:

server {
    listen unix:/var/run/tor-hs-kushal.sock;

    server_name kushal76uaid62oup5774umh654scnu5dwzh4u2534qxhcbi4wbab3ad.onion;
    access_log /var/log/nginx/kushal_onion-access.log;

    location / {
        return 301 https://$host$request_uri;


server {
    listen unix:/var/run/tor-hs-kushal-https.sock ssl http2;

    server_name kushal76uaid62oup5774umh654scnu5dwzh4u2534qxhcbi4wbab3ad.onion;
    access_log /var/log/nginx/kushal_onion-access.log;

Now if you start tor and also nginx pointing to the same unix domain, things will go fine. But, nginx will fail to restart, you will have to remove the socket files by hand to restart. This happens due to a bug in nginx. You can edit the restart process and fix this issue.

systemctl restart nginx

Add the following the configuration file in the correct location (between the comments):

### Editing /etc/systemd/system/nginx.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file

### Editing /etc/systemd/system/nginx.service.d/override.conf Anything between here and the comment below will become the new contents of the file
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry TERM/5 --pidfile /run/nginx.pid

### Lines below this comment will be discarded

If you go and read the original ExecStop value, you will find that it is using SIGQUIT, but that does not remove the socket files, only a SIGTERM does. You can read more in the []upstream bug](https://trac.nginx.org/nginx/ticket/753).

After this nginx should be able to restart without any trouble.

Thank you reader who emailed and asked for this.