“Willkommen auf der dunklen Seite der Macht, Alexander …”

Nein, ich meine nicht die antagonistische Fraktion aus einer sehr populären Filmreihe (deren Name nicht genannt werden muss), sondern die Apple-Fraktion bei NETWAYS.

Letzten Monat habe ich nämlich meine Ausbildung zum Fachinformatiker für Anwendungsentwicklung abgeschlossen und wurde in die Development-Abteilung übernommen.

Neuer Status – neues Gehalt, neue Aufgaben … und neues Arbeitsgerät. Ich habe mich bewusst für ein MacBook Pro entschieden, weil auf dieser Plattform sehr vieles viel besser und einfacher funktioniert und ich nicht bei jeder Kleinigkeit erst den Linux-Kernel patchen und neu kompilieren, SELinux abschalten oder die IPTables-Regeln anpassen muss. 😉

Wer weiß wann ich mit dem nächsten Kunden von Angesicht zu Angesicht zu tun haben werde – diesbzgl. will ich keine Risiken eingehen.

Abstriche muss ich keine machen – schließlich bietet MacOS X alles, was das Entwickler-Herz begehrt. Außer vielleicht …

Container

Auf Linux haben sie sich breit gemacht wie ein Türsteher: Docker, LXC, LXD und wie sie alle heißen. Auch BSD macht mit seinen Jails keine Kompromisse in Sachen Virtualisierung und Sicherheit.

Umso mehr wundert es mich, dass das BSD-basierende MacOS X dieses Feature nicht übernommen hat. Aber es wäre kein *nix-System, wenn man das nicht mit ein wenig Geschick nachrüsten könnte …

Dann eben so …

Auf meinem alten Arbeitsgerät habe ich Ubuntu 16.04 verwendet. Diese GNU/Linux-Distribution enthält von Haus aus LXD in den Paketquellen, womit ich in einer leichtgewichtigen und sicher isolierten Umgebung mal schnell was ausprobieren konnte.

Dieses Werkzeug kann ich mit einer Virtuellen Maschine problemlos weiterhin verwenden – nicht nur in der VM selbst, sondern auch vom Mac-Host aus. Genau dafür braucht man das o. g. “wenig Geschick” …

LXD Server einrichten

Man logge sich in die VM ein und erlange Administratorrechte. Dann installiert man LXD und richtet diesen darauf hin ein:

$ sudo -i
(...)
# apt install lxd
(...)
# lxd init
Name of the storage backend to use (dir or zfs) [default=dir]: 
Would you like LXD to be available over the network (yes/no) [default=no]? yes
Address to bind LXD to (not including port) [default=all]: 
Port to bind LXD to [default=8443]: 
Trust password for new clients: 
Again: 
Do you want to configure the LXD bridge (yes/no) [default=yes]?

Fast alle Abfragen des Installations-Assistenten können bedenkenlos mit der Eingabetaste bestätigt werden. Die von mir hervorgehobene Frage allerdings muss mit “yes” beantwortet werden – ansonsten fällt die Nutzung vom Host aus ins Wasser. Außerdem muss ein einigermaßen sicheres Passwort gewählt werden.

Der Frage nach der “LXD bridge” folgt ein weiterer, “pseudo-grafischer” Installations-Assistent. Dessen Fragen kann man ausnahmslos mit der Eingabetaste bestätigen.

Des weiteren wird später die IP der VM benötigt:

# ifconfig
enp0s5    Link encap:Ethernet  HWaddr 00:1c:42:8b:e9:ba  
          inet addr:10.211.55.19  Bcast:10.211.55.255  Mask:255.255.255.0
          inet6 addr: fdb2:2c26:f4e4:0:880a:a527:1a6:1130/64 Scope:Global
          inet6 addr: fdb2:2c26:f4e4:0:fc54:870c:56af:cba0/64 Scope:Global
          inet6 addr: fe80::fbc7:ab4d:d29f:e227/64 Scope:Link
(...)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
(...)

lxdbr0    Link encap:Ethernet  HWaddr 00:00:00:00:00:00  
          inet addr:10.83.127.1  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fdb3:61e3:ffb6:f62f::1/64 Scope:Global
          inet6 addr: fe80::4024:c9ff:fe4a:691b/64 Scope:Link
(...)

LXD Client einrichten

