Posts mit dem Label raspberrypi werden angezeigt. Alle Posts anzeigen
Posts mit dem Label raspberrypi werden angezeigt. Alle Posts anzeigen

19.04.2017

nginx auf Raspberry Pi beim booten automatisch starten (sysvinit)

Das im Titel geforderte hört sich erst mal nicht zu schwierig an, war in der Praxis aber mit einigen Fallstricken gespickt. Vielleicht hilft der Beitrag ja dem Einen oder Anderen, der wie ich kein wirklicher Linux Guru ist.

Hintergrund

Ich habe nginx auf einem Raspberry Pi (Standard Raspian image) als reverse proxy laufen um mit einer Portfreigabe auf dem Router verschiedene interne Dienste über das Internet erreichen zu können. Anleitungen gibt es viele im Netz und der proxy funktioniert soweit gut.
Vorausgesetzt nginx läuft....
Da der Raspberry auch ab und zu mal rebooted wird, sollte der nginx Dienst natürlich automatisch starten.


nginx beim booten starten, Versuch 1


Ein SysVinit script war schnell erstellt und wenn man in den nginx Konfigurationsdateien keine Fehler gemacht, läßt sich der server auch per
sudo /etc/init.d/nginx start
einfach starten.

Also einfach per
sudo update-rc.d nginx defaults
mit den entsprechenden runlevels verknüpft und rebooted. Das Ergebnis: Fehlschlag.

Der Grund findet sich in /var/log/nginx/error.log:
host not found in upstream "raspi1" in /etc/nginx/sites-enabled/main

nginx prüft die proxy Ziele beim Start und DNS ist anscheinend noch nicht verfügbar zu diesem Zeitpunkt.

Im /etc/init.d/nginx start script sind die Netzwerkdienste eigentlich als "Required" angegeben.
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO
Allerdings scheint DNS trotzdem noch nicht zu funktionieren, wenn nginx gestartet wird.
Ein manuelles Starten per
sudo /etc/init.d/nginx start
direkt nach dem Einloggen funktioniert.


nginx beim booten starten, Versuch 2

Nächster Versuch: nginx später starten.
sudo update-rc.d nginx defaults 99 10

No cigar. Funktioniert auch nicht.


nginx beim booten starten, Versuch 3


Nächster Versuch: Eintrag in rc.local

sudo nano /etc/rc.local

Und nginx von dort starten. Den Aufruf vor der letzten Zeile "exit 0" einfügen.

!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
sudo /etc/init.d/nginx start
exit 0

Dieser Versuch war endlich von Erfolg gekrönt.

Falls jemand systemd auf dem aktuellsten Raspian Jessie verwendet, sollte dieser hack nicht mehr erforderlich sein, da die Abhängigkeiten zu Netzwerkdiensten feiner angegeben werden können und man somit eine funktionierende Abhängigkeit zum DNS angeben kann (angeblich, noch nicht getestet).

Eine andere Lösung wäre, wenn nginx trotz "fehlendem" upstream starten würde und im Betrieb einen HTTP 5xx zurückgeben würde wenn der upstream wirklich nicht erreichbar ist.

10.10.2015

ADS-B Empfang per DVB-T Stick

Durch Zufall bin ich auf die Verwendung eines 10€ DVB-T Sticks als Software Defined Radio (SDR) gestoßen. Damit FM Radio zu hören ist nicht wirklich spannend, daß kann man auch einfacher ohne große Bastelei haben. Die Möglichkeit damit ADS-B Daten von Flugzeugen im Umkreis zu empfangen ist da schon interessanter. Im Folgenden wird Schritt für Schritt erklärt wie die benötigten Treiber und Grundprogramme (RTL-SDR) sowie dump1090 zum ADS-B Empfang aud einem Raspberry Pi B+ installiert werden. Dump1090 bring einen Webserver mit, der eine Kartenansicht mit allen empfangenen Flugbewegungen im Browser zeigt. Die Installationsschritte stammen aus verschiedenen Internetquellen, eine Suche sollte für fast jeden Spezialfall ein Ergebnis bringen.

