Fork Bombs verstehen und verhindern

Posted on November 29th, 2007

by jesse

Fork Bombs, gerade Linux Anfänger in gewissen IRC Channeln oder Foren (siehe ubuntuforums.org) fallen ihnen gerne zum Opfer, wenn sie eine der wichtigsten Regeln eines Anwenders missachten: niemals einen Befehl ausführen den man nicht versteht! Doch was steckt hinter den fiesen Sprengsätzen?

Eine Fork Bomb ist eine Form der Denial of Service Attacke gegen ein Computersystem, in dem Prozesse weitere laufende Prozesse erstellen können. Ziel dieser DoS Angriffe ist es, ein System handlungsunfähig zu machen indem man es mit verschiedensten Techniken an seine Grenzen bringt. Mit einer Fork Bomb startet man nun einen Prozess, der wiederum Kindprozesse startet die wiederum Kindprozesse ins Leben rufen. Dieser Spass geht solange weiter, bis auf dem System nichts mehr geht. Dem Anwender oder Admin bleibt nach kurzer Zeit nur noch die Möglichkeit, den Stecker zu ziehen.

Fork bomb principle by Dake

Die coolste und weitverbreitetste Fork Bomb ist wohl . ( ) { . | . & } ; . für die Bourne Again Shell. Was passiert im Detail, wenn man sie ausführt? Schön aufgeschlüsselt wird das im Packetfu Blog:

. () { . | . & } ; .
0 1  2 3 4 5 6 7 8 9

0 - Neue Funktion mit Namen definieren
1 - Die Klammern bezeichnen die Funktion, die ohne (optionale) Argumente auskommt
2 - Funktionsblock beginnt
3 - Ruft sich selbst, die gerade erstelle Funktion, rekursiv auf
4 - Öffnet eine Pipe zu einem weiteren Prozess
5 - Ruft sich selbst, die gerade erstelle Funktion, erneut rekursiv auf
6 - Der Fork (in den Hintergrund schieben)
7 - Funktionsblock wird geschlossen
8 - Beenden der Funktionsdeklaration
9 - Ausführen der Funktion

Oder wie von pimpmyshell.de dargestellt bedeutet das in ausgeschriebener Form:

forkbomb() {
forkbomb | forkbomb &
};
forkbomb

 

Klar soweit? Dann kommen wir automatisch zu der Frage, wie man sich gegen Fork Bombs und DoS Attacken im Allgemeinen schützen kann. Die Prophylaxe ist vor Allem dann wichtig, wenn man anderen Benutzern in irgendeiner Form Zugriff auf die eigenen Maschinen gewährt - ob mit root Rechten oder nicht. Besondere Bedeutung kommt da übrigens auch Webservern und den darauf laufenden Skripten zu. Weiss ein Angreifer, dass eine bestimmte Seite oder Webanwendung besonders viele Ressourcen benötigt, kann er durch gebündelte Zugriffe schon mit einem PC erhebliche Beeinträchtigungen erzeugen.

Abhilfe bietet Linux zum Beispiel mit den PAM Limits Modul an, das (meistens) in /etc/security/limits.conf konfiguriert wird. Auch hier erscheint einem auf den ersten Blick alles recht kryptisch. Zu tief in diese Datei eindringen macht mit Sicherheit für 90% der Leser keinen Sinn, daher gehe ich an dieser Stelle nur auf die wichtigsten und effektivsten Werte und Parameter ein.

Horizontal ist die Datei in <Domain>, <Type>, <Item> und <Value> unterteilt.

Domain kann hier Folgendes sein:

  • ein User,
  • eine Gruppe (mit @-Präfix),
  • die Wildcard * für den Standardeintrag,
  • die Wildcard % für das maxlogin Limit.

Type ist

  • 'soft' für das Erzwingen eines weichen Limits, das der User bei Bedarf anheben kann, oder
  • 'hard' für das Erzwingen eines harten, absoluten Limits, das nur der Superuser verändern darf.
  • Gibt man stattdessen ein '-' (Minus) an, gilt es für beide.

Und Item bezeichnet, was wir tatsächlich begrenzen möchten:

  • core: maximale Grösse in KB eines Core Files, welches vom Betriebssystem erstellt wird, wenn zum Beispiel ein Programm abstürzt
  • fsize: maximale Grösse in KB, die eine Datei haben darf
  • nofile: maximale Anzahl gleichzeitig geöffneter Dateien
  • rss: maximal verwendbarer Arbeitsspeicher (KB)
  • nproc: maximale Anzahl von Prozessen
  • maxlogins: maximale Anzahl der Logins für einen User
  • locks: maximale Anzahl von Dateisperren die ein User hält

In der Beispielkonfiguration sind wie erwähnt noch weitere Items vorhanden. Um beispielsweise einer Fork Bomb den Riegel vorzuschieben genügt es aber schon, nproc einen Wert zuzuweisen, also die Anzahl von Prozessen, die ein User ausführen darf, einzuschränken. Wir nehmen dazu an, dass alle Benutzer in der Gruppe users sind und legen folgenden Eintrag in der /etc/security/limits.conf an:

@users soft nproc 75
@users hard nproc 100

Ein User darf also 75 Prozesse laufen lassen. Bei Bedarf kann er sein Soft Limit auf 100 hochsetzen, da ist dann aber definitiv Schluss. Wo man die Grenze genau legt ist von System zu System unterschiedlich. KDE oder Gnome mit den zugehörigen Tools, dazu Firefox, Thunderbird, mpd und ein paar X-Shells, da kann es schonmal eng werden. Ausprobieren heisst die Devise. Anzeigen lassen sich die aktuellen Limits übrigens mit dem Befehl ulimit -a.

Weitere Informationen und Quellen:

yigg this

TV Programm in der Shell anzeigen

Posted on October 21st, 2007

by jesse

Ja, es ist still geworden bei uns. Viel zu tun, ein Auf und Ab. Ihr kennt das ja. Wird aber wieder besser werden.

Auf jeden Fall habe ich hier erstmal einen kleinen Tipp für diejenigen, die beim TV Programm lesen nicht von endlos viel Werbung, Flash und anderen Verbrechen erschlagen werden möchten:

alias tv="lynx -nolist -dump http://text.hoerzu.de/tv-programm/jetz.php"

Ab damit in die Shell RC und ein tv | less gibt Aufschluss. Denkbar wäre auch ein tv | grep -i pro7, nichts ist schneller ;-)

Ich wollte nun eigentlich noch ein Schmankerl hinzufügen und mit sed & Co Bewertung und Plot aus der IMDB zu den jeweiligen Titeln ausgeben lassen, leider verbieten deren Nutzungsbedingungen das jedoch. Lame.

Tunneln mit SSH als VPN-Ersatz

Posted on October 5th, 2007

by jesse

Zugegeben, einen RDP Port (Windows, Remote Desktop) nach aussen geöffnet zu haben ist ziemlich unverantwortlich. Deshalb hat mein Chef ein VPN eingerichtet. Weil Zeit bekanntlich Geld ist muss dafür das VOIP Gateway von AVM herhalten. Die Geschichte ist schön einfach einzurichten und alle Mitarbeiter können glücklich von zu Hause in das Büronetz. Alle ausser mir.

Ich habe zwar noch eine Windows Partition auf dem Notebook rumfliegen, allerdings ist es mir echt zu doof immer neu booten zu müssen nur weil ein ansonsten ziemlich rockender Hersteller auf Linux User pfeift und für sie keinen VPN CLient anbietet. Den Ausweg bietet mir da unser Linux Server, auf dem ein paar Testprojekte liegen. SSH verschlüsselt und ist auch sonst sicherer als alles, was Microsoft jemals in den Händen hatte. Also darf ich einen Port dafür aufmachen.

Diversen Traffic über SSH auf denselben Server tunneln kannte ich schon, aber wie komme ich mit meinem rdesktop von der Linux Box auf den Windows Server? Iptables? Viel einfacher!


(meine ersten Schritte mit GiMP und mal wieder zu viel Kaffee gehabt heute *g*)

Ich rufe SSH auf meiner Kiste mit:

ssh -g -L 3389:windowsserver.im.buero.lan:3389 linuxserver.von.aussen

auf und authentifiziere mich (mit Pubkeys hat man ähnliche Funktionalität wie mit den VPN Zertifikaten für die User).

Jetzt starte ich, immer noch lokal, meinen Remote Desktop Protocol Client und gebe als Zielserver mich selbst an:

rdesktop localhost

Meinem Chef als ein typischer Windows Administrator des Mittelstands wird das gefallen :-)

Übrigens, geholfen das zu verstehen hat mir diese Seite, mitdenken ist dort wegen ein paar Typos trotzdem gefordert.

How to check DMA mode on SATA drives (Tip)

Posted on October 3rd, 2007

This is just a short hint because I had some problems about finding out how to do it when I tried to use hdparm and sdparm for it. I wanted to find it out because I had some problems with it on the laptop and just wanted to check at the workstation to be sure it’s activated and that I am not loosing performance for nothing…

As hdparm is meant for IDE drives only, although it can read some data from Sata drives it lacks support for setting or reading the DMA mode (which is of course quite logical as the DMA mode is set or activated by the bios).

Thinking about it I remembered that if it is set by the bios itself it should give some output in dmesg while sata_nv or your equivalent chipset’s sata module is loaded.

So the solution is quite simple and straight forward. We grep the output of dmesg for DMA

dmesg |grep DMA

This should show something like that:

  DMA             0 ->     4096
  DMA32        4096 ->  1048576
  DMA zone: 56 pages used for memmap
  DMA zone: 1399 pages reserved
  DMA zone: 2544 pages, LIFO batch:0
  DMA32 zone: 7108 pages used for memmap
  DMA32 zone: 512796 pages, LIFO batch:31
forcedeth: using HIGHDMA
NFORCE-CK804: 0000:00:06.0 (rev f2) UDMA133 controller
    ide0: BM-DMA at 0xd000-0xd007, BIOS settings: hda:DMA, hdb:DMA
    ide1: BM-DMA at 0xd008-0xd00f, BIOS settings: hdc:DMA, hdd:DMA
hda: 160836480 sectors (82348 MB) w/1794KiB Cache, CHS=16383/255/63, UDMA(100)
hdc: ATAPI 40X DVD-ROM CD-R/RW drive, 2048kB Cache<4>hdc: drive side 80-wire cable detection failed, limiting max speed to UDMA33
sata_nv 0000:00:07.0: Using ADMA mode
ata1: SATA max UDMA/133 cmd 0xffffc2000031c480 ctl 0xffffc2000031c4a0 bmdma 0×000000000001d400 irq 22
ata2: SATA max UDMA/133 cmd 0xffffc2000031c580 ctl 0xffffc2000031c5a0 bmdma 0×000000000001d408 irq 22
ata1.00: ATAPI: TSSTcorp CDDVDW SH-S203B, SB00, max UDMA/100
ata1.00: configured for UDMA/100
sata_nv 0000:00:08.0: Using ADMA mode
ata3: SATA max UDMA/133 cmd 0xffffc2000031e480 ctl 0xffffc2000031e4a0 bmdma 0×000000000001e800 irq 21
ata4: SATA max UDMA/133 cmd 0xffffc2000031e580 ctl 0xffffc2000031e5a0 bmdma 0×000000000001e808 irq 21
ata3.00: ATA-7: SAMSUNG SP2504C, VT100-41, max UDMA7
ata3.00: configured for UDMA/133
ata4.00: ATA-7: SAMSUNG SP1614C, SW100-27, max UDMA7
ata4.00: configured for UDMA/133

As one can see, the DMA mode is activated by all SATA devices.

Estimate Emerge Time (New Genlop Feature)

Posted on July 21st, 2007

by jesse
Just read about this in the new Gentoo Linux Newsletter:

One can use genlop (0.30.7+) to estimate the time of an upcoming compile job now even if if a package has never been compiled on the system before. Just add the -q option which makes genlop query a database running on gentoo.linuxhowtos.org for compile times. The data is based on users with identical CPUs and it’s quite accurate since it calculates the average time.

Just give it a try with, e.g.: $ emerge -uDNpv world | genlop -p -q

If you didn’t know about genlop, emerge it with $ emerge -av app-portage/genlop

I usually use genlop to get the estimated time left when running a system update.

$ while genlop -c; do sleep 5; done

gives an output like

Currently merging 1 out of 6

* sys-libs/pam-0.99.8.0-r2

current merge time: 24 seconds.
ETA: 1 minute and 24 seconds.

Have fun :)


design: makequick.com | modificashuns and bugfixes by jesse
bottom