SafeChildren Banner

Havoc Oracle Solaris Experts

martes, 21 de diciembre de 2010

OpenIndiana, Developer Version b148

Introducción
Ya tenemos una nueva versión de OpenIndiana, la b148. Aunque todavía es una Developer Release, ya podemos actualizar nuestras instalaciones con un simple <pkg image-update>, ... y veremos cómo se comporta.

Como Actualizar OpenIndiana
Ya hemos comentado Cómo actualizar de OpenSolaris a OpenIndiana, para ello, utilizabamos los repositorios de OpenIndiana y, posteriormente lanzamos el <image-update&gt, pues, en esta ocasión haremos lo mismo, :D, pero sólo lanzaremos el <pkg image-update>, por ejemplo,
itily@openzooey:~$ pfexec pkg image-update
Después de la actualización se nos creará un nuevo Boot Enviroment, que activaremos con el reinicio del sistema, para ello, utilizaremos el comando <init 6>
itily@openzooey:~$ pfexec init 6

Comprobar la Versión
Al igual que sucedía con Solaris, para comprobar la versión, simplemente deberemos hacer un <cat /etc/release>
itily@openzooey:~$ cat /etc/release
                      OpenIndiana Development oi_148 X86
        Copyright 2010 Oracle and/or its affiliates. All rights reserved.
                        Use is subject to license terms.
                           Assembled 29 November 2010

Referencias

jueves, 16 de diciembre de 2010

Actualizar la versión del pool ZFS con zpool upgrade

Introducción
Después de ir actualizando nuestros sistemas -OpenIndiana, OpenSolaris y Solaris-, la versión del <pool> de ZFS que nuestro sistema soporta va en aumento, sin embargo, debemos ir actualizando nuestros pools creados.
Esto nos permitirá ir incluyendo las mejoras que, en materia de ZFS, se han ido introduciendo, además de soportar las nuevas propiedades y sobre todo, mejorar el rendimiento.


Comprobar nuestro zpool
Para verificar el estado de nuestro pool <zfs>, simplemente deberemos utilizar la opción <status> del comando <zpool>
root@openzooey:/# zpool status
  pool: rpool1
 state: ONLINE
status: The pool is formatted using an older on-disk       format. The pool can still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'.  Once this is done, the pool will no longer be accessible on older software versions.
 scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        rpool1      ONLINE       0     0     0
          c2d0s0    ONLINE       0     0     0

errors: No known data errors
El mensaje está claro: <el zpool está formateado usando un formato antiguo>, así que debemos actualizar nuestro <zpool> para que obtenga las últimas mejoras

Comprobar la Versión ZFS de nuestro Sistema y ZPOOLs a Actualizar
Para comprobar qué <zpool> deben ser actualizados, y qué versión es la que actualmente está activa en nuestro sistema, deberemos utilizar la opción <upgrade> del comando <zpool>, por ejemplo:
root@openzooey:/# zpool upgrade
This system is currently running ZFS pool version 28.

The following pools are out of date, and can be upgraded.  After being upgraded, these pools will no longer be accessible by older software versions.

VER  POOL
---  ------------
22   rpool1

Use 'zpool upgrade -v' for a list of available versions and their associated
features.


Solaris nos informa de qué <zpool> son los que debemos actualizar, además de la versión actual de ZFS pool que soportamos. Si queremos ver la lista de mejoras, es decir, el ChangeLog podemos utilizar la opción <-v>, por ejemplo:

root@openzooey:/# zpool upgrade -v
This system is currently running ZFS pool version 28.

The following versions are supported:

