Archiv ‘Linux’

Donnerstag, 22. Juni 2017

monit bei einem HTTP-Fehler keinen Alarm absetzen lassen

In der Standardkonfiguration meldet monit einen Alarm, wenn ein HTTP-Check eines Web-Servers eine HTTP-Response grösser/gleich 400 zurück gibt:

If not used, the http protocol test will fail if the status code returned is greater than or equal to 400. You can override this behaviour by using the status qualifier.

Quelle: Monit Version 5.23.0 — HTTP

Was aber, wenn eine HTTP-Response mit einem solchen Code das korrekte Funktionieren eines Web-Servers signalisiert und deshalb keinen Alarm generieren soll? Es gibt Abhilfe:

...
check host web.server.strasse.emeidi.local with address 10.10.10.10
if failed
   port 80
   protocol http
   request "/non/existent.php"
   status = 404
then alert
...

Quelle: Monit monitor http status with 404 page

Mittels des Keywords status = 000 gibt man an, was der tatsächlich erwartete Wert ist.

Tags: ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 22. Juni 2017

Wenn Embedded Linux-Geräte kein HTTP HEAD verstehen

Netzwerkgeräte in meinem Intranet überwache ich mit der quelloffenen Software monit. Seit ich einen meiner monit-Server auf Debian Stretch upgegradet habe, häuften sich „Geister“-Fehlermeldungen — immer in Bezug auf Checks, welche die Verfügbarkeit von Web-Oberflächen abfragen. Dies in folgender Form:

...
check host web.server.strasse.emeidi.local with address 10.10.10.10
    if failed port 80 protocol http for 10 cycles then alert
...

Mit dem Upgrade auf Debian Stretch wird auch monit von Version 5.9-1+deb8u1 auf Version 5.20.0-6 aktualisiert.

Ich wartete also den Moment ab, in welchem ich per E-Mail die Fehlermeldung erhielt, loggte mich per SSH auf den Server ein und führte zu Debugging-Zwecken eine Abfrage aus — die Idee war, auf dem selben Server die Abfrage zu simulieren, die monit gegen das entfernte System laufen lässt:

$ wget --server-response "http://10.10.10.10/"
--2017-06-22 22:05:25--  http://10.10.10.10/
Verbindungsaufbau zu 10.10.10.10:80 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 
  HTTP/1.1 200 OK
  Server: Router Webserver
  Connection: close
  Content-Type: text/html
  WWW-Authenticate: Basic realm="TP-LINK Wireless Dual Band Gigabit Router WDR3600"
Länge: nicht spezifiziert [text/html]
Wird in »index.html« gespeichert.

index.html                   [ <=>                              ]   7,66K  --.-KB/s    in 0,01s   

2017-06-22 22:05:25 (754 KB/s) - »index.html« gespeichert [7841]

Dies funktioniert problemlos. Was Cheibs?

Als ich mir die Dokumentation zu monit genauer anschaute, realisierte ich eine feine, aber entscheidende Option:

PROTO(COL) HTTP
     [USERNAME "string"]
     [PASSWORD "string"]
     [REQUEST "string"]
     [METHOD <GET|HEAD>]
     [STATUS operator number]
     [CHECKSUM checksum]
     [HTTP HEADERS list of headers]
     [CONTENT < "=" | "!=" > STRING]

Quelle: Monit Version 5.23.0 — HTTP

Mit [METHOD ] entscheidet man, ob man einen normalen HTTP-Request („GET“) versendet, oder aber nur einen „HEAD“-Request, der nur nach dem Header einer Web-Site frägt. Das spitzfindige an der Sache:

METHOD set the HTTP request method. If not specified, Monit prefers the HTTP HEAD request method to save bandwidth, unless a response content or response checksum is tested. As some webservers may not support the HEAD method, one may want to set the method explicitly.

Dann lass uns das doch mal so simulieren. wget verfügt über die entsprechende Option --spider, die HEAD-Requests versendet:

$ wget --spider --server-response "http://10.10.10.10/"
Spider-Modus eingeschaltet. Es wird geprüft, ob die Datei auf dem Server existiert.
--2017-06-22 22:04:36--  http://10.10.10.10/
Verbindungsaufbau zu 10.10.10.10:80 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 
  HTTP/1.1 501 Not Implemented
  Server: Router Webserver
  Connection: close
  WWW-Authenticate: Basic realm="TP-LINK Wireless Dual Band Gigabit Router WDR3600"
  Content-Type: text/html
--2017-06-22 22:04:37--  (Versuch: 2)  http://10.10.10.10/
Verbindungsaufbau zu 10.10.10.10:80 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 
  HTTP/1.1 200 OK
  Server: Router Webserver
  Connection: close
  Content-Type: text/html
  WWW-Authenticate: Basic realm="TP-LINK Wireless Dual Band Gigabit Router WDR3600"
Länge: nicht spezifiziert [text/html]
Datei auf dem Server existiert und könnte weitere Verweise enthalten,
aber Rekursion ist abgeschaltet -- kein Download.

Via: Wget HEAD request?

Et voilà, das war das Problem: Der Embedded Web Server auf dem zu überwachenden Gerät hat Probleme, wenn aus dem nichts ein HEAD-Request kommt. Beim zweiten Anlauf dann ist die Web-Seite offenbar gerendert und der HEAD-Request kann beantwortet werden.

monit scheint nun aber offenbar so programmiert zu sein, dass nach dem ersten Versuch und einer Antwort mit Fehlern kein zweiter Versuch lanciert wird. Deshalb auch die sporadischen Fehlermeldungen.

Wie löst man das Dilemma? Ich wandelte den Test folgendermassen um:

...
check host web.server.strasse.emeidi.local  with address 10.10.10.10
    if failed
	port 80
	protocol http
	with content = "Willkommen"
	for 10 cycles
    then alert
...

Die Anweisung with content = "Zeichenkette" forciert monit, einen GET-Request abzusetzen und keinen HEAD (da nur beim GET-Request ein HTTP-Body mitgeliefert wird). Und schwup, Problem gelöst.

Erweitert

Übrigens: Wem die Ausgabe von wget noch nicht ausreicht, da sie zu wenig geschwätzig ist, kann auch die Debug-Option verwenden:

$ wget --debug --spider --server-response "http://10.10.10.10/"
Setting --spider (spider) to 1
Setting --server-response (serverresponse) to 1
DEBUG output created by Wget 1.19.1 on darwin15.6.0.

Reading HSTS entries from /Users/user/.wget-hsts
Converted file name 'index.html' (UTF-8) -> 'index.html' (UTF-8)
Spider-Modus eingeschaltet. Es wird geprüft, ob die Datei auf dem Server existiert.
--2017-06-22 22:02:44--  http://10.10.10.10/
Verbindungsaufbau zu 10.10.10.10:80 … verbunden.
Created socket 4.
Releasing 0x00007ff99bc231e0 (new refcount 0).
Deleting unused 0x00007ff99bc231e0.

---request begin---
HEAD / HTTP/1.1
User-Agent: Wget/1.19.1 (darwin15.6.0)
Accept: */*
Accept-Encoding: identity
Host: 10.10.10.10
Connection: Keep-Alive

---request end---
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 
---response begin---
HTTP/1.1 501 Not Implemented
Server: Router Webserver
Connection: close
WWW-Authenticate: Basic realm="TP-LINK Wireless Dual Band Gigabit Router WDR3600"
Content-Type: text/html

---response end---

  HTTP/1.1 501 Not Implemented
  Server: Router Webserver
  Connection: close
  WWW-Authenticate: Basic realm="TP-LINK Wireless Dual Band Gigabit Router WDR3600"
  Content-Type: text/html
Closed fd 4
--2017-06-22 22:02:48--  (Versuch: 2)  http://10.10.10.10/
Verbindungsaufbau zu 10.10.10.10:80 … verbunden.
Created socket 4.
Releasing 0x00007ff99bc23110 (new refcount 0).
Deleting unused 0x00007ff99bc23110.

---request begin---
GET / HTTP/1.1
User-Agent: Wget/1.19.1 (darwin15.6.0)
Accept: */*
Accept-Encoding: identity
Host: 10.10.10.10
Connection: Keep-Alive

