Eine eigene Searx-Instanz unter Ubuntu 16.04 aufsetzen

| 18 Kommentare

Nachdem ich eine eigene Instanz von Searx, die searx.site aufgesetzt habe (zu der ich auch mein erstes Firefox-Addon veröffentlicht habe), wurde ich von einigen angesprochen, die Fragen zur Installation hatten oder bei denen es Probleme gab. Des Weiteren gibt es anscheinend bisher keine Anleitung, die z.B. auf das zusätzliche Einrichten des Filtron Proxys zum Schutz von Searx eingeht oder die die Einrichtung von Nginx mit Letsencrypt thematisiert. Daher ich beschlossen mich hier an einer Anleitung zu versuchen.

Hinweisen möchte ich aber mit Nachdruck noch einmal, dass zunächst das von den Entwicklern von Searx herausgegebene Tutorial beachtet werden sollte. Dort werden nötige Änderungen sicherlich schnell eingepflegt, was hier nicht unbedingt der Fall sein muss.

Diesem Tutorial folge ich hier in den ersten Schritten auch komplett. Unterschiede zu diesem mache ich deutlich und erläutere sie. Ich

Zunächst müssen die für Searx nötigen Pakete installiert werden (hier habe ich die Anleitung so verändert, dass ich Paket, die sonst später erst installiert werden, hier schon installiere):

Vorarbeiten

sudo apt-get install git build-essential libxslt-dev python-dev python-virtualenv python-babel zlib1g-dev libffi-dev libssl-dev uwsgi uwsgi-plugin-python nginx letsencrypt

Installation und Einrichtung von Searx

Anschließend kann Searx installiert werden und der Searx-Nutzer angelegt werden:

cd /usr/local
sudo git clone https://github.com/asciimoo/searx.git
sudo useradd searx -d /usr/local/searx
sudo chown searx:searx -R /usr/local/searx

Nun werden die Abhängigkeiten in einem virtualenv installiert:

sudo -u searx -i
cd /usr/local/searx
virtualenv searx-ve
. ./searx-ve/bin/activate
./manage.sh update_packages

Danach kann ein Key für Searx erzeugt und in die Konfigurationsdatei eingefügt werden:

sed -i -e "s/ultrasecretkey/`openssl rand -hex 16`/g" searx/settings.yml

Nun kann Searx schon gestartet werden, indem man

python searx/webapp.py

eingibt.

Mit Hilfe eines Browsers, der in der Konsole läuft, wie z.B. links2, kann man nun überprüfen, ob alles korrekt läuft. Hierzu einfach http://localhost:8888 eingeben.

Wenn alles korrekt läuft die Debug-Option in der settings.yml deaktivieren:
sed -i -e "s/debug : True/debug : False/g" searx/settings.yml

Nun kann die virtuelle Umgebung und der Searx-Nutzer beendet werden. Hierfür zweimal exit eingeben.

Anschließend folgende UWSGI-Konfig-Datei erstellen (hier habe ich im Gegensatz zu Original-Anleitung noch eine Ergänzung für die Zusammenarbeit mit dem Filtron-Proxy vorgenommen, s. Anmerkung)

nano /etc/uwsgi/apps-available/searx.ini

Dies einfügen:

[uwsgi]
# Who will run the code
uid = searx
gid = searx

# disable logging for privacy
disable-logging = true

# Number of workers (usually CPU count)
workers = 4

# The right granted on the created socket
chmod-socket = 666

# Plugin to use and interpretor config
single-interpreter = true
master = true
plugin = python
lazy-apps = true
enable-threads = true

# Module to import
module = searx.webapp

# Virtualenv and python path
virtualenv = /usr/local/searx/searx-ve/
pythonpath = /usr/local/searx/
chdir = /usr/local/searx/searx/

#filtron
http = 127.0.0.1:8888

Anschließend muss diese Konfiguration aktiviert und gestartet werden:

cd /etc/uwsgi/apps-enabled
ln -s ../apps-available/searx.ini
/etc/init.d/uwsgi restart

Nginx und Let’s Encrypt

Nachdem jetzt Searx als Daemon bereits läuft, wollen wir die Seite natürlich verfügbar machen. Hierfür legen wir zunächst einen Virtual-Host an, der sich erheblich von dem doch sehr einfachen Beispiel in der Original-Anleitung unterscheidet. Wir verlassen an dieser Stelle auch die Originalanleitung. Noch ein Hinweis: example.com natürlich immer durch die eigene Domain ersetzen. Es bietet sich an sich zunächst über sudo su Root-Rechte zu besorgen.

