Archiv ‘Uncategorized’

Sonntag, 19. Februar 2017

ELK: snmpd: Cannot statfs

Seit einer Woche läuft auf einem Laptop bei mir zu Hause der ELK-Stack und sammelt per Syslog die Logs aller meiner Devices an drei Standorten. In unregelmässigen Abständen werde ich hier über Erkenntnisse berichten, die ich dank der zentralisierten Analyse der Logs gemacht habe.

Heute geht es um snmpd und Mounts, deren Attribute der Daemon nicht auslesen kann. Dies äussert sich auf ELK mit folgenden Log-Meldungen:

... snmpd[1234] Cannot statfs /var/lib/docker/containers/: Permission denied ...
... snmpd[1234] Cannot statfs /var/lib/docker/aufs/mnt/: Permission denied ...
... snmpd[1234] Cannot statfs /run/docker/netns/: Permission denied ...
... snmpd[1234] Cannot statfs /run/user/1000/gvfs: Permission denied ...
... snmpd[1234] Cannot statfs /sys/kernel/debug/tracing: Permission denied ...

Ich versuchte mit verschiedenen Einträgen in /etc/snmp/snmpd.conf das auslesen dieser Mounts zu verhindern. Zuerst mittels der Direktive ignoredisk:

ignoredisk /run/user/*
ignoredisk /var/lib/docker/containers/*
ignoredisk /var/lib/docker/aufs/mnt/*
ignoredisk /run/docker/netns/*
ignoredisk /sys/kernel/debug/tracing

Das Blacklisting hatte leider keine Wirkung.

Auch der umgekehrte Weg, das Whitelisting, funktionierte nicht:

#includeAllDisks 10%
disk / 10%

Nach längeren Recherchen im Netz musste ich zum Schluss kommen, dass man solche Meldungen nicht mit Anpassungen an der SNMP-Konfiguration unterdrücken kann. Der Grund:

Because as I wrote in comment #2, snmpd reads /proc/mounts and runs statfs on each entry there. If any statfs call fails it logs an error. So, either stafs must not fail (i.e. no „net:[4026532288]“ entries in /proc/mounts) or snmpd must be fixed to log something more useful and only once.

Quelle: Bug 1314610 – snmpd complaining twice „Cannot statfs net:[********]#***: No such file or directory“ every 10 minutes

snmpd iteriert über die Einträge in /proc/mounts und führt ein statfs auf jeden Mountpoint durch. Das ist der Moment, in dem die Fehlermeldung geloggt wird.

Eine potentielle Lösung:

There needs to be an option to just make snmpd not try to look at these sort of mount points. The problem is that ignoreDisk only works for the devices, not mount points and a tmpfs has no „device“ name to match it by.

Quelle: snmpd storage reports all tmpfs and floods logfile

Dem Problem begegne ich nun, indem ich mit rsyslog solche snmpd-Fehlermeldungen ausfiltere und nicht zu Logstash übermittle. Der Filter dazu lautet:

if $programname == 'snmpd' and $msg contains 'statfs' then {

Tags: , , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 11. Januar 2017

Die Antwort eines US-Veteranen auf die „Bubble“-Theorie

Heute morgen machte auf Facebook ein Artikel zu einer Tweet-Serie eines US-Veteranen die Runde. Ich las die ersten paar Tweets, fand es dann aber zu dämlich, den in Kleinstteile aufgespaltenen Erguss zu Ende zu lesen.

Leute, wenn ihr viel zu sagen habt, verfasst einen Blog-Artikel, himmelheiland!

Der geistigen Gesundheit meiner Mitmenschen wegen habe ich den ganzen Text zu einem grossen Ganzen zusammenkopiert:

I need to rant because I’m fucking tired of this „bubble“ thing. I doubt many folks are gonna read this because it’s 3 am, but The first thing you should know about me is that I grew up in white poverty in Central Texas. My father is a lifelong car mechanic my mother has worked minimum wage jobs all her life, and my stepfather was junior enlisted in the Army. None of them have a college degree. None of them really stressed the importance of education to me, either. We were dirt poor. We lived in trailer parks all over Central Texas and were on welfare. I have been around „blue collar“ folks my whole life. Hell, „blue collar“ is a step up from my childhood experience. My family is poor and white and uneducated. Prime Trump audience. And I’m here to tell you that these folks–my people–don’t need your condescending conservative asses speaking for our „values“ because the truth is that 1) you don’t give a fuck about us and 2) we are not worthy of romanticizing. I am sick and fucking tired of impoverished white Americans being used as a political cudgel by rich Republicans against blacks against women, against Muslims, against Jews and LGBTQ folks and everyone else Republican politicians point to and say „See that? They’re to blame for your struggle. You’re hurting because of them.“ And the rhetorical device most often used for this is „the bubble“ and every buzzword that goes with it: Hollywood, elitist, liberal, communist, professor, etc. etc. fucking etc. Republicans have gotten a shit ton of mileage from impoverished and „blue collar“ white folks by claiming the people in power live in some „bubble“ in Washington and are „out of touch“ with real Americans. Tonight, @MeghanMcCain, the daughter of a U.S. senator someone who has enjoyed extraordinary privilege in her life took it upon herself to claim that, somehow, Meryl Streep’s speech is propagating some bullshit Hollywood-East Coast liberal „bubble“ and that „real Americans“ (she implied) this would vote for Trump as a backlash against elitism. Never-fucking-mind that Trump has gold-plated fixtures in every mansion he owns or that he got his start from his daddy’s seed money or that he wouldn’t piss on a poor white person if they were burning alive. Never mind all that because we’re supposed to believe that Donald fucking Trump is „one of the regular folks“. That he understands them. And you know what? They’re right. Trump understands these people because he knows they’re fucking morons. Yes, morons. These hicks and rednecks and „oh gawd, I’m just a good ole boy“ dumb-fucking morons who couldn’t differentiate between their ass and a hole in the ground who are so willfully fucking stupid that it’s a ceaseless wonder they manage to remind themselves to breathe. Trump knows these people. He knows that he can say and do and promise whatever the fuck he wants as long as he validates their insecurities and gives them a leader of „strength“ to follow, which means posturing like some silver-back gorilla at every perceived slight. He is the canvass upon which they project all their insecurities. These fucking morons who are afraid of blacks and empowered women and Latinos and receive welfare and Medicaid even while they rant against „government handouts“. And you, @MeghanMcCain, and all your conservative friends want us to believe that the „bubble“ is liberals on both coasts, not these white Americans who insulate themselves into an enormous social echo chamber, repeating the same stupid „facts“ and fears and conspiracy theories to each other and are buying into Trump only because he validates their racism, sexism, homophobia, xenophobia, and all the rest of it. You want us you, @MeghanMcCain, privileged white daughter of a U.S. senator who used her daddy’s connections to get this far ahead, want us to „step outside the bubble“ and enable this vicious hatred against our black friends, our Muslim and Jewish friends, our LGBTQ friends ..and all the women in our lives who, at this very moment, are scrambling to get IUDs because they may lose their right to privacy you want us to not act so „elitist“ and validate this bullshit? Well, I’ll you this much: there is no romance or gravitas to these people. You know what you call a bigoted moronic white person in a blue collar job? You call them a fucking bigoted moron. Because they are. And speaking as someone who is from this background–among the impoverished whites of Central Texas–you sure as hell don’t placate their violent hatred and give them any more encouragement to be hateful and violent. I seriously need to ask you this Do you have no honor, @MeghanMcCain? No integrity? Have you lost your fucking mind? Because from where I’m standing, you’re either pandering to these hateful white assholes to gain political clout–and god forbid Twitter RTs–or you really do believe all this shit. If it’s the former, you’re a fucking disgusting person for exploiting this hatred for your own gain. If it’s the latter, you’re a fucking disgusting person for perpetuating this bullshit fallacy: using hatred–vicious, deadly hatred–under the claim that liberals–not education, not the 1%, not the criminal behavior of the Republican Party–but LIBERALS are to blame for poor white misery. There are white Americans who have never known a life other than living paycheck-to-paycheck. They don’t have any friends of color. They believe women belong in the home. They think Islam is evil. They think Jews killed Jesus and will burn in hell. And you, @MeghanMcCain claim that I–a liberal on the East Coast who grew up a poor white kid in Central Texas–live in a bubble now and didn’t back then?Shame on you, @MeghanMcCain, and every Republican and journalist and pundit who makes the absurd fucking claim that the problem isn’t the guy in the White House enabling white supremacism, who pledged to have a Muslim registry, who encourages violence but that liberals aren’t being nice enough to vicious racists who would just as soon see me die for having sex with a black woman or for praying to Allah or escorting a friend to an abortion clinic. I say again, @MeghanMcCain, have you lost your fucking mind? I do not live in a bubble. Meryl Streep does not live in a bubble. And the folks of the East Coast–in which every race, religion gender identity, sexuality, ethnicity, etc. swirl around each other on a daily basis, live amongst each other, fight and love and work and play with other and challenge each other to the point where when someone’s an asshole, it isn’t because of their identity it’s because that individual is an asshole none of us live in a bubble. So, if you are, indeed, just exploiting white rage to pad your Twitter account and sell books and slots on networks, I say with all sincerity: fuck you. Or if you really do believe this may I suggest you, @MeghanMcCain, go live in these poor white areas and then tell me those aren’t „bubbles“. Until then, please keep your bullshit hot takes–borne out of your privileged, elitist, well-connected white existence–to yourself.

Quelle: 11:56 PM – 8 Jan 2017

Tags: , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 13. November 2016

UniFi Access Points mittels IKEA-Hack in der Wohnung platzieren

Zur selben Zeit, als ich Brandmelder angeschafft habe und mir am Überlegen war, wie man diese Sensoren ohne Beschädigung der Decken in der Wohnung platzieren kann, habe ich mir auch zwei UniFi Access Point angeschafft.

Der IKEA-Hack mit den Variera Tellerhaltern für die Montage der Brandmelder liess sich 1:1 auch auf die Access Points übertragen, da IKEA Tellerhalter in zwei Grössen im Angebot führt (die UniFis hätten rein vom Durchmesser überhaupt nicht in die Brandmelder-Halterung gepasst). Für UniFi Access Points eignet sich das grössere der beiden Modelle, das Teller in der Grösse von 19cm bis 32cm aufnimmt:

VARIERA Tellerhalter, Buche hell, Edelstahl (IKEA Artikelnummer 802.404.16; 9.95 CHF)

Wieso dieser Aufwand? UniFi Access Points senden ihre Signale in Form eines „Donuts“ aus, wenn der Access Point horizontal aufliegt. Der „Donut“ ist aus der horizontalen Sicht aber nicht symmetrisch: Auf der Deckenseite des Access Point mit der Zuführung des Ethernet-Kabels ist die Abstrahlung weniger wulstig als auf der Luftseite (dort, wo das Logo prangt und die blaue LED leuchtet):


NACHTRAG: Unter Antenna radiation pattern for UniFi AP (diagramm inside) habe ich weitere Diagramme gefunden:





Quelle: [Ervaringen/discussie] Ubiquiti-apparatuur

Dies ist einfach erklärbar: Die Macher der semi-professionellen Access Points gehen davon aus, dass die Dinger in der Regel an Decken montiert werden. Richtung Decke selber bringt eine WiFi-Durchdringung niemandem etwas, aber von der Decke weg (Richtung Zimmerboden) muss eine möglichst grosse Abdeckung erreicht werden.

Aus diesem Grund habe ich beide Access Points auf dem Tellerhalter montiert und in der Stube sowie im Büro möglichst an hoher Position aufgestellt. Das sieht dann so aus:

UniFi Access Point IKEA Variera Mount Living Room

Tags: , , , , , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 13. November 2016

Präsidentschaftswahlen USA 2016: Bissige audiovisuelle Kommentare

Mark Blyth

Der Politwissenschaftler Mark Blythe hat am Tag nach den Präsidentschaftswahlen anlässlich eines Seminars am Watson Institute for International and Public Affairs an der Brown University in Providence, Rhode Island, USA, seinen Kommentar zur angeblichen Unvorhersehbarkeit Trumps Wahl und eine Prognose auf die kommenden Monate und Jahre gegeben. Prognosethemen sind unter anderem das Verfassungsreferendum in Italien, die Front National in Frankreich, die AfD in Deutschland sowie die angespannte Lage im Baltikum. Mark erläutert auch aus wirtschaftspolitischer Geschichte, wie wir an diesem Punkt in der Geschichte angekommen sind: Eine Kritik an den Auswirkungen des ungebremsten Neoliberalismus seit 1985. Kurz:

So … They’re [losers of globalisation] a bit fed up with. So they’ve decided if they get any possible opportunity, whether this is Brexit, or the Italian constitutional referendum or anything […] to basically give the elites notice: „We’ve had enough of this!“ And that’s what this is.

Ich habe mir erlaubt, zwei von Marks Monologen zurechtzuschneiden und auf YouTube hochzuladen — ich empfinde beide Ausschnitte als äusserst sehenswert:

Quelle: Mark Blyth and Wendy Schiller – Election 2016: What Happened and Why?

Jonathan Pie

Jonathan Pie liest — analog zu Mark Blyth — der nur noch auf dem Papier „demokratischen“ Partei gehörig die Leviten:

Tags: , , , , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 7. September 2016

curlftpfs unter OS X mit unterschiedlichen Zeichensätzen

Nach dem Upgrade auf OS X El Capitan funktionierte auf meinem Mac mini ein Backup-Script plötzlich nicht mehr, welches jahrelang brav seinen Dienst verrichtete: Das Script mountet jede Nacht die von mir betreuten Web-Sites mit curlftpfs und synchronisiert die Dateien der Web-Site mittels rsync.

Bei bestimmten Web-Sites liefert der FTP-Server die Dateinamen im Latin1-Format aus, werden bei mir dann aber auf ein Dateisystem mit UTF-8 geschrieben. Hierzu bringt curlftpfs Kommandozeilenoptionen mit, mit welchen man die Dateinamen vor dem Schreiben umkonvertieren kann.

Der Fehler bei dieser Operation lautete:

$ /opt/local/bin/curlftpfs -s -r -o ftp_method=singlecwd -o defer_permissions -o modules=iconv,from_code=latin1 "domain.tld" "/Users/mario/Sites/ftpmounts/domain.tld"
fuse: dlopen(, 2): image not found

Schlussendlich realisierte ich, dass ich nun endlich auch die Linux-Kommandozeile unter OS X verwenden kann:

$ /opt/local/bin/curlftpfs -s -r -o ftp_method=singlecwd -o defer_permissions -o codepage=latin1 -o iocharset=utf8 "domain.tld" "/Users/mario/Sites/ftpmounts/domain.tld"

Issue auf Github: fuse: dlopen(, 2): image not found

Tags: , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 28. August 2016

Admin-Interface des Routers gegen das Internet (WAN) schliessen

Der Nachteil der Verwendung von Asuswrt-Merlin auf meinem Asus RT-AC66U-Router ist das latent vorhandene Gefrickel. Ich kann es kaum erwarten, bis mein Turris Omnia ankommt!

So musste ich vor einigen Monaten bemerken, dass das Web-Interface meines Routers aus dem Internet zugänglich ist, egal, ob ich diese Option im Web-GUI des Routers nun aktiviere oder deaktiviere. Das Interface läuft auf Port 8443 und ist nur mit HTTPS erreichbar (mit einem selber signierten Zertifikat).

Ich griff deshalb kurzerhand zu iptables, um diesen sicherheitsmässigen Fahrlässigkeit den Garaus zu machen: Ich loggte mich per SSH auf den Router ein und fand zuerst einmal das WAN-Interface heraus:

$ ifconfig
eth0       Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX 
           inet addr:85.X.X.X  Bcast:85.X.X.255  Mask:
           RX packets:662731029 errors:0 dropped:0 overruns:0 frame:0
           TX packets:536190886 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000 
           RX bytes:871096761 (830.7 MiB)  TX bytes:4294213359 (3.9 GiB)
           Interrupt:4 Base address:0x2000

Soso, eth0 also, da dies das einzige Interface mit einer öffentlichen IP war.

Folgender iptables-Befehl killt alle aus dem WAN stammenden Anfragen auf Port 8443:

# iptables -A INPUT -i eth0 -p tcp --destination-port 8443 -j REJECT
# iptables -A INPUT -i eth0 -p tcp --destination-port 22 -j REJECT

Wieso ich REJECT und nicht (wie ursprünglich konfiguriert) DROP gewählt habe? Drop versus Reject


Um sicherzugehen, dass die iptables auch wirklich nützen, habe ich mich dann des Tools NetRenderer bedient. In der Adresszeile des Web-Tools gebe ich


ein und warte, bis mir ein Timeout angezeigt wird. Wird stattdessen ein Zertifikat-Fehler angezeigt, weiss ich, dass die Verbindung (leider) immer noch möglich ist.


Auf StatusCake habe ich mir einen Check auf dieselbe URL eingerichtet, welcher mich alarmiert, sollte die Verbindung plötzlich wieder möglich sein (bspw. auf Grund eines Reboots). Dies war heute der Fall, nachdem die Regel 57 Tage und 9 Stunden gehalten hatte.


Himmelarsch, Port 22 (SSH) war auch die ganze Zeit über offen!

$ nmap -F 85.X.X.X
22/tcp   filtered ssh
135/tcp  filtered msrpc
139/tcp  filtered netbios-ssn
445/tcp  filtered microsoft-ds
8443/tcp filtered https-alt

Tags: , , , , , , , , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 23. Juni 2016

Ein kostenloses Comodo S/MIME E-Mail-Zertifikat lösen und auf iOS installieren

Comodo bietet kostenlose S/MIME-Zertifikate an, die die Authentizität einer E-Mail-Adresse belegen.

Heute habe ich bemerkt, dass mein letztes Jahr im Mai erstelltes Zertifikat abgelaufen ist, weshalb ich mich daran gemacht habe, ein neues Zertifikat zu lösen.

Leider gab es auf der Homepage des Produkts ein Stolperstein: Klicke ich (heute am 23. Juni 2016) auf den Button Sign Up, erhalte ich einen HTTP 400er zu Gesicht:

Comodo HTTP 400 Bad Request

Diesen Fehler umgeht man, indem man die anzuspringende URL etwas kürzt und auf einer Seite landet, die dem Design nach noch aus dem letzten Jahrhundert zu stammen scheint:

Application for Secure Email Certificate

Nachdem man die Angaben wahrheitsgetreu ausgefüllt hat (das Revocation-Passwort sicher ablegen; es könnte ein ungerades Mal nützlich erscheinen), erhält man nach wenigen Minuten ein E-Mail, welches einen Link enthält, mit welchem man die Datei CollectCCC.p7s herunterladen kann.

Nach einem Doppelklick wird die Datei in die OS X Keychain eingelesen. Ich wähle dazu die Login-Keychain. Soweit so gut.


Um das Zertifikat in unter iOS zu installieren und zu verwenden, muss man es im Format .p12 aus der Keychain exportieren. Hierzu öffnet man unter OS X die und selektiert unter Category „Certificates“:

Apple Keychain Certificates

Nun müssen folgende drei Elemente ausgewählt werden, damit das Zertifikat sauber mit allen Elementen aus der Keychain exportiert und in die iOS Profiles importiert werden kann:

Comodo SMIME Tree Export P12

Damit der Export des Private Keys klappt, wird man ganz am Schluss noch nach dem OS X Login-Passwort gefragt:

Apple Keychain login Password

Anschliessend mailt man sich die soeben erstellte Datei auf die eigene E-Mail-Adresse, öffnet das E-Mail in und klickt auf die .p12-Datei. Jetzt wählt man Install, gibt den iPhone-PIN ein und danach das Passwort, mit welchem man den Zertifikatbaum geschützt hat. Schlussendlich taucht das Zertifikat unter Profiles auf. Wenn man das Zertifikat nachträglich noch einmal anschauen möchte, findet man es unter Settings > General > Profiles.

Damit nun ausgehende E-Mails signiert (oder gar verschlüsselt) werden können, muss das Zertifikat noch mit dem betreffenden Mail-Account verknüpft werden: Settings > Mail, Contacts, Calendars > %Name des Mail-Accounts% > Account > Advanced:

S/MIME aktiviert man, Sign aktiviert man auch, wobei unterhalb des Schalters unter „CERTIFICATES“ das soeben aufgeführte Zertifikat aufgeführt sein und links mit einem Gutzeichen versehen sein sollte.

Tags: , , , , , , ,
Labels: Uncategorized

1 Kommentar | neuen Kommentar verfassen

Montag, 16. Mai 2016

MariaDB (MySQL) meldet Errcode: 24 „Too many open files“

Vorgestern habe ich auf Grund von Performance-Problemen beim Umstieg auf cacti spine die Datenbank auf meinem Linux-Server ausgetauscht: Statt MySQL kommt nun MariaDB zum Einsatz.

Heute nun wurde ich auf einen Kollateralschaden aufmerksam. Jede Nacht lasse ich ein Script laufen, welches meine MySQL-Datenbanken sperrt (LOCK-ed) und die Datenbankdateien in ein Sicherungsverzeichnis kopiert. Mit tarsnap schreibe ich die Datenbankdateien dann weg in die Cloud und habe so versionierte Datenbankbackups.

Seit dem Wechsel und einigen Anpassungen an der MySQL-Konfiguration (my.cnf) traten bei der Verwendung des Scripts Probleme auf:

mysqldump: Error: 'Out of resources when opening file '/tmp/#sql_4fde_2.MAD' (Errcode: 24 "Too many open files")' when trying to dump tablespaces
mysqldump: Got error: 23: "Out of resources when opening file './site_wedding/log.MYD' (Errcode: 24 "Too many open files")" when using LOCK TABLES

Und auch im mysql.log las ich:

May 16 06:30:02 ALPHA mysqld: 160516  6:30:02 [ERROR] Error in accept: Too many open files

Den Fehler behob ich mit folgenden Massnahmen:

Im Zuge des Performance-Tunings der Datenbank (für cacti spine) hatte ich folgende Zeilen in my.cnf eingefügt:

open_files_limit	= 80000

Beim Starten der Datenbank mittels

# systemctl start mysql

fand sich im MySQL-Log folgender Eintrag:

May 16 12:55:45 ALPHA mysqld: 160516 12:55:45 [Warning] Could not increase number of max_open_files to more than 1024 (request: 80162)

Offenbar waren 1024 gleichzeitig geöffnete File Handles nicht ausreichend.

Ich nahm deshalb folgende Anpassung an /etc/security/limits.conf vor:

mysql hard nofile 102400
mysql soft nofile 102400

Quelle: How to permanently raise ulimit ‚open files‘ and MySQL ‚open_files_limit‘

Ein Neustart von MySQL löste das Problem aber nicht; die Fehlermeldung im Log blieb bestehen (eventuell muss man den Server neu starten, damit diese Limits aktiv werden?).

Ein wenig Recherche fügte dann zu Tage, dass man dem MySQL-Server via der systemd Service-Datei selber eine Maximalzahl an File Handles zuweisen kann.

Unter Debian findet sich die Service-Datei unter /etc/systemd/system/mysql.service, wo ich folgende Zeile einfügte:


Anschliessend musste ich folgenden Befehl ausführen, damit die Anpassungen von systemd zur Kenntnis genommen werden:

# systemctl stop mysql
Warning: mysql.service changed on disk. Run 'systemctl daemon-reload' to reload units.
# systemctl daemon-reload
# systemctl start mysql

Beim Neustart von MySQL erschien die Fehlermeldung im mysql.log erneut, dieses Mal aber mit einer deutlichen höheren Zahl an gleichzeitig geöffneten Dateien:

May 16 13:02:57 ALPHA mysqld: 160516 13:02:57 [Warning] Could not increase number of max_open_files to more than 65536 (request: 80162)

Good enough, dachte ich mir. Deshalb entschied ich mich, erneut my.cnf anzupassen:

open_files_limit	= 60000

Noch einmal den Server neu starten, und gut war es:

# systemctl stop mysql
# systemctl start mysql

Bei der manuellen Ausführung des Scripts lief die Sause anschliessend durch, ohne zu stocken.

Tags: , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 17. April 2016 Toller Anbieter, bis auf den 10 Euro-Gutschein

Früher schwor ich auf, doch irgendwann einmal bekehrte mich zu ihrem Service. Eine andere Web-Site für Mietwagenbuchungen braucht der Ferienreisende nicht.

Doch wehe, man versucht diese ominösen 10 Euro-Gutscheine rückerstattet zu erhalten, welche der Anbieter gelegentlich per E-Mail versendet. Diese Gutscheine werden beim Erfassen und Bezahlen der Mietanfrage nicht etwa automatisch angerechnet, sondern müssen nach Rückgabe des Mietwagens online geltend gemacht werden.

Und hier begann für mich die Odyssee: Man hat erstens nur 30 Tage Zeit, die Vergütung einzufordern. Das heisst, dass man sich sofort nach der Rückkehr im E-Mail-Ordner umschauen und den Link im Erinnerungs-E-Mail anklicken sollte (immerhin ist der Anbieter so nett, dieses unaufgefordert zu versenden). Doch ohalätz, die Rückerstattung erfolgt zweitens nicht etwa auf die Kreditkarte, die man für die Online-Buchung verwendet hat (wäre ja zu einfach und die Auszahlungsrate läge bei 100 Prozent). Nein, man muss seine IBAN-Nummer angeben. Diese alleine reicht aber nicht, das Unternehmen wüsste gerne auch noch die Bankleitzahl. Und zu guter Letzt muss mit dem Geburtsdatum sichergestellt werden, dass auch wirklich der Kunde der Nutzniesser der Auszahlung ist.

Nun gut … ich tat, wie mir befohlen wurde, füllte das Formular aus, um dann mit folgender Fehlermeldung konfrontiert zu werden:

billiger-mietwagen Gutschein Rückerstattung

Wähle ich mich auf mein Benutzerprofil ein, steht dort mein Geburtsdatum aber klipp und klar: Kundenangaben

Das Problem könnte ich seinerzeit trotz mehrer Versuche nicht lösen (ein Schelm, wer Böses denkt …). Ich schrieb deshalb genau an dem Tag, an welchem das Angebot auslief, eine E-Mail an den Anbieter ( und teilte diesem mein Problem mit. Eine Antwort erhielt ich nie.

Als ich heute die Buchhaltung nachführte strahlte mir die erfreuliche Botschaft auf dem Kontoauszug entgegen: Halleluja, eine gute Seele hatte meine manuell übermittelten Rückerstattungsangaben gesichtet und entschieden, dass ich für eine Rückerstattung qualifiziert sei:

Credit Suisse Zahlungseingang SilverTours GmbH

Tags: , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 27. März 2016

Sismics Docs installieren

Als Projekt für das Oster-Wochenende habe ich mir die Installation eines Dokumentenmanagementsystems (DMS) vorgenommen. Ziel ist es, die von mir seit Jahren gescannten Einkaufsbelege sauber in einem Archiv abzulegen und die Belege anschliessend mit meiner selbstprogrammierten Buchhaltungs-Applikation (PHP/MySQL) zu verknüpfen.

Nach einem wenig erfolgsversprechenden Umweg über Alfresco (zu gross, zu komplex, beansprucht zu viele Ressourcen) landete ich schlussendlich bei Sismics Docs, auch wenn dieses in einer Übersicht quelloffener DMS aus dem Jahr 2010 nicht erwähnt wird. Die Screenshots haben mich überzeugt, die Software zu installieren und herunterzuladen.

Da ich mich nicht mit Java-Applikationen auskenne, liefere ich hier eine Installationsanleitung. Sie richtet sich an Personen, welche ausreichend Linux-Erfahrung haben, anstelle aus der Java- aber aus der PHP/MySQL-Ecke kommen.

Repository auschecken

Als erstes legen wir uns eine lokale Kopie des Git-Repositories an:

# mkdir /usr/local/bin/sismics
cd /usr/local/bin/sismics
git clone .

To Dock or not to Dock

Unter den Dateien des Repositories finden sich Hinweise darauf, dass der Entwickler Docker zu verwenden scheint; u.a. existieren im Wurzelverzeichnis des Repositories die Dateien Dockerfile, und

Ich konnte das Teil mit Docker aber nicht zum Laufen bringen. Dies aus mehreren Gründen:


Der kräftigere meiner beiden Linux-Server, welcher im Elternhaus läuft, hat Debian i686 installiert, ein 32-bit Linux. Docker erfordert x86_64 (64-bit). Ein forciertes Upgrade tönt nach digitalem Selbstmord.

Die Bit-Architektur überprüfen kann man dies mit folgendem Befehl:

$ uname -m

Docker installieren

Der Intel NUC, welcher in unserer Mietwohnung im Netzwerk hängt, hat ein x86_64 Linux am Laufen. Deshalb führte ich dort die Installation gemäss der offiziellen Anleitung aus.

Vorgängig musste ich noch herausfinden, welche Debian-Version ich installiert hatte:

# lsb_release -da
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 8.3 (jessie)
Release:	8.3
Codename:	jessie

Quelle: Check what Debian version you are running on your Linux system

Jessie! Anschliessend folgte ich der offiziellen Anleitung:

# apt-get install apt-transport-https ca-certificates
# apt-key adv --keyserver hkp:// --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
# echo "deb debian-jessie main" > /etc/apt/sources.list.d/docker.list
# apt-get update
# apt-get install docker-engine
# service docker start
# docker run hello-world

Bingo, Docker läuft.

Image nicht gefunden

Leider funktioniert die Generierung des Images für das Sismics Docs nicht:

# cd /usr/local/bin/sismics
# docker build -t sismics:0.1 .
Sending build context to Docker daemon 14.35 MB
Step 1 : FROM sismics/debian-java7-jetty9
Pulling repository
Error: image sismics/debian-java7-jetty9 not found

Mit dem Switch -t definiert man das Paket und den Tag (vgl. Docker — build.

*seufz* Okey, dann halt kein Docker.

Manuelle Installation

Nun gut, da wir den Docker-Weg nicht beschreiten können, verlassen wir den Intel NUC und wenden uns wieder dem kräftigeren Server zu.


Damit man schon nur die Testumgebung des DMS hockriegt, benötigt man folgende Pakete:

# apt-get install maven tesseract-ocr openjdk-7-jdk

Testinstallation bauen

Sobald die Pakete auf dem Rechner liegen, bauen wir uns die Testinstallation:

# cd /usr/local/bin/sismics/docs-parent
# mvn clean -DskipTests install
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] Docs Parent ........................................ SUCCESS [  7.114 s]
[INFO] Docs Core .......................................... SUCCESS [01:37 min]
[INFO] Docs Web Commons ................................... SUCCESS [ 47.086 s]
[INFO] Docs Web ........................................... SUCCESS [ 30.833 s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 03:02 min
[INFO] Finished at: 2016-03-27T09:52:29+00:00
[INFO] Final Memory: 34M/94M
[INFO] ------------------------------------------------------------------------

Testinstallation starten

Nun starten wir die Testinstallation, um zu sehen, ob alles wie gewünscht funktioniert:

# cd /usr/local/bin/sismics/docs-web
mvn jetty:run
[INFO] Started ServerConnector@b40c2f{HTTP/1.1}{}
[INFO] Started @23372ms
[INFO] Started Jetty Server

Sobald diese Anzeige erscheint, können wir mit einem Web-Browser auf den Applikationsserver zugreifen:

Das Standardpasswort des Administrator-Kontos lautet admin, wie eine Suche durch den Quellcode offenbart:

$ ack passw
19:     * Administrator's default password ("admin").

Java Advanced Imaging

Die Web-Oberfläche funktioniert, man kann Dateien hochladen — doch ausgerechnet das erste PDF produzierte folgende Fehlermeldung im Log der Applikation:

Cannot read JPEG2000 image: Java Advanced Imaging (JAI) Image I/O Tools are not installed

Diese Tools installiert man sich folgendermassen:

$ cd /tmp
$ wget ""
# bash /tmp/install-java-jai-imageio

Quelle: Install Java Advanced Imaging ImageIO Tools on a Linux Machine

ACHTUNG: Bitte den Inhalt aller aus dem Netz heruntergeladenen Bash-Scripts gründlich prüfen, bevor man sie unter dem root-Account ausführt.

Weitere Pakete installieren

Rückblickendes Ziel meines Sonntagsprojekts war es, die Applikation unter dem Java-Applikationsserver Jetty persistent zum Laufen zu bringen. Hierzu bauen wir uns ein sog. war-File. Damit das auch sauber funktioniert, benötigen wir folgende Pakete:

# apt-get install nodejs npm
# ln -s /usr/bin/nodejs /usr/bin/node
# npm install -g grunt-cli

Wir sehen, ob alle nötigen Komponenten da sind, wenn folgende Befehle einen Wert zurückgeben:

$ which node
$ which grunt

Insbesondere das node-Binary ist zwingend nötig — bei den ersten Kompilationsversuchen erschien folgende Fehlermeldung …

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Docs Web 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ docs-web ---
[INFO] Deleting /usr/local/bin/sismics/docs-web/target
[INFO] --- maven-antrun-plugin:1.8:run (default) @ docs-web ---
[INFO] Executing tasks

     [exec] /usr/bin/env: ‘node’: No such file or directory
     [exec] Result: 127
[INFO] Executed tasks
[INFO] --- maven-resources-plugin:2.7:resources (default-resources) @ docs-web ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO] Copying 1 resource

… und ich endete mit einem nur halbwegs funktionsfähigen .war, weil bestimmte nodejs-Komponenten fehlten:

     [exec] /usr/bin/env: ‘node’: No such file or directory
     [exec] Result: 127

Der oben angelegte Symlink löst dieses Problem:

     [exec] Running "clean:dist" (clean) task
     [exec] Running "ngmin:dist" (ngmin) task
     [exec] ngminifying src/app/docs/app.js, src/app/docs/controller/Login.js, src/app/docs/controller/Main.js, src/app/docs/controller/Navigation.js, src/app/docs/controller/document/Document.js, src/app/docs/controller/document/DocumentDefault.js, src/app/docs/controller/document/DocumentEdit.js, src/app/docs/controller/document/DocumentModalPdf.js, src/app/docs/controller/document/DocumentModalShare.js, src/app/docs/controller/document/DocumentView.js, src/app/docs/controller/document/DocumentViewActivity.js, src/app/docs/controller/document/DocumentViewContent.js, src/app/docs/controller/document/DocumentViewPermissions.js, src/app/docs/controller/document/FileModalView.js, src/app/docs/controller/document/FileView.js, src/app/docs/controller/settings/Settings.js, src/app/docs/controller/settings/SettingsAccount.js, src/app/docs/controller/settings/SettingsDefault.js, src/app/docs/controller/settings/SettingsGroup.js, src/app/docs/controller/settings/SettingsGroupEdit.js, src/app/docs/controller/settings/SettingsLog.js, src/app/docs/controller/settings/SettingsSecurity.js, src/app/docs/controller/settings/SettingsSecurityModalDisableTotp.js, src/app/docs/controller/settings/SettingsSession.js, src/app/docs/controller/settings/SettingsUser.js, src/app/docs/controller/settings/SettingsUserEdit.js, src/app/docs/controller/settings/SettingsVocabulary.js, src/app/docs/controller/tag/Tag.js, src/app/docs/controller/usergroup/GroupProfile.js, src/app/docs/controller/usergroup/UserGroup.js, src/app/docs/controller/usergroup/UserProfile.js, src/app/docs/directive/Acl.js, src/app/docs/directive/AuditLog.js, src/app/docs/directive/File.js, src/app/docs/directive/ImgError.js, src/app/docs/directive/InlineEdit.js, src/app/docs/directive/SelectRelation.js, src/app/docs/directive/SelectTag.js, src/app/docs/filter/Filesize.js, src/app/docs/filter/Newline.js, src/app/docs/filter/Shorten.js, src/app/docs/service/Tag.js, src/app/docs/service/User.js, src/app/share/app.js, src/app/share/controller/FileModalView.js, src/app/share/controller/FileView.js, src/app/share/controller/Main.js, src/app/share/controller/Share.js, src/app/share/controller/ShareModalPdf.js, src/app/share/filter/Filesize.js, src/app/share/filter/Newline.js
     [exec] Running "concat:docs" (concat) task
     [exec] File "dist/docs.js" created.
     [exec] Running "concat:share" (concat) task
     [exec] File "dist/share.js" created.
     [exec] Running "less:dist" (less) task
     [exec] File dist/less.css created.
     [exec] Running "concat:css" (concat) task
     [exec] File "dist/style.css" created.
     [exec] Running "cssmin:dist" (cssmin) task
     [exec] File 'dist/style/style.min.css' written.
     [exec] Uncompressed size: 165398 bytes.
     [exec] Compressed size: 31032 bytes gzipped (139383 bytes minified).
     [exec] Running "uglify:docs" (uglify) task
     [exec] File dist/docs.min.js created.
     [exec] Running "uglify:share" (uglify) task
     [exec] File dist/share.min.js created.
     [exec] Running "copy:dist" (copy) task
     [exec] Created 23 directories, copied 53 files
     [exec] Running "remove:dist" (remove) task
     [exec] Running "cleanempty:src" (cleanempty) task
     [exec] Cleaning dist/locale...OK
     [exec] Cleaning dist/lib...OK
     [exec] Running "htmlrefs:index" (htmlrefs) task
     [exec] Running "htmlrefs:share" (htmlrefs) task
     [exec] Running "replace:dist" (replace) task
     [exec] Done, without errors.

Quelle: run npm command gives error „/usr/bin/env: node: No such file or directory“

.war kompilieren

Nun ist alles da, um das .war zu kompilieren:

# cd /usr/local/bin/sismics/docs-web
# mvn -Pprod -DskipTests clean install
[INFO] Installing /usr/local/bin/sismics/docs-web/target/docs-web-1.0-SNAPSHOT.war to /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.war
[INFO] Installing /usr/local/bin/sismics/docs-web/pom.xml to /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.935 s
[INFO] Finished at: 2016-03-27T10:37:55+00:00
[INFO] Final Memory: 28M/68M
[INFO] ------------------------------------------------------------------------

Jetty installieren und das .war bekanntmachen

Als nächstes installiert man Jetty:

# apt-get install jetty9

Sobald Jetty existiert, kopiert man das vorhin kompilierte .war in folgendes Verzeichnis:

# cp /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.war /usr/share/jetty9/webapps/dms.war

ACHTUNG: Es gibt auch ein Verzeichnis /usr/share/jetty/webapps/; Jetty ignoriert dieses aber (meiner Meinung nach). Das .war gehört nicht hierhin.

Datenverzeichnis anlegen

# mkdir /var/docs
# chmod 777 /var/docs

Jetty neu starten

# service jetty9 start

Sismics Docs aufrufen

Sobald Jetty läuft, öffnet man den Browser wieder:

Man loggt sich ein, ändert das Admin-Passwort, erstellt weitere User, lädt ein Testdokument hoch, loggt sich wieder aus — und dann stoppt man Jetty testhalber wieder um sicherzugehen, dass die Daten und Konfiguration auch einen Stop des Applikationsservers überlegen:

# service jetty9 stop
# service jetty9 start

Nun sollte man sich mit dem soeben gesetzten Admin-Passwort einloggen können und das vorher hochgeladene Dokument sehen.

Fertig! Nun kann der Spass beginnen.

Die API-Dokumentation habe ich leider noch nicht gefunden …

Tags: , , , , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen