Searx is a free metasearch engine application that lets you host aggregated web results with a key focus on privacy. A metasearch engine can query multiple search engines to produce results without user tracking or profiling.
In this article, you will install Searx with Gunicorn and Nginx, then configure Morty as a web content sanitizer, and Filtron as the reverse HTTP proxy on an OpenBSD server.
Prerequisites
- Deploy an OpenBSD Rcs Server.
- Point a Subdomain to the server.
- SSH and Login as a regular user with doas privileges.
Create Users
Create new user accounts for Searx, Morty, and Filtron with no login access. For the user searx, the home directory should point to the service's root directory.
Create the Searx home directory.
$ doas mkdir /usr/local/searx Create a new user searx.
$ doas useradd -d /usr/local/searx/ -s /sbin/nologin -u 3000 searxGrant the user ownership rights to the home directory.
$ doas chown -R searx:searx /usr/local/searx/Create a new user morty.
$ doas useradd -s /sbin/nologin -u 30001 mortyCreate a new user filtron.
$ doas useradd -s /sbin/nologin -u 30002 filtronInstallation
Install Nginx
$ doas pkg_add nginx Allow Nginx to start at boot time.
$ doas rcctl enable nginxStart Nginx.
$ doas rcctl start nginxInstall Python, Pip, Git, and Go
$ doas pkg_add python3 py3-pip git py3-lxml goEnable as default pip.
$ doas ln -sf /usr/local/bin/pip3.8 /usr/local/bin/pipInstall Gunicorn
$ doas pip install gunicornInstall Morty
$ go get github.com/asciimoo/mortyMove Morty to a system-wide directory.
$ doas mv go/bin/morty /usr/local/bin/Install Filtron
$ go get github.com/asciimoo/filtronMove Filtron to a system directory.
$ doas mv go/bin/filtron /usr/local/bin/Install Searx
$ doas git clone "https://github.com/searx/searx.git" Move the file to the searx home directory.
$ doas cp -r searx /usr/local/searx/searx-filesInstall Searx requirements.
$ doas pip install -r /usr/local/searx/searx-files/requirements.txtConfigurations
Configure Filtron
Configure Filtron by making a copy of the default configuration file.
Create a new /etc/filtron directory.
$ doas mkdir -p /etc/filtronCopy the configuration file.
$ doas cp $HOME/go/pkg/mod/github.com/asciimoo/filtron@v0.2.0/example_rules.json /etc/filtron/rules.jsonConfigure Searx
Create a new Searx configuration directory.
$ doas mkdir -p /etc/searx/Make a copy the settings template to the directory.
$ doas cp /usr/local/searx/searx-files/utils/templates/etc/searx/use_default_settings.yml /etc/searx/settings.ymlGenerate a secret key and save it to the file.
$ doas sed -i -e "s/ultrasecretkey/$(openssl rand -hex 16)/g" "/etc/searx/settings.yml"Also, uncomment the last lines within the settings.yml file to enable Morty.
# uncomment below section if you have running morty proxy
#result_proxy:
# url : http://127.0.0.1:3000/
# key : !!binary "your_morty_proxy_key"Save and close the file.
Configure Nginx
First, backup the current Nginx configuration file.
$ doas cp /etc/nginx/nginx.conf /etc/nginx/nginx.ORIGThen, open and edit the main Nginx configuration file using your favorite editor.
$ doas nano /etc/nginx/nginx.confAdd the following lines of code within the HTTP block.
http {
#HTTP Server Block Begins
server {
listen 80;
listen [::]:80;
server_name search.example.com;
location /.well-known/acme-challenge/ {
rewrite ^/.well-known/acme-challenge/(.*) /$1 break;
root /acme;
}
}
}Save and close the file.
Next, request for a free Let's Encrypt SSL certificate to secure the server with encrypted HTTPS traffic.
Create a new acme-client configuration file.
$ touch doas /etc/acme-client.confOpen the file.
$ doas nano /etc/acme-client.confThen, paste the following contents:
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/ssl/private/letsencrypt.key"
}
domain search.example.com {
alternative names { search.example.com }
domain key "/etc/ssl/private/search.example.com.key"
domain certificate "/etc/ssl/search.example.com.crt"
domain full chain certificate "/etc/ssl/search.example.com.pem"
sign with letsencrypt
}Now, request a free certificate for the subdomain.
$ doas acme-client -v search.example.comOnce successful, edit the Nginx configuration file again to accept HTTPS traffic. On port 443.
Paste the following lines of code within a new server block:
http {
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name search.example.com;
location / {
proxy_pass http://127.0.0.1:4004/;
proxy_set_header Host $host;
proxy_set_header Connection $http_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Script-Name /searx;
}
location /static/ {
alias /usr/local/searx/searx-files/searx/static/;
}
location /morty {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
proxy_set_header Connection $http_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
}
ssl_certificate /etc/ssl/search.example.com.pem;
ssl_certificate_key /etc/ssl/private/search.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:ECDHE+ECDSA+AES+SHA256;
}
}Also, redirect all HTTP requests to HTTPS by including a 301 redirect within the first HTTP server block.
Your HTTP block should now be similar to the one below:
#HTTP Server Block Begins
server {
listen 80 default_server;
listen [::]:80;
server_name search.example.com;
return 301 https://$host$request_uri;
}Save and close the file.
Check the Nginx configuration file for errors.
$ doas nginx -tRestart Nginx.
$ doas rcctl restart nginxSetup System Services
To control Searx, Morty, Filtron, and Gunicorn as services on the server, set up new files in the rc.d directory.
Create the following files within the /etc/rc.d directory using your preferred text editor.
Gunicorn Searx:
$ doas nano /etc/rc.d/gunicornsearx
#!/bin/ksh
RUN_DIR="/var/run/gunicornsearx"
daemon="/usr/local/bin/gunicorn"
gunicornsearx_flags="-b 127.0.0.1:8001 --chdir /usr/local/searx/searx-files/searx --pythonpath /usr/local/searx/searx-files -p /var/run/gunicornsearx/gunicornsearx.pid -D searx.webapp"
gunicornsearx_user="searx"
. /etc/rc.d/rc.subr
pexp="/usr/local/bin/python.*"
# Process ID File
rc_pre() {
if [[ ! -d /var/run/gunicornsearx ]]; then
mkdir $RUN_DIR
chown -R searx:searx $RUN_DIR
fi
}
rc_stop() {
if [[ -f $RUN_DIR/gunisearx.pid ]]; then
kill $(cat $RUN_DIR/gunicornsearx.pid)
rm $RUN_DIR/gunicornsearx.pid
fi
}
rc_cmd $1Save and close the file.
Morty:
$ doas nano /etc/rc.d/morty
#!/bin/ksh
daemon="/usr/local/bin/morty"
morty_user="morty"
rc_bg=YES
. /etc/rc.d/rc.subr
rc_cmd $1Save and close the file.
Filtron:
$ doas nano /etc/rc.d/filtron
#!/bin/ksh
daemon="/usr/local/bin/filtron"
filtron_flags="-api '127.0.0.1:4005' -listen '127.0.0.1:4004' -rules '/etc/filtron/rules.json' -target '127.0.0.1:8001'"
filtron_user="filtron"
rc_bg=YES
. /etc/rc.d/rc.subr
rc_cmd $1Save and close the file.
Make the service scripts executable.
$ doas chmod +x /etc/rc.d/gunicornsearx /etc/rc.d/morty /etc/rc.d/filtronNow, enable each of the services to start at boot time.
$ doas rcctl enable filtron
$ doas rcctl enable morty
$ doas rcctl enable gunicornsearxThen, start all services one by one.
$ doas rcctl start filtron
$ doas rcctl start morty
$ doas rcctl start gunicornsearxConfigure Firewall
Back up the current packet filter firewall configuration file.
$ doas cp /etc/pf.conf /etc/pf.conf.bak Then, remove the default configuration file.
$ doas rm /etc/pf.confNext, edit a new pf.conf firewall configuration file using any text editor.
$ nano /etc/pf.confPaste the following rules to harden your server and only allow SSH, HTTP, HTTPS traffic.
# declare tcp ports
tcp_services = "{ sshd, http, https }"
# blocks all other unused ports
block all
# Allow Traffic from specified tcp ports
pass in on egress proto tcp to port $tcp_services
# Allow outgoing traffic
pass outSave and close the file.
Confirm the current firewall table with the following command.
$ doas pfctl -sr Reload the firewall.
$ doas pfctl -f /etc/pf.confTest the Server
Searx is up and running. Visit your subdomain to test the service.
http://search.example.comConclusion
Congratulations, you have hosted Searx on OpenBSD with Gunicorn and Nginx, then secured your server with HTTPS. For further in-depth documentation about the service, visit the Searx Github repository.