Zum Inhalt

Kategorie: Raspberry Pi

Pi-hole und DNS over HTTPS (DoH)

Out of the box kann Pi-hole bisher kein DoH, aber ein Docker Container eilt zur Hilfe: crazymax/cloudflared

Diesen kann man zusammen mit Pi-Hole starten und via TUNNEL_DNS_UPSTREAM einen oder mehrere DoH Server mitgeben. Pi-Hole bekommt dann den Container als DNS Server und nutzt dann (in-) direkt DoH.

version: "2.1"

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8000:80/tcp"
      - "8443:443/tcp"
    environment:
      TZ: Europe/Berlin
      WEBPASSWORD: zaewooQu0kaequaZ
      DNS1: 192.168.1.130#5053
      DNS2: 192.168.1.105#5053
      ServerIP: 192.168.1.105
      VIRTUAL_HOST: pihole.fritz.box
    volumes:
       - './etc-pihole/:/etc/pihole/'
       - './etc-dnsmasq.d/:/etc/dnsmasq.d/'
    dns:
      - 127.0.0.1
      - 46.182.19.48
    restart: unless-stopped
    networks:
        - pihole_net
    depends_on:
        - cloudflared

  cloudflared:
    image: crazymax/cloudflared:latest
    container_name: cloudflared
    ports:
      - "5053:5053/udp"
      - "49312:49312/tcp"
    environment:
      TZ: "Europe/Berlin"
      TUNNEL_DNS_UPSTREAM: "https://anycast.uncensoreddns.org/dns-query,https://unicast.uncensoreddns.org/dns-query,https://dns.digitale-gesellschaft.ch/dns-query,https://dot.ffmuc.net/dns-query"
      TUNNEL_DNS_PORT: 5053
    restart: unless-stopped
    networks:
        - pihole_net

networks:
  pihole_net:
    enable_ipv6: true
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "true"
    ipam:
      driver: default
      config:
      - subnet: fc00::/64

Bei mir sind das dann 192.168.1.130#5053 und 192.168.1.105#5053. Redundanz muss sein. 😉 Und via Port 49312 gibt es noch ein paar Metriken im Prometheus Format.

DoT (DNS over TLS) wäre auch eine Alternative, habe ich bisher aber nicht ausprobiert. Vielleicht bekommt Pi-hole ja auch irgendwann einmal native DoH oder DoT Unterstützung, dann sind Bastellösungen wie diese überflüssig.

Abschließend: Braucht man das wirklich? Nein, kann man aber.

Kleines Update vom 04.02.2021: IPv6 Konfiguration hinzugefügt, damit Pi-Hole als auch Cloudflared via IPv6 erreichbar sind im LAN.

Raspberry Pi Distro Update

Mein etwas in Jahre gekommener Raspberry Pi hat seit einiger Zeit keine Updates mehr bekommen. Auch wenn auf dem System nur noch FHEM und ein Pi-hole (in Docker) laufen, sind (Sicherheits-) Updates nicht unwichtig. Ein Blick auf die Infoseite zu Debian LTS bestätigte dann, mein raspbian auf Basis von Jessie (8) bekommt keinen Support mehr. Leider ist ein direktes Update von Jessie (8) auf Buster (10) nicht möglich bzw. nicht sinnvoll. Daher ist ein Zwischenschritt auf Stretch (9) notwendig. Im Endeffekt dauert es nur alles etwas länger, die Schritte für die Updates sind identisch. Vorab hab ich ein Backup der SD Karte mit Win32DiskImager gemacht; für alle Fälle.

Update Jessie auf Stretch:

sudo sed -i /deb/s/jessie/stretch/g /etc/apt/sources.list
sudo sed -i /deb/s/jessie/stretch/g /etc/apt/sources.list.d/*.list
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo apt-get autoremove
sudo apt-get autoclean
sudo reboot

Das hat sogar komplett problemlos geklappt. Bei Update von Stretch auf Buster kam dann aber ein kleines Problem dazwischen:

sudo sed -i /deb/s/stretch/buster/g /etc/apt/sources.list
sudo sed -i /deb/s/stretch/buster/g /etc/apt/sources.list.d/*.list
sudo apt-get update

sudo apt-get upgrade
# Hier funktionierte nun apt-listchanges nicht mehr, wegen einem fehlenden Python Paket: debconf
sudo apt-get remove apt-listchanges
sudo apt-get upgrade # neuer Versuch
sudo apt-get dist-upgrade

# debconf wieder manuell installieren
wget http://ftp.de.debian.org/debian/pool/main/d/debconf/debconf_1.5.61_all.deb
sudo dpkg -i debconf_1.5.61_all.deb

sudo apt-get autoremove
sudo apt-get autoclean
sudo reboot

Das zweite Update hat deutlich länger gedauert, aber letztendlich auch funktioniert. Hier das Ergebnis:

pi@raspberrypi:~ » cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

Pi-hole mit docker-compose

Auf einem Raspberry Pi oder einem anderen System mit einem Docker Daemon lässt sich Pi-hole sehr leicht betreiben. Hier das dazugehörige docker-compose.yml:

version: "2.1"

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8000:80/tcp"
      - "8443:443/tcp"
    environment:
      TZ: Europe/Berlin
      WEBPASSWORD: peeGhoh7voh9thim
      DNS1: 46.182.19.48
      DNS2: 80.241.218.68
      ServerIP: 192.168.1.105
      ServerIPv6: fd00::935d:666d:f026:8b11
      PROXY_LOCATION: pihole.fritz.box
      VIRTUAL_HOST: pihole.fritz.box
    volumes:
       - './etc-pihole/:/etc/pihole/'
       - './etc-dnsmasq.d/:/etc/dnsmasq.d/'
    dns:
      - 127.0.0.1
      - 46.182.19.48
    restart: unless-stopped
    networks:
        - pihole_net

networks:
  pihole_net:
    enable_ipv6: true
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "true"
    ipam:
      driver: default
      config:
      - subnet: fc00::/64

Angepasst werden müssen die IP Adresse (hier 192.168.1.105), VIRTUAL_HOST und am besten auch WEBPASSWORD. Die beiden hinterlegten DNS Server gehören zu dismail.de bzw. digitalcourage.de. Über Port 8000 ist dann die Weboberfläche erreichbar. Die IP Adresse des Docker Hosts stellt dann via Port 53 Pi-hole für DNS Anfragen bereit.

Update: IPv6 funktioniert nur bis zur docker-compose Version 2.1 und mit der zusätzlichen Network Konfiguration unten.

Via Telegram über SSH Logins informieren

Über die Telegram API kann man sich bequem benachrichtigen lassen, wenn sich ein Benutzer per SSH auf einem System eingeloggt hat. Dazu folgende Zeilen in die Datei /etc/ssh/sshrc einfügen.

IP=`echo $SSH_CONNECTION | cut -d " " -f 1`
HOSTNAME=`hostname`
MESSAGE="SSH Login on $HOSTNAME as $USER from $IP"
curl --output /dev/null -s -X POST -H 'Content-Type: application/json' -d "{\"chat_id\": \"-123456789\", \"text\": \"$MESSAGE\", \"disable_notification\": true}" https://api.telegram.org/bot123456789:hgDW0mvUcio_AF4Za1nh-aY7PX/sendMessage

Wie an die Chat ID und das Token für den Bot zu kommen ist, ist z.B. hier beschrieben.

ffmpeg unter Raspbian 8 Jessie installieren

Ob wirklich Raspbian 8 (Jessie) benutzt wird, kann so überprüft werden:

cat /etc/os-release

Die folgenden Befehle fügen das Jessie Backports Repository hinzu und installieren anschließend ffmpeg:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553
echo 'deb http://httpredir.debian.org/debian jessie-backports main contrib non-free' | sudo tee -a /etc/apt/sources.list.d/jessie-backports.list
sudo apt-get update
sudo apt-get install ffmpeg

Fertig. 🙂

SD Karte vom Raspberry Pi auf kleinere SD Karte klonen

Folgende Situation: Die 16GB SD Karte in meinem Raspberry Pi zickt in letzter Zeit regelmäßig wegen defekten Sektoren rum. Diverse Programme starten z.B. nicht mehr und mussten erneut installiert werden. Ärgerlich. Da ich zusätzlich noch einen 32GB USB Stick angeschlossen haben und auch ein NAS im Netzwerk zur Verfügung steht, dachte ich mir, ersetze ich die alte 16GB SD Karte einfach durch eine neue. Leider ist die neue SD Karte ein paar wenige MB kleiner als die alte, daher war eine einfache Prozedur à la Image erstellen (entweder mit Win32 Disk Imager unter Windows oder dd unter Linux) und zurückspielen keine Möglichkeit, selbst wenn die 16GB Speicherplatz auf der SD Karte alles andere als ausgenutzt wurden.

Folgende Prozedur hat nun scheinbar Erfolg gebracht. Alle Schritte habe ich auf einem Notebook mit SD Kartenleser durchgeführt.

Schritt 1: Partitionen verkleinern

  1. Die root Partition auf der alten SD Karte verkleinern, in meinem Fall großzügig um 1GB.
  2. Auch die erweiterte Partition um 1GB verkleinern. Dieser Schritt ist wichtig!

Schritt 2: Image mit dd erstellen

  1. sudo dd if=/dev/mmcblk1 of=~/raspi.img
    Hierbei wird die komplette SD Karte als Image gespeichert, d.h die Datei ist anschließend ca. 16GB groß.

Schritt 3: Image verkleinert auf die neue SD Karte schreiben

  1. Mit sudo fdisk -l ~/raspi.img die Größe der Partitionen anzeigen lassen:
    dennis@MSI-GE60:~$ sudo fdisk -l ~/raspi.img
    Medium raspi.img: 14,5 GiB, 15523119104 Bytes, 30318592 Sektoren
    Einheiten: sectors von 1 * 512 = 512 Bytes
    Sektorengröße (logisch/physisch): 512 Bytes / 512 Bytes
    I/O Größe (minimal/optimal): 512 Bytes / 512 Bytes
    Typ der Medienbezeichnung: dos
    Medienkennung: 0x000b2b81
    
    Gerät Boot Start Ende Sektoren Größe Id Typ
    raspi.img1 8192 2289062 2280871 1,1G e W95 FAT16 (LBA)
    raspi.img2 2289063 28221439 25932377 12,4G 5 Erweiterte
    raspi.img5 2293760 2359293 65534 32M 83 Linux
    raspi.img6 2359296 2488319 129024 63M c W95 FAT32 (LBA)
    raspi.img7 2490368 28221439 25731072 12,3G 83 Linux
  2. Hier sind raspi.img2 und raspi.img7 relevant: Die erweiterte und die root Partition:
    Beide haben als Ende 28221439. Ohne die Verkleinerungen aus dem ersten Schritt waren es in meinem Fall 30318591.
  3. Und so landet das erstelle Image auf der neuen SD Karte:
    sudo dd if=~/raspi.img of=/dev/mmcblk1 bs=1024 count=28221439
  4. Der Vorgang dauert sehr lange und es kommt am Ende eine Fehlermeldung, die neue SD Karte sei zu klein. Das ist korrekt und kann ignoriert werden, da dieser Bereich außerhalb der Partitionen liegt und damit keine Daten betroffen sind.
  5. (optional) Die Partionen können mit gparted wieder auf maximale Größe erweitert werden.
  6. Von der neuen SD Karte kann der Raspberry Pi nun booten.

Ach ja, der ganze Spaß hat 5 oder 6 Anläufe an mehreren Abenden benötigt. Adhoc hat das leider nicht funktioniert.

Datenbanken auf dem Raspberry Pi 3?

Ist es eine gute Idee, Datenbanken auf dem Raspberry Pi 3 zu betreiben? Nach meinen Erfahrungen der letzten Wochen, rate ich davon ab. Jedenfalls von größeren Datenbanken. Auf meinem Raspberry Pi 3 läuft eine PostgreSQL, die für kleine Datenmengen ausreichend ist, z.B. für Gogs (Git Repository). Zusätzlich liefen für ca. 1,5 Jahre Messdaten via FHEM in die Datenbank, was zu ca. 2,5 Millionen Datensätzen geführt hat. Und damit ist der Raspberry Pi 3 definitiv überfordert. Davor lagen diese Messdaten in einer SQLite Datenbank, die eine noch schlechtere Performance bot. Eine Java Applikation, die ebenfalls auf dem Raspberry Pi 3 läuft, hat für das Laden und Aufbereiten der Daten ca. 30 Minuten gebraucht. Die (momentane) Lösung ist, dass ich die Messdaten nun in einer MySQL Datenbank speichere, die auf einem vServer bei Host Europe läuft. Die Tabellen haben eine etwas andere Struktur, da ich direkt nach dem INSERT von neuen FHEM Messdaten diese via Trigger aufbereitet in eine andere Tabelle ablege. Der Start der Java Applikation hat sich auf ca. 30 Sekunden (nicht mehr Minuten!) reduziert. Der Zugriff auf die MySQL Datenbank erfolgt via SSH Tunnel, um die MySQL Datenbank auf dem vServer nicht direkt im Internet verfügbar zu machen.

nginx startet nicht mehr

Nach einem Reboot startete nginx auf meinem Raspberry Pi 3 nicht mehr. Es kam nur folgende Meldung:

pi@raspberrypi:/etc/nginx » sudo service nginx start
Job for nginx.service failed. See 'systemctl status nginx.service' and 'journalctl -xn' for details.

Auch der Hinweis auf systemctl status nginx.service brachte keine Erkenntnis:

pi@raspberrypi:/etc/nginx » sudo systemctl status nginx.service
? nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
   Active: failed (Result: signal) since Mo 2017-08-14 14:34:39 CEST; 6s ago
  Process: 17080 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=killed, signal=SEGV)

Aug 14 14:34:39 raspberrypi systemd[1]: nginx.service: control process exited, code=killed status=11
Aug 14 14:34:39 raspberrypi systemd[1]: Failed to start A high performance web server and a reverse proxy server.
Aug 14 14:34:39 raspberrypi systemd[1]: Unit nginx.service entered failed state.

Die letztendliche Lösung bestand aus dem Entfernen und der erneuten Installtion von nginx:

pi@raspberrypi:/etc/nginx » sudo apt-get remove nginx nginx-common
...
pi@raspberrypi:/etc/nginx » sudo apt-get install nginx
...

Verstanden habe ich Problem und Ursache nicht. Ich hoffe allerdings, dass das nicht die ersten Anzeichen sind, das sich die Speicherkarte im meinem Raspberry Pi ihrem Lebensende neigt.

 

SD Card Performance beim Raspberry Pi

Es gibt zwei praktische Scripte, um die Performance der SD Card im Raspberry Pi zu messen:

Leider ist die Performance meiner Sandisk SD Card überschaubar:

CONFIG:
CLOCK : 50.000 MHz
CORE : 400 MHz, turbo=
DATA : 512 MB, /root/test.dat

HDPARM:
======
Timing O_DIRECT disk reads: 64 MB in 3.03 seconds = 21.13 MB/sec
Timing O_DIRECT disk reads: 54 MB in 3.07 seconds = 17.60 MB/sec
Timing O_DIRECT disk reads: 64 MB in 3.05 seconds = 21.01 MB/sec

WRITE:
=====
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 106,699 s, 5,0 MB/s
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 102,108 s, 5,3 MB/s
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 96,1672 s, 5,6 MB/s

READ:
====
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 42,0239 s, 12,8 MB/s
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 40,9591 s, 13,1 MB/s
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 38,3425 s, 14,0 MB/s

RESULT (AVG):
============
Overlay config core_freq turbo overclock_50 WRITE READ HDPARM
400 0 50.000 MHz inf MB/s inf MB/s 19.90 MB/s

Update vom 02.10.2017: Hier meine neue Toshiba SD Karte mit etwas besserer Performance:


CONFIG:
CLOCK : 50.000 MHz
CORE : 400 MHz, turbo=
DATA : 512 MB, /root/test.dat

HDPARM:
======
Timing O_DIRECT disk reads: 66 MB in 3.06 seconds = 21.54 MB/sec
Timing O_DIRECT disk reads: 66 MB in 3.06 seconds = 21.59 MB/sec
Timing O_DIRECT disk reads: 66 MB in 3.07 seconds = 21.47 MB/sec

WRITE:
=====
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 66,0162 s, 8,1 MB/s
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 63,7488 s, 8,4 MB/s
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 66,6666 s, 8,1 MB/s

READ:
====
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 24,804 s, 21,6 MB/s
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 24,687 s, 21,7 MB/s
512+0 Datensätze ein
512+0 Datensätze aus
536870912 Bytes (537 MB) kopiert, 24,8026 s, 21,6 MB/s

RESULT (AVG):
============
Overlay config core_freq turbo overclock_50 WRITE READ HDPARM
400 0 50.000 MHz inf MB/s inf MB/s 21.55 MB/s