Dienstag, 8. Oktober 2013

Unter Linux eine aktive screen-Session übernehmen

Ab und zu kommt es vor, dass sich mein alter Mac mini in den Ruhemodus versetzt, während ich noch per SSH mit einer screen-Session verbunden bin. Mit folgendem Befehl kann ich die Session nach einem neuen Login mit SSH übernehmen:

$ screen -d -r

-d bedeutet „detach“, -r bedeutet „resume“.

Tags: ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Montag, 7. Oktober 2013

Mit Google Docs Spreadsheet eine Variable von einer Internet-Seite abrufen und als Zellwert verwenden

In Google Docs Spreadsheet ist es äusserst einfach, eigene Zellfunktionen zu definieren und diese danach mit einer JavaScript-basierten Funktion zu hinterlegen.

Ich habe mir diese Funktionalität zu Nutzen gemacht, um via meinen Linux-Server die aktuellen Gold- und Silberpreise in Schweizer Franken von einer Web-Site auszulesen und als „rohe“ Zahl an eine Zelle eines Google Docs Spreadsheet weiterzugeben. Basierend auf diesem Wert werden danach weitere Berechnungen in anderen Zellen angestossen.

Zuerst habe ich hierzu ein Spreadsheet eröffnet und sogleich unter Tools > Script editor… ein Script namens „Code.gs“ erstellt. Dort habe ich folgende (hier anonymisierte) JavaScript-Funktion abgelegt:

function getQuote(item) {
  if(item.length < 3) {
    return '#ERROR: parameter too short';
  }
  
  var response = UrlFetchApp.fetch("http://site.tld/index.php?item=" + item + "&raw=true");
  
  quoteRaw = response.getContentText();
  quote = parseFloat(quoteRaw).toFixed(2);
  
  return quote;
}

Anschliessend habe ich in der Zelle A1 den Wert „Gold“ hinterlegt. In Zelle A2 habe ich notiert „=getQuote(A1)“. Sobald man die Zelle A2 verlässt, versucht Google, die URL aufzurufen und die Antwort in eine Zahl umzuwandeln. Dies setzt natürlich voraus, dass das PHP-Script auf dem entfernten keinen HTML-Code zurückgibt, sondern Plaintext. Sobald Google die Funktion getQuote() aufruft, steht in der Zelle für ein bis zwei Sekunden „Thinking…“, während Google im Hintergrund meinen Server kontaktiert und die hinterlegte URL aufruft. Sobald der Wert empfangen wurde, wird dieser in der Zelle angezeigt.

Nebenbemerkung: Ja, den Umweg über meinen eigenen Server könnte ich mir selbstverständlich sparen. Ich bin mir es aber zu Schade, a) ausgedehntes JavaScript zu programmieren, zumal b) Google keine guten Debug-Werkzeuge im Script-Editor bereitstellt. Stattdessen verlasse ich mich auf PHP, Apache und auf dem Server installierte Linux-Tools mit ihren ausgefeilten Funktionen und einem sauberen Debug Logging.

Tags: , , , , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Montag, 7. Oktober 2013

Apache liefert ungefähr richtige Dateinamen aus

Ungefähr einmal im Jahr konfiguriere ich unter einer Mac OS X-Installation den lokalen Web-Server, um auf dem Gerät Web-Applikationen zu entwickeln. Und bei jedem Mal vergesse ich in der Regel, dass unter Mac OS X das Apache-Modul mod_negotiation installiert ist, welches spätestens bei der Verwendung von mod_rewrite zu komischem Verhalten führt.

Beispiel: Ich rufe im Browser die URL http://localhost/article/132 auf, welche eigentlich mittels mod_rewrite auf index.php umgeleitet werden sollte. Habe ich im DocumentRoot des Web-Servers aber dummerweise ein Script namens article.php rumliegen, wird Apache die Rewrite-Regeln nicht beachten und stattdessen article.php aufrufen.

Unter Mac OS X könnte man nun rabiaterweise einfach das Laden von mod_negotiation verhindern. Leider führt das zu neuen Problemen und Fehlermeldungen, welche ich hier aus Zeitgründen nicht ausführen möchte, weshalb man stattdessen die mod_negotiation-Funktionalität in der VirtualHost-Konfiguration für das DocumentRoot und alle darunterliegenden Verzeichnisse deaktiviert:

...
Options -Multiviews
...

Und gut is …

Tags: , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Montag, 7. Oktober 2013

Ein PHP-Script so geschwätzig wie möglich machen

<?php
	ini_set('error_reporting',E_ALL);
	ini_set('display_errors',1);

	...
?>

Tags: , , , , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Dienstag, 1. Oktober 2013

Zahlencodes von Samsonite Aeris Spinner-Koffern ändern

Tags: , ,
Labels: Reisen

Keine Kommentare | neuen Kommentar verfassen

Freitag, 27. September 2013

Mit PHPs SimpleXML auf XML-Namespaces zugreifen

Das klappt tatsächlich, auch wenn der Code damit nicht mehr so simpel wird.

XML

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:georss="http://www.georss.org/georss">
<channel>
<title>foursquare checkin history for Mario A.</title>
<description>foursquare checkin history for Mario A.</description>
<link>https://foursquare.com/emeidi</link>
<atom:link type="application/rss+xml" rel="self" href="https://feeds.foursquare.com/history/.rss" />
<item>
<title>Migros</title>
<description>@ Migros</description>
<link>https://foursquare.com/emeidi/checkin/</link>
<pubDate>Fri, 27 Sep 13 17:22:13 +0000</pubDate>
<guid isPermaLink="false"></guid>
<georss:point>46.9490403456011 7.440057740911321</georss:point>
</item>
<item>
<title>Bahnhof Bern</title>
<description>@ Bahnhof Bern</description>
<link>https://foursquare.com/emeidi/checkin/</link>
<pubDate>Fri, 27 Sep 13 17:21:57 +0000</pubDate>
<guid isPermaLink="false"></guid>
<georss:point>46.94901360281286 7.440102388543716</georss:point>
</item>
<item>
...

PHP

...
foreach($xml->channel->item as $item) {
    $coords = $item->children('http://www.georss.org/georss')->point;
}
...

Via: SimpleXML and namespaces

Tags: , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 25. September 2013

Das Mac OS X Terminal mit dem aktuellen Finder-Pfad öffnen

Wer sich fliessend zwischen den zwei Welten — dem OS X GUI und dem Unix-Terminal — bewegt, wird die Minimalapplikation Go2Shell äusserst nützlich finden. Nachdem man sie als Button in die Finder Button-Leiste gezogen hat, kann man auf Knopfdruck das Mac OS X Terminal (Unix-Shell) öffnen und findet sich im selben Ordner wieder, welchen man gerade im Finder sieht.

Die umgekehrte Variante sei hier selbstverständlich auch noch am Rande erwähnt:

$ open .

öffnet ein Finder-Fenster mit dem Verzeichnis, in welchem sich der Shell-Benutzer gerade befindet.

Tags: , , , , , ,
Labels: Apple

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 18. September 2013

Den Raspberry Pi mit rsync über SSH auf die Synology DiskStation sichern

Als Gedankenstütze nachfolgend einige Lösungen für Probleme, die sich mir in den Weg stellten:

Mac OS X

$ ssh-keygen -t rsa -b 2048 -f id_rsa_dashboard_vault

Die Aufforderung, ein Passwort für den Private Key zu generieren, bestätigt man mit ENTER — der Private Key wird so nicht zusätzlich mit einem Passwort geschützt, weil dies den automatisierten Login von Raspberry Pi auf die DiskStation verhindern würde.

Der Befehl erstellt zwei Dateien:

  • id_rsa_dashboard_vault
  • id_rsa_dashboard_vault.pub

Synology DiskStation

Als erstes richtet man sich über die Web-Oberfläche einen normalen Benutzer dashboard ein, in dessen Home-Verzeichnis die Backup-Daten geschrieben werden.

Hierzu müssen dem Benutzer Schreibrechte auf /homes gegeben werden. Ansonsten sieht man sich beim Starten des Backup-Scripts (s. unten) mit folgender Fehlermeldung gegenüber:

ERROR: module is read only

Quelle: Rsync over ssh: “ERROR: module is read only” suddenly appeared

Wichtig ist weiter, dass der SSH-Zugang über die Web-Oberfläche aktiviert wurde.

/etc/passwd

