Kostenlose Domain-Weltkarte für Blogger inkl. Spende für den guten Zweck

Datum18. April 2013 · Kommentare0 Kommentare

Gerade habe ich bei Caschy von einer Aktion gelesen, bei der Blogger für einen Bericht über ebenjene Aktion kostenfrei eine hochwertige Domain-Weltkarte erhalten können (sonst 27 Euro). Zusätzlich und eigentlich viel wichtiger ist, dass der Veranstalter checkdomain pro verschickter Karte noch 10 Euro an die Deutsche Kinder­krebs­stiftung spendet (egal ob gekauft oder als Blogger gratis erhalten).

Domain-Weltkarte von checkdomain

Die Karte ist 114 × 70 cm groß und beidseitig auf mattem Premium-Papier (250 g/m2) bedruckt. Allein schon wegen der Spende eine super Sache. Also mitmachen!

SNMP-Abfragen in Python mit PySNMP

Datum30. März 2013 · Kommentare0 Kommentare

Im Folgenden möchte ich eine kurze Einführung in das Durchführen der elementaren SNMP-Abfragen in Python mithilfe von PySNMP geben. Aus leidiger Erfahrung weiß ich, dass die PySNMP-Dokumentation nur einige sehr knappe Anhaltspunkte zur Bedienung liefert und daher nur begrenzt hilfreich ist.
Es wird vorausgesetzt, dass Erfahrung mit der Programmierung in Python vorhanden ist und die Grundbegriffe von SNMP bekannt sind.

PySNMP installieren

Vorab sollte man die Python-Pakete PyASN1 und PySNMP herunterladen, entpacken und jeweils deren Installationsprozess ausführen:

~/pyasn1-0.1.6$ sudo python setup.py install
running install
running build
running build_py
running install_lib
[...]
running install_egg_info
Writing /usr/local/lib/python2.7/dist-packages/pyasn1-0.1.6.egg-info
~/pysnmp-4.2.4$ sudo python setup.py install
running install
running build
running build_py
creating build
[...]
running install_scripts
copying build/scripts-2.7/build-pysnmp-mib -> /usr/local/bin
copying build/scripts-2.7/libsmi2pysnmp -> /usr/local/bin
changing mode of /usr/local/bin/build-pysnmp-mib to 755
changing mode of /usr/local/bin/libsmi2pysnmp to 755
running install_egg_info
Writing /usr/local/lib/python2.7/dist-packages/pysnmp-4.2.4.egg-info

Gemeinsamkeiten der Abfragen

Für alle Abfragen bietet PySNMP eine einheitliche Schnittstelle an. Nachfolgend ist die Syntax einmal stichpunktartig anhand einer SNMP-GET-Abfrage aufgelistet:

from pysnmp.entity.rfc3413.oneliner import cmdgen

cmdGen = cmdgen.CommandGenerator()

errorIndication, errorStatus, errorIndex, varBinding = cmdGen.getCmd(
	cmdgen.CommunityData(Community),
	cmdgen.UdpTransportTarget((Hostname oder IP, Port)),
	...
)

if errorIndication or errorStatus:
	print "Fehler"
else:
	print varBinding

Zunächst importieren wir das entsprechende Modul, um dann daraus gleich den sogenannten CommandGenerator zu instanzieren. In diesem rufen wir die entsprechende Methode (hier getCmd) auf und übergeben ihr den Community-String (CommunityData) und die Informationen, um den SNMP-Zielagenten (UdpTransportTarget) zu erreichen. Weitere Parameter sind dann spezifisch für die jeweilige Anfrage und werden weiter unten erläutert. Einen Fehler können wir anhand der Rückgabeparameter errorIndication, errorStatus und errorIndex erkennen, welche weitere Informationen zum aufgetretenen Fehler liefern. In varBinding sind im Erfolgsfall die Rückgabewerte zu finden.

SNMP GET-Abfragen (snmpget)

Anschließend können wir unsere erste kleine Abfrage schreiben, welche den lokalen Hostnamen abruft. Grundlage hierfür ist ein simples SNMP-GET.

from pysnmp.entity.rfc3413.oneliner import cmdgen

cmdGen = cmdgen.CommandGenerator()

errorIndication, errorStatus, errorIndex, varBinding = cmdGen.getCmd(
	cmdgen.CommunityData("public"),
	cmdgen.UdpTransportTarget(("localhost", 161)),
	"1.3.6.1.2.1.1.5.0"
)

if errorIndication or errorStatus:
	print "Fehler"
else:
	print varBinding
$ python snmp.py
[(ObjectName(1.3.6.1.2.1.1.5.0), OctetString('ubuntu'))]

Wir nutzen den Object Identifier (OID) von iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1).sysName(5) und dessen erste Instanz (0) und erhalten als Rückgabe eine Liste von Tupeln bestehend aus dem gefundenen OID und dem zugehörigen Wert in Form eines OctetString nach RFC 1902.

Abfragen mehrerer Werte und Entpacken von Funktionsargumenten

Wenn wir mehrere Werte benötigen, beispielsweise Hostname und Uptime, können wir getCmd auch mehrere OIDs übergeben:

errorIndication, errorStatus, errorIndex, varBinding = cmdGen.getCmd(
	cmdgen.CommunityData("public"),
	cmdgen.UdpTransportTarget(("localhost", 161)),
	"1.3.6.1.2.1.1.5.0", "1.3.6.1.2.1.1.3.0"
)
$ python snmp.py
[(ObjectName(1.3.6.1.2.1.1.5.0), OctetString('ubuntu')), (ObjectName(1.3.6.1.2.1.1.3.0), TimeTicks(201146))]

Sehr nützlich ist in diesem Zusammenhang auch das Entpacken von Funktionsargumenten, wodurch wir auch eine Liste/Tupel von Object Identifiern übergeben können. Analog zum vorigen Beispiel würde das so aussehen:

OIDS = ["1.3.6.1.2.1.1.5.0", "1.3.6.1.2.1.1.3.0"]

errorIndication, errorStatus, errorIndex, varBinding = cmdGen.getCmd(
	cmdgen.CommunityData("public"),
	cmdgen.UdpTransportTarget(("localhost", 161)),
	*OIDS
)

SNMP GETNEXT-Abfragen (snmpwalk)

Für ein SNMP GETNEXT (z.B. zum Durchlaufen der Interface-Tabelle iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).interfaces(2).ifTable(2)) steht ebenso eine Klasse, nextCmd, zur Verfügung.

errorIndication, errorStatus, errorIndex, varBinding = cmdGen.nextCmd(
	cmdgen.CommunityData("public"),
	cmdgen.UdpTransportTarget(("localhost", 161)),
	"1.3.6.1.2.1.2.2"
)
$ python snmp.py
[[(ObjectName(1.3.6.1.2.1.2.2.1.1.1), Integer(1))], [(ObjectName(1.3.6.1.2.1.2.2.1.1.2), Integer(2))], [(ObjectName(1.3.6.1.2.1.2.2.1.1.3), Integer(3))], [(ObjectName(1.3.6.1.2.1.2.2.1.2.1), OctetString('lo'))], [(ObjectName(1.3.6.1.2.1.2.2.1.2.2), OctetString('eth0'))], ...]

Hier erhalten wir eine Liste von Listen von Tupeln der Netzwerkadapter und einiger Informationen zu ihnen (Name, Geschwindigkeit, Status, etc.). Auch hier könnten wir durch das Entpacken von Funktionsargumenten wieder mehrere Werte gleichzeitig abfragen.

SNMP SET-Abfragen (snmpset)

Zum Setzen von Werten können wir PySNMP natürlich auch verwenden. Wichtig ist, dass wir hier noch das Modul rfc1902 aus pysnmp.proto importieren, um die Werte auch gemäß den SNMP-SMI-Datentypen setzen zu können (siehe RFC 1902), was auch dringend anzuraten ist.

from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.proto import rfc1902

errorIndication, errorStatus, errorIndex, varBinding = cmdGen.setCmd(
	cmdgen.CommunityData("secret"),
	cmdgen.UdpTransportTarget(("localhost", 161)),
	("1.3.6.1.2.1.1.4.0", rfc1902.OctetString("Administrator"))
)

if errorIndication or errorStatus:
	print "Fehler"
else:
	print varBinding
$ python snmp.py
[(ObjectName(1.3.6.1.2.1.1.4.0), OctetString('Administrator'))]

Wir haben eine andere SNMPv2-Community (secret) genutzt, weil nur diese auf dem hier verwendeten System Schreibzugriff besitzt. Zudem haben wir der Methode die zu setzenden Werte als Tupel aus OID und Wert übergeben.
Selbstverständlich könnten wir zum gleichzeitigen Setzen mehrerer Werte das Entpacken von Funktionsargumenten (s.o.) verwenden. Dazu muss eine Liste von Tupeln bestehend aus OID und zu setzendem Wert übergeben werden. Bedenken sollten wir aber, dass SNMP-SET-Operationen atomar sind, was bedeutet, dass entweder sämtliche Werte erfolgreich gesetzt werden oder keiner. Schlägt also das Setzen eines Wertes aus der übergebenen Liste fehl, wird kein einziger Wert aus der Liste gesetzt.

Im Beispiel haben wir die erste Instanz der System-Kontaktperson (iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1).sysContact(4).0) auf Administrator gesetzt. Hierzu benötigen wir aus dem Modul rfc1902 die Klasse OctetString und instanzieren sich gleich mit dem zu setzenden String. Analog können wir das auch für die anderen Datentypen in RFC 1902 tun. Als Rückgabe erhalten wir wieder eine Liste von Tupeln mit der OID und dem neu gesetzten Wert, wenn die Operation erfolgreich war.

Ein Übersicht der im RFC-1902-Modul zur Verfügung stehenden Datentypen findet sich übrigens hier. Hilfreich ist auch zu wissen, welche Werte in der Objektdatenbank, der sogenannten Management Information Base (MIB), typischerweise zu finden und von welchem Datentyp diese sind. Anhaltspunkte, insbesondere für Cisco-Hardware liefert z.B. der Cisco SNMP Object Navigator.

Nginx im Dual-Stack-Verfahren betreiben

Datum01. November 2012 · Kommentare0 Kommentare

Obwohl der Umstieg auf IPv6 eher schleppend vorangeht (in Deutschland ist der IPv6-Traffic unter 1%), sollte man sich schon jetzt für die Zukunft rüsten. Sofern man eine IPv6-Adresse sein Eigen nennen darf, kann man den sogenannten Dual-Stack-Betrieb fahren, bei dem ein Host zusätzlich zur altbekannten IPv4-Adresse über eine IPv6-Adresse erreichbar ist. Setzt man Nginx als Webserver ein, ist die Konfiguration hierfür sehr einfach. Zunächst sollte man aber überprüfen, ob die eingesetzte Nginx-Version überhaupt mit IPv6 umgehen kann:

$ nginx -V
nginx version: nginx/1.1.19
TLS SNI support enabled
configure arguments: [...] --with-ipv6 [...]

Wenn in den Konfigurationsargumenten der Schalter --with-ipv6 gesetzt wurde, steht dem Dual-Stack nichts mehr im Wege. Nun sollte man in der Nginx-Konfiguration für den Host (oder den primären Host im Falle von namensbasiertem Virtual Hosting) die nachfolgenden Listen-Optionen setzen. Zu finden ist diese Konfigurationsdatei meist als Symlink unter /etc/nginx/sites-enabled/default.

server {
	listen [::]:80 ipv6only=on;
	listen 80;

	server_name example.org localhost 127.0.0.1;

	[...]
}

Sie sorgen dafür, dass Nginx auf allen Netzwerkschnittstellen auf eingehende IPv6- und IPv4-Verbindungen auf Port 80 lauscht. Theoretisch wäre die erste Zeile ohne die Option ipv6only=on ausreichend. Im Test traten jedoch einige Probleme dabei auf, sodass sie besser gesetzt wird. Ohne diese Option würde beim Binden auf IPv6 gleichzeitig das Binden auf IPv4 erfolgen, wodurch die folgende Zeile (also listen 80) nicht nur unnötig wäre, sondern so schlicht nicht funktionieren würde (klar, der Port ist schon durch die erste Option gebunden und damit „besetzt“). Der Start von Nginx würde mit folgender Fehlermeldung fehlschlagen:

Restarting nginx: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
nginx.

Daher wird durch ipv6only=on angezeigt, dass wirklich nur auf IPv6 gebunden werden soll. In der nächsten Zeile erfolgt dann explizit das Binden auf IPv4.

Dasselbe kann nun auch für einen SSL-Host erfolgen:

server {
	listen [::]:443 ipv6only=on;
	listen 443;

	server_name example.org localhost 127.0.0.1;

	[...]
}

Sollten noch weitere virtuelle Hosts vorhanden sein, so kann der Dual-Stack-Betrieb für diese analog eingestellt werden. Zwingend beachten sollte man dabei jedoch, dass die Option ipv6only=on bei diesen nicht mehr gesetzt werden muss bzw. darf.

Abschließend kann der Nginx-Server neu gestartet werden:

$ /etc/init.d/nginx restart
oder unter Ubuntu
$ service nginx restart

Neues Projekt: jScrollPresenter

Datum08. September 2012 · Kommentare0 Kommentare

In letzter Zeit hat sich hier wenig getan. Das lag zum einen daran, dass ich anderweitig viel beschäftigt war und zum anderen, dass ich an einem neuen Projekt geschraubt habe. Es ging dabei um die Erstellung eines Plugins für jQuery mit dem sich sogenannte Slides (im Grunde so etwas wie Folien bei einer Präsentation) horizontal anordnen und durchscrollen lassen.

Es gibt zwar schon einige bestehende Plugin-Ansätze, diese waren mir jedoch zu überladen und schwierig anzupassen. Aus diesem Grund wurde jScrollPresenter als einfache und leichtgewichtige Alternative geschaffen. jScrollPresenter kommt bereits auf meiner Web-Visitenkarte zum Einsatz und leistet dort gute Dienste.

Ich verweise an dieser Stelle einfach mal auf die Demo-Seite, denn dort kann man weitere Informationen und eine Vorstellung davon erhalten, was mit dem Plugin zu erreichen ist. Außerdem ist dort der Download möglich.

Fußmatte „Dieser Bewohner ...“ von getDigital.de im Test

Datum28. Juli 2012 · Kommentare1 Kommentar

Fast jeder YouTube-Nutzer hat beim Versuch, ein Video anzuschauen, schon einmal folgende Meldung bekommen.

YouTube Fehlermeldung

Über die Gründe könnte man sich sicher stundenlang auslassen und beschweren. Die Jungs und Mädels von getDigital.de, dem deutschsprachigen Geek-Shop haben als kleine Satire auf diese nervige Meldung eine Fußmatte in ihren Shop aufgenommen, deren Botschaft über jeden Zweifel erhaben ist. Mit dem freundlichen Aufdruck „Dieser Bewohner ist für dich nicht verfügbar. Das tut mir leid.“ werden unliebsame Zeitgenossen direkt vor der Haustür abgewimmelt wohingegen Eingeweihte sofort Bescheid wissen.

Freundlicherweise wurde mir ein Testexemplar zu Verfügung gestellt, das ich auf Herz und Nieren untersuchen durfte. Zunächst erst einmal einen Dank an getDigital.de für die freundliche und zugügige Abwicklung (Donnerstagnachmittag bestellt, Samstag angekommen).

Vor dem Auspacken … Nach dem Auspacken …

Nun erst einmal zu den „technischen Daten“. Die Matte ist, wie viele andere Fußmatten auch, aus Kokosfasern gefertigt, die sehr hart und deshalb genau richtig zum Fußabstreifen sind. Sie hat die (von mir gemessenen) Maße von 59,5 cm auf 40,0 cm und ist 1,5 cm dick. Auf der Vorderseite ist der oben beschriebene witzige Satz zu finden und zusätzlich noch ein abstraktes trauriges Gesicht. Die Rückseite ist aus weichem und rutschfestem PVC.
Anzumerken ist, dass der Aufdruck (wenn man das so nennen darf) oberflächlich ist (also die Fasern sind nicht durchgängig bis hinunter gefärbt) und auch, im Gegensatz zu den Produktfotos von getDigital leicht unscharf ist. Das macht aber nichts, weil man ihn trotzdem gut lesen kann.
Aufpassen sollte man beim Auspacken, da die Fußmatte sehr dazu neigt, viele kleine Fasern (ähnlich wie kleine Holzspäne) abzusondern, sodass der Boden danach mit diesen Fasern gespickt ist. Also am Besten draußen auspacken, vorzugsweise direkt am künftigen Einsatzort. Das hilft auch gegen den doch sehr aufdringlichen Plastikgeruch. Der sollte sich nach ein paar Tagen an der frischen Luft aber verzogen haben.

Gesamtansicht der Fußmatte Nahaufnahme der Fasern Fußmatte im Einsatz

Alles in allem eine sehr gute Fußmatte und auch der Preis von 19,95 € für eine hochwertige Fußmatte aus Kokosfasern geht in Ordnung. Vergleichbare Produkte liegen ebenfalls in diesem Preisbereich.
Bedenken habe ich noch, wenn die Fußmatte ganz allein draußen rumliegt. Denn ich konnte beobachten, dass sich schon einige Leute nach dieser dekorativen Matte umgedreht haben und nicht so freundliche Zeitgenossen könnten dabei womöglich in Versuchung kommen sie zu entwenden ;-). Daher ist mein Tipp, sie besser hinter der Eingangstür zu platzieren, wobei dabei natürlich der „Abschreckungsfaktor“ der Nachricht und der Gag-Faktor verloren gehen.