VER  DESCRIPTION
---  ----------------------------------------------------
 1   Initial ZFS version
 2   Ditto blocks (replicated metadata)
 3   Hot spares and double parity RAID-Z
 4   zpool history
 5   Compression using the gzip algorithm
 6   bootfs pool property
 7   Separate intent log devices
 8   Delegated administration
 9   refquota and refreservation properties
 10  Cache devices
 11  Improved scrub performance
 12  Snapshot properties
 13  snapused property
 14  passthrough-x aclinherit
 15  user/group space accounting
 16  stmf property support
 17  Triple-parity RAID-Z
 18  Snapshot user holds
 19  Log device removal
 20  Compression using zle (zero-length encoding)
 21  Deduplication
 22  Received properties
 23  Slim ZIL
 24  System attributes
 25  Improved scrub stats
 26  Improved snapshot deletion performance
 27  Improved snapshot creation performance
 28  Multiple vdev replacements

For more information on a particular version, including supported releases,
see the ZFS Administration Guide.
Actualización de Versión
ATENCIÓN: Antes de actualizar un <zpool> asegurate que todos tus Boot Enviroment están actualizados, sino, no podrás ejecutarlos desde una versión anterior.

Para actualizar la versión de nuestro zpool, simplemente utilizaremos el comando <zpool upgrade> de la siguiente forma:
zpool upgade {-a | poolname}
Donde podemos utilizar <-a> para actualizar todos los zpool del sistema, o, por el contrario podemos ir actualizando uno a uno. Por ejemplo, para actualizar todos de una vez:
root@openzooey:/# zpool upgrade -a
This system is currently running ZFS pool version 28.

Successfully upgraded 'rpool1'

Y comprobamos su estado volviendo a llamar a <zpool status>
root@openzooey:/# zpool status
  pool: rpool1
 state: ONLINE
 scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        rpool1      ONLINE       0     0     0
          c2d0s0    ONLINE       0     0     0

errors: No known data errors

Conclusiones
En esta ocasión hemos visto cómo actualizar el pool de ZFS es realmente sencillo, aunque como siempre unas cosas a tener en cuenta antes de empezar:
  • Haz copias de seguridad
  • Verifica tus copias de seguridad
  • Procede a actualizar tu sistema
No será la primera -ni la última- que alguien me suplica que recupere algún sistema donde no hay copias de seguridad ... y no siempre es posible.

Referencias

lunes, 6 de diciembre de 2010

Utilizar yesterday y today en PostgreSQL como Constantes

Introducción
Hace algunos días hablábamos de las opciones de Manejo de Fechas e Intervalos en PostgreSQL, y cómo se incluían unas <palabras reservadas> para obtener el día de ayer <yesterday> o de hoy <today>, por ejemplo:
search=> select 'today'::date;
    date  
------------
 2010-12-06
(1 row)

search=> select 'yesterday'::date;
    date  
------------
 2010-12-05
(1 row)
Partiendo de ello, vamos a ver algunas implicaciones de utilizar estas sustituciones dentro de Vistas, y cómo podemos solucionarlo.
Tabla de Ejemplo
Lo primero que vamos a hacer es crear una tabla llamada <havoc_test> donde pondremos un nombre y una fecha:
search=> create table havoc_test(nombre character varying, fecha date);
CREATE TABLE
Ahora, añadimos unos registros con los valores de fecha de <yesterday>, <today> y <now()>
search=> insert into havoc_test(nombre, fecha) values ('yesterday', 'yesterday'::date);
INSERT 0 1
search=> insert into havoc_test(nombre, fecha) values ('today', 'today'::date);
INSERT 0 1
search=> insert into havoc_test(nombre, fecha) values ('now', 'now()'::date);
INSERT 0 1
search=> select * from havoc_test;
  nombre   |   fecha    
-----------+------------
 yesterday | 2010-12-05
 today     | 2010-12-06
 now       | 2010-12-06
(3 rows)
Ahora, nos creamos una vista para obtener todos los registros de ayer, por ello, utilizaremos <fecha='yesterday'::date> como condición del where
search=> create or replace view yesterday_v as            select * from havoc_test where fecha = 'yesterday'::date;
CREATE VIEW
search=> select * from yesterday_v;
  nombre   |   fecha    
-----------+------------
 yesterday | 2010-12-05