Den DVB-T Stick als Software Defined Radio im Frequenzbereich von ca. 24-1800 MHz benutzen kann man auch z.B. mit SDRSharp (SDR#).So kann man auch unter Windows erstmal mit der Hardware spielen. Achtung: Nicht den mitgelieferten Treiber installieren, der ist "nur" für DVB-T Empfang gedacht.


Benötigte Hardware

DVB-T Stick

Ich benutze zwei Sticks, einen mit dem Chipsatz RTL2832U+R820T und einen mit RTL2832U+R820T2. Der R820T2 soll etwas besser sein als der R820T, da ich ihn aber erst jetzt in Betrieb nehme, kann ich noch nichts dazu  sagen.
Bei den einschlägigen Online-Shops sollten sich beide Versionen für ~10€ inklusive Versand finden lassen.

Antenne

Wenn man nicht abseits jeglicher Flugrouten wohnt reicht für die ersten Versuche die mitgelieferte DVB-T Antenne aus. Um die Empfangleistung zu optimieren kann man später mit kleinem finanziellen Aufwand auch eigene Antennen basteln.

Installation

Die Installation geschieht in zwei Schritten. Zuerst wird der Treiber für den DVB-T Stick installiert (RTL-SDR) und danach dump1090 um ADS-B Nachrichten zu Empfangen. Den Stick am besten erst nach erfolgter Installation der Software einstecken.

Installation von RTL-SDR

Folgende packages installieren:

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install git-core
$ sudo apt-get install git
$ sudo apt-get install cmake
$ sudo apt-get install libusb-1.0-0-dev
$ sudo apt-get install build-essential

Folgende Befehle laden den RTL-SDR Treiber Sourcecode für den DVB-T Stick und starten die Installation

$ cd ~
$ git clone git://git.osmocom.org/rtl-sdr.git
$ cd rtl-sdr
$ mkdir build
$ cd build
$ cmake ../ -DINSTALL_UDEV_RULES=ON
$ make
$ sudo make install
$ sudo ldconfig

$ cd ~
$ sudo cp ./rtl-sdr/rtl-sdr.rules /etc/udev/rules.d/
$ sudo shutdown -h now

Nun den DVB-T Stick einstecken und den Raspberry wieder starten.

Test

Mit 'rtl_test' kann die Installation getestet werden. Die Ausgabe sollte ungefähr wie folgt aussehen, der Test kann mit Ctrl-C abgebrochen werden.

$ rtl_test
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
Sampling at 2048000 S/s.

Sollte der Test folgende Meldung bringen:
Kernel driver is active, or device is claimed by second instance
In the first case, please either detach or blacklist the kernel
(dvb_usb_rtl28xxu), or enable automatic detaching at compile time

usb_claim_interface error -6
Error opening the RTLSDR device: Device or resource busy
Ist der Stick schon vom Betriebssystem als TV Gerät in Beschlag genommen. Dies kann man folgendermassen verhindern:

$ sudo nano /etc/modprobe.d/rtl-sdr-blacklist.conf

Und folgende Einträge machen:
blacklist dvb_usb_rtl28xxu
blacklist e4000
blacklist rtl2832

Danach den Raspberry neustarten.

Installation von dump1090

dump1090-mutability installieren
$ wget https://github.com/mutability/mutability-repo/releases/download/v0.1.0/mutability-repo_0.1.0_armhf.deb
$ sudo dpkg -i mutability-repo_0.1.0_armhf.deb
$ sudo apt-get update && sudo apt-get install dump1090-mutability
Es empfiehlt sich dump1090 automatisch per init script starten zu lassen.

Dump1090 kann jederzeit mit folgendem Befehl konfiguriert werden:
$ sudo dpkg-reconfigure dump1090-mutability
Zum Anfang sollte man mit den Standardeinstellungen hinkommen. Will man von einem anderen Gerät den dump1090 Webserver erreichen, muß man 'Interface address to bind to' leer lassen, andernfalls kann man den Server nur vom Raspberry selbst aus erreichen.
Die Kartenansicht kann je nach Konfiguration z.B. unter http://meinraspberry:8080 aufgerufen werden (meinraspberry natürlich ensprechend ersetzen).

02.10.2015

Dynamisches DNS per Rasperry Pi aktualisieren

Da mein DSL Router (FritzBox) nur einen Anbieter für dynamisches DNS (DynDNS) gleichzeitig aktualisiert und ich der automatischen Aktualisierung nicht 100% traue wird diese Aufgabe jetzt zusätzlich von einem Raspberry Pi erledigt, was folgende Vorteile hat:
  • Man kann mehrere DynDNS services gleichzeitig benutzen und aktualisieren;
  • Die Aktualisierung wird per cron regelmäßig angestoßen;
  • Alle Aktivitäten werden in ein log file geschrieben;
  • Die Lösung ist erweiterbar (z.B. email Benachrichtigung bei IP Änderung).
Das script basiert auf der Arbeit von https://github.com/AntonioCS/no-ip.com-bash-updater. Das geänderte script benutzt unter anderem curl statt wget, da ich mit wget Probleme bei der SSL Verbindung hatte. Wer weitere oder andere Anbieter von dynamischem DNS verwenden will, muß sich die ensprechende update URL besorgen und das bestehende script erweitern.

Zuerst das script anlegen mit, z.B. mit:

nano ~/no-ip-updater.sh
Folgenden Inhalt einfügen:
#!/bin/bash
# The script assumes existing user 'pi'
# Ensure to URL encode if required (e.g.encode the @ as %40)
# Change below to match your NO-IP user/email
USERNAME=your.name%40email.com
# Change below to match your NO-IP password
PASSWORD=your-NO-IP-cleartext-password
# Change below
HOST_NOIP=mygreathostname.ddns.org
LOGFILE=/var/log/no-ip-updater.log
STOREDIPFILE=/home/pi/current_ip
USERAGENT="My bash No-IP Updater"

if [ ! -e $STOREDIPFILE ]; then
  touch $STOREDIPFILE
fi

NEWIP=$(wget -q -O - "http://myexternalip.com/raw")
STOREDIP=$(cat $STOREDIPFILE)

if [ "$NEWIP" != "$STOREDIP" ]; then
  RESULT=$(curl --silent --user-agent "$USERAGENT" "https://$USERNAME:$PASSWORD@dynupdate.no-ip.com/nic/update?hostname=$HOST_NOIP&myip=$NEWIP" >> $LOGFILE)
  LOGLINE="[$(date +"%Y-%m-%d %H:%M:%S")] Updated IP from $STOREDIP to $NEWIP"
  #ADD MORE SERVICES HERE IF REQUIRED
  echo $NEWIP > $STOREDIPFILE
else
  LOGLINE="[$(date +"%Y-%m-%d %H:%M:%S")] No IP change"
fi
echo $LOGLINE >> $LOGFILE
exit 0
Das script abspeichern (bei nano mit Ctrl-O Ctrl-X) und ausführbar machen.

chmod +x ~/no-ip-updater.sh
Jetzt fehlt noch der Eintrag in der crontab um das script regelmäßig auszuführen. Die crontab des aktuellen Benutzers (pi) editieren mit:

crontab -e
Und folgende Zeile hinzufügen um das script z.B. alle 20 Minuten auszuführen:

*/20 * * * *  sudo /home/pi/no-ip-updater.sh
Fertig.

19.02.2014

Raspberry Pi - CPU Temperatur mit Cacti loggen

Der Raspberry Pi bietet die Möglichkeit die Temperatur der CPU und der GPU auszulesen. Aus verschiedenen Gründen (Gehäuseeinbau, Overclocking, ...) kann es sinnvoll sein diese Temperaturen im Auge zu behalten. Auf meinem betroffenen Pi läuft schon eine Cacti Installation, also warum diese nicht für diesen Zweck benutzen. Codebeispiele zum Auslesen der Temperaturen findet man leicht im Netz, hier zwei Beispiele:

Shell
#!/bin/bash
cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp)
cpuTemp1=$(($cpuTemp0/1000))
cpuTemp2=$(($cpuTemp0/100))
cpuTempM=$(($cpuTemp2 % $cpuTemp1))

gpuTemp0=$(/opt/vc/bin/vcgencmd measure_temp)
gpuTemp0=${gpuTemp0//\'C/}
gpuTemp0=${gpuTemp0//temp=/}
echo  gpu_temp:$gpuTemp0 cpu_temp:$cpuTemp1"."$cpuTempM

Python
import commands

def get_cpu_temp():
    tempFile = open( "/sys/class/thermal/thermal_zone0/temp" )
    cpu_temp = tempFile.read()
    tempFile.close()
    return float(cpu_temp)/1000
    # Uncomment the next line if you want the temp in Fahrenheit
    #return float(1.8*cpu_temp)+32

def get_gpu_temp():
    gpu_temp = commands.getoutput( '/opt/vc/bin/vcgencmd measure_temp' ).replace( 'temp=', '' ).replace( '\'C', '' )
    return  float(gpu_temp)
    # Uncomment the next line if you want the temp in Fahrenheit
    # return float(1.8* gpu_temp)+32

def main():
  print "cpu_temp:{0:.1f} gpu_temp:{1:.1f}".format(get_cpu_temp(),get_gpu_temp())
if __name__ == '__main__':
    main()

Nach dem Test der Skripte in der shell fehlt - um die Temperaturen mit Cacti zu loggen - also nur noch eine Cacti "Data Input Method", die eins der Skripte aufruft, eine Cacti "Data Source" und ein Cacti "Graph", der die Temperaturen anzeigt.

Leider stellte sich der Erfolg nicht umgehend ein. Das RRD file blieb leer und ein Blick in das Cacti log file zeigte:
CMD: bash /home/pi/cacti/pitemp.sh, output: U 
Diese Zeile bedeutet, daß bei der Ausführung des Skripts irgendetwas schiefgegangen ist. Leider weiß ich nicht wie man mehr Details zu dem aufgetretenen Fehler rauskriegen kann (für Hinweise wie man das macht wäre ich dankbar). Da das Skript außerhalb von Cacti funktioniert, lohnt es sich hier die Rechtevergabe genauer unter die Lupe zu nehmen. Die Cacti poller.php, welche die einzelnen Skripte zum Daten sammeln aufruft läuft bei meiner Installation unter dem Benutzer "www-data", ich habe allerdings an verschiedener Stelle auch schon von anderen Benutzern (z.B. "cactiuser") gelesen. Ein Blick in die crontab verschafft hier Klarheit.
Es stellte sich das Kommando zum Auslesen der GPU Temperatur als Übeltäter heraus.
sudo -u www-data /opt/vc/bin/vcgencmd measure_temp
VCHI initialization failed

Um die GPU Temperatur mit obigem Kommando auslesen zu können muß der Benutzer, unter welchem die poller.php ausgeführt wird, in die Gruppe "video" aufgenommen werden.

usermod -a -G video www-data
Man sollte seine Skripte also immer unter dem Benutzer testen, welcher auch die poller.php von Cacti ausführt. Ein erneuter Blick in das Cacti log file zeigt nun, daß das Skript korrekt ausgeführt wird.
CMD: bash /home/pi/cacti/pitemp.sh, output: gpu_temp:42.2 cpu_temp:42.2
Wem die GPU Temperatur nicht so wichtig ist, z.B. im headless  Betrieb wo die GPU Temperatur wahrscheinlich nie höher als die CPU Temperatur ist, der liest im Skript einfach nur die CPU Temperatur aus, was für alle Benutzer ohne weiteres möglich ist.


Das Ergebnis, noch ohne Overclocking, Pi liegt ohne Gehäuse im Schrank:
Raspberry Pi CPU und GPU Temperatur einer Woche in Cacti (RRDTool)

Zu Cacti

Das Speichern sowie Konsolidieren der Daten in einer Round Robin Database (RRD) und das Erzeugen der Graphen erfolgt mittels RRDTool. RRDTool kann auch ohne Cacti benutzt werden. Ich verwende Cacti, da hiermit ein Webinterface für die Administration und die Anzeige der verschiedenen Graphen zur Verfügung steht. Cacti erledigt auch das regelmäßige Polling der verschiedenen Datenquellen (z.B. das hier vorgestellte script) um die darzustellenden Daten einzusammeln und per RRDTool in die Datenbank zu schreiben.
Die Installation von Cacti auf dem Raspberry Pi erfolgt einfach über den Paketmanager, hierzu finden sich viele Anleitung im Netz.