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