Dem neu erstellten Benutzer müssen wir nun eine gültige Login-Shell zuweisen:

...
dashboard:x:1029:100::/var/services/homes/dashboard:/bin/ash

Erfasst man hier ein nicht existierendes Login-Shell, kriegt man beim Debugging des publickey SSH-Logins folgende komische Infos ans Gesicht geworfen:

...
Authentication succeeded
...
Permission denied
...

Um sicher zu gehen, dass die Login-Shell richtig konfiguriert ist, macht man als auf der DiskStation eingeloggter User root folgendes:

# su dashboard

Wechselt man in ein neues Shell, ist /etc/passwd korrekt konfiguriert.

/var/services/homes/dashboard/.ssh/authorized_keys

In dieser Datei legen wir den Public Key ab (id_rsa_dashboard_vault.pub).

/etc/ssh/sshd_config

Wahrscheinlich müsste man hier gar nichts anpassen, beim Debugging habe ich es dann doch getan (wohl unnötigerweise):

$ cat sshd_config | grep -v "^#" | sort
AllowTcpForwarding no
AuthorizedKeysFile	.ssh/authorized_keys
ChallengeResponseAuthentication no
ChrootDirectory none
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_rsa_key
LogLevel INFO
Match User root
    AllowTcpForwarding yes
Protocol 2
PubkeyAuthentication yes
Subsystem       sftp    internal-sftp -f DAEMON -u 000
SyslogFacility AUTH
UseDNS no
UsePAM yes

Raspberry Pi

/root/.ssh/config

Host vault
   Hostname 10.0.44.44
   User dashboard
   IdentityFile ~/.ssh/id_rsa_dashboard_vault

In der Datei ~/.ssh/id_rsa_dashboard_vault legt man den Private Key ab.

Login überprüfen

Dies sollte nun ohne Eingabe eines Passwortes möglich sein:

$ ssh vault

Bei einer Fehlermeldung helfen die Optionen -v, -vv und -vvv weiter:

$ ssh -v vault

/usr/local/bin/backup.sh

Folgendes Script sichert / (root) des Raspberry Pis auf den Host vault in den Pfad /volume1/homes/dashboard/backups/. Auf dem Raspberry Pi nicht mehr vorhandene Dateien werden auf der DiskStation gelöscht.

#!/bin/sh

RSYNC=`which rsync`

if [ ! -e "$RSYNC" ]
then
	echo "rsync binary not found: '$RSYNC'"
	exit 1
fi

TODAY=`date +"%F_%T"`
SNAPSHOTFILE="/var/log/rsync/$TODAY.snapshot.txt"
#touch "$SNAPSHOTFILE"
echo "$TODAY" > "$SNAPSHOTFILE"

if [ ! -f "$SNAPSHOTFILE" ]
then
	echo "Could not create snapshotfile '$SNAPSHOTFILE'"
else
	echo "Snapshotfile created at:"
	ls -l "$SNAPSHOTFILE"
fi

LOGFILE="/var/log/rsync/$TODAY.log.txt"
EXCLUDEFILE="/usr/local/bin/backup-exclude.txt"

SOURCE="/"
DEST="vault:/volume1/homes/dashboard/backups/"

echo "Running rsync ..."
$RSYNC -avz --log-file="$LOGFILE" --exclude-from="$EXCLUDEFILE" --delete -e ssh "$SOURCE" "$DEST" 
echo "Backup complete."

exit 0

/usr/local/bin/backup-exclude.txt

