MIT-Kurs "Computer Systems Security". Vorlesung 6: „Chancen“, Teil 3

Massachusetts Institute of Technology. Vorlesung # 6.858. "Sicherheit von Computersystemen." Nikolai Zeldovich, James Mickens. 2014 Jahr


Computer Systems Security ist ein Kurs zur Entwicklung und Implementierung sicherer Computersysteme. Die Vorträge behandeln Bedrohungsmodelle, Angriffe, die die Sicherheit gefährden, und Sicherheitstechniken, die auf jüngsten wissenschaftlichen Arbeiten basieren. Zu den Themen gehören Betriebssystemsicherheit, Funktionen, Informationsflussmanagement, Sprachsicherheit, Netzwerkprotokolle, Hardwaresicherheit und Sicherheit von Webanwendungen.

Vorlesung 1: „Einführung: Bedrohungsmodelle“ Teil 1 / Teil 2 / Teil 3
Vorlesung 2: „Kontrolle von Hackerangriffen“ Teil 1 / Teil 2 / Teil 3
Vorlesung 3: „Pufferüberläufe: Exploits und Schutz“ Teil 1 / Teil 2 / Teil 3
Vorlesung 4: „Trennung von Privilegien“ Teil 1 / Teil 2 / Teil 3
Vorlesung 5: „Woher kommen Sicherheitssysteme?“ Teil 1 / Teil 2
Vorlesung 6: „Chancen“ Teil 1 / Teil 2 / Teil 3

Zielgruppe: Wenn diese UID nur Lesezugriff auf diese Datei bietet und Sie auch über einen Dateideskriptor verfügen, können Sie dann die Berechtigung zum Lesen dieser Datei erhalten, wenn Sie die UID verlieren?

Professor: Ja, da es in Katalogen erscheinen wird. Denn sobald Sie die Funktion zur Datei hinzufügen, ist es soweit. Es steht Ihnen mit besonderen Privilegien usw. offen. Das Problem ist jedoch, dass sie dieses hybride Design haben.

Das heißt, sie sagen - Sie können Verzeichnissen wirklich Funktionen hinzufügen und eine neue Datei öffnen, während Sie parallel arbeiten. Möglicherweise fügen Sie die Funktion einem Verzeichnis wie / etc hinzu , haben jedoch keinen obligatorischen Zugriff auf alle Dateien im Verzeichnis / etc. Sobald Sie jedoch in den Funktionsmodus wechseln, können Sie versuchen, diese Dateien zu öffnen, da Sie wissen, dass Sie Zugriff auf das Verzeichnis / etc haben . Immerhin ist es bereits geöffnet. Warum geben Sie mir keine Datei mit dem Namen "Passwort" in diesem Verzeichnis?



Und dann muss der Kernel entscheiden, ob Sie die Datei in diesem Verzeichnis im Lese- oder Schreibmodus öffnen dürfen oder was Sie haben. Ich denke, dies ist der einzige Ort, an dem Sie dieses externe Privileg noch benötigen, da sie versucht haben, ein kompatibles Design zu erstellen, bei dem sie nicht zu natürliche Semantik verwendeten, um den Betrieb von Verzeichnissen zu beschreiben. Dies scheint der einzige Ort zu sein, an dem die Prinzipien zum Einrichten eines Unix- Dateisystems erhalten bleiben.

Teilnehmerin: Gibt es noch andere solche Orte?

Professor: gute Frage. Ich denke, ich muss ihren vorherigen Quellcode abrufen, um herauszufinden, was passiert, aber die meisten anderen Situationen erfordern keine UID- Überprüfung. Weil es zum Beispiel nicht für Netzwerke verwendet wird. Dies sind wahrscheinlich die üblichen Dateisystemvorgänge. Wenn Sie ein gemeinsam genutztes Speichersegment haben, öffnen Sie es einfach und fertig.

Zielgruppe: Können Sie bitte noch einmal erklären, wie genau die Benutzer-ID lautet, wenn Sie über die Funktion " Fähigkeit" verfügen?

Professor: Dies ist wichtig, wenn Sie die Möglichkeit haben, zu katalogisieren. Die Frage ist, was bietet Ihnen diese Gelegenheit? Betrachten Sie eine Interpretation, zum Beispiel den Status der Fähigkeiten eines sauberen Systems, nicht Capsicum . Wenn Sie in einem solchen System die Möglichkeit haben, ein Verzeichnis zu erstellen, haben Sie bedingungslosen Zugriff auf alle Dateien in diesem Verzeichnis.

Unter Unix ist dies normalerweise nicht der Fall. Sie können das Verzeichnis als / etc öffnen, es enthält jedoch viele Systemdateien, in denen vertrauliche Informationen gespeichert werden können, z. B. der private Schlüssel des Servers. Die Tatsache, dass Sie dieses Verzeichnis öffnen und durchblättern können, bedeutet nicht, dass Sie keine Dateien in diesem Verzeichnis öffnen können. Wenn Sie also Zugriff auf das Verzeichnis haben, haben Sie Zugriff auf die Dateien.

Wenn Sie in Capsicum das Verzeichnis / etc öffnen und dann in den Funktionsmodus wechseln, geschieht Folgendes. Sie sagen: „Ich weiß nicht, was dieses Verzeichnis ist. Ich füge nur einen Dateideskriptor hinzu. " Es gibt eine Datei namens "Schlüssel". Warum öffnen Sie diese Datei nicht "Schlüssel" ? Nur weil Sie in diesem Moment wahrscheinlich nicht möchten, dass dieser funktionsbasierte Prozess diese Datei öffnet, weil Sie sie nicht benötigen. Auf diese Weise können Sie jedoch Unix- Berechtigungen für die Datei umgehen.

Daher denke ich, dass die Autoren dieses Artikels die Entwicklung eines Systems, das bestehende Sicherheitsmechanismen nicht verletzt, sorgfältig angegangen sind.

Teilnehmerin: Das heißt, Sie sagen, dass Sie in einigen Fällen eine Kombination dieser beiden Sicherheitsfaktoren verwenden können? Das heißt, obwohl der Benutzer die Datei im Verzeichnis ändern kann, hängt es von seiner Benutzer-ID ab, auf welche Dateien er zugreift.

Professor: Ja genau. In der Praxis müssen Sie in Capsicum vor dem Wechseln in den Funktionsmodus erraten, welche Dateien Sie möglicherweise später benötigen. Möglicherweise benötigen Sie gemeinsam genutzte Bibliotheken, Textdateien, Vorlagen, Netzwerkverbindungen usw. Deshalb öffnen Sie dies alles im Voraus. Und es ist nicht immer notwendig zu wissen, welche Datei Sie benötigen. Also haben diese Leute es so gemacht, dass Sie einfach den Dateideskriptor des Verzeichnisses öffnen und die Dateien anzeigen können, die Sie später benötigen. Es kann jedoch sein, dass diese Dateien nicht über dieselben Berechtigungen verfügen wie Sie. Genau aus diesem Grund wird eine Kombination aus zwei Sicherheitsfaktoren verwendet - Überprüfung der Funktionen und der Benutzer- UID . Dies ist also Teil des Kernel-Mechanismus.



Warum brauchen sie eine Bibliothek wie libcapsicum ? Ich denke, es gibt zwei wichtige Dinge, die sie in dieser Bibliothek unterstützen.

Eine davon ist, dass sie eine Funktion namens lch_start implementieren , die Sie anstelle der Funktion cap_enter verwenden sollten. Eine weitere Funktion von libcapsicum ist das Konzept von fd-Listen, mit denen Dateideskriptoren nach Zahlen übergeben werden. Der Zweck dieser FD-Listen ist leicht zu erklären. Dies ist im Grunde eine Verallgemeinerung der Verwaltung und Übergabe von Dateideskriptoren durch Unix zwischen Prozessen. Unter herkömmlichem Unix und Linux , das Sie heute verwenden, werden beim Starten des Prozesses einige Dateideskriptoren an dieses übergeben. Sie öffnen einfach einige Dateideskriptoren mit ganzzahligen Werten aus dieser Tabelle und starten den untergeordneten Prozess, den Sie benötigen. Oder Sie führen eine bestimmte Binärdatei aus, die alle diese offenen Slots in der fd- Tabelle erbt. Es gibt jedoch keinen anderen guten Weg, diese Dinge zu benennen, als Zahlen als Namen zu verwenden.

Stellen Sie sich ein Beispiel vor, in dem Steckplatz 0 für die Eingabe, Steckplatz 1 für die Ausgabe und Steckplatz 2 für das Drucken von Fehlermeldungen verwendet wird. So funktioniert es unter Unix . Und es funktioniert gut, wenn Sie nur diese drei Dateien oder drei Datenströme in den Prozess übertragen.



In Capsicum kommt es jedoch vor, dass Sie viel mehr Dateideskriptoren in Ihrem Pfad „durchgehen“. Wenn Sie also einen Dateideskriptor für einige Dateien übergeben, durchlaufen Sie einen Dateideskriptor für eine Netzwerkverbindung, einen Deskriptor für eine gemeinsam genutzte Bibliothek und so weiter. Das Verwalten all dieser Nummern ist ziemlich mühsam. Daher bietet libcapsicum tatsächlich die Möglichkeit, den Namen dieser früheren Dateideskriptoren zwischen Prozessen unter Verwendung eines hierarchischen Namens zu abstrahieren, der anstelle dieser obskuren Ganzzahlen verwendet wird.
Dies ist eines der einfachen Dinge, die sie in ihrer Bibliothek bereitstellen. Damit ich den Dateideskriptor an den Prozess übergeben und ihm einen Namen geben kann, spielt es keine Rolle, welche Nummer angegeben ist. Diese Methode ist viel einfacher.

Sie haben noch einen weiteren, komplizierteren Sandbox-Startmechanismus. Dies ist lch , die Sandbox-Host- API , die verwendet wird, anstatt nur in den Modus für Funktionsfunktionen zu wechseln. Warum brauchten sie mehr als einen einfachen Einstieg in einen Opportunity-Modus? Was stört Sie normalerweise beim Erstellen einer Sandbox?

Zielgruppe: Wahrscheinlich löscht lch alle geerbten Dinge, um einen "sauberen" Start des Systems zu gewährleisten.

Professor: Ja. Ich denke, dass sie sich Sorgen machen, alles zu berücksichtigen, auf das die Sandbox Zugriff hat. Die Sache ist, wenn Sie nur cap_enter auf der Ebene des Kernelmechanismus aufrufen, wird es funktionieren. Richtig? Es verhindert nur, dass Sie neue Möglichkeiten entdecken.

Das Problem ist jedoch, dass möglicherweise viele Dinge vorhanden sind, auf die der Prozess bereits Zugriff hat.

Daher denke ich, dass das einfachste Beispiel das Vorhandensein offener Dateideskriptoren ist, die Sie vergessen haben, und die einfach von diesem Prozess vererbt werden.



Zum Beispiel betrachteten sie tcpdump . Zuerst haben sie tcpdump geändert, indem sie einfach cap_enter aufgerufen haben, noch bevor sie alle eingehenden Netzwerkverbindungen analysieren wollten . In gewisser Weise funktioniert dies gut, da Sie nicht mehr Capability- Funktionen erhalten können. Beim Betrachten des Deskriptors für geöffnete Dateien wurde ihnen jedoch klar, dass Sie vollen Zugriff auf das Benutzerterminal haben, da Sie einen Deskriptor für offene Dateien dafür haben. Damit können Sie alle vom Benutzer ausgeführten Tastenanschläge und dergleichen abfangen. Das ist also wahrscheinlich kein guter Plan für tcpdump . Weil Sie nicht möchten, dass jemand Ihre Tastaturaktivität abfängt.

Daher haben sie im Fall von tcpdump die Dateideskriptoren manuell geändert und ihnen einige Funktionen hinzugefügt, um die Arten von Vorgängen einzuschränken, die Sie ausführen können. Wenn Sie sich erinnern, enthält die Funktion in Capsicum auch diese zusätzlichen Bits, die die Klasse von Operationen angeben, die für einen bestimmten Dateideskriptor ausgeführt werden können. Daher nehmen sie grundsätzlich an, dass der Dateideskriptor 0 ist. Er zeigt auf das tty-Benutzerterminal. Anfangs war es nur ein direkter Zeiger auf die tty- Struktur im Kernel. Um die Art der Operationen zu begrenzen, die für diesen Deskriptor ausgeführt werden können, haben sie in der Mitte eine Zwischen-Beta-Struktur der Funktionen eingeführt. Daher verweist der Dateideskriptor auf diese Funktionsstruktur und bereits auf die reale Datei, auf die Sie zugreifen möchten. Und diese Fähigkeitsstruktur enthält einige einschränkende Bits oder Berechtigungen für ein Dateideskriptorobjekt, die implementiert werden können.

Daher können Sie mit der Standarddateneingabe in tcpdump nichts damit anfangen. Sie können nur sehen, dass es existiert, und das ist es. Für den Ausgabedateideskriptor bot sich die Möglichkeit, etwas darauf zu schreiben, den Datensatz jedoch nicht zu ändern, dh die vorgenommenen Änderungen können nicht abgebrochen werden.



Was könnten Sie sich sonst noch Sorgen machen, wenn Sie die Sandbox starten? Ich denke über den Status des Dateideskriptors nach. Ist noch etwas wichtig? Ich denke unter Unix sind dies Dateideskriptoren und Speicher.

Eine andere Sache ist, dass diese Leute besorgt sind, dass in Ihrem Adressraum möglicherweise vertrauliche Daten früher zugewiesen werden. Und der Prozess, den Sie in der Sandbox isolieren möchten, kann den gesamten verfügbaren Speicher lesen. Wenn es also ein Kennwort gibt, das Sie zuvor überprüft haben, wenn sich der Benutzer anmeldet und Sie den Speicher noch nicht gelöscht haben, kann dieser Prozess es lesen und etwas „Interessantes“ tun.

Sie haben dieses Problem folgendermaßen gelöst: In lch_start müssen Sie ein "frisches" Programm ausführen. Sie nehmen das Programm und packen alle Argumente, alle Dateideskriptoren, die Sie ihm bereitstellen möchten. Anschließend starten Sie einen neuen Prozess oder starten die Neuinitialisierung des gesamten virtuellen Speicherbereichs. Und dann besteht kein Zweifel daran, dass dieser Prozess keine zusätzlichen Berechtigungen erhält, die sich auf den Satz vertraulicher Daten auswirken. Dies ist genau das, was Sie in Bezug auf Binärnamen , Argumente und Programmfunktionen an die Funktion lch_start übergeben haben.

Zielgruppe: Was passiert, wenn der von Ihnen gestartete Prozess binäre setuid = 0 enthält ?

Professor: Ich denke, diese Leute verwenden im Feature-Modus keine Setuid- Binärdateien, um seltsame Interaktionen zu vermeiden, die auftreten können. Sie implementieren diese Regel: Sie können ein setuid- Programm haben, das seine Berechtigungen von der setuid- Binärdatei erhält, und dann cap_enter oder lch_start aufrufen . Sobald Sie jedoch in den Funktionsmodus wechseln, können Sie keine zusätzlichen Einstellungen wiederherstellen.

Im Prinzip könnte dies funktionieren, aber es wäre sehr seltsam. Wenn Sie sich erinnern, ist die UID im Feature-Modus nur wichtig, wenn Sie Dateien in einem Verzeichnis öffnen. Daher ist unklar, ob dies wirklich ein großartiger Plan für zusätzliche Privilegien ist oder ob es Mängel gibt.

Teilnehmerin: Zuvor haben wir darüber gesprochen, warum die Bibliothek eine strikte Trennung zwischen den beiden Sicherheitsfaktoren nicht wirklich unterstützt. Aber wir müssen lch_start nicht verwenden?

Professor: Das stimmt. Angenommen, Sie haben etwas wie tcpdump oder gzip - dies ist eine andere Sache, mit der sie arbeiten. Sie gehen davon aus, dass die Anwendung wahrscheinlich nicht gefährdet ist, und es gibt einige grundlegende Funktionen der Anwendung, und Sie kümmern sich darum, wie sie sich in der Sandbox verhält. Im Fall von tcpdump werden Pakete aus dem Netzwerk analysiert, im Fall von gzip werden Dateien entpackt. Und bis zu einem gewissen Punkt gehen Sie davon aus, dass der Prozess alles richtig macht und es keine Schwachstellen gibt. Daher vertrauen Sie darauf , dass er lch_start ausführt und glaubt, dass er das Image korrekt erstellt, alle Funktionen korrekt konfiguriert und sich dann auf weitere Systemaufrufe außerhalb des Funktionsmodus beschränkt.

Und dann starten Sie gefährliche Dinge. Aber bis dahin war die Installation korrekt und Sie haben keine Möglichkeit, aus dieser Sandbox herauszukommen. Ich denke, Sie müssen sehen, wie Sie den Funktionsmodus für Sandbox-Anwendungen tatsächlich verwenden können.

Also haben wir ein bisschen über tcpdump gesprochen . Wie isolieren Sie diesen Prozess? Ein weiteres interessantes Beispiel ist das Programm gzip , das Dateien komprimiert und dekomprimiert. Warum machen sie sich also Sorgen um den Sandkasten? Ich denke, sie befürchten, dass der Dekomprimierungscode möglicherweise fehlerhaft ist oder dass Fehler bei der Speicherverwaltung, der Pufferverwaltung während der Dekomprimierung usw. auftreten.



Eine weitere interessante Frage ist, warum die Änderungen für gzip viel komplizierter erscheinen als für tcpdump . Ich denke, das liegt daran, wie die Anwendung intern strukturiert ist, oder? Wenn Sie also eine Anwendung haben, die einfach eine Datei komprimiert oder eine Datei entpackt hat, ist es normal, sie einfach zu starten, ohne sie im Funktionsmodus zu ändern. Sie geben ihm einfach einen neuen Standard zum Entpacken von etwas, und der Standard liefert entpackte Daten am Ausgang, und dies wird gut funktionieren.

Das Problem ist, wie es bei solchen Sandbox-Methoden fast immer der Fall ist, dass die Anwendung tatsächlich eine viel komplexere Prozesslogik aufweist. Beispielsweise kann gzip mehrere Dateien gleichzeitig komprimieren und so weiter. In diesem Fall haben Sie an der Spitze der Anwendung einen führenden Prozess, der über zusätzliche Rechte verfügt, um mehrere Dateien zu öffnen, zu packen usw. Und die Kernlogik muss oft ein weiterer unterstützender Prozess sein. Im Fall von gzip war die Anwendung nicht so strukturiert, dass Komprimierung und Dekomprimierung als separate Prozesse fungierten. Daher mussten sie die Implementierung des gzip- Kernels und einige Strukturen der Anwendung selbst ändern, damit sie nicht nur einfach Daten an die Dekomprimierungsfunktion übertragen, sondern auch über einen RPC- Aufruf gesendet oder tatsächlich in eine Art fast Dateideskriptor geschrieben wurden. Dies sollte verhindern, dass Probleme von Drittanbietern auftreten und praktisch ohne Berechtigungen entpackt werden. Das einzige, was gzip gleichzeitig tun konnte, war, die entpackten oder komprimierten Daten an den Prozess zurückzugeben, der sie aufgerufen hat.

Eine weitere Hausaufgabe ist, wie Sie Capsicum in OKWS tatsächlich verwenden. Was denkst du darüber? Wäre es hilfreich? Würden die OKWS- Leute gerne auf FreeBSD upgraden, weil es so viel einfacher zu bedienen ist? Wie würden Sie Capsicum unter FreeBSD verwenden ?

Teilnehmerin: Man könnte einige strenge Einschränkungen aufheben.

Professor: Ja, wir könnten sie vollständig durch ein Verzeichnis von Dateideskriptoren und -funktionen ersetzen. Sie müssten keine verwirrende Chroot einrichten. Anstatt chroot mit vielen kleinen Dingen zu verwenden, können Sie die Berechtigungen einfach sorgfältig festlegen. Sie können einfach genau die Dateien öffnen, die Sie benötigen. Das scheint also ein großes Plus zu sein.

Als Nächstes haben Sie in OKWS den OK- Startdienst, mit dem alle übergeordneten Prozesse gestartet werden sollen. Sobald sie sterben, kehrt das Signal zu okld zurück , um den "toten" Prozess neu zu starten. Und dieses Ding müsste root ausführen, weil es die Prozesse in der Sandbox isolieren musste. Es gibt jedoch eine Reihe von Dingen in OKWS , die mit Capsicum verbessert werden könnten.

Beispielsweise könnten Sie okld weitaus weniger Berechtigungen gewähren. Zum Port 80 benötigen Sie beispielsweise Root-Rechte. Danach können Sie alles andere sicher in die Sandbox stellen, da keine Root-Rechte mehr benötigt werden. Es ist also ziemlich cool. Vielleicht können Sie dem Prozess sogar das Recht übertragen, auf die Anforderungen einer anderen Person zu antworten, z. B. einen Systemüberwachungsprozess, der nur diesen Prozessdeskriptor oder Prozessdeskriptor für einen untergeordneten Prozess enthält, und wenn ein solcher Prozess abstürzt, wird ein neuer gestartet. Daher halte ich die Möglichkeit, eine Sandbox ohne Root-Rechte zu erstellen, für sehr nützlich.

Zielgruppe: Sie können jedem Prozess einen Dateideskriptor zuweisen, mit dem Sie nur Einträge zum Protokoll hinzufügen können.

Professor: Ja, und das ist ziemlich cool. Wie wir letztes Mal gesagt haben, kann oklogd die Protokolldatei "durcheinander bringen". Und wer weiß, was der Kernel ihm erlaubt, wenn er den Dateideskriptor der Protokolldatei selbst hat. Wir können jedoch die Funktionen des Dateideskriptors genauer bestimmen, indem wir ihm eine Protokolldatei geben und angeben, dass er nur schreiben, aber nichts suchen kann. Daher erhalten wir die Funktion "Nur Anhängen", wenn Sie nur ein "Schreiber" für diese Datei sind. Es ist sehr bequem. Sie können dem Prozess die Berechtigung zum Schreiben in die Datei erteilen, diese jedoch nicht lesen. Dies ist nur mit Unix- Berechtigungen sehr schwierig.

Capsicum ?

: , , , . , , , .

: , . Capsicum , , . .

: , , okld . , .

: , . . , , Capability , . , , , , , .
, OKWS . . , , , . .

, , «». , . , , , , . .
: «» , , ?

: , FreeBSD . , - , . FreeBSD Casper , , Capability . , «».

- , , , - , , Casper .



, «» . . , , , Casper - .

, , - . , Unix FD . , . , , .

, FreeBSD , DNS . DNS -, «». , tcpdump . tcpdump , IP-. , , DNS -.

, , DNS- DNS-, . Casper , DNS-.

, , , Capsicum? ? ? , , . Capsicum , ?

tcpdump GZIP , , . ?



: , , , . , Capability .

: , . Capsicum , , . , , . , , , , Capsicum , .

, «». , TCP — helper , , , , . , , , .

: , .

: , . . , . lth_start , . , , , - .

, , Capsicum . , , , . Unix - , .

, . , . , , . , .

, Chrome . , , , Unix, -, Unix .

, ?

: .

: . . , . , , , , .

Unix , . , . , . . , .

. Linux , setcall , , . , Capsicum , , Capsicum , . Linux setcall , . , , Linux .

, — , , , , . , - , «//», . Capsicum Hier können Sie den Prozess für eine bestimmte Datei und nicht für das gesamte Home-Verzeichnis starten.


Die Vollversion des Kurses finden Sie hier .

Vielen Dank für Ihren Aufenthalt bei uns. Gefällt dir unser Artikel? Möchten Sie weitere interessante Materialien sehen? Unterstützen Sie uns, indem Sie eine Bestellung aufgeben oder sie Ihren Freunden empfehlen. Habr-Benutzer erhalten 30% Rabatt auf ein einzigartiges Analogon von Einstiegsservern, das wir für Sie erfunden haben: Die ganze Wahrheit über VPS (KVM) E5-2650 v4 (6 Kerne) 10 GB DDR4 240 GB SSD 1 Gbit / s $ 20 oder wie teilt man den Server? (Optionen sind mit RAID1 und RAID10, bis zu 24 Kernen und bis zu 40 GB DDR4 verfügbar).

3 Monate kostenlos bei Bezahlung eines neuen Dell R630 für einen Zeitraum von sechs Monaten - 2 x Intel Deca-Core Xeon E5-2630 v4 / 128 GB DDR4 / 4 x 1 TB Festplatte oder 2 x 240 GB SSD / 1 Gbit / s 10 TB - ab 99,33 USD pro Monat , nur bis Ende August, Bestellung kann hier sein .

Dell R730xd 2 mal günstiger? Nur wir haben 2 x Intel Dodeca-Core Xeon E5-2650v4 128 GB DDR4 6 x 480 GB SSD 1 Gbit / s 100 TV von 249 US-Dollar in den Niederlanden und den USA! Lesen Sie mehr über den Aufbau eines Infrastrukturgebäudes. Klasse mit Dell R730xd E5-2650 v4 Servern für 9.000 Euro für einen Cent?

Source: https://habr.com/ru/post/de418221/


All Articles