---request end---
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 
---response begin---
HTTP/1.1 200 OK
Server: Router Webserver
Connection: close
Content-Type: text/html
WWW-Authenticate: Basic realm="TP-LINK Wireless Dual Band Gigabit Router WDR3600"

---response end---

  HTTP/1.1 200 OK
  Server: Router Webserver
  Connection: close
  Content-Type: text/html
  WWW-Authenticate: Basic realm="TP-LINK Wireless Dual Band Gigabit Router WDR3600"
Länge: nicht spezifiziert [text/html]
Closed fd 4
Datei auf dem Server existiert und könnte weitere Verweise enthalten,
aber Rekursion ist abgeschaltet -- kein Download.

Via: What headers are automatically send by wget?

Sackgassen

Initial befürchtete ich, dass der Web-Server des Zielsystems sich am User-Agent des Requests verschluckt. Doch dies war eine falsche Vermutung. Nichtdestotrotz könnte man monit so konfigurieren, dass es einen alternativen User-Agent sendet:


‚User-Agent‘ header can not be set via ‚http headers‘ array

Und noch ein anderes Beispiel: Trying to configure monit to use https protocol but it sticks with http

Tags: , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Samstag, 6. Mai 2017

Netdata von einem Linux-System entfernen

Vor einiger Zeit bin ich wohl über einen Hacker News-Post auf Netdata aufmerksam geworden und habe mir die Software kurzerhand auf zwei Servern installiert. Wie ich nun, einige Monate später, feststellen musste, habe ich die Web-Applikation nie verwendet. Somit weg damit.

Leider scheint die Software keine Uninstall-Funktion mit sich zu bringen.

Ein Kommentar zu einem GitHub-Issue „Uninstall netdata? #103“ hilft weiter und empfiehlt folgendes selbstgebasteltes Script:

# killall netdata
# rm -Rf /usr/sbin/netdata
# rm -Rf /etc/netdata
# rm -Rf /usr/share/netdata
# rm -Rf /usr/libexec/netdata
# rm -Rf /var/cache/netdata
# rm -Rf /var/log/netdata
# rm -Rf /opt/netdata
# userdel netdata
# groupdel netdata

Hat bei mir geklappt.

Tags: , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 5. April 2017

Zeichenkette auf der Linux-Kommandozeile in mehreren Dateien suche und ersetzen

Heute hat Cyon meinen Web-Server gezügelt. Dies machte es nötig, dass ich meine Postfix-Konfiguration auf einem halben dutzend Linux-Servern anpassen musste.

Da ich für jeden Server spezifische Konfigurationsdateien verwende, machte ich mich auf die Suche nach einer einfachen Lösung, wie man die Zeichenkette server41.cyon.ch mit s056.cyon.net ersetzen konnte.

Und zwar auf der Kommandozeile, mit einem Befehl?

Wie üblich half Stackexchange weiter:

$ sed -i -- 's/server41.cyon.ch/s056.cyon.net/g' *

Quelle: How can I replace a string in a file(s)?

Und schwupp-di-wupp waren die Konfigurationsdateien angepasst.

Tags: , , , , , ,
Labels: IT, Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 19. Februar 2017

ELK: Race Condition mit resolv.conf und WiFi

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.

Dank ELK fand ich auf Grund von postfix Log-Meldungen bald einmal heraus, dass mein Raspberry Pi 3, welcher ein Dashboard in unserer Wohnung antreibt, keine E-Mails versenden kann. postfix konnte den Hostnamen meines Mail-Providers nicht auflösen:

DASHBOARD postfix/error[1234]: ABCDEF: to=<log@domain.tld>, orig_to=<root@dashboard>, relay=none, delay=40662, delays=40584/78/0/0.27, dsn=4.4.3, status=deferred (delivery temporarily suspended: Host or domain name not found. Name service error for name=server41.cyon.ch type=A: Host not found, try again)

Nach einer längeren Debugging-Session dann die Erkenntnis:

The problem is that Postfix checks /etc/resolv.conf before the WiFi is connected. Therefore, /var/spool/etc/postfix/resolv.conf stays empty after the boot and mails cannot be sent.

Quelle: Postfix error: Host or domain name not found

Genau das war das Problem. Während der Kommentator auf Superuser empfiehlt, postfix erst nach der erfolgreichen WiFi-Verbindung zu starten, löste ich das Problem anderweitig, indem ich einen Cron-Job einrichtete:

...
*/1 * * * *	root	cp /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
...

Sicherlich nicht sexy, aber es löst das Problem (und schafft eventuell einige andere).

Tags: , , , , , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 5. Februar 2017

imapfilter wechselnde Zertifikats-Fingerabdrücke ignorieren lassen

imapfilter funktioniert bei mir wunderbar, um in meiner INBOX eintreffende Mails automatisiert in Unterordner zu verschieben.

Dann und wann bricht das per Cron aufgerufene Script seine Arbeit aber ab, weil das Zertifikat des Mail-Servers gewechselt wurde:

imapfilter: certificate mismatch in non-interactive mode

imapfilter muss in einem solchen Fall interaktiv gestartet und das neue Zertifikat permanent akzeptiert werden.

Wen dieses Verhalten stört und die eindeutige Identifikation seiner Gegenseite weniger wichtig ist als ein sauber durchlaufendes Script, fügt oben an seine imapfilter-Regeln folgende Zeile ein:

...
options.certificates = false
...

Quelle: Ignore certificate fingerprint mismatch

Ich habe das bei mir nur für ein kaum genutztes Gmail-Konto aktiviert.

Das Problem könnte mit den hier geschilderten zwei gleichzeitig aktiven, unterschiedlichen Gmail-Zertifikaten zusammenhängen.

Tags: , , , , ,
Labels: Linux

1 Kommentar | neuen Kommentar verfassen

Sonntag, 15. Januar 2017

snmpd-Konfiguration unter OpenWrt (Turris Omnia) anpassen

Auf Grund des in meinem Forum-Artikels geschilderten Problems der nicht zugänglichen Web-Interfaces meines Turris Omnias (das Problem trat kürzlich wieder auf), entschied ich mich, den von /tmp verwendeten Speicherplatz zu überwachen und mich beim Unterschreiten eines bestimmten Wertes zu alarmieren.

Was gibt es besseres, als den bereits laufenden SNMP-Daemon für diese Information anzuzapfen? Doch leider realisierte ich erst nach ein, zwei Stunden pröbeln, dass snmpd Dateisysteme vom Typ tmpfs nicht in den SNMP-Baum aufnimmt (weitere Diskussion hier sowie hier).

Doch vorerst setzte ich mich mit der snmpd-Konfiguration unter /etc/snmp/snmpd.conf auseinander. Beim Turris Omnia handelt es sich hierbei um einen Symlink auf die Datei /var/run/snmpd.conf. Doch bearbeitet man diese Datei und startet SNMP über die LuCI-Web-Oberfläche neu, werden die Anpassungen wie von Geisterhand mit den ursprünglichen Standardwerten überschrieben.

Nach ca. einer halben Stunde pröbeln und Googlen dann die Erkenntnis: Die Konfigurationsdatei ist — wie für OpenWrt typisch — unter /etc/config/snmpd abgelegt. Und zwar in einem OpenWrt-Format.

Darauf gestossen bin ich, als ich folgenden Befehl ausgeführt habe, welcher mir den Standort aller Dateien dieses Pakets zeigt:

# opkg files snmpd
Package snmpd (5.4.4-3) is installed on root and has the following files:
/etc/init.d/snmpd
/etc/config/snmpd
/usr/sbin/snmpd
/etc/snmp/snmpd.conf

Nimmt man die Anpassungen an sysLocation und sysContact hier vor, bleiben sie beim Neustarten des Daemons wie auch des Routers erhalten. Doch leider kann man in der unnötig komplexen Syntax nicht einfach neue Direktiven einbauen — diese müssen dem Start-Script unter /etc/init.d/snmpd explizit bekannt sein. So ist es zwar möglich, Einträge in der Form

disk /tmp 10%

einzubauen, indem man die Datei unter /etc/config/snmpd mit folgenden Zeilen ergänzt:

...
config disk
	option partition /tmp
	option size '10%'

Doch den Parameter includeAllDisks kennt das Script nicht. Halleluja für die aus meiner Sicht unnötige Komplexität, die dieser zusätzliche Konfigurationslayer dem Benutzer aufzwingt …

Im Internet habe ich nach etwas Googlen einen Patch gefunden, mit welchem der includeAllDisks-Parameter nachgerüstet werden kann. Mein Code von /etc/init.d/snmpd schaut deshalb nun so aus:

...
snmpd_disk_add() {
        local cfg="$1"
        local disk='disk'

        config_get partition "$cfg" partition
        [ -n "$partition" ] || return 0
        config_get size "$cfg" size
        [ -n "$size" ] || return 0

        if [ "$partition" == "includeAllDisks" ]; then
            echo "includeAllDisks $size" >> $CONFIGFILE
        else
            echo "disk $partition $size" >> $CONFIGFILE
        fi
        #echo "$disk $partition $size" >> $CONFIGFILE
}
...

Nun ist es mir möglich, includeAllDisks in der Konfiguration zu verwenden:

...
config disk
	option partition includeAllDisks
	option size '90%'
...

Den Daemon startet man über LuCI-Oberfläche neu, indem man zu System > Startup navigiert und beim Paket snmp den Restart-Button drückt.

Auf Grund des oben genannten Problems mit tmpfs-Partitionen erschien die gesuchten Informationen aber nie im SNMP-Baum.

Schlussendlich entschied ich mich für den Quick-und-Dirty-Ansatz. Ich ergänzte die crontab mittels

# crontab -e

mit folgendem Befehl:

...
0 4 * * *   rm -rf /tmp/beaker
...

Der Ordner wird nun pro-aktiv jede Nacht um 4 Uhr morgens zwangsweise gelöscht.

Dennoch hätte ich gerne die Möglichkeit, mittels Cacti den Zuwachs der Partition zu überwachen, um zu sehen, ob die Grösse stetig zunimmt, oder ob es einzelne Episoden mit plötzlichem Grosswachstum gibt.

Nachtrag

Allenfalls könnte man mit folgendem Script etwas basteln:

snmpd-tmpfs.sh

Tags: , , , , ,
Labels: IT, Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 27. November 2016

Die REST-API von SeedDMS ansprechen

Vor einiger Zeit habe ich mir auf meinem Linux-Server hier zu Hause das Dokumentenmanagement-System SeedDMS installiert. Ich habe dieses Produkt ausgewählt, weil es mit PHP programmiert ist (eine Alternative benötigt Java und scheint nach einem Testlauf nicht die erhofte Maturität aufzuweisen.)

Obwohl die Installation dieses Produkts auch nicht ganz simpel ist (dies erläutere ich dereinst in einem separaten Blog-Artikel), weist es die nötige Maturität aus und bringt eine ansehnliche Liste von Features mit. Grösstes Manko ist eine aktuelle, für Endanwender verständliche Dokumentation.

Eine der von mir gesuchten Funktionalitäten ist die REST API, welche man unter der URL /restapi/index.php ansprechen kann.

Als ich damit die ersten API-Calls machen wollte, kam leider eine leere Antwort zurück. Im php.err fand sich folgende Zeile:

...
[27-Nov-2016 11:55:44 Europe/Zurich] PHP Warning:  require(Slim/Slim.php): failed to open stream: No such file or directory in /var/www/seeddms/restapi/index.php on line 55
[27-Nov-2016 11:55:44 Europe/Zurich] PHP Fatal error:  require(): Failed opening required 'Slim/Slim.php' (include_path='/var/www/seeddms/::.:/usr/share/php/') in /var/www/seeddms/restapi/index.php on line 55
...

Hmmm! Da scheinen mit der Quickstart-Version 5.0.7 (die einzige, die ich auf meinem Server zum Laufen gebracht zu habe) nicht alle externen Dependencies mitzukommen.

Ein Issue auf Sourceforge bestätigt meine Vermutung, bringt aber keine Lösung mit (was bringt es dem Endbenutzer, wenn die Dependency im README ergänzt wird?).

Ein, zwei Google-Suchen später finde ich dann einerseits die Web-Site des Frameworks, andererseits das Github-Repository.

Doch wie und wo installiere ich das Paket nun?

Eine weitere Google-Suche leitet mich auf eine Web-Site weiter, welche die Dokumentenstruktur einer älteren SeedDMS-Installation auflistet und dabei auch einen Ordner Slim aufweist. Der Ordner enthält folgende Dateien:

Als ich diese Struktur mit dem Github-Repository verglich, konnte ich keine Ähnlichkeiten feststellen.

Dann der Geistesblitz: Vielleicht verwendet SeedDMS noch eine ältere Version des Frameworks? Richtig geraten: Aktuell trägt das Framework die Version 3.0, SeedDMS baut aber auf Version 2.0 des Frameworks auf.

Ein Blick auf die Dateistruktur des 2.x Branches bestätigt meine Vermutung. Ich lade mir von diesem Branch die ZIP-Datei herunter und kopiere anschliessend den Unterordner Slim im Ordner Slim-2.x in das Web-Root von SeedDMS (/var/www/seeddms/Slim).

Nun klappt der Aufruf der API, weil PHP die Include-Datei unter /var/www/seeddms/Slim/Slim.php findet!

Am Ende der /restapi/index.php findet sich auch eine Liste aller verfügbarer API-Calls:

$app->post('/login', 'doLogin');
$app->get('/logout', 'doLogout');
$app->get('/account', 'getAccount');
$app->get('/search', 'doSearch');
$app->get('/searchbyattr', 'doSearchByAttr');
$app->get('/folder/:id', 'getFolder');
$app->post('/folder/:id/move', 'moveFolder');
$app->delete('/folder/:id', 'deleteFolder');
$app->get('/folder/:id/children', 'getFolderChildren');
$app->get('/folder/:id/parent', 'getFolderParent');
$app->get('/folder/:id/path', 'getFolderPath');
$app->get('/folder/:id/attributes', 'getFolderAttributes');
$app->post('/folder/:id/createfolder', 'createFolder');
$app->put('/folder/:id/document', 'uploadDocument');
$app->get('/document/:id', 'getDocument');
$app->delete('/document/:id', 'deleteDocument');
$app->post('/document/:id/move', 'moveDocument');
$app->get('/document/:id/content', 'getDocumentContent');
$app->get('/document/:id/versions', 'getDocumentVersions');
$app->get('/document/:id/version/:version', 'getDocumentVersion');
$app->get('/document/:id/files', 'getDocumentFiles');
$app->get('/document/:id/file/:fileid', 'getDocumentFile');
$app->get('/document/:id/links', 'getDocumentLinks');
$app->get('/document/:id/attributes', 'getDocumentAttributes');
$app->put('/account/fullname', 'setFullName');
$app->put('/account/email', 'setEmail');
$app->get('/account/locked', 'getLockedDocuments');
$app->post('/accounts', 'createAccount');
$app->get('/accounts/:id', 'getAccountById');
$app->put('/accounts/:id/disable', 'setDisabledAccount');
$app->post('/groups', 'createGroup');
$app->get('/groups/:id', 'getGroup');
$app->put('/groups/:id/addUser', 'addUserToGroup');
$app->put('/groups/:id/removeUser', 'removeUserFromGroup');
$app->put('/folder/:id/setInherit', 'setFolderInheritsAccess');
$app->put('/folder/:id/access/group/add', 'addGroupAccessToFolder'); // 
$app->put('/folder/:id/access/user/add', 'addUserAccessToFolder'); // 
$app->put('/folder/:id/access/group/remove', 'removeGroupAccessFromFolder'); 
$app->put('/folder/:id/access/user/remove', 'removeUserAccessFromFolder'); 
$app->put('/folder/:id/access/clear', 'clearFolderAccessList');
$app->run();

