Frage

Ich arbeite mich durch UNIX Network Programming Volume 1 von Richard Stevens und dem Versuch, ein TCP Echo-Client zu schreiben, die das Telnet-Protokoll verwendet. Ich bin immer noch in den frühen Stadien und versuche, die Lese zu schreiben und Funktionen schreiben.

Ich mag es schreiben, die mich verwenden / O-Multiplexing und die Select-Funktion, weil es muss Multi-Client sein, und ich will nicht, um zu versuchen und C ++ Themen angehen zu lernen, während ich versuche, das lernen Berkeley Sockets-Bibliothek zur gleichen Zeit. Am Ende des Kapitels über die I / O-Multiplexing Stevens hat einen kleinen Abschnitt über die DOS-Attacken, wo er sagt, dass die Methode, die ich plane über die Verwendung zu DoS-Angriffen anfällig ist, die einfach ein einzelnes Byte senden nach dem Verbinden und dann hängen. Er erwähnt 3 mögliche Lösungen danach - nicht-blockierende IO, Gewindeschneiden (out) und ein Timeout auf den I / O-Operationen platzieren.

Meine Frage ist, gibt es andere Möglichkeiten, einen solchen Angriff zu vermeiden? Und wenn nicht, wer von ihnen ist die beste? Ich sah den Abschnitt über auf einen Timeout auf dem Betrieb setzen, aber es sieht nicht wie etwas, was ich tun will. Die Methoden, die er schlägt vor, für die es ziemlich komplex aussehen zu tun, und ich bin nicht sicher, wie sie in arbeiten, was ich schon habe. Ich habe nur im Kapitel über NIO sah, es sieht aus wie es die Art und Weise gerade jetzt zu gehen, aber ich würde gerne sehen, ob es noch andere Möglichkeiten, um diese, bevor ich noch ein paar Stunden durch die Kapitel verbringt Pflug.

Irgendwelche Ideen?

War es hilfreich?

Lösung

  

... gibt es andere Möglichkeiten zur Vermeidung eines solchen Angriffs?

Ja, asynchronen I / O ist eine weitere allgemeine Ansatz.

Wenn das Problem ist, dass eine Blockierung read() Ihre Ausführung auf unbestimmte Zeit aussetzen, Ihre allgemeinen Gegenmaßnahmen sind dann:

  1. Haben mehrere Ausführungs-Threads

    Multi-Threaded, Multiprozess, beide.

  2. Zeitgesteuertes die Sperroperation

    z. B. momentane (non-blocking I / O) oder nicht (SO_RCVTIMEO, alarm() usw.)

  3. asynchron

    z. B. aio_read

  

... Welche von diesen ist die beste?

Für den Neuling, würde ich vorschlagen, nicht blockierende E / A in Kombination mit einem zeitlich begrenzten select() / poll(). Ihre Anwendung kann zu verfolgen, ob eine Verbindung erzeugt hat „genug Daten“ (zum Beispiel eine ganze Zeile) in einer „kurz genug Zeit.“

Dies ist eine leistungsstarke, meist tragbare und verbreitete Technik.

Allerdings ist die bessere Antwort ist, „es kommt.“ Plattform-Unterstützung und, noch wichtiger, Design Auswirkungen dieser Entscheidungen haben sich auf einem von Fall zu Fall beurteilt werden.

Andere Tipps

Essentielle Lesung: The C10K Problem

Mit Gewinden (oder Prozessen) pro Verbindung sorgt für sehr einfachen Code. Die Grenze für die Anzahl der Verbindungen ist wirklich die Grenze für die Anzahl der Threads Ihr System kann bequem Multi-Task.

asynchronen IO Mit allen Steckdosen in einem einzigen Thread setzen nicht so einfach Code ist (schön durch libevent gewickelt und libev2 ) ist aber viel besser skalierbar - seine durch die Anzahl der geöffneten Datei beschränkt Griffe Ihr System ermöglicht und - auf den letzten linux baut zum Beispiel - das in Millionen gemessen werden kann! Die meisten Web-Servern und anderen Servern verwenden asynchrone IO aus diesem Grund.

Allerdings Ihrem Server ist immer noch eine endliche Ressource, die erschöpft werden kann, und es gibt viel schlimmere Angriffe als nur aus ausgelastet, neue Verbindungen zu behandeln.

Firewalls und Schadensbegrenzung z.B. Sicherungen, DMZs usw. sind wesentliche Elemente in einer echten Internet verbundenen Dienstleistungen.

Wenn Sie gerade erst begonnen Socket-Programmierung zu lernen, würden Sie wahrscheinlich besser dran konzentriert sich auf die Grundfunktionalität von Steckdosen und nicht besorgniserregend nur noch so viel über Sicherheitsfragen. Wenn Sie ein paar Client-Server-Anwendungen geschrieben haben und gründlich verstehen, wie sie funktionieren, werden Sie in einer besseren Position sein, um zu verstehen, wie sie brechen .

Die Sicherung eines Internet verbundenen Netzwerkanwendung vor böswilligen Clients ist durchaus nicht trivial, und wahrscheinlich beinhaltet alle erweiterten Techniken, die Sie erwähnt, und dann einige! Zum Beispiel ist es üblich, einen Teil der Verantwortung aus dem Anwendungscode an den Router oder Firewall-Ebene zu bewegen. Sie könnten nur Zugriff auf vertrauenswürdige Hosts zu beschränken, oder übermäßige Verbindungsversuche und Drossel erkennen oder sie blockieren, bevor der Verkehr immer Ihre Anwendung trifft.

  

Meine Frage ist, gibt es andere Möglichkeiten, einen solchen Angriff zu vermeiden?

Für einen Server ich einen Timer auf der Anwendungsebene wollen würde:

  • Eingabedatenpuffer pro Verbindung
  • Dumb Socket-Lesen-Code liest Daten aus der Steckdose in den Eingangspuffer
  • Anwendungsspezifische Code analysiert den Inhalt des Eingangspuffers

Der anwendungsspezifischen Code kann die Verbindung beenden mit Eingangspuffern verbunden, die für ‚zu lange‘ im Leerlauf hat.

Auf diese impliziert asynch I / O oder eine dedizierte I / O-Thread [s].

Was ich vorher getan haben, dabei zu helfen (circa 1997 :) war zu verlangen, dass eine magische Zahl innerhalb einer gewissen Zeit sonst wurde die Verbindung geschlossen gesendet werden.

Wenn Sie eine asynchrone Verbindung dann wird die Steckdose nicht blockiert werden, und Sie würden einen Thread benötigen, die durch die Liste der aktuellen Verbindungen abfragen können, die keinen gültigen Befehl gesendet haben, und wenn nach etwa 20 ms eine Nachricht wasn ‚t empfangen das bedeutet ein gültiger Befehl, dann die Verbindung schließen, und tun, was Bereinigungs Sie tun müssen.

Das ist nicht perfekt, aber für die aktuelle Sorge kann es helfen, es zu lösen, und lassen Sie die Ressourcen nicht, indem sie zu viele Verbindungen verbraucht wird.

So macht es einen Haupt-Thread und ein zweites Gewinde benötigt zur Reinigung, so ist es nicht single-threaded.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top