Da die Entwickler von LXD sich bemüht haben, nicht von Linux-spezifischen Funktionalitäten Gebrauch zu machen, funktioniert der LXD Client auch auf MacOS. Den muss man nur noch vom LXD Server in Kenntnis setzen.

Sobald das getan ist, kann auch schon der erste Container in Betrieb genommen werden.

$ brew install lxc
(...)
$ lxc remote add u1604vm 10.211.55.19
Certificate fingerprint: a761f551dffdf47d9145da2aa16b4f6be242d960ce1697994c969e495b0724fd
ok (y/n)? y
Admin password for u1604vm:
Client certificate stored at server:  u1604vm
$ lxc launch ubuntu:16.04 u1604vm:test1
Creating test1
Starting test1ge: rootfs: 100% (37.78MB/s)
$ lxc exec u1604vm:test1 -- bash
root@test1:~# man perlfunc

Fazit

Es muss nicht immer Docker sein.

Gerade wenn das Testsystem sich möglichst so verhalten soll wie eine VM oder eine Physische Maschine ist LXD auf jeden Fall einen Blick Wert – auch auf dem Mac.

Alexander Klimov

Autor: Alexander Klimov

Alexander hat 2017 seine Ausbildung zum Developer bei NETWAYS erfolgreich abgeschlossen. Als leidenschaftlicher Programmierer und begeisterter Anhänger der Idee freier Software, hat er sich dabei innerhalb kürzester Zeit in die Herzen seiner Kollegen im Development geschlichen. Wäre nicht ausgerechnet Gandhi sein Vorbild, würde er von dort aus daran arbeiten, seinen geheimen Plan, erst die Abteilung und dann die Weltherrschaft an sich zu reißen, zu realisieren - tut er aber nicht. Stattdessen beschreitet er mit der Arbeit an Icinga Web 2 bei uns friedliche Wege.

Store passwords like a boss #2

Als Programmierer von Webanwendungen, die Ihre Benutzer selbst verwalten, kommt man um das Thema Sicherheit nicht herum – so auch ich als Mitentwickler von Icinga Web 2.

Aus diesem Anlass habe ich recherchiert, wie Passwörter von Benutzern sinnvoll gespeichert werden können und mein neu gewonnenes Wissen geteilt.

Darüber hinaus habe ich vorgeschlagen, Icinga Web 2 dementsprechend zu erweitern. Eric hat diesen Vorschlag begutachtet und mich auf eine Alternative aufmerksam gemacht, nämlich…

password_hash()

PHP bietet seit Version 5.5 u. a. diese Funktion, um Passwörter zu verschlüsseln. Diese ersetzt meine selbst geschriebene Funktion aus dem Vorgänger-Blogpost vollständig:

$encryptedNewPassword = password_hash($newPassword, PASSWORD_DEFAULT);

Der Rückgabe-Wert kann direkt in einer Datenbank gespeichert werden – so einfach ist das.

Der zweite Parameter der Funktion bestimmt den Verschlüsselungs-Algorithmus. Damit kann man diesen zwar frei wählen, aber ich empfehle, den Standard vorzuziehen, denn dieser ändert sich (laut Doku) mit neueren PHP-Versionen zu Gunsten der Sicherheit. Damit bleiben zumindest die neuen/geänderten Passwörter aktuell was die Sicherheit angeht.

password_verify()

Wie der Name schon andeutet, überprüft diese Funktion ein vom Benutzer eingegebenes Passwort auf Übereinstimmung mit einem verschlüsselten Passwort:

$ok = password_verify($enteredPassword, $encryptedPassword);
if ($ok) {
    ...

password_needs_rehash()

Wie bereits erläutert: mit einem neuen Standard-Verschlüsselungs-Algorithmus werden automatisch alle neu verschlüsselten Passwörter sicherer. Aber was ist mit den bereits bestehenden?

Da bestehende Passwörter (aus gutem Grund!) nur verschlüsselt vorliegen, können sie nicht alle “in einem Abwasch” migriert werden. Die einzige Gelegenheit ist die Anmeldung eines Benutzers, die das Klartext-Passwort erfordert. Und als wäre die Funktion für diese Gelegenheit geschrieben…

if ($ok) {
    $outdated = password_needs_rehash($encryptedPassword, PASSWORD_DEFAULT);
    if ($outdated) {
        $encryptedPassword = password_hash($enteredPassword, PASSWORD_DEFAULT);
    }
    ...

Fazit

Der IT-Branche wird nicht umsonst nachgesagt, dass sie eine “permanente Innovation” vollbringe. Umso wichtiger ist es, aus Gründen der Datensicherheit, mit der dunklen Seite der Macht mitzuhalten.

Denn die sind böse, sehr böse…

Alexander Klimov

Autor: Alexander Klimov

Alexander hat 2017 seine Ausbildung zum Developer bei NETWAYS erfolgreich abgeschlossen. Als leidenschaftlicher Programmierer und begeisterter Anhänger der Idee freier Software, hat er sich dabei innerhalb kürzester Zeit in die Herzen seiner Kollegen im Development geschlichen. Wäre nicht ausgerechnet Gandhi sein Vorbild, würde er von dort aus daran arbeiten, seinen geheimen Plan, erst die Abteilung und dann die Weltherrschaft an sich zu reißen, zu realisieren - tut er aber nicht. Stattdessen beschreitet er mit der Arbeit an Icinga Web 2 bei uns friedliche Wege.

Alt, aber bewährt

Immer wieder geht es in der IT um Vergleiche,  z.B. bei der Web-Entwicklung (NodeJS vs. PHP), der Datenhaltung (MongoDB vs. SQL-Datenbanken) oder auch scheinbaren Kleinigkeiten wie das Einlesen einer Datei in den Arbeitsspeicher.

Letztgenannter Vorgang würde bspw. in der Programmiersprache C unter Linux und anderen POSIX-Systemen wie folgt aussehen (Prüfungen auf Fehler habe ich der Übersichtlichkeit halber weggelassen):

void* read_file(char const *path, size_t *length) {
    int fd;
    struct stat stats;
    void *buf, *pos;
    ssize_t current_read;
    size_t remain;
    
    fd = open(path, O_RDONLY);
    fstat(fd, &stats);
    buf = malloc(stats.st_size);
 
    pos = buf;
    remain = stats.st_size;
    for (;;) {
        current_read = read(fd, pos, remain);        
        if (current_read == 0) {
            break;
        }
 
        *(char**)&pos += current_read;
        remain -= (size_t)current_read;
    }
    
    close(fd);
    *length = stats.st_size;
    return buf;
}

Die Alternative dazu wäre die Verwendung von mmap():

void* read_file_via_mmap(char const *path, size_t *length) {
    int fd;
    struct stat stats;
    void *addr, *buf;
    
    fd = open(path, O_RDONLY);
    fstat(fd, &stats);
    addr = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0);
    buf = malloc(stats.st_size);
 
    memcpy(buf, addr, stats.st_size);
 
    munmap(addr, stats.st_size);
    close(fd);
    *length = stats.st_size;
    return buf;
}

Deren Verfechter werben damit, dass die Anzahl der Systemaufrufe pro Datei konstant ist. Dem kann ich nicht widersprechen – die Datei wird mit open() geöffnet und mit mmap() in den Adressbereich integriert. Damit kann auf den Inhalt zugegriffen werden als befände er sich im Arbeitsspeicher. Das ermöglicht das anschließende Kopieren mit Hilfe von memcpy().

Aber das hilft einem nur weiter, wenn das auch tatsächlich messbar Zeit spart – dies ist definitiv nicht der Fall:

aklimov@ws-aklimov:~$ time ./read garbage

real    0m8.108s
user    0m0.000s
sys     0m3.664s
aklimov@ws-aklimov:~$ time ./mmap garbage

real    0m8.099s
user    0m0.652s
sys     0m3.000s
aklimov@ws-aklimov:~$

Das Lesen einer Datei (3 GB) hat im konkreten Fall nicht viel weniger Zeit in Anspruch genommen. Die Verwendung von mmap() hat lediglich ca. 660 Millisekunden von der linken in die rechte Tasche transferiert. Um genau zu sein – die Systemaufrufe der konventionellen Methode (strace):

open("garbage", O_RDONLY)               = 3                                                                                                                                                  
read(3, "\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0"..., 3221225472) = 2147479552                                                      
read(3, "\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0\377\0"..., 1073745920) = 1073745920                                                      
read(3, "", 0)                          = 0
close(3)                                = 0

… vs. mmap():

open("garbage", O_RDONLY)               = 3
mmap(NULL, 3221225472, PROT_READ, MAP_SHARED, 3, 0) = 0x7ff5423c6000
munmap(0x7ff5423c6000, 3221225472)      = 0
close(3)                                = 0

Zwar benötigt die konventionelle Methode im konkreten Fall einen Systemaufruf mehr, aber angesichts der Dateigröße ist das meiner Meinung nach trotzdem vergleichsweise effizient.

Fazit

Nicht alles was glänzt ist auch Gold. Und mit Kaffeesatzlesen ist niemandem geholfen.

Alexander Klimov

Autor: Alexander Klimov

Alexander hat 2017 seine Ausbildung zum Developer bei NETWAYS erfolgreich abgeschlossen. Als leidenschaftlicher Programmierer und begeisterter Anhänger der Idee freier Software, hat er sich dabei innerhalb kürzester Zeit in die Herzen seiner Kollegen im Development geschlichen. Wäre nicht ausgerechnet Gandhi sein Vorbild, würde er von dort aus daran arbeiten, seinen geheimen Plan, erst die Abteilung und dann die Weltherrschaft an sich zu reißen, zu realisieren - tut er aber nicht. Stattdessen beschreitet er mit der Arbeit an Icinga Web 2 bei uns friedliche Wege.

Wird auch mal Zeit, dass einer reagiert…

Dass unsere Gesellschaft es sich gut und gerne möglichst bequem macht hat Bernd schon hinreichend ausgeführt.

Dies gilt allerdings nicht nur im politischen Kontext, sondern auch im IT-Kontext.

Paradebeispiel

M$ Windows gehört aktuell der Löwenanteil des Desktop-PC-Marktes – aber nicht unbedingt der Qualität wegen, sondern u.a. aus folgendem Grund:

Einige (vor allem im gewerblichen Bereich) häufig unumgängliche “Killer-Apps” wie M$ Office oder Adobe Photoshop laufen schlichtweg nur auf Windows (oder Mac OS).

Um von diesem hoch unsicheren, kostenpflichtigen, spionierenden und nicht-quelloffenen Betriebssystem wegzukommen, muss der Benutzer zumindest folgende Hürden überwinden:

  • (darauf kommen, dass überhaupt ein Betriebssystem außer Windows und Mac OS existiert)
  • bspw. GNU/Linux herunterladen und auf CD/DVD/USB-Stick brennen
  • davon booten und das System installieren
  • sich in das System und die Unterschiede zu Windows einarbeiten
  • Alternativen für ihre Killer-Apps suchen (sofern überhaupt vorhanden!)
  • sich in letztgenannte einarbeiten…

In solchen Fällen habe ich volles Verständnis für den Sieg der Faulheit. Henry Ford hat mal gesagt:

Denken ist die schwerste Arbeit, die es gibt. Das ist wahrscheinlich auch der Grund, warum sich so wenige Leute damit beschäftigen.

Aber das geht auch viel einfacher – ohne als böser Raubkopierer vom rechten Weg abzukommen – mit …

ReactOS

ReactOS ist keine GNU/Linux-Distribution, die es sich zur Aufgabe gemacht hat, Windows äußerlich möglichst ähnlich zu sehen.

Es ist ein eigenständiges, von Grund auf geschriebenes Betriebssystem, dessen Ziel es ist, möglichst vollständig zu Windows kompatibel zu sein.

Ich selbst habe ReactOS ausprobiert und teile meine Erfahrungen hier mit euch…

Ran an die Buletten!

Wie üblich habe ich das OS in einer virtuellen Maschine ausprobiert – konkret mit VirtualBox. Nachdem ich das ISO-Abbild heruntergeladen habe erstellte ich eine neue virtuelle Maschine…

Es ist wichtig, dass das Modell der (virtuellen) Netzwerkkarte mit dem von mir gewählten übereinstimmt (3. Bild) – sonst kann es passieren, dass das Netzwerk überhaupt nicht funktioniert.

Sobald der Bootvorgang abgeschlossen war, fand ich einen Windows-XP-ähnlichen Assistenten vor – mit dem Unterschied, dass ich die Sprache frei wählen konnte. (Pfeiltasten oben/unten, dann Eingabetaste)

Sobald das vollbracht ist, muss eigentlich nur noch die Eingabetaste malträtiert werden, bis dieser Assistent durch ist…

Dann gilt es einen Neustart abzuwarten. Beim darauf folgenden Assistenten muss man fast genau so wenig den Kopf anstrengen.

Ich habe zwar Name und Organisation angegeben, hätte aber auch genau so gut immer nur direkt “weiter” drücken können…

Nachdem einem weiteren Neustart kann man auch schon loslegen. Fehlermeldungen wie diese habe ich für meinen Teil bedenkenlos weggeklickt:

Aber…

Da war noch was…

Ein gesunder Geist in einem gesunden Körper. Und ein guter Web-Browser auf einem guten Betriebssystem.

Ich habe die Firefox-Versionen 3.6, 28 und 45 aus dem ReactOS-Paketmanager (Ja, Paketmanager! 😀 ) ausprobiert und meine, dass 28 aktuell der beste Kompromiss aus Funktionalität und Stabilität ist…

Fazit

Ist ReactOS nun für den Produktivbetrieb zu empfehlen?

Meiner Meinung nach noch definitiv nicht.

Neben der o.g. mangelhaften Unterstützung von Netzwerkkarten ist das System (… wie sagt man da noch gleich politisch korrekt …) leicht absturzgefährdet.

Konkret habe ich versucht, mir Visual Studio 2015 Community herunterzuladen (erstmal nur herunterzuladen!) …

(-.-“)

Alexander Klimov

Autor: Alexander Klimov

Alexander hat 2017 seine Ausbildung zum Developer bei NETWAYS erfolgreich abgeschlossen. Als leidenschaftlicher Programmierer und begeisterter Anhänger der Idee freier Software, hat er sich dabei innerhalb kürzester Zeit in die Herzen seiner Kollegen im Development geschlichen. Wäre nicht ausgerechnet Gandhi sein Vorbild, würde er von dort aus daran arbeiten, seinen geheimen Plan, erst die Abteilung und dann die Weltherrschaft an sich zu reißen, zu realisieren - tut er aber nicht. Stattdessen beschreitet er mit der Arbeit an Icinga Web 2 bei uns friedliche Wege.

Schwarze Magie für GNU/Linux-Nerds

“Linux ist der beste Virenschutz”, heißt es in “Fachkreisen”. “Installiere Linux und Du wirst fortan ruhiger schlafen können!” Ähm… falsch.

Ja, Linux ist ein guter Anfang was die Herstellung der Sicherheit auf dem eigenen Rechner betrifft. Aber es hilft einem nichts ohne brain.exe. Vor allem wenn man es mit einem Magier zu tun bekommt…

Mögen die Spiele beginnen!

ps -fu nagios

Wer auf das Monitoring-System Zugriff hat, hat viel Macht.

Wo Bernd recht hat, hat er recht – nicht umsonst nimmt z. B. Gunnars Jabber-Notification-Skript Nutzername und Passwort via Umgebungsvariablen entgegen. Check- und Notification-Skripte, die diesem Beispiel nicht folgen, reißen eine Sicherheitslücke auf, die jeder Systemnutzer ganz einfach ausnutzen kann:

aklimov@icinga2:~$ ps -fu nagios
UID        PID  PPID  C STIME TTY          TIME CMD
nagios    8128     1  0 11:10 ?        00:00:00 /usr/lib/x86_64-linux-gnu/icinga2/sbin/icinga2 --no-stack-rlimit daemon -e /var/log/icinga2/error.log
nagios    8148  8128  0 11:10 ?        00:00:00 /usr/lib/x86_64-linux-gnu/icinga2/sbin/icinga2 --no-stack-rlimit daemon -e /var/log/icinga2/error.log
nagios    8433  8148  0 11:17 ?        00:00:00 /usr/lib/nagios/plugins/check_ping -6 -H ::1 -c 200,15% -w 100,5%
nagios    8434  8433  0 11:17 ?        00:00:00 /bin/ping6 -n -U -w 10 -c 5 ::1
nagios    8435  8148  0 11:17 ?        00:00:00 /usr/lib/nagios/plugins/check_ping -4 -H 127.0.0.1 -c 200,15% -w 100,5%
nagios    8436  8148  0 11:17 ?        00:00:00 /usr/lib/nagios/plugins/check_ping -H 127.0.0.1 -c 5000,100% -w 3000,80%
nagios    8437  8435  0 11:17 ?        00:00:00 /bin/ping -n -U -w 10 -c 5 127.0.0.1
nagios    8438  8436  0 11:17 ?        00:00:00 /bin/ping -n -U -w 30 -c 5 127.0.0.1

Schwarze Magie ist hier noch nicht im Spiel. (Aber dieses Beispiel ist auch nur zum Aufwärmen.)

strace -p

Was tut ein Programm so alles wenn ich gerade mal nicht hinschaue? Um diese Frage zu beantworten, wird nicht zwangsläufig der Quellcode benötigt. In vielen Fällen reicht bereits strace:

aklimov@WS-AKlimov:~$ echo $$  # Prozess-ID der Shell
20901
aklimov@WS-AKlimov:~$ strace -p20901
strace: Process 20901 attached
wait4(-1,

Der Ausgabe können wir entnehmen, dass die Shell gerade darauf wartet, dass ein beliebiger Kindprozess (z. B. strace) sich beendet.

Diese Art der Hexenkunst hat sich bereits rumgesprochen und die Kernel-Entwickler haben ihre Wirkung eingedämmt. Daher konnte ich ohne weiteres nur den Elternprozess von strace als Beispiel nehmen.

gdb -p

Ich erinnere mich noch genau an diese eine AWP-Unterrichtsstunde in der Berufsschule:
Es ging darum, dass ein C/C++-Programm auf mehrere Module aufgeteilt werden kann. Mit dem static-Schlüsselwort sei es möglich, “modulglobale” Variablen zu erstellen – d. h. Variablen, die zwar global, aber nur für das eigene Modul sichtbar sind. Ein Argument des Lehrers für solche Variablen war allen Ernstes die Sicherheit. Und die Übung zu diesem Thema bestand darin, in einem Modul ein Passwort vor den anderen Modulen zu verbergen.
Wenn der wüsste…

Zunächst starte ich in einem neuen Terminal cat:
aklimov@WS-AKlimov:~$ cat

Damit haben wir auch schon unseren “Opfer”-Prozess, der im konkreten Fall auf eingehende Daten wartet.

Darauf hin öffne ich ein zweites Terminal (mit den gleichen Benutzerrechten!) und starte gdb:
aklimov@WS-AKlimov:~$ ps -ef |grep cat
aklimov  10217 10149  0 12:25 pts/11   00:00:00 cat
aklimov  11088 10298  0 12:26 pts/12   00:00:00 grep cat
aklimov@WS-AKlimov:~$ gdb -p 10217
GNU gdb (Debian 7.11.1-2+b1) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
(...)
Attaching to process 10217
(...)
(gdb)

Die schwarze Magie daran…

… besteht darin, dass ich nun innerhalb dieses Prozesses schalten und walten kann wie ich will. (Und sämtlichen Speicher aller Module auslesen.)

Beispielsweise kann ich den Standard-Eingabe-Datenstrom (Stdin) des Prozesses on-the-fly durch /dev/null ersetzen (ohne ihn zu verlieren):

Aktion (Beschreibung) Aktion (GDB) Datei-Deskriptoren
/dev/null öffnen (gdb) p open("/dev/null", 0)
$1 = 3
0 /dev/pts/1
3 /dev/null
Stdin sichern (gdb) p dup(0)
$2 = 4
0, 4 /dev/pts/1
3 /dev/null
Datenstrom umleiten (gdb) p dup2(3, 0)
$3 = 0
4 /dev/pts/1
0, 3 /dev/null
Redundanten Deskriptor schließen (gdb) p close(3)
$4 = 0
4 /dev/pts/1
0 /dev/null
Programm-Ausführung fortsetzen (gdb) c
Continuing.
[Inferior 1 (process 10217) exited normally]
(gdb)
N/A

Fazit

Linux nimmt einem keinerlei Sicherheitsfragen vollständig ab. Es gibt einem lediglich die Möglichkeit, sich selbst um diese zu kümmern (und sie nicht der NSA zu überlassen).

Gehet hin und sichert euch!

Alexander Klimov

Autor: Alexander Klimov

Alexander hat 2017 seine Ausbildung zum Developer bei NETWAYS erfolgreich abgeschlossen. Als leidenschaftlicher Programmierer und begeisterter Anhänger der Idee freier Software, hat er sich dabei innerhalb kürzester Zeit in die Herzen seiner Kollegen im Development geschlichen. Wäre nicht ausgerechnet Gandhi sein Vorbild, würde er von dort aus daran arbeiten, seinen geheimen Plan, erst die Abteilung und dann die Weltherrschaft an sich zu reißen, zu realisieren - tut er aber nicht. Stattdessen beschreitet er mit der Arbeit an Icinga Web 2 bei uns friedliche Wege.