proc/*
sys/*
dev/*
tmp/*
run/*
mnt/*

Quelle: Can a Raspberry Pi be used to create a backup of itself?

/etc/crontab

...
4 0 * * *	root	/usr/local/bin/backup.sh

Hiermit wird das Backup-Script täglich um 4 Uhr morgens ausgeführt.

Links

Tags: , , , ,
Labels: Linux

1 Kommentar | neuen Kommentar verfassen

Mittwoch, 18. September 2013

Hostpoint: Immer mal wieder zickt die Datenbank …

Irgendwann ab den frühen 2000ern habe ich alle meine Web-Projekte über das Shared Hosting von Hostpoint AG im Internet bereitgestellt, und dort sind sie in den meisten Fällen noch heute.

Spätestens seit ich diese mit eMeidi.smt laufenden Web-Sites jede Minute mit Pingdom überwache, realisiere ich, wie instabil Hostpoints Hosting ist. Verglichen mit einem an der Uni Bern gehosteten virtualisierten Root-Server (Debian und VMware ESX) und eMeidi.com, welches beim Hoster meines Vertrauens Cyon GmbH in Basel läuft, haben wir es bei Hostpoint mit einem hostingmässigen Drittwelt-Land zu tun.

Dank den vom eMeidi.smt im Dateisystem abgelegten Fehlermeldungen lässt sich rückwirkend jeweils rasch eruieren, wo denn das Problem des Pingdom-Alarms lag. Als Beispiel sei hier der Ausfall vom 13. September 2013 zwischen 8:47 und 9:23 erwähnt:

#2003: Can't connect to MySQL server on 'sekneueg.mysql.db.internal' (13) in /home/sekneueg/public_html/irgendwo/mysql.class.php:240 for URI </> with referer <unknown>

Tjach, dumm gelaufen, ne? In den letzten 30 Tagen betrug die Uptime für diese spezifische Web-Site nur 99.68%, was Ausfällen von insgesamt 2 Stunden und 21 Minuten entspricht. Die längsten Ausfälle fanden am 26. August (57 Minuten), 13. September (36 Minuten) und am 22. August (11 Minuten) statt. Erbärmlich, zumal es sich dabei nicht etwa um Wartungsarbeiten mitten in der Nacht gehandelt hat, sondern um Ausfälle während Bürozeiten.

Der Fall ist klar: Die Profis von heute hosten bei der Cyon GmbH. Da hilft es auch nichts, wenn der Ausfall-anfällige Konkurrenzhoster aus Rapperswil-Jona den bloggenden Tom anheuert – dessen Lohn (sorry, Tom!) würde man lieber in bessere und stabilere Hard- und Software stecken als unnütze Gutfühl-PR.

Tags: , ,
Labels: Web

3 Kommentare | neuen Kommentar verfassen

Freitag, 13. September 2013

RAMShop: Hände weg von diesem Anbieter

Nachfolgend ein Mail, das ich an diesen auf Ricardo.ch präsenten Versandhändlers auf Grund des Kaufs eines Kabels vom Typ Samsung APCBS10UBE gesendet habe:

Guten Tag

Es freut mich, von jemanden Antwort zu erhalten der sich in ganzen deutschen Sätzen ausdrücken kann.

On 10.09.2013 13:53, ricardo.ch-Dept., RAMshop wrote:
> Ich musste ebenfalls
> feststellen, dass Ihre Angaben korrekt sind!

Sag‘ ich doch schon lange …

> Dies ist natürlich ein Fehler!

Schön, dass Sie zum selben Schluss kommen.

> Ich habe noch ein Kabel mit der korrekten Angabe gefunden!
> Ich werde Ihnen noch heute dieses Kabel mit A-Post zusenden!

Das Kabel ist gestern angekommen. Es handelt sich nun um das korrekte Modell, welches tadellos funktioniert.

Die Ware kam in einem Plastic-Umschlag der Post an. Ein Hinweiskleber teilte mir mit, dass der Brief bei der Verarbeitung kaputt gegangen ist. Bereits die erste Sendung kam in diesem Zustand an, weshalb ich mich schon fragen muss, ob sie effektiv keine geeignete Versandmaterialien haben (bspw. gepolsterter Umschlag)? Aber wahrscheinlich ist das ein Resultat der von Ihnen betriebenen Gewinnmaximierung.

> Darf ich Sie bitten, uns das falsche Kabel wieder zurück zusenden?
> Verwenden Sie dafür bitte unsere Rückversandmarke
> welche Sie im Anhang an dieses Mail finden.

Das Kabel ist unterwegs zurück an Sie – in einem geeigneten Umschlag, welcher nicht kaputt gehen kann.

Ein schaler Nachgeschmack bleibt: Wieso versenden Sie Waren an Kunden mit 1 Franken-Porto, verlangen auf Ricardo aber 2.50 CHF Versandgebühren und senden mir für die Rücksendung des Kabels eine Rückversandmarke im Wert von über 3 Franken?

Gruss
Mario Aeby

Tags: , , , ,
Labels: Shopping

34 Kommentare | neuen Kommentar verfassen