Tags

arm arpaname bin_sh blocage blosxom bsd bsdfrance cblog certification chroot cluster dg834 dhcp diffusion dns dnsmasq dom0 domU dovecot fail-over fail2ban firefox fossil freebsd ftp git guruplug install ipv6 jail kernel kimsufi lex libre linutop liste makefile mikrotik ml150 mohawk nanojail netbook netbsd nginx ntp ntp.org openbsd openntpd openrd opensmtpd openwrt orke pkgng poudriere privee proxy pxe python rc.conf rescue reverse rmll routage route rrdcgi sendmail serial sieve sjail sl2009 ssd sshd symon unbound update usb var_empty vimperator world xen yacc zfs

Powered by

blOg
maRkdown
awK
shEll

22/12/2013

[ nanojail jail chroot ]

201312220844 nanojail jail chroot

Nanojail

En se bauguenaudant sur certains canaux irc poilus dédiés aux boules de geisha, il est possible que l'expression 'nanojail' surgisse. "C'est quoi t'est-ce ?" barrit notre Béru national. Je m'en vais ci-dessous satisfaire cette soif inextinguible de savoir.

On peut commencer par là où tout a commencé.

Une jail est communément décrite comme un "chroot aux stéroïdes". C'est donc avant tout un chroot. Un chroot mode larache:

$ cd $HOME/tmp && mkdir monchroot && mkdir monchroot/bin && cp /bin/sh monchroot/bin
$ sudo chroot monchroot /bin/sh
ELF interpreter /libexec/ld-elf.so.1 not found
$ mkdir monchroot/libexec && cp /libexec/ld-elf.so.1 monchroot/libexec/
Shared object "libedit.so.7" not found, required by "sh"
$ ldd /bin/sh
/bin/sh:
        libedit.so.7 => /lib/libedit.so.7 (0x80083c000)
        libncurses.so.8 => /lib/libncurses.so.8 (0x800a64000)
        libc.so.7 => /lib/libc.so.7 (0x800cb2000)
$ mkdir monchroot/lib && cp /lib/libedit.so.7 /lib/libncurses.so.8 /lib/libc.so.7 monchroot/lib
$ sudo chroot monchroot /bin/sh
Cannot read termcap database;
using dumb terminal settings.
# exit
$ sudo truss -o /tmp/truss chroot monchroot /bin/sh
Cannot read termcap database;
using dumb terminal settings.
# exit
$ grep termcap /tmp/truss
open("/root/.termcap.db",O_RDONLY,00)            ERR#2 'No such file or directory'
open("/root/.termcap",O_RDONLY,00)               ERR#2 'No such file or directory'
open("/usr/share/misc/termcap.db",O_RDONLY,00)   ERR#2 'No such file or directory'
open("/usr/share/misc/termcap",O_RDONLY,00)      ERR#2 'No such file or directory'
open("/etc/termcap.small.db",O_RDONLY,00)        ERR#2 'No such file or directory'
open("/etc/termcap.small",O_RDONLY,00)           ERR#2 'No such file or directory'
write(1,"Cannot read termcap database;\n",30)    = 30 (0x1e)
$ mkdir monchroot/etc && cp /etc/termcap.small monchroot/etc
$ sudo chroot monchroot /bin/sh
# echo *
bin etc lib libexec
# exit

Comme on peut le voir, les joies des binaires dynamiques nous obligent à quelques manipulations que d'aucuns n'hésiteraient pas à qualifier de fastidieuses mais c'est parce qu'ils sont chafouins. Un bon chroot n'est pas un chroot mort mais est composé:

En bonne loutr^Wfeign^W^Wbon admin que je suis, un bon vieux script des familles va me simplifier la vie:

$ ./chroot.sh
Usage: ./chroot.sh [-v] [-h] /path/to/chroot [cmd] [arg1 args2 ... argn]
-v    verbose
-h    this message
cmd   command:
                init: initialize chroot
                pkg:  add packge(s) in chroot
                fix:  fix missing shared objects
                man:  search for manpage in chroot

Example:

./chroot.sh /home/dsx/chroots/fossil init 
./chroot.sh /home/dsx/chroots/fossil pkg fossil
./chroot.sh /home/dsx/chroots/fossil fix /usr/local/bin/fossil
./chroot.sh /home/dsx/chroots/fossil /usr/sbin/inetd

./chroot.sh /home/dsx/chroots/http init
./chroot.sh /home/dsx/chroots/http pkg mohawk
./chroot.sh /home/dsx/chroots/http man -k mohawk

Premier essai, sans les mains:

$ mkdir majail && ./chroot.sh majail init && sudo chroot majail /bin/sh
tar: Removing leading '/' from member names
If you need log, don't forget to add '-l /usr/home/dsx/jails/majail/dev' on syslogd_flags and restart (not reload) syslogd

tar: Removing leading '/' from member names
tar: Removing leading '/' from member names
# echo *
bin dev etc lib libexec sbin usr var
# exit

Deuxième essai, avec une seule main:

$ ./chroot.sh majail/ /usr/bin/bsdtar 
tar: Removing leading '/' from member names
$ sudo chroot majail/ /usr/bin/bsdtar --help                                                               
bsdtar: manipulate archive files
First option must be a mode specifier:
  -c Create  -r Add/Replace  -t List  -u Update  -x Extract
Common Options:
  -b #  Use # 512-byte records per I/O block
  -f <filename>  Location of archive (default /dev/sa0)
  -v    Verbose
  -w    Interactive
[ snip le reste ]

Passons aux choses sérieuses: l'installation d'un package. Heureusement pour nous, bapt@ the famous nous a bien maché le travail car son formidable engin^Woutil^W gestionnaire de package est jail/chroot compliant. Les plus curieux s'étant déja fendu d'un "ls -Rl majail", ils auront compris que le script a préparé le terrain.

Un petit mot concernant les packages:

Si localhost est utilisé par défaut, on peut adapter cette configuration en modifiant le fichier majail/usr/local/etc/pkg/repos/local_pkg.conf

$ ./chroot.sh majail pkg mohawk
Updating repository catalogue
digests.txz                                                           100% 1960     1.9KB/s   1.9KB/s   00:00
packagesite.txz                                                       100%   12KB  11.6KB/s  11.6KB/s   00:00
Incremental update completed, 34 packages processed:
0 packages updated, 0 removed and 34 added.
The following 2 packages will be installed:

        Installing libevent2: 2.0.21
        Installing mohawk: 2.0.10

The installation will require 2 MB more space

318 kB to be downloaded
libevent2-2.0.21.txz                                                  100%  283KB 283.4KB/s 283.4KB/s   00:00
mohawk-2.0.10.txz                                                     100%   35KB  35.0KB/s  35.0KB/s   00:00
Checking integrity... done
[1/2] Installing libevent2-2.0.21... done
[2/2] Installing mohawk-2.0.10... done
$ sudo chroot majail/ /usr/local/sbin/mohawk -v
Shared object "libutil.so.9" not found, required by "mohawk"

Toutes les librairies nécessaires au bon fonctionnement de mohawk ne sont pas présentes dans le chroot, on fixe cela:

$ ./chroot.sh majail/ fix majail/usr/local/sbin/mohawk 
tar: Removing leading '/' from member names
$ sudo chroot majail/ /usr/local/sbin/mohawk -v
mohawk/2.0.10

Le plus dur est fait. Reste à configurer mohawk:

$ mkdir majail/chroot/www && echo "BSD rulez" > majail/chroot/www/index.html
$ cat >> majail/usr/local/etc/mohawk.conf
user nobody
chroot /chroot
mime_type { html text/html txt text/plain }
vhost default {
  listen on 10.30.12.1
  rootdir /www
}
^D

Ma configuration réseau est la suivante:

$ ifconfig alc0 | egrep "(^alc0|inet )"
alc0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        inet 172.16.30.12 netmask 0xffffff00 broadcast 172.16.30.255
$ ifconfig lo1 | egrep "(^lo1|inet )"
lo1: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        inet 10.30.12.1 netmask 0xffffff00 

J'ai déjà un mohawk qui écoute sur localhost, j'adapte donc la configuraion réseau. Un petit test avant la "jailification":

$ sudo chroot majail/ /usr/local/sbin/mohawk -c /usr/local/etc/mohawk.conf
$ printf "GET /index.html HTTP/1.0\r\n\r\n" | nc 10.30.12.1 80
HTTP/1.0 200 OK
Last-Modified: Sun, 22 Dec 2013 10:06:14 GMT
Content-Length: 10
Content-Type: text/html

BSD rulez
$ cat majail/var/run/mohawk.pid
12394
$ sudo kill 12394

Mes jails sont sur l'interface lo1 et ont chacune une adresse. Je vais utiliser 10.30.12.80 et je dois modifier majail/usr/local/etc/mohawk.conf en conséquence:

$ cat majail/usr/local/etc/mohawk.conf
user nobody
chroot /chroot
mime_type { html text/html txt text/plain }
vhost default {
  listent on lo1
  rootdir /www
}
$ cat /etc/jail.conf
majail {
        path = "/home/dsx/tmp/$name";
        host.hostname = "www.example.com";
        ip4.addr = lo1|10.30.12.80;
        exec.start = "/usr/local/sbin/mohawk -c /usr/local/etc/mohawk.conf";
}
$ sudo jail -c majail
majail: created
$ jls -v
   JID  Hostname                      Path
        Name                          State
        CPUSetID
        IP Address(es)
    15  www.example.com               /usr/home/dsx/tmp/majail
        majail                        ACTIVE
        2     
        10.30.12.80    

Roulements de tambours, sonnez trompettes:

$ printf "GET /index.html HTTP/1.0\r\n\r\n" | nc 10.30.12.80 80
HTTP/1.0 200 OK
Last-Modified: Sun, 22 Dec 2013 10:06:14 GMT
Content-Length: 10
Content-Type: text/html

BSD rulez

Et voilà une nanojail prête à l'emploi. Un seul binaire, quelques dépendances, le tout dans moins de 10Mo. C'est ça une nanojail. Le script kivabien est ici.


Lien vers ce billet

28/03/2010

[ cblog chroot nginx reverse proxy ]

201003282136 cblog chroot nginx reverse proxy

cblog et chroot

Pour ceux qui ne connaissent pas, cblog est un moteur de blog écrit en C. J'y contribue un peu et je vais donc décrire comment je l'utilise.

Une fois les dépendances installées (clearsilver, fcgi-devkit et tinycdb), on peut récupérer cblog:

dsx@devel> git clone git://brokk.etoilebsd.net/CBlog.git
dsx@devel> cd CBlog
dsx@devel> make

On peut définir le chemin vers le fichier cblog.cdb:

dsx@devel> make CDB_PATH=/var/db

Pour vérifier ce chemin (utile pour le chroot):

dsx@devel> ./cli/cblogctl path
/var/db/cblog.cdb

Les chroot c'est bien mais il est très facile d'oublier un fichier. Pas de soucis ici:

dsx@devel> sudo ./chroot_cblog.sh

chroot_cblog.tgz contient tout ce qu'il nous faut. On ne peut pas utiliser Freebsd et zfs sans faire de jail. J'utilise pour ce faire deux petits scripts de ma composition:

root@kimsufi# ./mk_template medium
root@kimsufi# ./mk_template large
root@kimsufi# ./mk_jail medium proxy 'lo1|172.16.0.1'
root@kimsufi# ./mk_jail large blog 'lo1|172.16.0.2'

Une jail 'proxy' avec un nginx servira de reverse proxy tandis qu'une jail 'blog' fera tourner cblog dans un chroot.

Je commence par faire mon package 'nginx':

dsx@compil> cd /usr/ports/www/nginx-devel
dsx@compil> sudo make config
  [x] ipv6
  [x] http_module
  [x] http_cache_module
  [x] http_rewrite_module
  [x] http_ssl_module
  [x] www
dsx@compil> sudo make
dsx@compil> sudo make package

Je configure mon reverse proxy:

dsx@proxy> sudo pkg_add /tmp/nginx-devel-0.8.34.tbz
dsx@proxy> sudoedit /usr/local/etc/nginx/nginx.conf
[ snip ]
server {
    listen 80;
    server_name blog.bsdsx.fr;
    access_log off;
    location / {
        proxy_pass http://172.16.0.2/;
        proxy_set_header Host $host;
    }
}

Attention au access_log à off, c'est uniquement pour ne pas logguer plusieurs fois les requêtes. On passera à off une fois le reverse proxy correctement configuré (chemin, adresse ip...). Pour ceux qui se demande pourquoi un reverse proxy la réponse est simple: si je peux multiplier les jails, il n'en est pas de même avec mes ipv4. Tout le traffic http sur ipv4 arrive sur le reverse proxy qui dispatche vers la bonne jail (qui elle est accessible aussi en ipv6). De plus si un jour le besoin de cache se fait sentir, quelques directives proxy_cache_ et fastcgi_cache_ et le tour est joué.

Pour finir le gros morceau: la jail 'blog' avec son chroot.

root@blog# pkg_add -r spawn-fcgi
Fetching ftp://ftp.fr.freebsd.org/pub/FreeBSD/ports/amd64/packages-8.0-release/Latest/spawn-fcgi.tbz... Done.
root@blog# mkdir /usr/local/chroot/bsdsx
root@blog# tar xzvf /tmp/chroot_cblog.tgz -C /usr/local/chroot/bsdsx

Et c'est parti pour la lecture de chroot.txt.


Lien vers ce billet