From 23f0e1561767dd8a396188e317bae5920d171ea8 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Sun, 16 Aug 2015 16:38:25 +0200 Subject: Initial import of my nikola website --- blog/2005/KnastHorst.md | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 blog/2005/KnastHorst.md (limited to 'blog/2005/KnastHorst.md') diff --git a/blog/2005/KnastHorst.md b/blog/2005/KnastHorst.md new file mode 100644 index 0000000..af9e571 --- /dev/null +++ b/blog/2005/KnastHorst.md @@ -0,0 +1,128 @@ + + +Auf meinem gute-Freunde-Shell-Server, auf dem auch diese edle Seite liegt, hatte ich bisher ein +FreeBSD4.(5-11) installiert. In diesem wurden 14 sogenannte Jails gefahren. Das ist der +FreeBSD-Ansatz, chroot soweit zu treiben, damit in virtuellen FreeBSD-Systemen root-Rechte +vergeben zu koennen, ohne damit die Integritaet des Hostsystems zu beeintraechtigen. + +Einige jails werden als shared service von $kumpel und mir betrieben, so ein mail-, ein www- +und ein nameserver, andere in die Hand von Freunden gedrueckt. Da der Server wegen .. sagen +wir, Rechenschwaechen .. des derzeitigen Hosters dort nicht mehr stehen bleiben kann und somit +ein Umzug auf andere Hardware notwendig wird, werde ich die Gelegenheit nutzen, auf ein +FreeBSD5 oder 6 zu wechseln. + +Das bringt mehrere Vorteile mit sich: a) sind nuetzliche Tools zur Jailverwaltung, naemlich jls +und jexec und 'kill -j' hinzugekommen, b) hat es das script `/etc/rc.d/jail` und +macht jails laufen lassen zum Spass und c) sind da viele nette Features im Kernel, wie z.B. KSE, +die das OS snappier[tm] machen sollten. + +Bisher musste ich alle jails muehsam von einem selbstgehackten Scripteset kontrollieren lassen. +Um nicht fuer jedes jail ein komplettes Betriebssystem auf der Platte herumliegen zu haben +(kostet viel Platz), wird die Welt aufgeteilt in ein zentral gewartetes basejail (`/bin +/sbin /usr/bin /usr/include /usr/lib /usr/libexec /usr/sbin /usr/src /usr/share /usr/ports +/usr/src`) und die zweite, vom User anpassbare Haelfte, das "newjail" (kostet wenig Platz, +um die 8MB). Ersteres wird nun readonly in jedes Jail (nach `/usr/jails/*/basejail`) +gemounted. Softlinks lassen dann z.B. `/usr/bin` nach `/basejail/usr/bin` +zeigen. (`man jail` zeigt die Schritte, die man braucht, sich ein basejail zu +basteln, ein lokales cvs-repository hilft). Soweit, so gut. + +Nun gab es dieses kleine Problem: fuer das simple loopback-Mounten eines Verzeichnisses hat +sich FreeBSD mount_nullfs ausgedacht. Doch ein kleiner Blick in die man-page macht einem den +Mut, den man braucht, seinen Mailserver darauf aufzubauen: "THIS FILE SYSTEM TYPE IS NOT +YET FULLY SUPPORTED (READ: IT DOESN'T WORK) AND USING IT MAY, IN FACT, DESTROY DATA ON YOUR SYSTEM. +USE AT YOUR OWN RISK. BEWARE OF DOG. SLIPPERY WHEN WET." Meine ersten Versuche vor ein +paar Jahren ergaben genau dies: crashes und komische Effekte im Filesystem. Spaetere Experimente von +Freunden erbrachten zwar keine Crashes mehr, dafuer aber ploetzliche hohe CPU-Load. Aus diesem +Grund werkelt nun zur Zeit auf dem Server noch ein nfs-server, der fuer localhost das basejail +exportiert und lauter mount_nfs, die es wieder mounten. (Dazu muss man erstmal [portmap +patchen](http://lists.freebsd.org/pipermail/freebsd-bugs/2004-November/010320.html)) Mit so einem Setup kann man nicht prahlen gehen :( + +Neulich entdeckte ich jedoch [die +Todoliste fuer die 6.0er Release](http://www.freebsd.org/releases/6.0R/todo.html), in der angedeutet wird, dass "Nullfs (and perhaps +other filesystems) use an absurdly small hash size that causes significant performance +penalties." Der Source (`/usr/src/sys/fs/nullfs/null_subr.c`) verriet mir +auch `#define NNULLNODECACHE 16`. Also, wenn die zu kleinen Hashs deren einziges +Problem sind... Ich habe aus der 16 eine 65536 gemacht, neuen Kernel gebaut und habe nun das +basejail endlich per nullfs gemounted. (Zur Zeit laufen 12 Jails auf einer Testinstallation, die +dann auf den neuen Server uebernommen wird.) + +Die Features des jail-scripts aus der `/etc/rc.d` sind zwar grossartig, aber echt +unglaublich wirklich voll total mies dokumentiert. Die jails, die das System starten soll, +traegt man space-separiert in der `/etc/rc.conf` in `jail_list="JAILNAME1 +JAILNAME2..."` ein. Dann macht man noch `jail_enable="YES"` an und beim Startup +werden alle jails hochgefahren. Die Parameter dafuer traegt man in Variablen wie zum Beispiel +`jail_JAILNAME_ip="10.1.1.200"` ein (nicht vergessen, der Netzwerkkarte auch die +aliase fuer alle IPs zu geben). Punkte sind in den Variablen ungern gesehn, bei mir heisst das +dann immer erdgeist_org, also spaeter auch +`jail_erdgeist_org_option_enable="YES"`. + +Dann ist cool, dass jedes jail eine eigene fstab mitbekommt. Wer +`jail_JAILNAME_mount_enable="YES"` anhat, kann beim jail Starten +`/etc/fstab.JAILNAME` mounten lassen. Bei mir steht da naetuerlich +`"/usr/jails/basejail /usr/jails/JAILNAME/basejail nullfs ro 0 0"`. Fertig ist der +Lack. Wer `jail_JAILNAME_devfs_enable="YES"` (immer gern genommen mit +`jail_JAILNAME_devfs_ruleset="devfsrules_jail"`, wegen der Sicherheit, wissenschon) +anhat, findet auch gleich ein /dev im jail gemounted vor, aehnlich verhaelt es sich mit +`jail_JAILNAME_procfs_enable="YES"` und +`jail_JAILNAME_fdescfs_enable="YES"`. + +Das Verwalten der jails ist nun simpel, eigentlich haette das gleich vom rc.d-script mit +erledigt werden koennen: Man legt sich ein `/etc/jails/` oder so an, in das man die +config-Bloecke fuer jeweils ein jail zusammenfasst, also z.B. +`/etc/jails/erdgeist_org` und schreibt in seine `/etc/rc.conf` +`jail_list=`ls /etc/jails/``, und included danach `. /etc/jails/*`. + +Beim Erzeugen eines neuen jails kopiert man aus dem "newjail" mittels `mkdir +/usr/jails/$JAILNAME && cd /usr/jails/newjail && find * | cpio -p -d -v +/usr/jails/JAILNAME` das Skelett. `/etc/resolv.conf`, +`/etc/rc.conf`, `/etc/passwd` und +`/home/admin/.ssh/authorized_keys` im newail gleich zu bevoelkern macht sich auch +immer gut, sonst vergisst man das. (Auch wichtig fuer den sshd: nicht vergessen, dass man im +Hostsystem alle Services nur auf die IP des Hostsystems binden lassen sollte, sonst kann man das +im Jail nicht mehr.) Danach erzeugt man (beispielsweise aus einer template-config) das File, was +nach `/etc/jails/JAILNAME` soll. Ausserdem legt man die +`/etc/fstab.JAILNAME` an. Done. + +Da wir `/usr/ports` mit dem basejail readonly gemounted haben (dadurch reicht es, +einmal jede Nacht ein `cvsup` auf die ports im Hostsystem zu machen), muessen wir den +jails sagen, dass sie die ports nicht in `/usr/ports/X/Y/work` sondern irgendwo +anders bauen sollen, wo man schreiben darf, die distfiles koennen natuerlich auch nicht nach +`/usr/ports/distfiles`. Das macht man in der `/etc/make.conf`. Bei mir +steht da `WRKDIRPREFIX=/var/ports` und `DISTDIR=/var/ports/distfiles`. Das +schreibt man am besten gleich ins newjail. + +Diese Vorgehensweise steht eigentlich auch dem Hostsystem gut. Man kann naemlich spielen alle +work-directories und distfiles an einem zentralen Punkt loeschen: `rm -rf +/var/ports/*` statt rekursivem `make distclean` oder `rm -rf +*/*/work/` in `/usr/ports`. Eigentlich koennte man die distfiles zwischen den +jails noch in einem unionfs teilen, aber erstens liest sich die Doku zu mount_unionfs NOCH +entmutigender, als die von mount_nullfs und zweitens muesste fuer den Fall, dass korrupte +distfiles rumliegen, immer ein hostsystem-Admin putzen kommen. + +Nun zum wirklich Betrieb der jails: Einzelne jails kann man mit `sudo sh /etc/rc.d/jail +start JAILNAME` anstossen, die `jail_list` wird genommen, wenn man keinen +jail-Namen angibt. Alle laufenden jails, inklusive ihrer jail-id kann man sich mit +`jls` angucken. Nachtraeglich tasks an ein jail haengen geht mit `sudo jexec +jail-id cmd`, wobei man da meist `/bin/csh` nimmt. Mit `sudo jexec jail-id +ps auxw` kann man sich dann die laufenden Programme im jail angucken. Beim Traversieren der +jail-Verzeichnisse (bei mir in /usr/jails) aus dem Hostsystem sollte man DRINGEND auf softlinks +aufpassen. Gerne verpeilt werden `/usr/jails/JAILNAME/home -> /usr/home`, was einem +Aerger mit den Homeverzeichnissen im Hostsystem einbringen kann und natuerlich +`/usr/jails/JAILNAME/usr/bin -> /basejail/usr/bin`. Jail anhalten geht mit `sudo +sh /etc/rc.d/jail stop JAILNAME`. + +Zu guter letzt noch ein paar Fallstricke: im jail geht ping nicht. Das liegt daran, dass man +keine raw sockets aufmachen darf, da man in diese natuerlich jede IP als Source IP eintragen +koennte und damit das Sicherheitskonzept der jails umginge. ping ist aber sehr nuetzlich. Das +script `/usr/local/bin/jailping` bestehend aus `finger $*@HOSTSYSTEM` +gepaart mit einem fingerd, der `read input; (ping ${input%^M} 2>&1)` fuer +Verbindungen aus den jails erlaubt, schafft Abhilfe. Am besten noch `alias +ping='/usr/local/bin/jailping'`. Done. + +Hostname im jail aendern verbieten mit `jail_set_hostname_allow="NO"` in der +`/etc/rc.conf`. Ein Sicherheitsfeature, was gern abgeschaltet wird (auch in meinem +jail-Server, wegen der Datenbanken, die es brauchen), ist sysvipc. +`jail_sysvipc_allow` und postgresql geht. -- cgit v1.2.3