Eine simple API-Abfrage schaut folgendermassen aus:

  1. /restapi/index.php/login mit den POST-Parametern user und pass
  2. Das Session-Cookie mydms_session=XXX; in eine Variable speichern. Es muss bei allen folgenden API-Calls mit übermittelt werden
  3. /restapi/index.php/searchbyattr?name=AttrName&value=AttrValue mit den GET-Parametern name und value
  4. Die Antwort wird als JSON zurückgegeben, welche mit json_decode() in ein PHP-Objekt/Array geparsed werden kann

Tags:
Labels: IT, Linux

Keine Kommentare | neuen Kommentar verfassen

Freitag, 21. Oktober 2016

Wenn eine Linux-Anwendung trotz logrotate in das rotierte Log-File schreibt

Am letzten Wochenende habe ich meine Site-to-Site OpenVPN-Infrastruktur auf Vordermann gebracht (Github-Repo folgt). Da ich aus Debugging-Gründen anfänglich sehr, sehr viel geloggt habe (verb 5 in der lokalen OpenVPN .conf-Datei) sind die Log-Dateien innert eines Tages auf satte 110 MB angewachsen. Mittlerweile — da alles sauber läuft — verwende ich verb 3 und die Log-Files sind nur noch einige Kilobytes gross.

Dennoch habe ich mich entschieden, logrotate so zu konfigurieren, dass die Log-Dateien täglich rotiert werden. Leider musste ich nach der ersten Durchführung aber realisieren, dass OpenVPN munter weiter in /var/log/openvpn/append.log.1 weiterschreibt, obwohl nun /var/log/openvpn/append.log angesagt wäre. Mit meinem Linux-Halbwissen gehe ich davon aus, dass der Filepointer des OpenVPN-Daemons auf dieselbe Datei zeigt, auch wenn sich deren Namen ändert.

Glücklicherweise kennen die Entwickler von logrotate dieses Problem und bieten dafür eine handliche Option namens copytruncate an:

/var/log/openvpn/*.log {
	daily
	missingok
	rotate 366
	compress
	delaycompress
	copytruncate
	create 600 root root
}

Quelle: openvpn logrotate

Tags: , , ,
Labels: Linux

1 Kommentar | neuen Kommentar verfassen

Mittwoch, 31. August 2016

Server mit vergessenen SSH-Schlüsseln ausfindig machen

Vor einigen Tagen habe ich das Schlüsselmanagement für meine SSH-Zugänge völlig umgekrempelt.

Da ich auf Nummer sicher gehen wollte, dass ich den alten Private Key nicht auf bei mir in Vergessenheit geratenen Systemen übersehen hatte, analysierte ich in den Folgetagen die Log-Datei /var/log/auth.log auf meinem zentralen Linux-Server.

Sucht man mittels cat | grep nach „Failed“, erhält man Einträge in der folgenden Form:

...
Aug 25 22:37:09 ALPHA sshd[8539]: Failed publickey for %user% from 85.X.X.X
...

Dies ist aber nur der Beginn der Nachforschung — als nächstes muss man stark hirnen, auf welchem Server das betreffende Script laufen könnte — schliesslich gibt ssh nur eine öffentliche IP-Adresse aus (der verursachende Server steht hinter einem NAT-Router und besitzt eine private IP).

Tags: , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen