Tag 84/2016: How to deny requests by filename, extension and patterns with nginx in a comfortably bureaucratic manner

In a current setup where nginx acts as a reverse proxy to some Apaches I want to deny access to some useless Flotsam & Jetsam files.

What I not want is to craft wonderful regular expressions that suffice type 3 of a Chomsky-Hierarchy while learning about Pumping-Lemmata, albeit that sounds very alluring for an annoyingly hot summerday later this year (Todo).

So in order to keep my various location directives specific as they are I create a map like this (example):

map $uri $reqhide {
 default 0;
 "~*robots.txt$" 0;
 "~*\.(md|txt)$" 1;
 "~*liesmich\.html$" 1;
}

This map has to be created in the http context of a config file and can then be used in if-conditions within location blocks. It uses the special parameter default to set the variable $reqhide in case of any non-matching pattern. If I want to hide files later on like all .txt files I set $reqhide to 1. A request for „robots.txt“ is caught by the first matching regular expression, so a request for „foo.txt“ is caught by the second that goes for all .txt files. The complete order of priority is explained in the map-module-docs.

As this wonderfully unknown (to many) article on nginx.com notes, the only 100% safe things in if conditions are return and rewrite statements.

So I just do something like

location / {
  [...]
  if ($reqhide) {
    return 404;
  }
  [...]
}

to make the response a 404-File-not-found lie.

Tag 81/2016: Slack-based silence

Bei täglicher Anwendung von Slack stellt sich auch bei großen Teams im gleichen Raum schon bald eine fast unheimliche Stille ein, Gespräche verstummen, leises Geklacker der Tastaturen, konzentrierte Augenblicke auf Monitore, Individualpräferenzmusik aus den Individualpräferenzkopfhörern.

Dennoch eifrige Geschwätzigkeit in den Channels, garniert mit einem bunten Strauß Emojis.

Surreales fand ich immer schon gut, wenn es Humor hat.

Tag 80/2016: Amazing Nexus-Tablet Experiences

Nach einem Betriebssystem-Update kommt der Hinweis, dass eine Konto-Synchronisation erforderlich sei. Bitte geben Sie Ihr Passwort ein. Doch wiederholt bricht der Dialog mitten im Tippen ab und meldet, das Passwort sei falsch. Yo, wenn ich es doch wenigstens mal ganz eingeben hätte können. Ich tippe auf geplante Obsoleszenz der Software, die in der auf die Hardware festgefrorenen Version nicht mehr mit Zwei-Faktor-Authentifizierung zurecht kommt und statt sinnvolle Hinweise zu geben nur abranzt.

Irgendwann dann die Entscheidung, es mal mit dem Werkszustand zu probieren, löscht man halt alles, ist man ja seit Erfindung der Betriebssysteme gewohnt: „Boote einfach mal“, „Installier mal wieder frisch“.

Cooool, nach dem Werkszustand-Neuanfang offeriert mir das Tablet, ein anderes Gerät an die Rückseite zu halten um via NFC-Kopplung („Nahfeldkommunikation„) die Einstellungen zu synchronisieren. Mach ich mit dem Schlautelefon, ein Tonsignal deutet an, dass es funktioniert. Trotzdem kommt kurz danach die Meldung, dass die Wiederherstellung der Apps und Einstellungen nicht funktioniert, zusammen mit dem Button „Erneut versuchen„. Als Softwareentwickler kennt man diese „Erneut versuchen“ Buttons ja – die bedeuten rein gar nichts und sind nur der Beitrag der Psychologie zur Informatik. Also lustlos 20-30x draufgedrückt, nur so zum Spaß. Beim 31. Nichterfolg dann auf Überspringen.

Es präsentiert sich das werkszustandsneue Setup mit ein bisschen Einstellungen, die es zumindest nach dem Passworteingeben von Mountain View rübergeschafft haben. Verschlüsselung muss natürlich auch wieder manuell aktiviert werden, für die das Tablet aber vorher auf 100% Akkustand geladen werden muss, obwohl es aktuell eh schon am Kabel hängt.

In diesem Zustand der Trostlosigkeit gibt es die ursprüngliche Wiederherstellensupersyncfunktion offenbar nicht mehr, um es in bekannter „Versuchen Sie es zu einem späteren Zeitpunkt erneut“ – Manier sporadisch zu, ähm, versuchen. Wenn doch, bitte Tipp als Kommentar hinterlassen, Danke.

Tag 74/2016: Don’t trick the recruiter

Sehr geehrter Herr Eidenschink, wir suchen für ein Projekt in Hamburg einen Web Architekten… Sie sind verantwortlich für… Rest-Interfaces/ Python/ Django/ DB-Modellierung… Dauer 6 Monate… ab sofort…

Sehr geehrte Frau X, vielen Dank für Ihre Anfrage… So ein Talent bekommen Sie nicht alle Tage… Verdoppeln Sie den Stundensatz… Massagen am Arbeitsplatz… Ich trinke gerne den El Carretil von Artadi oder den Terreus von Mauro… frische Obstschalen… Kickerraum…

Sehr geehrter Herr Eidenschink, ich habe kurz Rücksprache gehalten… kein Problem… alles ist arrangiert… wir erwarten Sie ab Montag… haben Sie Verständnis, dass Sie im Falle des Nichterscheinens Bekanntschaft mit dem Inneren eines unserer Barrique-Fässer machen werden… hochkomplex, tief und nuancenreich…

Sehr geehrte Frau X, ich weiß nicht, wer in der Pause an meinem Computer getippt hat… Sorry… Versehen…

Sehr geehrter Herr Eidenschink, wir freuen uns… Also dann bis Montag!

 

Tag 41/2016: Falsche Spuren

Eine Ansible-Anweisung in einem Webserver-Task hat mir heute den Apache ausgeknipst. Genauer gesagt eine fehlerhafte Anweisung im „lineinfile“ -Modul. Das Modul benutzt man vor allem, um eine einzelne Zeile in einer Datei zu finden und auszutauschen.

Spoiler: Ich wollte in der ports.conf aus „Listen 80“ ein explizites „Listen 127.0.0.1:80“ machen und habe stattdessen bei jedem Durchlauf „Listen 127.0.0.1:80“ hinzugefügt. Irgendwann stand es 5x drin, was 4x zuviel ist.

Ein „apachectl configtest“ meldet leider fröhlich „Syntax OK“ – die manpage weist ja auch darauf hin „This test does not catch all errors“, weil es hauptsächlich die Syntax analysiert.

Beim „service apache2 restart“ kommt dann „Address already in use: AH00072: make_sock: could not bind to address“ und „no listening sockets available, shutting down“ und dann final „the apache2 instance did not start within 20 seconds. Please read the log files to discover problems“. Das Error-Log bleibt leer.

Bei der Fehlersuche habe ich zuerst mit netstat und lsof hantiert und war von der doch eigentlich freien Adresse:Port-Kombi irritiert. Bis die Ansible-Script-Recherche mich auf die ports.conf-Veränderung gebracht hat.

Was könnten die Alternativen auf Apache-Seite sein? Gleiche Konfigurationsanweisungen wie eine einzige Anweisung behandeln? Eine aussagekräftigere Fehlermeldung?

Tag 40/2016: Faschingsdienstag-Erkenntnisse

Dies und das.

  • Auf einem der Mailserver habe ich eine fail2ban-Regel, die jeden via DNSBL abgelehnten Einlieferungsversuch findet und die IP für ein paar Stunden sperrt. Das via Munin geplottete Resultat über die letzten Wochen zeigt das Ansteigen der IP-Sperren immer über die Mittagszeit.
  • HTTP/2-Experimente sind notwendig, um mit dem Protokoll der Zukunft frühzeitig Erfahrungen zu sammeln. Dieser Blog-Post hat mich auf diese Implementierung Nghttp2 gebracht. Als weitere Alternative zum ngx_http_v2-Modul von nginx.
  • Gluster und Ceph kenne ich und ich bin in dem Zusammenhang heute über Sheepdog gestolpert. Bookmark gesetzt. Notiz: Demnächst mal das gluster_volume Modul von Ansible laufen lassen, auf das mich die Readme vom geerlingguy-Repository zur GlusterFS-Rolle gebracht hat.
  • WordPress at Scale hat Potential, ist im Moment aber noch ein bisschen zu Highlevel. Am Besten ergänzen mit highscalability.com.

Tag 33/2016: Wohin mit dem Server?

Das alte Server-Ding ist so schwer, dass mir die Vorteile der Cloud plötzlich sehr einleuchtend erscheinen. Cloud, Wolke, Wölkchen, leicht, luftig.

Bisher war der Server im Besprechungsraum, weshalb man dort lieber nichts besprechen wollte, denn der Server ist nicht nur schwer, sondern auch laut.

Ein Kollege und ich überlegen uns Lösungen. Den Abluftbereich mit Styropor zukleben? Wirksam, aber nur für kurze Zeit. Kaputt nutzt der Server ja nix.

Wir gehirnstürmen Ideen wie

  • Server in den Schrank stellen („Hört ihr das auch?“)
  • Server auf den Flur stellen („Wem gehört der Hund?“)
  • Server in die Teeküche neben den Kühlschrank stellen („Ist das die neue Kaffeemaschine?“)
  • Server in ein Toilettenabteil stellen („Hallo? Geht es Ihnen gut?“)
  • Server mit John Bates aus dem Piloten von Downton Abbey vergleichen („Warten Sie. Bleiben Sie hier und wir reden nie wieder über diese Sache!“)

Nachdem der Lösungsraum eine gewisse kritische Menge erreicht hat sind wir glücklich und wenden uns wieder anderen Dingen zu.


Update 8.2.2016: Das alte (verstaubte) Servernetzteil gegen ein aktuelles ausgetauscht und die Aktion war von Erfolg gekrönt.

Foto eines verstaubten alten Server-Netzteils.

Tag 27/2016: DevOps und Continuous Deployment als Grundlage für Sicherheitsmaßnahmen

Schon ein bisschen her, immer noch interessant, der Vortrag von Zane Lackey und Dan Kaminsky „Delivering Security: Faster, Better, Cheaper“ auf der Velocity NY 2013:

Auszug: Dank Continuous Deployment können wir schneller, besser und billiger ausliefern. Damit es funktioniert, müssen wir kontrollieren, reporten und in Echtzeit auf unsere Fehler aufmerksam werden. Die aufgesetzte Infrastruktur erlaubt uns, das Prinzip „Entdeckung vor Prävention“ umzusetzen. Fehler machen wir sowieso permanent. Da wir im Rahmen des CD den Normalzustand kennen, sind Abweichungen davon die Warnsignale, die uns auf gezielte Angriffsversuche aufmerksam machen.

Der Angriff ist dann nur ein weiterer Fehler, auf den pragmatisch – und schnell – reagiert werden kann.

Tag 18/2016: Python-Repräsentation einer YAML-Datei ausgeben

Zur Zeit kodifiziere ich das Setup einiger alter Server in Ansible-Skripte. Dank Virtualisierung und Cloud ist es mittlerweile einfach, Migrationen auf neue Betriebssysteme und Versionsstände im Vorfeld durchzuspielen. Die neuen Setups profitieren auch vom Know-how aus zahlreichen anderen Ansible-Scripten, z.B. auf Github, weil man immer wieder auf nützliche Vorgehensweisen und Module stößt.

Bei den Core-Modulen copy, file, lineinfile und template setze ich nach Möglichkeit immer explizit group, owner und mode so restriktiv wie möglich – der SuSE-Paranoid-Mode bei den Dateirechten fehlt mir bei Debian/Ubuntu einfach 🙂 Ansonsten Tags setzen mindestens für Packages und Services. Und vor dem Schreiben eigener Rollen lohnt es sich immer, nach bereits erprobten und universellen Rollen Ausschau zu halten.

Zwar ist die Struktur eines YAML-Dokuments leicht zu verstehen, aber trotzdem ist manchmal ein schneller Blick auf die Python-Repräsentation hilfreich. Das kann man beispielsweise mit ein paar Zeilen Python selbst erledigen. „Tag 18/2016: Python-Repräsentation einer YAML-Datei ausgeben“ weiterlesen