Self-hosting searX with Filtron and Caddy

I’ve recently begun the process of changing my online lifestyle to be a bit more privacy inclined, this has involved a few changes:

  • I have removed Chrome from my computer and replaced it with Firefox
  • I’ve updated my pi-hole DNS block lists to block a significant number of privacy-breaching trackers/domains
  • I’ve changed my domain’s email MX servers to use ProtonMail (I have a Professional account with them, which allows me to bring my own custom domain, setting up catch-all email forwarding, and a few other nice things)
  • I’ve recently changed my search engine of choice to searX (a self-hosted instance of it as well)

This post will discuss how I configured my self-hosted instance of searX with caddy as a reverse proxy and a filtering agent called Filtron to keep the searX instance from being abused by bad people/robots.

First step is simple enough, follow the instructions on the installation page for searX: https://asciimoo.github.io/searx/dev/install/installation.html

Once I reached the section for uwsgi, I quickly found out that Filtron doesn’t like forwarding to destinations that are unix sockets, so I had to figure out how to get searX to persist across reboots/crashes without using uwsgi. Luckily, I’m not the only person who wanted to achieve this. Another user has already done most of the leg work and wrote a basic systemd service file for searX and published it as a github issue: https://github.com/asciimoo/searx/issues/985

After a few tweaks I was satisfied with the following:

[Unit]
Description=searx
After=syslog.target network.target

[Service]
Type=simple
User=searx
WorkingDirectory=/usr/local/searx
ExecStart=/usr/local/searx/searx-ve/bin/python /usr/local/searx/searx/webapp.py
TimeoutStopSec=5
Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target

And while I was here, I went ahead and created the service file for Filtron:

[Unit]
Description=filtron
After=syslog.target network.target

[Service]
Type=simple
User=root
ExecStart=/usr/local/go/bin/filtron -rules "/root/rules.json"
TimeoutStopSec=5
Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target

After this, I did a quick systemctl daemon-reload to get the service files read by systemd and moved on. I modified the settings in searx/settings.yml to my liking and set the listening address to be 127.0.0.1:8888 so I can point Filtron to it later on.

Next was to install Filtron. Filtron is a golang binary that requires at least golang version 1.9 because of the maths/bit dependency it uses. The install steps are pretty simple on the github repo: https://github.com/asciimoo/filtron

Once you have it installed, I dumped the customized searX rules.json included in part of searX’s installation page into a file on disk and feed it to Filtron. Now that Filtron is happily listening on 127.0.0.1:4004 and forwarding requests to searX on 127.0.0.1:8888 after filtering out abusers per the rules.json file provided, its time to move on to caddy.

Caddy is probably the easiest part of this setup, I simply added an extra server block and configured it to pass the connection to Filtron:

searx.odin.lan {
        tls tyler@tpage.io

        log /var/log/caddy/searx.odin.lan-443.log {

        rotate_size 50  # Rotate after 50 MB
        rotate_age  90  # Keep rotated files for 90 days
        rotate_keep 20  # Keep at most 20 log files
        rotate_compress # Compress rotated log files in gzip format
        }

        proxy / 127.0.0.1:4004 {
                websocket
                transparent
        }
}

Then I added a DNS record to point searx.odin.lan to my server’s IP address and restarted caddy. Once I verified that the dns resolved I started Filtron and searX by enabling and starting their respective systemd service and I was off to the races!

Further reading: