Day 009: Werkzeuge für Sysadmins

Schon ein paar Jahre her, der Vortrag von Charly Kuehnast auf der 7. Secure Linux Administration Conference (https://www.youtube.com/watch?v=M5LzL2JfpOI) – aber ich bin gerade erst darüber gestolpert und notiere mir die Tools, die ich bei nächster Gelegenheit ausprobieren werde:

So.

Episode 38/2017: Fundstück des Tages

Backticks oder Shell-Expansion bei Befehlen auf der Kommandozeile?

Das sagen das IEEE und The Open Group  in The Open Group Base Specifications Ausgabe 7, IEEE Std 1003.1-2008, 2016 Edition. Eine schöne Antwort dazu auch auf Stackexchange.

Meine Entscheidung nach der Lektüre: Ich bevorzuge immer noch die Shell-Expansion-Schreibweise.

Episode 20/2017: In einer fremden Stadt

Notiz an mich: In einer fremden Linux-Stadt, irgendwo in den Wolken, soll ich ein privates Netzwerk konfigurieren. Wie finde ich heraus, wie das private Netzwerkinterface benannt ist, ohne den Support zu kontaktieren?

Die aktuellen Interfaces, z.B.

ifconfig

Dann via Kernel:

ls /sys/class/net
oder
cat /proc/net/dev

Oder über die PCI-Devices („lspci“):

lspci | egrep -i --color 'network|ethernet'

bzw. die Hardware („lshw“):

lshw -class network

Tag 189/2016: namei – follow a pathname until a terminal point is found

DESCRIPTION

namei interprets its arguments as pathnames to any type of Unix file (symlinks, files, directories, and so forth). namei then follows each pathname until an endpoint is found (a file, a directory, a device node, etc). If it finds a symbolic link, it shows the link, and starts following it, indenting the output to show the context.

This program is useful for finding "too many levels of symbolic links" problems.

Example:

# namei -l $(pwd)
f: /usr/local/bin
drwxr-xr-x root root /
drwxr-xr-x root root usr
drwxr-xr-x root root local
drwxr-xr-x root root bin

This short post exists merely for me because everytime this command would be handy I have to waste 10 Google-Minutes to find it („No! Not the ls command“, „No! Not find with arguments“, „No! …“).

For example: Now that you know what it does (see example output) try to search for it not using phrases from the description above. If you have a nice phrase please leave it in the comments…

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 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.