nano /etc/nginx/sites-available/example.com.conf

Und dies dort einfügen:

server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /usr/local/searx;

access_log /dev/null;
error_log /dev/null;
# Useful for Let's Encrypt
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;

access_log /dev/null;
error_log /dev/null;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header "X-Content-Security-Policy" "default-src 'self'; object-src 'self'; script-src 'self'";

add_header X-XSS-Protection "1; mode=block";

ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_dhparam /etc/letsencrypt/dhparams.pem;
ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:EECDH:EDH:!MD5:!RC4:!LOW:!MEDIUM:!CAMELLIA:!ECDSA:!DES:!DSS:!3DES:!NULL;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 5m;
ssl_stapling on;
ssl_stapling_verify on;

root /usr/local/searx;

location / {
proxy_set_header Host $http_host;
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_pass http://127.0.0.1:4004/;
}

}

Anschließend kann diese Konfiguration bereits aktiviert werden (funktionier so aber noch nicht):

cd /etc/nginx/sites-enabled
ln -s ../sites-available/example.com.conf

Wer genau hingesehen hat, dem ist aufgefallen, dass in der Nginx-Konfiguration bereits der Pfad zu Zertifikaten von Letsencrypt angelegt waren. Diese müssen nun aber zunächst erzeugt werden. Hierzu zunächst Nginx stoppen:

systemctl stop nginx

Um dann das Zertifikat zu erzeugen:
letsencrypt certonly --standalone -d example.com

und Nginx wieder starten und das Zertifikat noch einmal neu mit der Webroot-Methode anfragen (Letsencrypt fragt, ob ein neues Zertifikat ausgestellt werden soll. Diese Option wählen):
systemctl start nginx
letsencrypt certonly --webroot -d example.com -w /usr/local/searx

Da die Zertifikate von Let’s Encrypt nur 90 Tage gültig sind, sollte man sie automatisch erneuern lassen. Hierzu legen wir einen Cron-Job an, der täglich läuft:

nano /etc/cron.daily/letsencrypt-renew

Und fügen dies ein und speicher und schließen die Datei:

#!/usr/bin/env bash
letsencrypt renew
systemctl reload nginx

Nun noch Diffie-Hellman-Parameter erzeugen (dies kann dauern!):

openssl dhparam -out /etc/letsencrypt/dhparams.pem 2048

Filtron

Mit der oben beschriebenen Konfiguration läuft Searx immer noch nicht, da die Konfiguration auf den Betrieb mit dem Proxy Filtron ausgelegt ist, der unsere Instanz z.B. vor der Nutzung durch Bots schützen soll, weil dies dazu führen könnte, dass die Suchmaschinen, die Searx anfragt uns nach einiger Zeit ablehnen.

Zunächst muss für den Betrieb von Filtron Go installiert werden (hierwird davon ausgegangen, dass immer noch der Root-Nutzer genutzt wird. Wenn nicht noch einmal „sudo su“ eingeben):

apt-get install golang

Damit wir Go persistent nutzen können, müssen wir die Standard-Shell von Dash auf Bash ändern. Hierzu

dpkg-reconfigure dash

eingeben und bei dem sich öffnenden Dialog „Nein“ wählen (Danke @matze für den Hinweis).

Dann legen wir zunächst einen Nutzer für Filtron an und weisen ihm einen Ordner zu:

cd /usr/local
mkdir filtron
useradd filtron -d /usr/local/filtron
chown filtron:filtron -R /usr/local/filtron

Anschließend machen wir uns zum Nutzer filtron und richten Go für diesen ein:

sudo -u filtron -i
cd /usr/local/filtron
mkdir ~/.go
echo "GOPATH=$HOME/.go" >> ~/.bashrc
echo "export GOPATH" >> ~/.bashrc
echo "PATH=\$PATH:\$GOPATH/bin # Add GOPATH/bin to PATH for scripting" >> ~/.bashrc
source ~/.bashrc

Anschließend kann Filtron installiert werden:
go get github.com/asciimoo/filtron

Ob die Installation funktioniert hat, kann man z.B. mit der Ausgabe der Hilfe von Filtron ausprobieren:

".go/bin/filtron" --help

Wir benötigen noch ein Regelset für Filtron (wer die folgenden Regeln verändern möchte, findet hier Informationen).

nano rules.json

Hier dies einfügen und an die eigenen Bedürfnisse anpassen:

[
{
"name": "search request",
"filters": ["Param:q", "Path=^(/|/search)$"],
"interval": 60,
"limit": 60,
"actions": [
{"name": "log",
"params": {"destination": "stderr"}},
{"name": "block",
"params": {"message": "Rate limit exceeded"}}
],
"subrules": [
{
"name": "roboagent limit",
"interval": 60,
"limit": 5,
"filters": ["Header:User-Agent=(curl|cURL|Wget|python-requests|Scrapy|FeedFetcher|Go-http-client)"],
"actions": [
{"name": "block",
"params": {"message": "Rate limit exceeded"}}
]
},
{
"name": "botlimit",
"limit": 0,
"stop": true,
"filters": ["Header:User-Agent=(Googlebot|bingbot|Baiduspider|yacybot|YandexMobileBot|YandexBot|Yahoo! Slurp|MJ12bot|AhrefsBot|archive.org_bot|msnbot|MJ12bot|SeznamBot|linkdexbot|Netvibes|SMTBot|zgrab|James BOT)"],
"actions": [
{"name": "block",
"params": {"message": "Rate limit exceeded"}}
]
},
{
"name": "IP limit",
"interval": 60,
"limit": 60,
"stop": true,
"aggregations": ["Header:X-Forwarded-For"],
"actions": [
{"name": "block",
"params": {"message": "Rate limit exceeded"}}
]
},
{
"name": "rss/json limit",
"interval": 60,
"limit": 5,
"stop": true,
"filters": ["Param:format=(csv|json|rss)"],
"actions": [
{"name": "block",
"params": {"message": "Rate limit exceeded"}}
]
},
{
"name": "useragent limit",
"interval": 60,
"limit": 15,
"aggregations": ["Header:User-Agent"],
"actions": [
{"name": "block",
"params": {"message": "Rate limit exceeded"}}
]
}
]
}
]

Wer möchte kann nun schon ausprobieren, ob Filtron läuft:

filtron -rules rules.json

Doch wir werden Filtron noch mit Hilfe von Systemd daemonizieren (Sagt man das so?). Daher den Prozess beenden (STRG+C) und den User filtron verlassen:

exit

Nun eine neue Datei erstellen:

nano /etc/systemd/system/filtron.service

Und dies einfügen und wie gehabt speichern und schließen:

[Unit]
Description=filtron proxy

[Service]
Type=simple
User=filtron

ExecStart=/usr/local/filtron/.go/bin/filtron -rules /usr/local/filtron/rules.json

TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target

Anschließend kann dann der neue Service aktiviert und gestartet werden:

systemctl enable /etc/systemd/system/filtron.service
systemctl start filtron.service

Ob Filtron wunschgemäß läuft, kann nun folgendermaßen überprüft werden:
systemctl status filtron.service

Anpassungen
Jetzt sollte die Metasuchmaschine Searx mit dem Proxy Filtron laufen. Abschließend können noch einige Anpassungen vorgenommen werden. So habe ich z.B. Google als Quelle deaktivieren müssen, da hier immer eine Fehlermeldung auftauchte. Das Problem ist aber bekannt. Suchmaschinen können in der Datei /usr/local/searx/searx/settings.yml aktiviert und deaktivert werden. Nur immer daran denken, nach einer Veränderung UWSGI neu zu starten:

systemctl restart uwsgi

Viel Spaß beim Aufsetzen von Searx! Ich freue mich über (konstruktives) Feedback!

Mir haben beim Verfassen dieser Anleitung folgende Quellen sehr geholfen:

Autor: Alexander Kallenbach

Mein Name ist Alexander Kallenbach. Ich schreibe hier auf Scroom über alles mögliche – vor allem aber über IT. Hierbei interessieren mich besonders freie und/oder quelloffene Software sowie deren Entwicklung und Einsatz. Außerdem interessieren mich Auswirkungen von IT auf unser Leben. Hierbei ist die Nutzung von Daten und somit auch Datenschutz ein Themenbereich.

18 Kommentare

  1. Hi Alexander, ich finde es super, hier eine solche Anleitung zu finden. Habe natürlich direkt damit begonnen, bleibe aber leider bei der Einrichtung von Filtron hängen.

    $ source ~/.bashrc
    -sh: 1: source: not found

    /usr/local# go get github.com/asciimoo/filtron
    package github.com/asciimoo/filtron: cannot download, $GOPATH not set. For more details see: go help gopath

    Wo ist der Fehler?

    Gruß matze

    • Hm, nutzt du ein Standard-Ubuntu? Ist dir aufgefallen, dass die zwei Zeilen über source ~/.bashrc eigentlich eine ist? (Habe gerade ein Plugin installiert, mit dessen Hilfe jetzt auch u.a. Zeilennummern angezeigt werden)

      Habe es gerade noch einmal auf einer andern Maschine getestet und dort ging es.

  2. Ja, ein Standard Ubuntu Server 16.04.03, der als voreingestellte Shell /bin/dash eingestellt hat und diese hat „source“ wohl nicht mit an Board. Kann daher auch nicht ausgeführt werden. Einfach zu /bin/bash wechseln
    $ls -l `which sh` #überprüfen
    /bin/sh -> dash

    $sudo dpkg-reconfigure dash # „nein“ wählen

    $ls -l `which sh`
    /bin/sh -> bash

    Ich musste beim nginx noch folgende auskommentierte Zeilen in der /etc/nginx/nginx.conf aktivieren, sonst startete der Webserver nicht:

    server_names_hash_bucket_size 64;
    server_name_in_redirect off;

    Und schon läuft der Rest 🙂

    Gruß matze

  3. Hallo Alexander,

    ich gehe mal davon aus, das bei Ubuntu Server in der minimalen Ausführung, „source“ in der dash nicht enthalten ist, in der normalen Ubuntu Version, sprich Ubuntu Desktop aber schon.

    Gruß,

    Matze

  4. ja, oder meiner 🙂

    Gruß,
    Matze

  5. Hello
    Wow amazing tutorial

    I was thinking that could be great have a docker with this installation, could be a good idea to grow up more public instances???

    Why u use filtron and not morty?

    Thanks, and great job again

  6. Hi Alexander,

    ich versuche gerade auf meinem Ubuntu 16.04 Server Deine super Anleitung abzuarbeiten.

    Leider kommt bei dem Befeh
    „echo „GOPATH=$HOME/.go“ >> ~/.bashrc“
    folgende Fehlermeldung:
    $ echo „GOPATH=$HOME/.go“ >> ~/.bashrc
    -sh: syntax error near unexpected token `;&‘
    $

    Weißt Du was ich hier falschmache?
    Wäre echt super.

    Vielen Dank und Gruß
    Tom

    • Hey Tom,

      hast du den Hinweis von Matze (steht mittlerweile auch im Artikel) beachtet?:

      „dpkg-reconfigure dash

      eingeben und bei dem sich öffnenden Dialog „Nein“ wählen“

      Anscheinend waren aber auch die entsprechenden Zeichen in meinem Beitrag nicht korrekt formatiert. Ich habe dies geändert, so dass du diese jetzt auch wieder kopieren können müsstest.

      MfG

      Alexander

      PS: Deinen zweiten Kommentar lösche ich, da er ja dieselbe Anfrage enthält.

  7. Hi Alex,

    ja das habe ich so gemacht.
    Und sorry… Mein Kommentar wurde nicht angezeigt, deswegen hatte ich erneut geschrieben.

    Gruß
    Tom 🙂

  8. Hallo,

    wie sieht es mit der Installation von Morty aus? Macht die Sinn, ist das überflüssig?Wenn das sinnvoll ist, könntest du deine Anleitung noch um die Installationsschritte für Morty erweitern?

    Gruß
    Simon

  9. Hallo!
    In dieser Anleitung wird noch Morty installiert. https://raspiblog.noblogs.org/post/2018/01/27/installing-searx-with-apache-and-morty/

    Ist Das sinnvoll?

    Gruß Simon

  10. Hallo

    wenn ich nach deiner Beschreibung gehe bekomme ich in Nginx eine weiße Seite. Und zwar ab da wo ich unter:

    location / {
    proxy_set_header Host $http_host;
    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_pass http://127.0.0.1:4004/;

    eingebe. Da bekomme ich ein connection refused. Ich habe searx, uwsgi und filtron installiert nach der Anleitung. Den Rest nicht.

    Hat jemand eine Idee war es nicht klappt? Reicht der Eintrag in der searx.ini http = 127.0.0.1:8888

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.