sábado, 22 de diciembre de 2007

Ext2 y NTFS en OpenSolaris



En este breve artículo vamos a comentar como ser capaz de acceder a los datos de una determinada partición Ext2 o NTFS desde nuestro sistema OpenSolaris.

Lo primero que tenemos que hacer es descargarnos estos dos paquetes: FSWpart y FSWfsmisc de la distribucion Belenix.

Posteriormente los instalamos:

# gunzip -c FSWpart.tar.gz | tar xvf -

# pkgadd -d . FSWpart

# gunzip -c FSWfsmisc.tar.gz | tar xvf -

# pkgadd -d . FSWfsmisc

Y ya podemos montar de manual las particiones de estos dos sistemas de ficheros:

# mount -F ext2fs /dev/dsk/c0d0s4 /mnt

# mount -F ntfs /dev/dsk/c0d0s5 /mnt

O si necesitamos que se monten automatiamente en el arranque del sistema, indicarlo con una entrada para cada una de ellas en la tabla /etc/vfstab.

Como ayuda para identificar las particiones de un disco recnocido, no es necesario utilizar el comando format e ir navegando por sus distintas opciones... es más sencilla esta otra opción:

# /usr/bin/prtpart /dev/rdsk/c0d0 -ldevs

domingo, 16 de diciembre de 2007

Congreso Hispalinux 2007



Como miembro activo de la Comunidad Hispana OpenSolaris, aprovecho este post para anunciar la presentación que realizé el pasado sabado 15/12/2007 en la décima edición del Congreso Hispalinux 2007, el cual tuvo lugar en Caceres (Extremadura).

La presentación ya esta disponible tanto en este blog como la sección de Orange Books del portal de la Comunidad Hispana.

OpenSolaris - Almacenamiento con ZFS

lunes, 10 de diciembre de 2007

filtros TCP_WRAPPER



Una de las nuevas funcionalidades de seguridad que incorpra Solaris 10 / OpenSolaris reside que la mayoria de servicios de red o de acceso al sistema ya estan integrados con TCP_WRAPPER.

En este articulo vamos a ver como permitir/denegar el acceso al puerto TCP 1111, el cual es habilitado por el proceso rpcbind (utilizado para clientes NFS, NIS...). Es decir podemos limitar los hosts que envian peticiones de tipo RPC a nuestro sistema.

Dentro de SMF, entramos en este servicio de red, asi:

# svccfg
svc:> select network/rpc/bind
svc:/network/rpc/bind> listprop
config application
config/allow_indirect boolean true
config/verbose_logging boolean true
config/enable_tcpwrappers boolean true
fs dependency
fs/entities fmri svc:/system/filesystem/minimal
fs/grouping astring require_all
fs/restart_on astring none
fs/type astring service
identity dependency
identity/entities fmri svc:/system/identity:node
identity/grouping astring require_all
identity/restart_on astring refresh
identity/type astring service
sysidtool dependency
sysidtool/entities fmri svc:/system/sysidtool:net
sysidtool/grouping astring require_all
sysidtool/restart_on astring none
sysidtool/type astring service
routing dependency
routing/entities fmri svc:/network/initial:default
routing/grouping astring optional_all
routing/restart_on astring none
routing/type astring service
general framework
general/entity_stability astring Unstable
general/single_instance boolean true
start method
start/exec astring "/lib/svc/method/rpc-bind %m"
start/group astring root
start/limit_privileges astring :default
start/privileges astring basic,file_chown,file_chown_self,file_owner,net_privaddr,proc_setid,sys_nfs
start/project astring :default
start/resource_pool astring :default
start/supp_groups astring :default
start/timeout_seconds count 60
start/type astring method
start/use_profile boolean false
start/user astring root
start/working_directory astring :default
stop method
stop/exec astring "/lib/svc/method/rpc-bind %m %{restarter/contract}"
stop/group astring root
stop/limit_privileges astring :default
stop/privileges astring basic,proc_owner
stop/project astring :default
stop/resource_pool astring :default
stop/supp_groups astring :default
stop/timeout_seconds count 60
stop/type astring method
stop/use_profile boolean false
stop/user astring root
stop/working_directory astring :default
tm_common_name template
tm_common_name/C ustring "RPC bindings"
tm_man_rpcbind template
tm_man_rpcbind/manpath astring /usr/share/man
tm_man_rpcbind/section astring 1M
tm_man_rpcbind/title astring rpcbind

Habilitamos el filtrado:

svc:/network/rpc/bind> setprop config/enable_tcpwrappers=true

Finalizamos la edicion de este servicio y lo reiniciamos:

svc:/network/rpc/bind> end

# svcadm restart rpc/bind

Justo en este momento, ya estamos en condiciones de configurar el acceso. Denegamos todo y unicamente permitimos el acceso a través de la interface de loopback.

# cat /etc/hosts.deny
ALL: ALL

# cat /etc/hosts.allow
rpcbind: 127.0.0.1

Y comprobamos que dicho filtrado es correcto:

# uname -a
SunOS opensolaris 5.10 Generic_120012-14 i86pc i386 i86pc

# telnet opensolaris 1111
Trying 10.73.130.251…
telnet: connect to address 192.168.1.3: Connection refused

Fácil, no?

lunes, 3 de diciembre de 2007

SVM fácil y rápido


En este artículo vamos a ver de forma sencilla y cómoda como actualizar nuestro Solaris 10 / OpenSolaris corriendo el mínimo riesgo posible.

Partimos de una situación inicial en la cual tenemos una configuración básica de Solaris Volume Manager para el filesystem / y el área de swap.

# uname -a
SunOS opensolaris 5.10 Generic_120012-14 i86pc i386 i86pc

# df -h| grep dsk
/dev/md/dsk/d0 5,4G 4,2G 1,2G 79% /

# swap -l
swapfile dev swaplo bloques libre
/dev/md/dsk/d10 85,10 8 1048568 1048568

La configuración del RAID 1 (mirror) en cada uno de los filesystem implicados es esta:

# metastat -p
d10 -m d11 d12 1
d11 1 1 c0d0s1
d12 1 1 c0d1s1
d0 -m d1 d2 1
d1 1 1 c0d0s0
d2 1 1 c0d1s0

Luego en ese momento ejecutamos el script unmirror.sh, asi:

# ./unmirror.sh
bash-3.00# ./unmirror.sh
d10: subduplicación d12 quitada
d0: subduplicación d2 quitada
Press any key to reboot system. After rebooting, check //log/unmirror_cont.log for result.
y

El sistema se reiniciará y arrancará sin ningun tipo de RAID 1, luego unicamente los cambios en la actualización del mismo o su parcheado se registraran en los subdiscos activos en ese momento.

# metastat -p
d10 -m d11 1
d11 1 1 c0d0s1
d0 -m d1 1
d1 1 1 c0d0s0
d12 1 1 c0d1s1
d2 1 1 c0d1s0

Por lo tanto, siempre podremos arrancar nuestro sistema con los subdiscos que no estan activos y que no se ven afectados por este proceso de actualización.

* * * ACTUALIZAMOS * * *

Una vez que el sistema ya actualizado arranca perfectamente, simplemente con el siguiente script (generado por el anterior "unmirror.sh"), volvemos a crear la tolerancia a fallos a nivel del mirror activa en el próximo arranque, asi:

# ./remirror

metainit: opensolaris: d10: unidad ya configurada

metainit: opensolaris: d0: unidad ya configurada

The output of metastat -p is:
d10 -m d11 d12 1
d11 1 1 c0d0s1
d12 1 1 c0d1s1
d0 -m d1 d2 1
d1 1 1 c0d0s0
d2 1 1 c0d1s0
Press any key to reboot system to finish mirroring.

lunes, 26 de noviembre de 2007

FTP Anónimo



Tanto en Solaris 10, como en OpenSolaris hay algunos cambios en cuanto a la generación de un servidor FTP acotado para el acceso permitido de cualquier usuario sin cuenta en nuestro sistema.

Por defecto el demonio que nos permite ejecutar el servidor FTP (WU-FTP) estará activo y controlado por SMF.

# svcs -a | grep ftp
online 15:28:42 svc:/network/ftp:default

Lo primero que vamos a realizar es crear un $HOME para el usuario ftp, asi:

# mkdir -p /export/ftp/{pub,bin,dev,etc,usr/lib}

Una vez realizado, copiamos el binario del comando "ls" y le asignamos los permisos necesarios:

# cp /usr/bin/ls /export/ftp/bin
# chmod 111 /export/ftp/bin/ls

Solo nos queda copiar a ese path las librerias necesarios para le ejecución de dicho binario:

# cp /usr/lib/ld.so* /export/ftp/usr/lib
# cp /usr/lib/libc.so.1 /usr/lib/libdl.so.1 /export/ftp/usr/lib
# cp /usr/lib/libintl.so.1 usr/lib/libw.so.1 /export/ftp/usr/lib
# cp /usr/lib/nss*.so.1 /export/ftp/usr/lib
# cp /usr/lib/libnsl.so.1 /export/ftp/usr/lib
# cp /usr/lib/straddr.so /export/ftp/usr/lib

Y los correspondientes ficheros de configuración:

# cp /etc/passwd /etc/group /etc/netconfig /export/ftp/etc
# cp /etc/nsswitch.conf /export/ftp/etc

Con su asignación correcta de permisos:

# chmod 555 /export/ftp/usr/lib/*
# chmod 444 /export/ftp/etc/*
# chmod 555 /export/ftp/usr/lib
# chmod 555 /export/ftp/usr
# chmod 555 /export/ftp/bin
# chmod 555 /export/ftp/dev
# chmod 555 /export/ftp/etc
# chmod 755 /export/ftp/pub
# chmod 555 /export/ftp

Es en este momento cuando creamos el usuario ftp con acceso anónimo al sistema por este procolo TCP.

# vi /etc/passwd
ftp:x:30000:30000:Anonymous FTP:/export/ftp:/bin/false

# vi /etc/shadow
ftp:NP:6445::::

Y por ultimo securizamos todo el $HOME:

# chown -R root /export/ftp

Hemos conseguido un acceso anónimo real a nuestro servidor FTP, completamente acotado en el PATH que hemos reservado (/export/ftp) y además de forma enjaulada ya que nunca podra subir directorios por el arbol de directorios.

jueves, 15 de noviembre de 2007

III Jornadas COPLA



Como miembro activo de la Comunidad OpenSolaris en Castellano, aprovecho este post para anunciar la presentación que realizé el pasado viernes 23/11/2007 en la tercera edición de las jornadas COPLA de la Universidad de Alicante.

La presentación ya esta disponible tanto en este blog como la sección de Orange Books del portal de la Comunidad Hispana.

OpenSolaris - Un sistema operativo para el futuro

lunes, 5 de noviembre de 2007

Zonas y Contenedores bajo ZFS



Una de las ventajas de crear zonas y/o contenedores bajo el nuevo sistema de ficheros ZFS, reside que nos podemos apoyar en la creación de sanpshot y clones para mover un contenedor de un sistema real (anfitrión) a otro.

La zona global origen tiene como hostname "opensolaris" y el sistema anfitrión destino se denomina "opensolaris2".

Partimos de una zona de tipo BrandZ acotada en cuanto al consumo de memoria y swap:

# hostname
Opensolaris

# zonecfg -z zonelx info
zonename: zonelx
zonepath: /opt/zones/zonelx
brand: lx
autoboot: false
bootargs: -m verbose
pool:
limitpriv:
scheduling-class:
ip-type: shared
net:
address: 10.73.130.249/24
physical: pcn0
capped-memory:
physical: 256M
[swap: 128M]
[locked: 50M]
rctl:
name: zone.max-swap
value: (priv=privileged,limit=134217728,action=deny)
rctl:
name: zone.max-locked-memory
value: (priv=privileged,limit=52428800,action=deny)

y de los siguientes filesystems ZFS:

# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 1,57G 380M 26,5K none
mypool/zonas 1,57G 380M 1,57G /opt/zones/

Lo primero que hacemos es "desenganchar" del sistema anfitrión origen, el contenedor que vamos a mover:

# zoneadm -z zonelx detach

Posteriormente realizamos un snapshot de dicho filesystem sobre el que reside el contenedor denominado zonelx.

# zfs snapshot mypool/zonas@Snap1


# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 1,34G 2,94G 24,5K none
mypool/zonas 1,34G 2,94G 1,34G /opt/zones/
mypool/zonas@Snap1 0 - 1,34G -

Una vez que tenemos la imagen como resultado de la snapshot, realizamos un backup de la misma a un fichero local.

# zfs send mypool/zonas@Snap1 > /opt/zones/zonelx.Backup1 &

Y ese mismo fichero resultado del backup lo llevamos por ssh al anfitrión destino.

# scp /opt/zones/zonelx.Backup1 un38134@10.73.130.247:/export/home/un3813 &


Una vez que estamos en el sistema destino, unicamente creamos el pool ZFS deniminado "mypool" y sobre el realizamos la importación del fichero resultado del backup de la snapshot realizado en el sistema origen.

# hostname

opensolaris2

# df -h

Sistema de archivos tamaño usados aprovechar capacidad Montado en
/dev/dsk/c0d0s0 5,4G 3,8G 1,6G 71% /
/devices 0K 0K 0K 0% /devices
ctfs 0K 0K 0K 0% /system/contract
proc 0K 0K 0K 0% /proc
mnttab 0K 0K 0K 0% /etc/mnttab
swap 811M 856K 810M 1% /etc/svc/volatile
objfs 0K 0K 0K 0% /system/object
/usr/lib/libc/libc_hwcap1.so.1
5,4G 3,8G 1,6G 71% /lib/libc.so.1
fd 0K 0K 0K 0% /dev/fd
swap 810M 40K 810M 1% /tmp
swap 810M 28K 810M 1% /var/run
mypool 1,9G 24K 1,9G 1% /mypool

# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 91K 1,94G 24,5K none

# zfs receive mypool/zonas < /export/home/un38134/zonelx.Backup1

# zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 1,34G 2,94G 24,5K none
mypool/zonas 1,34G 2,94G 1,34G /opt/zones/
mypool/zonas@Snap1 0 - 1,34G -

Una vez importado el sanpshot ZFS podemos crear el contenedor, asi:

# zonecfg -z zonelx

zonecfg:zfszone2> create -a /opt/zonas/zonelx
zonecfg:zfszone2> exit

Una vez creada la zona, la podemos "enganchar" en el anfitrión destino.

# zoneadm -z zonelx attach

# zoneadm list -iv

ID NAME STATUS PATH BRAND IP
0 global running / native shared
- zonelx installed /opt/zones/zonelx lx shared

Una vez creada, la podemos arrancar y acceder a ella.

# zoneadm -z zonelx boot


# zlogin zonelx
[Conectado a la zona 'zonelx' pts/2]

Welcome to your shiny new Linux zone.

- The root password is 'root'. Please change it immediately.

- To enable networking goodness, see /etc/sysconfig/network.example.

- This message is in /etc/motd. Feel free to change it.

For anything more complicated, see:
http://opensolaris.org/os/community/brandz/

You have mail.
# uname -a
Linux zonelx 2.4.21 BrandZ fake linux i686 i686 i386 GNU/Linux


# ifconfig -a

eth0 Link encap:Ethernet HWaddr 00:0C:29:2D:04:A0
inet addr:10.73.130.249 Bcast:10.73.130.255 Mask:255.255.255.0
UP BROADCAST RUNNING SLAVE MTU:1500 Metric:1

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING SLAVE MTU:8232 Metric:1

Luego de una forma sencilla y con muy poco tiempo de perdia de servivio hemos movido un contenedor (con toda su configuración) de un sistema anfitrión inicial a otro destino.

lunes, 22 de octubre de 2007

Screencast ZFS



Aprovecho este articulo para adjuntar un par de enlaces geniales acerca de la gestión de discos que podemos realizar de forma sencilla con el nuevo sistema de ficheros del futuro: ZFS.

1.- Administración Básica ZFS. (con audio en Inglés). En este vídeo se muestra fácilmente la creación de 100 sistemas de ficheros practicamente en 5 minutos.

2.- Administración Avanzada ZFS. En este vídeo se muestra la recuperación silenciosa de sistemas de ficheros ZFS y como se pueden reparar de la corrupción de datos que ocurre en ocasiones en los volúmenes reflejados.

Espero os sirva de ayuda.

miércoles, 17 de octubre de 2007

Contenedores BrandZ



Tras la publicación de la nueva Release 8/07 de Solaris 10 por parte de Sun Microsystems, caben destacar entre sus nuevas funcionalidades, la posibilidad de configurar los Contenedores a través de la propia configuracion de las zonas virtuales, al igual que la asignación dedicada de los interfaces de red reales de la zona global.

La funcionalidad de asignar un interface de la zona global (anfitrión) para una zona virtual, no es compatible actualmente con las de tipo BrandZ, pero si el sistema virtualizado es Solaris 10 se puede configurar facilmente en la seccion general, asi:

# zonecfg -z zonepruebas
zonelx: No se ha configurado esa zona
Use 'create' para comenzar a configurar una zona nueva.
zonecfg:zonepruebas> create
zonecfg:zonepruebas> set zonepath=/opt/zones/zonepruebas
zonecfg:zonepruebas> set ip-type=exclusive
zonecfg:zonepruebas> add net
zonecfg:zonepruebas:net> set physical=pcn0
zonecfg:zonepruebas:net> end
zonecfg:zonepruebas> exit

Posteriormente configurariamos el interface de red pcn0 en el sistema virtualizado como si se tratase del anfitrión, e incluso podemos filtrar su tráfico con IPFilter.

# zlogin -C zonepruebas

# ifconfig pcn0 plumb

# ifconfig pcn0 inet 192.168.1.2 netmask 255.255.255.0 broadcast +

# route add default 10.73.130.1

# cat /etc/ipf/ipf.conf
### Block all inbound and outbound traffic by default
block in log on pcn0 all head 100
block out log on pcn0 all head 150

### Allow inbound SSH connections
pass in quick proto tcp from any to any port = 22 keep state group 100

### Allow my box to utilize all UDP, TCP and ICMP services
pass out quick proto tcp all flags S/SA keep state group 150
pass out quick proto udp all keep state group 150
pass out quick proto icmp all keep state group 150

# svcadm enable ipfilter

# ipf -f /etc/ipf.conf

En el siguiente ejemplo vamos a definir la configuración de una zona virtual (en la que instalaremos una imagen de CentOS 3.0) la cual vamos a acotar en cuanto a sus recursos de CPU y memoria durante su definición, asi:

# zonecfg -z zonelx
zonelx: No se ha configurado esa zona
Use 'create' para comenzar a configurar una zona nueva.
zonecfg:zonelx> create -t SUNWlx
zonecfg:zonelx> set zonepath=/opt/zones/zonelx
zonecfg:zonelx> set autoboot=true
zonecfg:zonelx> add net
zonecfg:zonelx:net> set physical=pcn1
zonecfg:zonelx:net> set address=10.73.130.249/24
zonecfg:zonelx:net> end
zonecfg:zonelx> add dedicated-cpu
zonecfg:zonelx:dedicated-cpu> set ncpus=1-2
zonecfg:zonelx:dedicated-cpu> end
zonecfg:zonelx> add capped-memory
zonecfg:zonelx:capped-memory> set physical=256m
zonecfg:zonelx:capped-memory> set swap=128m
zonecfg:zonelx:capped-memory> set locked=50m
zonecfg:zonelx:capped-memory> end
zonecfg:zonelx> verify
zonecfg:zonelx> commit
zonecfg:zonelx> exit

La configuración de la memoria de tipo contenedor tambien la podemos realizar cuando el contenedor se esta ejecutando, a través del Resource Manager, asi:

# rcapadm -z zonelx -m 256m

Y lo mismo el area de swap:

# prctl -n zone.max-swap -v 128m -t privileged -r -e deny -i zone zonelx

Instalamos la imagen de CentOS 3.0...

# zoneadm -z zonelx install -d /export/home/un38134/centos_fs_image.tar.bz
Installing zone 'zonelx' at root directory '/opt/zones'
from archive '/export/home/un38134/centos_fs_image.tar.bz'

This process may take several minutes.
Setting up the initial lx brand environment.
System configuration modifications complete.

Installation of zone 'zonelx' completed successfully.

Details saved to log file:
"/opt/zones/root/var/log/zonelx.install.747.log"

# zoneadm list -iv
ID NAME STATUS PATH BRAND IP
0 global running / native shared
1 zonelx running /opt/zones/zonelx lx shared
- zonepruebas installed /opt/zones/zonepruebas native shared

# zonecfg -z zonelx info
zonename: zonelx
zonepath: /opt/zones/zonelx
brand: lx
autoboot: false
bootargs: -m verbose
pool:
limitpriv:
scheduling-class:
ip-type: shared
net:
address: 10.73.130.249/24
physical: pcn0
capped-memory:
physical: 256M
[swap: 128M]
[locked: 50M]
rctl:
name: zone.max-swap
value: (priv=privileged,limit=134217728,action=deny)
rctl:
name: zone.max-locked-memory
value: (priv=privileged,limit=52428800,action=deny)

Arrancamos la zona.

# zoneadm -z zonelx boot

Y ya podemos acceder a nuestro contenedor con Linux.

# zlogin zonelx
[Conectado a la zona 'zonelx' pts/2]

Welcome to your shiny new Linux zone.

- The root password is 'root'. Please change it immediately.

- To enable networking goodness, see /etc/sysconfig/network.example.

- This message is in /etc/motd. Feel free to change it.

For anything more complicated, see:
http://opensolaris.org/os/community/brandz/

You have mail.

# uname -a
Linux zonelx 2.4.21 BrandZ fake linux i686 i686 i386 GNU/Linux

# ifconfig -a
eth0 Link encap:Ethernet HWaddr 00:0C:29:2D:04:A0
inet addr:10.73.130.249 Bcast:10.73.130.255 Mask:255.255.255.0
UP BROADCAST RUNNING SLAVE MTU:1500 Metric:1

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING SLAVE MTU:8232 Metric:1
~.

A diferencia con el articulo anterior de este mismo blog, hemos trasformado la zona virtual de tipo BrandZ en un contenedor con unos pocos parametros definidos en su configuración.

martes, 11 de septiembre de 2007

Firewall IPFilter



Desde el punto de vista de la Seguridad, una de las nuevas funcionalidades (a parte de JASS, TCP_WRAPPER, RBAC y SMF) de Solaris 10 y OpenSolaris es la incorporación de IPFilter como herramienta de filtrado (tcp/udp) y NAT con el Soporte de Sun Microsystems.

En versiones anteriores de Solaris (a partir de la 8 y todavia compatible en 9), se incorporó de forma gratuita el producto SunScreen en su version Lite hasta la v3.1.

En este articulo vamos a configurar de forma sencilla la proteccion de nuestro sistema con unas simples reglas y entender su funcionamiento.

Inicializamos los modulos del Kernel.

# ipf -E

Y ya podemos activar el uso de este software, gestionandolo a través de SMF.

# svcadm enable ipfilter

# svcs | grep ipfilter
online 11:17:24 svc:/network/ipfilter:default

# tail -f /var/svc/log/network-ipfilter\:default.log
[ abr 25 18:14:26 Disabled. ]
[ abr 25 18:14:26 Rereading configuration. ]
[ abr 25 18:30:41 Disabled. ]
[ sep 11 11:17:11 Enabled. ]
[ sep 11 11:17:14 Executing start method ("/lib/svc/method/ipfilter start") ]
[ sep 11 11:17:24 Method "start" exited with status 0 ]

Luego ya podemos testear su estado, asi:

# ipfstat -iol
empty list for ipfilter(out)
empty list for ipfilter(in)

Esto es debido a que todavia no esta configurado. Tenemos que crear un fichero /etc/ipf/pfil.ap en el cual indicamos la interfaz sobre la que va a actuar este software, y el fichero /etc/ipf/ipf.conf en el cual implementamos nuestra politica de reglas de filtrado o NAT.

# ifconfig -a
lo0: flags=2001000849 mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
pcn0: flags=201000843 mtu 1500 index 2
inet 10.73.130.251 netmask ffffff00 broadcast 10.73.130.255
ether 0:c:29:ef:ed:da

# vi /etc/ipf/pfil.ap
P Filter pfil autopush setup
#
# See the autopush(1M) manpage for more information.
#
# Format of the entries in this file is:
#
#major minor lastminor modules
#iprb -1 0 pfil
#elxl -1 0 pfil
pcn0 -1 0 pfil
#e1000g -1 0 pfil
#bge -1 0 pfil
#nf -1 0 pfil
#fa -1 0 pfil
#ci -1 0 pfil
#el -1 0 pfil
#ipdptp -1 0 pfil
#lane -1 0 pfil
#dnet -1 0 pfil
#pcelx -1 0 pfil
#spwr -1 0 pfil

# vi /etc/ipf/ipf.conf
#
# ipf.conf
#
# IP Filter rules to be loaded during startup
#
# See ipf(4) manpage for more information on
# IP Filter rules syntax.

# Block any packets which are too short to be real
block in quick all with short
#
# drop and log any IP packets with options set in them.
block in all with ipopts
#
# Allow all traffic on loopback.
pass in quick on lo0 all
pass out quick on lo0 all
#
# Public Network. Block everything not explicity allowed.
#block in log on pcn0 all
block in log on pcn0 from any to any port = 22
block out on pcn0 all
#
# Allow pings out.
pass out quick on pcn0 proto icmp all keep state
#
# for testing, allow pings from ben and jerry
pass in quick on pcn0 proto icmp from 10.73.130.122/32 to 10.73.130.251/32
#
# Allow outbound state related packets.
pass out quick on pcn0 proto tcp/uDp from any to any keep state
#
# allow ssh from 172.16.0.0/16 only.
# pass in log quick on pcn0 from 172.16.0.0/16 to 172.16.1.100/32 port = 22
# Actually, allow ssh only from ben, jerry, MSU
pass in quick on pcn0 proto tcp from 10.73.130.122/32 to 10.73.130.251/32 port = 22

En esta sencilla configuración hemos bloqueado todo el trafico y unicamente permitimos desde la ip 10.73.130.122 acceder por ssh a la ip 10.73.130.251, ademas del trafico icmp.

Volvemos a reiniciar el servicio y listamos las reglas de nuevo.

# svcadm disable ipfilter
# svcadm enable ipfilter
# ipftsat -iol
pass out quick on lo0 all
block out on pcn0 all
pass out quick on pcn0 proto icmp from any to any keep state
pass out quick on pcn0 proto tcp/udp from any to any keep state
block in quick from any to any with short
block in from any to any with ipopts
pass in quick on lo0 all
block in log on pcn0 from any to any port = 22
pass in quick on pcn0 proto icmp from 10.73.130.122/32 to 10.73.130.251/32
pass in quick on pcn0 proto tcp from 10.73.130.122/32 to 10.73.130.251/32 port = ssh

Luego si lanzamos una conexión con un cliente ssh, desde la ip 10.73.130.68 con destino la ip 10.73.130.122, vemos facilmente como es rechazada:

# tail -f /var/adm/ipfilter.log
11/09/2007 19:11:41.430677 pcn0 @0:4 b 10.73.130.68,50315 -> 10.73.130.251,22 PR tcp len 20 44 -S IN

Y además las estadisticas desde que se inicio el servicio.

# ipfstat -hio
0 pass out quick on lo0 all
3 block out on pcn0 all
0 pass out quick on pcn0 proto icmp from any to any keep state
2 pass out quick on pcn0 proto tcp/udp from any to any keep state
0 block in quick from any to any with short
0 block in from any to any with ipopts
0 pass in quick on lo0 all
7 block in log on pcn0 from any to any port = 22
0 pass in quick on pcn0 proto icmp from 10.73.130.122/32 to 10.73.130.251/32
2 pass in quick on pcn0 proto tcp from 10.73.130.122/32 to 10.73.130.251/32 port = ssh

Pero si uno no esta demasiado familiarizado con este tipo de Firewalls a nivel de comandos, siempre podemos recurrir a la ultilización de alguna GUI. Para este particular FwBuilder es una de las mejores soluciones de código abierto compatible 100% con IpFilter y Solaris 10.

lunes, 3 de septiembre de 2007

Discos SAN gobernados por VxVM



En Solaris 10, si disponemos de una SAN de cualquier fabricante de almacenamiento (SUN, Hitachi, EMC, HP, IBM...), podemos acceder a los discos de dos formas:

1.- Utilizando el cliente de la SAN propio de cada fabricante. (Ej: Powerpath de EMC)

2.- Utilizando un cliente universal, como puede ser Veritas Volume Manager.

Antes de nada, tenemos que verificar que tenemos una correcta configuración hardware de las tarjetas de fibra (HBA) mediante las cuales vamos a conectar nuestro sistema a la SAN, a través de los switches de fibra.

En nuestro escenario particular utilizaremos dos tarjetas HBA de tipo Emulex, conectándonos a una cabina Symetrix de EMC y utilizando el módulo DMP del VxVM para la gestión de los discos.

Confirmamos que tenemos instalado el driver del fabricante de dichas HBAs.

# pkginfo | grep -i lpfc
system lpfc Emulex LightPulse FC SCSI/IP Host Bus Adapter driver
# pkginfo -l lpfc
PKGINST: lpfc
NAME: Emulex LightPulse FC SCSI/IP Host Bus Adapter driver
CATEGORY: system
ARCH: sparc
VERSION: Release 6.11c
BASEDIR: /
PSTAMP: sunv24020070207110814
INSTDATE: Mar 05 2007 16:19
STATUS: completely installed
FILES: 30 installed pathnames
16 shared pathnames
15 directories
9 executables
3690 blocks used (approx)

La configuración de las mismas reside fundamentalmente en dos ficheros /kernel/drv/lpfc.conf (identificación de los puertos "world wide name" (WWN) y los target de cada HBA, que presenta la cabina a nuestro sistema) y /kernel/drv/sd.conf (asociación de cada target y lun libre, asignado por el sistema a cada disco descubierto)

Y el paquete con todos los binarios que utilizaremos posteriormente (dependiente del anterior).

# pkginfo | grep HBAnyware
system HBAnyware Emulex HBAnyware FC Host Bus Adapter Remote Manager
# pkginfo -l HBAnyware
PKGINST: HBAnyware
NAME: Emulex HBAnyware FC Host Bus Adapter Remote Manager
CATEGORY: system
ARCH: sun4u
VERSION: 3.1a12
BASEDIR: /
PSTAMP: utilsun0420070103103238
INSTDATE: Mar 05 2007 16:26
STATUS: completely installed
FILES: 505 installed pathnames
10 shared pathnames
17 directories
24 executables
55388 blocks used (approx)

Tras la instalación de estos paquetes y el reinicio de nuestro sistema, podemos comprobar que a nivel software el sistema este correctamente configurado para soportar FCP.

# /usr/sbin/lpfc/lputil
LightPulse Common Utility for Solaris/SPARC. Version 2.0a13 (1/3/2006).
Copyright (c) 2005, Emulex Corporation
Emulex Fibre Channel Host Adapters Detected: 2
Host Adapter 0 (lpfc2) is an LP9K (Ready Mode)
Host Adapter 1 (lpfc3) is an LP9K (Ready Mode)

MAIN MENU
1. List Adapters
2. Adapter Information
3. Firmware Maintenance
4. Reset Adapter
5. Persistent Bindings
0. Exit
Enter choice => 2
ADAPTER INFORMATION MENU
1. PCI Configuration Parameters
2. Adapter Revision Levels
3. Wakeup Parameters
4. IEEE Address
5. Loop Map
6. Status & Counters
7. Link Status
8. Configuration Parameters
0. Return to Main Menu
Enter choice => 4
0. lpfc2
1. lpfc3
Select an adapter => 0
IEEE Address for Adapter 0:
[10000000] [C94951F4] <- WWN de la HBA

# format -e
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c0t0d0
/pci@1f,4000/scsi@3/sd@0,0
1. c0t8d0
/pci@1f,4000/scsi@3/sd@8,0
2. c0t9d0
/pci@1f,4000/scsi@3/sd@9,0
3. c0t10d0
/pci@1f,4000/scsi@3/sd@a,0
4. c0t11d0
/pci@1f,4000/scsi@3/sd@b,0
5. c0t12d0
/pci@1f,4000/scsi@3/sd@c,0
6. c5t0d0
/pci@1f,4000/lpfc@2/sd@0,0
7. c5t0d117
/pci@1f,4000/lpfc@2/sd@0,75
8. c5t0d118
/pci@1f,4000/lpfc@2/sd@0,76
9. c5t0d119
/pci@1f,4000/lpfc@2/sd@0,77
10. c5t0d120
/pci@1f,4000/lpfc@2/sd@0,78
11. c5t0d121
/pci@1f,4000/lpfc@2/sd@0,79
12. c5t0d122
/pci@1f,4000/lpfc@2/sd@0,7a
13. c5t0d123
/pci@1f,4000/lpfc@2/sd@0,7b
14. c5t0d124
/pci@1f,4000/lpfc@2/sd@0,7c
15. c5t1d0
/pci@1f,4000/lpfc@2/sd@1,0
16. c5t1d117
/pci@1f,4000/lpfc@2/sd@1,75
17. c5t1d118
/pci@1f,4000/lpfc@2/sd@1,76
18. c5t1d119
/pci@1f,4000/lpfc@2/sd@1,77
19. c5t1d120
/pci@1f,4000/lpfc@2/sd@1,78
20. c5t1d121
/pci@1f,4000/lpfc@2/sd@1,79
21. c6t0d0
/pci@1f,4000/lpfc@4/sd@0,0
22. c6t0d117
/pci@1f,4000/lpfc@4/sd@0,75
23. c6t0d118
/pci@1f,4000/lpfc@4/sd@0,76
24. c6t0d119
/pci@1f,4000/lpfc@4/sd@0,77
25. c6t0d120
/pci@1f,4000/lpfc@4/sd@0,78
26. c6t0d121
/pci@1f,4000/lpfc@4/sd@0,79
27. c6t0d122
/pci@1f,4000/lpfc@4/sd@0,7a
28. c6t0d123
/pci@1f,4000/lpfc@4/sd@0,7b
29. c6t0d124
/pci@1f,4000/lpfc@4/sd@0,7c
30. c6t1d0
/pci@1f,4000/lpfc@4/sd@1,0
31. c6t1d117
/pci@1f,4000/lpfc@4/sd@1,75
32. c6t1d118
/pci@1f,4000/lpfc@4/sd@1,76
33. c6t1d119
/pci@1f,4000/lpfc@4/sd@1,77
34. c6t1d120
/pci@1f,4000/lpfc@4/sd@1,78
35. c6t1d121
/pci@1f,4000/lpfc@4/sd@1,79

Ya son visibles los discos de la región permitida de la SAN a la que tiene acceso nuestro sistema, luego podemos comenzar a instalar VxVM a traves del CD-ROM:

# mount -F hsfs -o ro /dev/dsk/c0t6d0s2 /opt
# cd /opt/software/
# ls
10_Recommended.zip fcaw
C500A5.TXT file_system
CO150A9.PRG getting_started.pdf
EMCPower.SOLARIS.5.0.0.GA.b141.tar gnu
EMCpower installer
LP6DUTIL.EXE lpfc
LP6DUTIL.doc perl
O150a9.txt readme.txt
authentication_service readme_Sol_2612.txt
cd393a0.awc samplescript.txt
cd393a0.zip storage_foundation
cdc393a0.awc storage_foundation_cluster_file_system
cluster_management_console storage_foundation_for_db2
cluster_server storage_foundation_for_oracle
cluster_server_agents storage_foundation_for_oracle_rac
co150a9.zip storage_foundation_for_sybase
emc volume_manager
fca-pci.pkg volume_replicator
fca-pci2612.tar windows

# ./installer -rsh
Storage Foundation and High Availability Solutions 5.0

Symantec Product Version Installed Licensed
===========================================================================
Veritas File System 5.0 yes
Veritas Volume Manager 5.0 yes
Veritas Volume Replicator 5.0 no
Veritas Storage Foundation 5.0 no
Veritas Storage Foundation for Oracle 5.0 no
Veritas Storage Foundation for DB2 no no
Veritas Storage Foundation for Sybase no no
Veritas Storage Foundation Cluster File System 5.0 no
Veritas Storage Foundation for Oracle RAC 5.0 no

Task Menu:

I) Install/Upgrade a Product C) Configure an Installed Product
L) License a Product P) Perform a Pre-Installation Check
U) Uninstall a Product D) View a Product Description
Q) Quit ?) Help

Enter a Task: [I,C,L,P,U,D,Q,?] Enter a Task: [I,C,L,P,U,D,Q,?] I
...

Una vez instalado y reiniciado de nuevo el sistema, listamos las controladoras:

# vxdmpadm listctlr all
CTLR-NAME ENCLR-TYPE STATE ENCLR-NAME
=====================================================
c0 Disk ENABLED Disk
c6 EMC ENABLED EMC1
c5 EMC ENABLED EMC1
c5 EMC ENABLED EMC0
c6 EMC ENABLED EMC0

Y los discos a los que podemos acceder a traves de ellas:

# vxdmpadm getsubpaths ctlr=c0
NAME STATE[A] PATH-TYPE[M] DMPNODENAME ENCLR-TYPE ENCLR-NAME ATTRS
================================================================================
c0t0d0s2 ENABLED(A) - c0t0d0s2 Disk Disk -
c0t8d0s2 ENABLED(A) - c0t8d0s2 Disk Disk -
c0t9d0 ENABLED(A) - c0t9d0 Disk Disk -
c0t10d0 ENABLED(A) - c0t10d0 Disk Disk -
c0t11d0 ENABLED(A) - c0t11d0 Disk Disk -
c0t12d0 ENABLED(A) - c0t12d0 Disk Disk -

La controladora c0 nos permite acceder a los discos locales, como podemos comprobar:

# cfgadm -al
Ap_Id Type Receptacle Occupant Condition
c0 scsi-bus connected configured unknown
c0::dsk/c0t0d0 disk connected configured unknown
c0::dsk/c0t6d0 CD-ROM connected configured unknown
c0::dsk/c0t8d0 disk connected configured unknown
c0::dsk/c0t9d0 disk connected configured unknown
c0::dsk/c0t10d0 disk connected configured unknown
c0::dsk/c0t11d0 disk connected configured unknown
c0::dsk/c0t12d0 disk connected configured unknown
c1 scsi-bus connected unconfigured unknown
c2 scsi-bus connected unconfigured unknown

# vxdmpadm getsubpaths ctlr=c6
NAME STATE[A] PATH-TYPE[M] DMPNODENAME ENCLR-TYPE ENCLR-NAME ATTRS
================================================================================
c6t0d117s2 ENABLED(A) - c5t0d117s2 EMC EMC1 -
c6t0d118s2 ENABLED(A) - c5t0d118s2 EMC EMC1 -
c6t0d119s2 ENABLED(A) - c5t0d119s2 EMC EMC1 -
c6t0d120s2 ENABLED(A) - c5t0d120s2 EMC EMC1 -
c6t0d121s2 ENABLED(A) - c5t0d121s2 EMC EMC1 -
c6t0d122s2 ENABLED(A) - c5t0d122s2 EMC EMC1 -
c6t0d123s2 ENABLED(A) - c5t0d123s2 EMC EMC1 -
c6t0d124s2 ENABLED(A) - c5t0d124s2 EMC EMC1 -
c6t1d117s2 ENABLED(A) - c6t1d117s2 EMC EMC0 -
c6t1d118s2 ENABLED(A) - c6t1d118s2 EMC EMC0 -
c6t1d119s2 ENABLED(A) - c6t1d119s2 EMC EMC0 -
c6t1d120s2 ENABLED(A) - c6t1d120s2 EMC EMC0 -
c6t1d121s2 ENABLED(A) - c6t1d121s2 EMC EMC0 -

# vxdmpadm getsubpaths ctlr=c5
NAME STATE[A] PATH-TYPE[M] DMPNODENAME ENCLR-TYPE ENCLR-NAME ATTRS
================================================================================
c5t0d117s2 ENABLED(A) - c5t0d117s2 EMC EMC1 -
c5t0d118s2 ENABLED(A) - c5t0d118s2 EMC EMC1 -
c5t0d119s2 ENABLED(A) - c5t0d119s2 EMC EMC1 -
c5t0d120s2 ENABLED(A) - c5t0d120s2 EMC EMC1 -
c5t0d121s2 ENABLED(A) - c5t0d121s2 EMC EMC1 -
c5t0d122s2 ENABLED(A) - c5t0d122s2 EMC EMC1 -
c5t0d123s2 ENABLED(A) - c5t0d123s2 EMC EMC1 -
c5t0d124s2 ENABLED(A) - c5t0d124s2 EMC EMC1 -
c5t1d117s2 ENABLED(A) - c5t1d117s2 EMC EMC0 -
c5t1d118s2 ENABLED(A) - c5t1d118s2 EMC EMC0 -
c5t1d119s2 ENABLED(A) - c5t1d119s2 EMC EMC0 -
c5t1d120s2 ENABLED(A) - c5t1d120s2 EMC EMC0 -
c5t1d121s2 ENABLED(A) - c5t1d121s2 EMC EMC0 -

Pero si listamos todos los discos que ve VxVM, es como si existieran el doble... aunque realmente son los mismos a través de la controladora c5 y c6, ya que lo único que cambia es la bandeja de la cabina por la que ataca cada una de las HBA (EMC1 o EMC2).

# vxdisk list
DEVICE TYPE DISK GROUP STATUS
c0t0d0s2 auto:sliced rootdisk rootdg online
c0t9d0 auto:sliced - - online
c0t10d0 auto:none - - online invalid
c0t11d0 auto:none - - online invalid
c0t12d0 auto:none - - online invalid
c5t0d117s2 auto:none - - online invalid
c5t0d118s2 auto:none - - online invalid
c5t0d119s2 auto:none - - online invalid
c5t0d120s2 auto:none - - online invalid
c5t0d121s2 auto:none - - online invalid
c5t0d122s2 auto:none - - online invalid
c5t0d123s2 auto:none - - online invalid
c5t0d124s2 auto:none - - online invalid
c5t1d117s2 auto:none - - online invalid
c5t1d118s2 auto:none - - online invalid
c5t1d119s2 auto:none - - online invalid
c5t1d120s2 auto:none - - online invalid
c5t1d121s2 auto:none - - online invalid
c6t1d117s2 auto:none - - online invalid
c6t1d118s2 auto:none - - online invalid
c6t1d119s2 auto:none - - online invalid
c6t1d120s2 auto:none - - online invalid
c6t1d121s2 auto:none - - online invalid
c6t0d117s2 auto:none - - online invalid
c6t0d118s2 auto:none - - online invalid
c6t0d119s2 auto:none - - online invalid
c6t0d120s2 auto:none - - online invalid
c6t0d121s2 auto:none - - online invalid
c6t0d122s2 auto:none - - online invalid
c6t0d123s2 auto:none - - online invalid
c6t0d124s2 auto:none - - online invalid

Realizamos un escaneo de los discos desde VxVM:

# vxdctl enable

Inicializamos 3 de los discos, es decir a partir de ese momento VxVM va a gestionar toda su informacion de forma completa.

# vxdisksetup -i c6t1d119
# vxdisksetup -i c6t1d120
# vxdisksetup -i c6t1d121

# vxdisk list | egrep "c6t1d119|c6t1d120s2|c6t1d121s2"
c6t1d119s2 auto:cdsdisk - - online
c6t1d120s2 auto:cdsdisk - - online
c6t1d121s2 auto:cdsdisk - - online

Creamos un grupo de discos denominado app_dg asignandole estos discos.

# vxdg init app_dg c6t1d119s2=c6t1d119
# vxdg -g app_dg adddisk c6t1d120s2=c6t1d120
# vxdg -g app_dg adddisk c6t1d121s2=c6t1d121

Y creamos un volumen test de 3GB de tipo stripe, el cual daremos formato VxFS y montaremos como filesystem /prueba:

# vxassist -g app_dg make test 3072m layout=stripe
# mkfs -F vxfs -o largefiles /dev/vx/rdsk/app_dg/test
# vxprint -g app_dg -th

dg app_dg default default 27000 1176279780.32.teras6

dm c6t1d119s2 c6t1d119s2 auto 65536 47452288 -
dm c6t1d120s2 c6t1d119s2 auto 65536 47452288 -
dm c6t1d121s2 c6t1d119s2 auto 65536 47452288 -

v test - ENABLED ACTIVE 2097152 SELECT - fsgen
pl test-01 test ENABLED ACTIVE 2097152 STRIPE - RW
sd c6t1d119s2-01 test-01 c6t1d119s2 0 2097152 0/0 c6t1d119 ENA
sd c6t1d120s2-01 test-01 c6t1d120s2 0 2097152 1/0 c6t1d120 ENA
sd c6t1d121s2-01 test-01 c6t1d121s2 0 2097152 2/0 c6t1d121 ENA

# mount -F vxfs /dev/vx/dsk/app_dg/test /prueba

Luego a parte de las bondades que nos proporcina una SAN en cuanto a rendimiento, replicacion y backup, hemos conseguido un filesystem VxFS gestionado por VxVM de una región de discos permitida de la SAN. La ventaja de este modelo es simple: si la controladora c6 que sirve una de las dos HBAs deja de funcionar, siempre podremos acceder a los datos por el camino que nos quedaría de la controladora c5 que sirve la otra HBA y además este cambio seria trasparante ya que lo realizaría el módulo DMP.

martes, 7 de agosto de 2007

Adivinar contraseñas con DTRACE


Una de las nuevas funcionalidades de Solaris 10 y Opensolaris reside en la incorporacion de todo un framewok de instrumentacion como DTRACE.

Si nos descargamos el DtraceToolKit, el cual es un conjunto de scripts dtrace, bien documentados y desarrollados directamente por la comunidad, podemos fijarmos en particular en la utilizacion de sshkeysnoop.d como una variante del script dtrace shellsnoop. En su ejecucion nos permite capturar todas las contraseñas (incluso a traves de ssh) que se establezcan desde nuestro sistema con destino otros hosts, asi:

# uname -iX
i86pcSystem = SunOS
Node = opensolaris
Release = 5.11
KernelID = snv_57
Machine = i86pc
BusType =
Serial =
Users =
OEM# = 0
Origin# = 1
NumCPU = 1

Identificado nuestro sistema, lanzamos el sshkeysnoop.d.

# pwd
/opt/DTT/Apps

# ./sshkeysnoop.d
UID PID PPID TYPE TEXT

Y esperamos que desde cualquier sesión de terminal o consola, algun usuario de nuestro sistema intente establecer una sesion ssh con otro host.

# ssh pepe@opensolaris
Contraseña:
Last login: Tue Aug 7 12:12:53 2007 from opensolaris
Sun Microsystems Inc. SunOS 5.11 snv_57 October 2007
$ bash
$ hostname
opensolaris

Esto es lo que observamos en la captura del sshkeysnoop.d.

# ./sshkeysnoop.d
UID PID PPID TYPE TEXT
0 10873 10852 cmd ssh pepe@opensolaris
lib/libc.so.1
0 10873 10852 key 8
0 10873 10852 key L
0 10873 10852 key u
0 10873 10852 key c
0 10873 10852 key a
0 10873 10852 key s
0 10873 10852 key 0
0 10873 10852 key 1
^C

Luego vemos claramente como en el sistema opensolaris, el usuario pepe tiene como contraseña para acceder 8Lucas01.

jueves, 2 de agosto de 2007

Zonas, Contenedores y recursos CPU


Si tenemos dos Zonas definidas en nuestro sistema a parte de la global (zonepruebas y zonepruebas2), podemos gestionar sus consumos de recusros CPU a través del (FSS). Fair Share Scheduler: Este software permite asignar a cada aplicacion los recusos maximos de CPU del total de procesadores del sistema, por si se producen situaciones de competencia.

bash-3.00# zoneadm list -cv
ID NAME STATUS PATH BRAND IP
0 global running / native shared
7 zonepruebas running /zonas/pruebas native shared
9 zonepruebas2 running /zonas/pruebas2 native shared

Vemos como las zonas estan corriendo y podemos comenzar a definir los limites en los pooles que posteriormente asociaremos a cada una de ellas.

bash-3.00# cat > /etc/poolcfg
create pool zone1-pool ( string pool.scheduler = "FSS" )
create pool zone2-pool ( string pool.scheduler = "FSS" )
^C

Recargamos la configuración definida en el fichero /etc/poolcfg.

bash-3.00# pooladm -x; pooladm -s; poolcfg -f /etc/poolcfg ; pooladm -c

bash-3.00# psrset

Y la comprobamos:

bash-3.00# pooladm

system default
string system.comment
int system.version 1
boolean system.bind-default true
string system.poold.objectives wt-load

pool zone2-pool
int pool.sys_id 3
boolean pool.active true
boolean pool.default false
string pool.scheduler FSS
int pool.importance 1
string pool.comment
pset pset_default


pool pool_default
int pool.sys_id 0
boolean pool.active true
boolean pool.default true
int pool.importance 1
string pool.comment
pset pset_default

pool zone1-pool
int pool.sys_id 2
boolean pool.active true
boolean pool.default false
string pool.scheduler FSS
int pool.importance 1
string pool.comment
pset pset_default


pset pset_default
int pset.sys_id -1
boolean pset.default true
uint pset.min 1
uint pset.max 65536
string pset.units population
uint pset.load 9699
uint pset.size 1
string pset.comment

cpu
int cpu.sys_id 0
string cpu.comment
string cpu.status on-line

Si todo ha ido OK, podemos habilitar el FSS en nuestro anfitrion y reiniciarlo.

bash-3.00# dispadmin -d FSS

bash-3.00# hostname
opensolaris

bash-3.00# init 6

Al arrancar el anfitrión (zona global), comprobamos la gestión de recursos en los procesos del sistema mediante el FSS.

bash-3.00# ps -feac
UID PID PPID CLS PRI STIME TTY TIME CMD
root 0 0 SYS 96 14:38:21 ? 0:03 sched
root 1 0 FSS 39 14:38:24 ? 0:00 /sbin/init
root 2 0 SYS 98 14:38:24 ? 0:00 pageout
root 3 0 SYS 60 14:38:24 ? 0:00 fsflush
root 261 1 FSS 54 14:39:27 ? 0:01 /usr/lib/hal/hald --daemon=yes
root 7 1 FSS 59 14:38:28 ? 0:05 /lib/svc/bin/svc.startd
root 9 1 FSS 29 14:38:28 ? 0:11 /lib/svc/bin/svc.configd
root 342 1 FSS 59 14:39:52 ? 0:00 /usr/sbin/syslogd
root 333 305 FSS 57 14:39:51 ? 0:00 /usr/lib/saf/ttymon
root 295 262 FSS 59 14:39:34 ? 0:00 /usr/lib/hal/hald-addon-storage
un38134 468 467 FSS 1 14:43:00 syscon 0:00 -bash
root 472 468 FSS 59 14:43:02 syscon 0:00 -sh
root 163 1 FSS 59 14:39:11 ? 0:00 /usr/sbin/nscd
root 316 7 FSS 46 14:39:51 console 0:00 /usr/lib/saf/ttymon -g -d /dev/console -l console -m ldterm,ttcompat -h -p open
root 100 1 FSS 29 14:39:00 ? 0:00 /usr/lib/sysevent/syseventd
root 255 1 FSS 59 14:39:25 ? 0:01 /usr/lib/fm/fmd/fmd
root 127 1 FSS 54 14:39:05 ? 0:00 /usr/sbin/mdmonitord
root 133 1 FSS 58 14:39:06 ? 0:00 /usr/lib/power/powerd
root 460 1 FSS 3 14:40:55 ? 0:00 /usr/lib/sendmail -bd -q15m -C /etc/mail/local.cf
daemon 134 1 FSS 59 14:39:07 ? 0:00 /usr/lib/crypto/kcfd
smmsp 461 1 FSS 52 14:40:55 ? 0:00 /usr/lib/sendmail -Ac -q15m
root 121 1 FSS 57 14:39:03 ? 0:00 /usr/lib/picl/picld
root 190 1 FSS 53 14:39:14 ? 0:00 /usr/sbin/cron
root 132 1 FSS 29 14:39:06 ? 0:00 devfsadmd
un38134 467 464 FSS 59 14:43:00 ? 0:00 /usr/lib/ssh/sshd
root 262 261 FSS 59 14:39:28 ? 0:00 hald-runner
root 315 1 FSS 59 14:39:51 ? 0:00 /usr/lib/rmvolmgr -s
root 305 7 FSS 58 14:39:50 ? 0:00 /usr/lib/saf/sac -t 300
daemon 242 1 FSS 56 14:39:19 ? 0:00 /usr/lib/dbus-daemon --system
root 367 1 FSS 1 14:39:55 ? 0:00 /usr/lib/ssh/sshd
root 476 472 FSS 1 14:43:06 syscon 0:00 bash
root 318 1 FSS 58 14:39:51 ? 0:00 /usr/lib/utmpd
root 477 476 FSS 59 14:43:14 syscon 0:00 ps -feac
root 387 1 FSS 17 14:39:56 ? 0:00 /usr/perl5/bin/perl /usr/lib/intrd
noaccess 458 1 FSS 57 14:40:18 ? 0:13 /usr/java/bin/java -server -Xmx128m -XX:+BackgroundCompilation -XX:PermSize=32m
root 464 367 FSS 59 14:42:44 ? 0:00 /usr/lib/ssh/sshd

En este momento ya podemos asociar los valores definidos en los distintos pooles para cada una de nuestras zonas, convirtiendolas en Contenedores.

bash-3.00# zonecfg -z zonepruebas
zonecfg:zonepruebas> set pool=zone1-pool
zonecfg:zonepruebas> add rctl
zonecfg:zonepruebas:rctl> set name=zone.cpu-shares
zonecfg:zonepruebas:rctl> add value (priv=privileged,limit=30,action=none)
zonecfg:zonepruebas:rctl> end
zonecfg:zonepruebas> verify
zonecfg:zonepruebas> exit

bash-3.00# zonecfg -z zonepruebas2
zonecfg:zonepruebas> set pool=zone1-pool
zonecfg:zonepruebas> add rctl
zonecfg:zonepruebas:rctl> set name=zone.cpu-shares
zonecfg:zonepruebas:rctl> add value (priv=privileged,limit=15,action=none)
zonecfg:zonepruebas:rctl> end
zonecfg:zonepruebas> verify
zonecfg:zonepruebas> exit

bash-3.00# zoneadm list -cv
ID NAME STATUS PATH BRAND IP
0 global running / native shared
7 zonepruebas installed /zonas/pruebas native shared
9 zonepruebas2 installed /zonas/pruebas2 native shared

Arrancamos las zonas zonepruebas y zonepruebas2.

bash-3.00# zoneadm -z zonepruebas boot

bash-3.00# zoneadm -z zonepruebas2 boot

y ademas podemos comprobar la gestión de recursos de ambas zonas.

bash-3.00# zonefss -l
ID NAME SHARES
0 global 1
7 zonepruebas 30
9 zonepruebas2 15

Vamos a utilizar este scrpit en Perl para estresar las zonas y medir sus consumo de CPU del total de procesadores del sistema.

bash-3.00# more cpuhog.pl
#!/usr/bin/perl
print "eating the CPUs\n";
foreach $i (1..16) {
$pid = fork();
last if $pid == 0;
print "created PID $pid\n";
}
while (1) {
$x++;
}

Por tanto, ejecutamos el cpuhog.pl tanto en el solaris anfitrion(zona global), como en las zonas definidas zonepruebas y zonepruebas2 y obervamos que al establecerse competencia por el uso de todos los recursos de CPU del sistema nunca se limitan los limites establecidos a traves del FSS.

bash-3.00# prstat -Z
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
3825 root 3272K 1112K run 54 0 0:00:04 3,5% cpuhog.pl/1
3821 root 3272K 1112K run 54 0 0:00:03 3,4% cpuhog.pl/1
3819 root 3272K 1112K run 52 0 0:00:03 3,3% cpuhog.pl/1
3830 root 3272K 1112K run 52 0 0:00:03 3,3% cpuhog.pl/1
3829 root 3272K 1112K run 54 0 0:00:04 3,2% cpuhog.pl/1
3827 root 3272K 1112K run 51 0 0:00:03 3,2% cpuhog.pl/1
3815 root 3272K 1112K run 54 0 0:00:03 3,1% cpuhog.pl/1
3826 root 3272K 1112K run 54 0 0:00:03 3,1% cpuhog.pl/1
3807 root 3272K 1176K run 51 0 0:00:04 3,0% cpuhog.pl/1
3817 root 3272K 1112K run 54 0 0:00:03 3,0% cpuhog.pl/1
3828 root 3272K 1112K run 52 0 0:00:03 3,0% cpuhog.pl/1
3813 root 3272K 1112K run 54 0 0:00:03 3,0% cpuhog.pl/1
3823 root 3272K 1112K run 52 0 0:00:03 3,0% cpuhog.pl/1
3811 root 3272K 1112K run 52 0 0:00:04 2,9% cpuhog.pl/1
3805 root 3276K 1996K run 53 0 0:00:03 2,8% cpuhog.pl/1
ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE
7 38 94M 87M 11% 0:01:24 52% zonepruebas
9 39 98M 91M 11% 0:01:01 32% zonepruebas2
0 54 113M 111M 13% 0:00:46 7,8% global


Total: 131 processes, 452 lwps, load averages: 52,23, 22,69, 16,04

Pero si matamos el proceso cpuhog.pl de las zona zonepruebas2 unicamente, el FSS permite a la zona zonepruebas (conde si corre todavia el cpuhog.pl) utilizar la suma de los limites de ambas en cuanto a su utilización de los recursos de CPU del sistema, ya que todavia entra en competencia con el anfitrion (zona global), asi:

bash-3.00# prstat -Z
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
3827 root 3272K 1112K run 59 0 0:00:11 6,9% cpuhog.pl/1
3830 root 3272K 1112K run 59 0 0:00:10 5,0% cpuhog.pl/1
3805 root 3276K 1996K run 59 0 0:00:10 4,9% cpuhog.pl/1
3811 root 3272K 1112K run 59 0 0:00:10 4,8% cpuhog.pl/1
3825 root 3272K 1112K run 59 0 0:00:11 4,8% cpuhog.pl/1
3808 root 3272K 1112K run 59 0 0:00:10 4,8% cpuhog.pl/1
3809 root 3272K 1112K run 59 0 0:00:11 4,8% cpuhog.pl/1
3823 root 3272K 1112K run 59 0 0:00:10 4,8% cpuhog.pl/1
3815 root 3272K 1112K run 59 0 0:00:10 4,8% cpuhog.pl/1
3807 root 3272K 1176K run 59 0 0:00:11 4,7% cpuhog.pl/1
3813 root 3272K 1112K run 59 0 0:00:10 4,7% cpuhog.pl/1
3826 root 3272K 1112K run 59 0 0:00:10 4,7% cpuhog.pl/1
3828 root 3272K 1112K run 59 0 0:00:10 4,7% cpuhog.pl/1
3819 root 3272K 1112K run 59 0 0:00:10 4,6% cpuhog.pl/1
3817 root 3272K 1112K run 59 0 0:00:10 4,6% cpuhog.pl/1
ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE
7 38 94M 87M 11% 0:03:23 82% zonepruebas
0 54 113M 111M 13% 0:01:07 13% global
9 22 93M 88M 11% 0:00:23 0,1% zonepruebas2


Total: 114 processes, 435 lwps, load averages: 43,77, 32,25, 20,90

Y unicamente consumira practicamente el 100% de la CPU del sistema, cuando matamos el proceso cpuhog.pl en el anfitrion (zona global), asi:

bash-3.00# prstat -Z
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
3813 root 3272K 1112K run 1 0 0:00:21 5,7% cpuhog.pl/1
3807 root 3272K 1176K run 2 0 0:00:21 5,7% cpuhog.pl/1
3828 root 3272K 1112K run 1 0 0:00:20 5,7% cpuhog.pl/1
3830 root 3272K 1112K run 1 0 0:00:20 5,6% cpuhog.pl/1
3809 root 3272K 1112K run 1 0 0:00:21 5,5% cpuhog.pl/1
3808 root 3272K 1112K run 3 0 0:00:21 5,5% cpuhog.pl/1
3826 root 3272K 1112K run 1 0 0:00:20 5,5% cpuhog.pl/1
3829 root 3272K 1112K run 3 0 0:00:21 5,5% cpuhog.pl/1
3821 root 3272K 1112K run 1 0 0:00:21 5,5% cpuhog.pl/1
3825 root 3272K 1112K run 1 0 0:00:21 5,5% cpuhog.pl/1
3811 root 3272K 1112K run 2 0 0:00:21 5,4% cpuhog.pl/1
3823 root 3272K 1112K run 17 0 0:00:20 5,3% cpuhog.pl/1
3805 root 3276K 1996K run 15 0 0:00:21 5,3% cpuhog.pl/1
3815 root 3272K 1112K run 3 0 0:00:20 5,3% cpuhog.pl/1
3819 root 3272K 1112K run 8 0 0:00:20 5,2% cpuhog.pl/1
ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE
7 38 94M 87M 11% 0:06:18 94% zonepruebas
0 37 108M 109M 13% 0:00:49 3,8% global
9 22 93M 88M 11% 0:00:23 0,1% zonepruebas2


Total: 97 processes, 418 lwps, load averages: 29,05, 33,26, 23,69

Y todo vuelve a la normalidad cuando matamos el proceso cpuhog.pl en la zona zonepruebas.

bash-3.00# prstat -Z
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
3779 root 5660K 3504K cpu0 1 0 0:00:08 3,0% prstat/1
3769 un38134 10M 2400K sleep 59 0 0:00:00 0,3% sshd/1
456 noaccess 77M 53M sleep 56 0 0:00:29 0,2% java/24
3234 noaccess 76M 53M sleep 52 0 0:00:15 0,1% java/24
3600 noaccess 78M 55M sleep 56 0 0:00:13 0,1% java/24
3482 root 3456K 1684K sleep 59 0 0:00:00 0,0% syslogd/11
3267 root 7904K 2020K sleep 59 0 0:00:00 0,0% sendmail/1
3609 root 7904K 2024K sleep 59 0 0:00:00 0,0% sendmail/1
125 root 1556K 1104K sleep 6 0 0:00:00 0,0% powerd/3
121 root 2984K 1976K sleep 29 0 0:00:00 0,0% picld/4
315 root 2096K 1368K sleep 59 0 0:00:00 0,0% hald-addon-stor/1
307 root 1232K 844K sleep 59 0 0:00:00 0,0% utmpd/1
308 root 1920K 1160K sleep 59 0 0:00:00 0,0% sac/1
291 root 5260K 3672K sleep 59 0 0:00:00 0,0% hald/4
132 root 5748K 2404K sleep 29 0 0:00:00 0,0% mdmonitord/1
ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE
0 37 108M 109M 13% 0:00:56 3,5% global
7 21 89M 84M 10% 0:00:28 0,2% zonepruebas
9 22 93M 88M 11% 0:00:23 0,1% zonepruebas2


Total: 80 processes, 401 lwps, load averages: 11,29, 25,84, 22,50

Pero podemos asegurarnos que el anfitrion (zona global) tenga asegurado un limite en modo privilegiado del total de recursos de CPU para la ejecucion de sus procesos al igual que hemos realizado con las Zonas zonepruebas y zonepruebas2.

bash-3.00# prctl -n zone.cpu-shares -i zone global
zone: 0: global
NAME PRIVILEGE VALUE FLAG ACTION RECIPIENT
zone.cpu-shares
privileged 1 - none -
system 65,5K max none -
bash-3.00# prctl -n zone.cpu-shares -v 20 -r -i zone global

bash-3.00# prctl -n zone.cpu-shares -i zone global
zone: 0: global
NAME PRIVILEGE VALUE FLAG ACTION RECIPIENT
zone.cpu-shares
privileged 20 - none -
system 65,5K max none -

bash-3.00# zonefss -l
ID NAME SHARES
0 global 20
7 zonepruebas 30
9 zonepruebas2 15

Luego si ejecutamos de nuevo el script cpuhog.pl tanto en el anfitrion, como en las zonas zonepruebas y zonepruebas2, podemos ver que el limte de consumo de los recursos CPU por parte de la zona global ha aumentado significativamente.

bash-3.00# prstat -Z
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
3918 root 3272K 1112K run 43 0 0:00:01 2,9% cpuhog.pl/1
3893 root 3272K 1176K run 45 0 0:00:01 2,7% cpuhog.pl/1
3899 root 3272K 1112K run 45 0 0:00:01 2,6% cpuhog.pl/1
3917 root 3272K 1112K run 45 0 0:00:01 2,5% cpuhog.pl/1
3916 root 3272K 1112K run 1 0 0:00:01 2,3% cpuhog.pl/1
3911 root 3272K 1112K run 3 0 0:00:01 2,3% cpuhog.pl/1
3914 root 3272K 1112K run 2 0 0:00:01 2,3% cpuhog.pl/1
3903 root 3272K 1112K run 3 0 0:00:01 2,2% cpuhog.pl/1
3895 root 3272K 1112K run 3 0 0:00:01 2,2% cpuhog.pl/1
3871 root 3272K 1108K run 48 0 0:00:01 2,2% cpuhog.pl/1
3909 root 3272K 1112K run 45 0 0:00:01 2,1% cpuhog.pl/1
3915 root 3272K 1112K run 33 0 0:00:01 2,1% cpuhog.pl/1
3897 root 3272K 1112K run 17 0 0:00:01 2,1% cpuhog.pl/1
3891 root 3276K 1996K run 3 0 0:00:01 2,0% cpuhog.pl/1
3880 root 3272K 1108K run 24 0 0:00:01 2,0% cpuhog.pl/1
3888 root 3272K 1108K run 27 0 0:00:01 1,9% cpuhog.pl/1
3906 root 3272K 1112K run 1 0 0:00:01 1,9% cpuhog.pl/1
3872 root 3272K 1108K run 44 0 0:00:01 1,9% cpuhog.pl/1
3867 root 5660K 3504K cpu0 53 0 0:00:01 1,9% prstat/1
3901 root 3272K 1112K run 45 0 0:00:01 1,9% cpuhog.pl/1
3877 root 3272K 1108K run 48 0 0:00:01 1,8% cpuhog.pl/1
ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE
7 38 94M 87M 11% 0:00:47 37% zonepruebas
0 54 113M 111M 13% 0:01:06 31% global
9 39 98M 91M 11% 0:00:32 24% zonepruebas2


Total: 131 processes, 452 lwps, load averages: 34,82, 11,46, 11,51

Como conclusión podemos ver que con el mecanismo de pooles de Solaris 10 y Opensolaris asignamos mediante el FSS los recursos de CPU del total de nuestro sistema (2, 4, 8, 16, etc...) a cada una de las Zonas, convirtiendolas en contenedores que nunca superaran su umbral definido como consumo maximo.

lunes, 30 de julio de 2007

SMF y Privilegios


Ha diferencia de las versiones anteriores de Solaris 6 y 7 donde para establecer privilegios teniamos que recurrir a software externo al sistema, como SUDO... y Solaris 8, 9 donde podiamos realizar este tipo de acciones con RBAC ya como parte del mismo. En Solaris 10 y OpenSolaris con la inclusión de SMF (Service Management Facility) la pespectiva cambia y podemos ser capaces de definir que usuario y que acciones puede realizar (parar, arrancar...) sobre un servicio del sistema que incluso levante un socket tcp/udp por debajo del puerto 1024 sin ser root.

En este ejemplo lo vamos a realizar con Apache2 gestionado como servicio a traves de SMF.

# svcs apache2
STATE STIME FMRI
disabled 19:12:02 svc:/network/http:apache2
# svcadm -v enable -s apache2
svc:/network/http:apache2 enabled.
# ps -aef | grep apache | grep -v grep
webservd 14836 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 14837 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 14839 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
root 14835 10895 0 15:25:03 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 14838 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 14840 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
# ptree 14835
10895 zsched
14835 /usr/apache2/bin/httpd -k start
14836 /usr/apache2/bin/httpd -k start
14837 /usr/apache2/bin/httpd -k start
14838 /usr/apache2/bin/httpd -k start
14839 /usr/apache2/bin/httpd -k start
14840 /usr/apache2/bin/httpd -k start

Vemos como por defecto el proceso que realmente levanta el socket abierto en el puerto tcp 80 es iniciado como root y no tiene ningun tipo de privilegios.

# ppriv -S 14835
14835: /usr/apache2/bin/httpd -k start
flags =
E: zone
I: basic
P: zone
L: zone

Esto lo vamos a cambiar para el usuario webservd, asi:

# svcadm -v disable svc:/network/http:apache2
svc:/network/http:apache2 inhabilitado.
# svccfg -s apache2
svc:/network/http:apache2> setprop start/user = astring: webservd
svc:/network/http:apache2> setprop start/group = astring: webservd
svc:/network/http:apache2> setprop start/privileges = astring:
basic,!proc_session,!proc_info,!file_link_any,net_privaddr

svc:/network/http:apache2> setprop start/limit_privileges = astring: :default
svc:/network/http:apache2> setprop start/use_profile = boolean: false
svc:/network/http:apache2> setprop start/supp_groups = astring: :default
svc:/network/http:apache2> setprop start/working_directory = astring: :default
svc:/network/http:apache2> setprop start/project = astring: :default
svc:/network/http:apache2> setprop start/resource_pool = astring: :default
svc:/network/http:apache2> end
# svcprop -v -p start apache2
start/exec astring /lib/svc/method/http-apache2\ start
start/timeout_seconds count 60
start/type astring method
start/user astring webservd
start/group astring webservd
start/privileges astring
basic,!proc_session,!proc_info,!file_link_any,net_privaddr
start/limit_privileges astring :default
start/use_profile boolean false
start/supp_groups astring :default
start/working_directory astring :default
start/project astring :default
start/resource_pool astring :default
# svcadm -v refresh apache2
Action refresh set for svc:/network/http:apache2.
# svcadm -v enable -s apache2
svc:/network/http:apache2 habilitado.
# ps -fea|grep apache
webservd 3957 3953 0 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 3956 3953 1 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 3953 1 2 19:21:11 ? 0:01 /usr/apache2/bin/httpd -k start
webservd 3955 3953 1 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 3954 3953 0 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 3958 3953 0 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
# netstat -an|grep -i listen
*.22 *.* 0 0 49152 0 LISTEN
*.111 *.* 0 0 49152 0 LISTEN
*.59597 *.* 0 0 49152 0 LISTEN
*.80 *.* 0 0 49152 0 LISTEN
*.22 *.* 0 0 49152 0 LISTEN
*.80 *.* 0 0 49152 0 LISTEN

Y teniendo en cuenta lo que significa cada privilegios, vemos los que le hemos asignado.

# ppriv -v -l proc_exec proc_fork net_privaddr
proc_exec
Allows a process to call execve().
proc_fork
Allows a process to call fork1()/forkall()/vfork()
Configuring the Apache2 Service 7
net_privaddr
Allows a process to bind to a privileged port number.
The privilege port numbers are 1-1023 (the traditional
UNIX privileged ports) as well as those ports marked as
"udp/tcp_extra_priv_ports" with the exception of the ports
reserved for use by NFS.
# ppriv -S 3953
3953: /usr/apache2/bin/httpd -k start
flags =
E: net_privaddr,proc_exec,proc_fork
I: net_privaddr,proc_exec,proc_fork
P: net_privaddr,proc_exec,proc_fork
L: all

Luego hemos conseguido que el usuario webservd sea capaz de arrancar y para el servicio apache2, levantando un socket en el puerto tcp 80 sin necesidad de cambiar la identidad a root en ningún momento.

Habilitar SAR


A diferencia de como podiamos habilitar este comando en versiones antiguas de Solaris (9 y anteriores), asi:

# vi /etc/init.d/perf
if [ -z "$_INIT_RUN_LEVEL" ]; then
set -- `/usr/bin/who -r`
_INIT_RUN_LEVEL="$7"
_INIT_RUN_NPREV="$8"
_INIT_PREV_LEVEL="$9"
fi

if [ $_INIT_RUN_LEVEL -ge 2 -a $_INIT_RUN_LEVEL -le 4 -a \
$_INIT_RUN_NPREV -eq 0 -a \( $_INIT_PREV_LEVEL = 1 -o \
$_INIT_PREV_LEVEL = S \) ]; then

/usr/bin/su sys -c "/usr/lib/sa/sadc /var/adm/sa/sa`date +%d`"
fi

Descomentando las lineas en negrita, y ejecutando este script:

# /etc/init.d/perf
# sar
10:43:26 unix restarts
Average 0 0 0 100
# uname -a
SunOS alfacar 5.9 Generic_118558-35 sun4u sparc SUNW,Ultra-5_10

Unicamente nos quedaría comprobar que todo queda listo en el cron.

# crontab -l sys
0 * * * 0-6 /usr/lib/sa/sa1
20,40 8-17 * * 1-5 /usr/lib/sa/sa1
5 18 * * 1-5 /usr/lib/sa/sa2 -s 8:00 -e 18:01 -i 1200 -A

En Solaris 10 y OpenSolaris, con la aparición de SMF (Service Management Facility) como gestor de los distintos procesos de arranque del sistema, manteniendo todavia compatibilidad con los clásicos niveles de ejecución (Run Levels), se realiza de forma diferente:

# sar
sar: can't open /var/adm/sa/sa30
No such file or directory
# svcs |grep sa
online 10:38:51 svc:/system/sac:default
# svcadm enable svc:/system/sar:default
# svcs |grep sar
online 10:43:58 svc:/system/sar:default
# sar
SunOS opensolaris 5.11 snv_57 i86pc 07/30/2007
10:43:58 %usr %sys %wio %idle
10:43:58 unix restarts
# uname -a
SunOS opensolaris 5.11 snv_57 i86pc i386 i86pc
# crontab -l sys
0 * * * 0-6 /usr/lib/sa/sa1
20,40 8-17 * * 1-5 /usr/lib/sa/sa1
5 18 * * 1-5 /usr/lib/sa/sa2 -s 8:00 -e 18:01 -i 1200 -A
# svcs | grep cron
online 11:00:11 svc:/system/cron:default
# svcadm restart svc:/system/cron:default
# tail -f /var/cron/log
! ******* CRON ABORTED ******** lun jul 30 11:02:55 2007
! *** cron started *** pid = 567 lun jul 30 11:02:55 2007