(1 row)
El resultado es correcto, o mejor dicho, a simple vista es correcto, sin embargo, PostgreSQL nos sustituirá los valores de <yesterday> o <today> por los valores constantes, es decir, <2010-12-05> en nuestro caso. 

Si nos fijamos en cómo PostgreSQL ha creado la vista, veremos que ha sustituido el valor de <yesterday> por el día de ayer:


search=> \d yesterday_v;
       View "public.yesterday_v"
 Column |       Type        | Modifiers 
--------+-------------------+-----------
 nombre | character varying | 
 fecha  | date              | 
View definition:
 SELECT havoc_test.nombre, havoc_test.fecha
   FROM havoc_test
  WHERE havoc_test.fecha = '2010-12-05'::date;

Cuando nosotros lo que queríamos era que, en función del día actual, nos mostrase "ayer", pero no de forma constante.

Para solucionar este problema, simplemente pondremos <yesterday> como constante de texto, es decir, construiremos la cadena "al vuelo" y así PostgreSQL no realizará la sustitución hasta su ejecución. Veamos un ejemplo:
search=> create or replace view yesterday_v as
select * from havoc_test where fecha = cast('' || 'yesterday' || '' as date);
CREATE VIEW
search=> \d yesterday_v; 
View "public.yesterday_v"
 Column |       Type        | Modifiers
--------+-------------------+-----------
 nombre | character varying |
 fecha  | date              |
View definition:
 SELECT havoc_test.nombre, havoc_test.fecha
   FROM havoc_test
  WHERE havoc_test.fecha = (((''::text || 'yesterday'::text) || ''::text)::date);

search=> select * from yesterday_v; 
  nombre   |   fecha  
-----------+------------
 yesterday | 2010-12-05
(1 row)

Conclusiones
Como podemos comprobar, ahora hemos conseguido lo que inicialmente queríamos, tratar los valores de <yesterday> como constante.

lunes, 29 de noviembre de 2010

Cómo configurar HTTPS en Tomcat utilizando Roles y Privilegios

Introducción
Ya hemos visto en ocasiones anteriores Cómo Instalar Apache Tomcat en Solaris. Además, con los conocimientos que hemos adquirido sobre RBAC, Roles, Privilegios y Seguridad en Solaris, podemos realizar la instalación con un nivel de seguridad muy elevado.

En esta ocasión vamos a ver cómo podemos configurar un conector HTTPS en Apache Tomcat, utilizando un puerto no privilegiado, por ejemplo 8443, y luego, veremos cómo podemos utilizar el puerto privilegiado 443 sin tener que lanzar Apache Tomcat con <root>.

Instalación de Apache Tomcat
Para su instalación seguiremos los pasos del post Cómo Instalar Apache Tomcat en Solaris 10 utilizando SMF para su gestión, aunque haremos algunos cambios -ahora que conocemos RBAC y Roles-

Diferencias en la Instalación
Cuando hablábamos de Cómo Instalar Tomcat en Solaris 10 utilizando SMF, todavía no habíamos mencionado el tema de RBAC, Roles y Privilegios, por lo tanto, no podíamos entrar en mucha complicación. Ahora bien, ya estamos en disposición de poder instalarlo de una forma mucho más segura y eficiente utilizando: roles, privilegios y autorizaciones.


Creación de la Clave RSA
En nuestro ejemplo vamos a generar un clave <auto sellada>, es decir, que seremos nosotros mismos quienes validemos la firma.

Esta funcionalidad nos permite establecer certificados de forma sencilla, aunque no es recomendable para su puesta en producción -sobre todo si es un servicio a terceros-, principalmente porque al estar validado por nosotros mismos, el navegador nos mostrará un mensaje de aviso.

Sin embargo, para pruebas es una forma muy sencilla de trabajar -y barata-. En nuestro caso, queremos crear el keystore en <$TOMCAT_HOME/cert/havoctec-tomcat>
$ cd $TOMCAT_HOME
$ mkdir cert
$ chmod 700 cert
$ chown appserver:root cert
Ahora podemos utilizar la utilidad <keytool> de Java para generar la clave RSA que utilizaremos en Tomcat
$ keytool -keystore /var/sfchildren/appserver/tomcat-6.0/cert/havoctec-tomcat -genkey -keyalg RSA -alias havoctec
Escriba la contraseña del almacén de claves: havoctec 
Volver a escribir la contraseña nueva: havoctec
¿Cuáles son su nombre y su apellido?
  [Unknown]:  Urko Benito
¿Cuál es el nombre de su unidad de organización?
  [Unknown]:  HavocTec S.L.
¿Cuál es el nombre de su organización?
  [Unknown]:  HavocTec S.L.
¿Cuál es el nombre de su ciudad o localidad?
  [Unknown]:  MADRID
¿Cuál es el nombre de su estado o provincia?
  [Unknown]:  SPAIN
¿Cuál es el código de país de dos letras de la unidad?
  [Unknown]:  ES
¿Es correcto CN=Urko Benito, OU=HavocTec S.L., O=HavocTec S.L., L=MADRID, ST=SPAIN, C=ES?
  [no]:  si

Escriba la contraseña clave para
        (INTRO si es la misma contraseña que la del almacén de claves):  havoctec
Esto nos ha creado una nueva clave RSA en el almacén que hemos indicado, en nuestro caso
<$TOMCAT_HOME/cert>, sin embargo, los permisos son muy leves, y es interesante modifcarlos para que sólo el dueño pueda leer y escribir en el él, por ejemplo:
$ ls -ltr
total 4
-rw-r--r--   1 appserver asengine    1381 nov 29 09:18 havoctec-tomcat
$ chmod 600 havoctec-tomcat
$ ls -ltr
total 4
-rw-------   1 appserver asengine    1381 nov 29 09:18 havoctec-tomcat

Creación del Connector HTTPS en puerto NO PRIVILEGIADO (8443)
Por último, definiremos un conector HTTPS en el archivo de configuración <$TOMCAT_HOME/conf/server.xml> donde deberemos indicarle la ubicación del keystore, y su contraseña, por ejemplo, en nuestro caso la ubicación del certificado es <$TOMCAT_HOME/cert/havoctec-tomcat> y su contraseña <havoctec>

$ vi $TOMCAT_HOME/conf/server.xml

    <Connector
        port="8443"
        protocol="HTTP/1.1"
        SSLEnabled="true"
        maxThreads="150"
        scheme="https"
        secure="true"
        clientAuth="false"
        keystoreFile="/var/sfchildren/appserver/tomcat-6.0/cert/havoctec-tomcat"
        keystorePass="havoctec"

        sslProtocol="TLS" />

:wq

Conexión mediante HTTPS a Tomcat
Ya podemos iniciar nuestro servidor Apache Tomcat (si lo tenemos levantado, deberemos reiniciarlo) y con un navegador nos conectaremos al puerto 8443 utilizando HTTPS

Mi servidor de ejemplo está en la IP 192.168.1.13 y, cuando me conecto con Safari al servicio veo el siguiente mensaje de aviso -como ya os he comentado es debido a que hemos "auto firmado" el certificado-

 Si pulso sobre "Mostrar Certificado" puedo ver los datos que he introducido en le comando <keytool> para su generación.


Funciona! No ha sido tan difícil, no? Ahora bien, el puerto para el protocolo HTTPS es el 443, y no el 8443 así que tenemos diferentes opciones para poder hacer una conexión HTTPS utilizando la forma <https:// ....>
  • Utilizamos <ipfilter> para redirigir el tráfico
  • Configuramos el usuario (role) de Apache Tomcat para permitirle utilizar puertos privilegiados
  • Ponemos un <reverse proxy> con soporte SSL
Como veis son muchas las opciones, aunque hoy vamos a ver una muy sencilla -ahora que conocéis RBAC, Roles y Privilegios- vamos a otorgar el privilegio <net_privaddr>


Configuración Privilegios Role o Usuario
Para poder hacer que nuestro <role> o <user> levante el servicio Tomcat en un puerto privilegiado, deberemos añadir el privilegio <net_privaddr>, para ello simplemente deberemos ejecutar (el <role> encargado de levantar el servicio de Tomcat en mi caso es <appserver>)
root@openzooey:/# rolemod -K defaultpriv=basic,net_privaddr appserver

A continuación, modificaremos el conector para que, en vez de escuchar en el puerto 8443 lo haga en le 443 y levantaremos nuestro Tomcat

$ $TOMCAT_HOME/bin/shutdown.sh
$ vi $TOMCAT_HOME/conf/server.xml
    <Connector
        port="443"
        protocol="HTTP/1.1"
        SSLEnabled="true"
        maxThreads="150"
        scheme="https"
        secure="true"
        clientAuth="false"
        keystoreFile="/var/sfchildren/appserver/tomcat-6.0/cert/havoctec-tomcat"
        keystorePass="havoctec"

        sslProtocol="TLS" />
 :wq
$ $TOMCAT_HOME/bin/startup.sh


Conclusiones
En esta ocasión hemos visto como con el uso de privilegios nos permite hacer cosas que antes deberíamos delegar en <root>, además, de esta forma podemos tener un sistema muy seguro y controlado.



Referencias

miércoles, 17 de noviembre de 2010

Política de Contraseñas en OpenIndiana y Solaris

Introducción
Una característica no tan conocida de OpenIndiana y Solaris, es el uso de diccionarios de contraseñas dentro de las opciones de la política de contraseñas.

Por defecto, Solaris no establece ninguna política de contraseñas fuertes, es decir, longitudes mínimas, formato, que no sean igual que el login, etc. Sin embargo, todo esto es configurable.

En esta ocasión, veremos cómo podemos mejorar la seguridad modificando los parámetros de longitud, duración y, por último, utilizaremos un diccionario para que Solaris evalúe la contraseña antes de asignarla.

Algoritmo de Encriptación
En Solaris, el algoritmo de encriptación asignado por defecto era el original de UNIX, que se mantenía por compatibilidad, sin embargo, este algoritmo tenía muchas limitaciones, y a día de hoy, no es nada seguro.

En OpenIndiana, sin embargo, se utiliza el algoritmo SHA256 por defecto para hacer el "hashing" de las contraseñas mucho más seguro.

Asignar un Algoritmo Nuevo
La definición del algoritmo que Solaris u OpenIndiana utilizará para "crypt", se encuentra definido en el archivo </etc/security/policy.conf>, para ello, modificaremos el valor de la propiedad <CRYPT_DEFAULT> y pondremos un valor definido en el archivo de configuración </etc/security/crypt.conf>, veamos un ejemplo.

Vamos a definir que Solaris/OpenIndiana utilice como algoritmo SHA512, que, según el archivo </etc/security/crypt.conf> corresponde con el valor "6", por lo tanto,
root@openzooey:/# cat /etc/security/crypt.conf 
# The algorithm name __unix__ is reserved.

1       crypt_bsdmd5.so.1
2a      crypt_bsdbf.so.1
md5     crypt_sunmd5.so.1
5       crypt_sha256.so.1
6       crypt_sha512.so.1
root@openzooey:/# vi /etc/security/policy.conf
  ...
  CRYPT_DEFAULT=6
  ...

:wq
Por último, cambiamos la contraseña de nuestro usuario, en mi caso <webope>
root@openzooey:/# passwd webope
New Password:
Re-enter new Password:
passwd: password successfully changed for webope
root@openzooey:/# cat /etc/shadow |grep webope
webope:$5$5TGOqra.$WjEbK0J.v.9SjU61cYUrJmtaz3UuHS/FoE.CXApNF05:14920::::::

Longitud Mínima, Historial y Formato de contraseñas
La definición de las propiedades de la contraseña, es decir, longitud, formato, historial, etc. se encuentra definida en el archivo < /etc/default/passwd>.
Vamos a ver cómo podemos hacer nuestra política de contraseñas más segura incluyendo:
  • PASSLENGTH. Longitud Mínima, 8
  • MINALPHA. Letras, 2
  • MINDIGIT. Números, 2
  • MINSPECIAL. Caracteres Espaciales, 1
Editamos el archivo </etc/default/passwd> con esto valores, y comprobamos su funcionamiento
root@openzooey:/# vi /etc/default/passwd
  MINALPHA=2
  MINDIGIT=2
  MINSPECIAL=1
  NAMECHECK=YES
  PASSLENGTH=8
:wq
Una cosa importante a tener en cuenta, es que, como en muchas situaciones en Solaris, el usuario <root> puede hacer lo que quiera, y esta es una de ellas.

Me explico, por ejemplo, si he cambiado la política de contraseñas con los valores anteriores, teóricamente no puedo asignar la password <1234> -ya que incumple todas: longitud, digitos, caracteres especiales, etc.

Sin embargo, si yo lo hago con <root> no tendré ningún problema, por ejemplo:
root@openzooey:/# passwd test
New Password: test
Re-enter new Password: test
passwd: password successfully changed for test
Pero si lo intento con el usuario
root@openzooey:/# su - test
OpenIndiana     SunOS 5.11      oi_147  September 2010
test@openzooey:~$ passwd test
Enter existing login password: testNew Password: hola
passwd: Password too short - must be at least 8 characters.

Please try again
New Password: ^C
Utilizar un Diccionario
Por último, tenemos la posibilidad de utilizar un diccionario de contraseña para evitar que nuestros usuarios no sean creativos con sus contraseñas, :D.

Deberemos descomentar la opción <DICTIONDBDIR=/var/passwd> del archivo de configuración </etc/default/passwd> para indicarle al comando <passwd> que su diccionario está en </var/passwd>.

Este path es configurable, es decir, podemos asignar el que queramos, sin embargo, </var/passwd> es el path que Solaris utiliza por defecto
Para ello, utilizaremos el comando <mkpwdict> que tiene el siguiente formato:
# mkpwdict -s file1,file2,filen -d destino
Donde file1, file2, filen serán archivos que contienen la lista de palabras sobre las cuales vamos a crear el diccionario, y <destino> el lugar donde lo almacenaremos. Si no ponemos ningún destino, se utilizará el asignado en <DICTIONDBDIR>.

Comprobamos que está descomentada la opción DICTIONDBDIR del archivo </etc/default/passwd>, si no fuese así deberíamos descomentarla.
root@openzooey:/# cat /etc/default/passwd |grep DICTIONDBDIR|grep -v ^#
DICTIONDBDIR=/var/passwd
A continuación nos creamos un archivo con las palabras sobre las cuales queremos crear el diccionario, por ejemplo:
root@openzooey:/# vi /tmp/words
rootROOT
testTEST
12345678
qwerty12
abcdefgh
1234abcd
1234ABCD
Creamos el diccionario y probamos
root@openzooey:/# mkpwdict -s /tmp/words
mkpwdict: using default database location: /var/passwd.

root@openzooey:/# passwd test
New Password: test
Re-enter new Password: test
passwd: password successfully changed for test
root@openzooey:/# su - test
OpenIndiana     SunOS 5.11      oi_147  September 2010
test@openzooey:~$ passwd test
Enter existing login password: test
New Password: 1234ABCD
passwd: password is based on a dictionary word.

Please try again
New Password: ^C

Conclusiones

Aunque las versiones de Solaris 10, 9, 8 venían con una configuración muy baja en cuanto a temas de seguridad, en OpenIndiana, y, recientemente en Solaris 11 han mejorado mucho este tema.

Principalmente el algoritmo UNIX ya no es el usado por defecto, además de incluir una longitud mínima, aunque todavía no incluyen un diccionario por defecto.

Espero que con estas pequeñas aclaraciones, podamos mejorar la seguridad de nuestros sistemas Solaris y así hacerlo más "Rock Solid" todavía,


Referencias