miércoles, 13 de octubre de 2010

Uso de SSH (parte 1)

Tradicionalmente utilizamos telnet para iniciar una sesión en nuestro servidor, sin embargo, este protocolo no cuenta con ningún tipo de seguridad, por lo que basta conectar un analizador de protocolo a la red para averiguar lo que se escribe desde una IP determinada, es por eso que se recomienda utilizar en su lugar el SSH, el cual, esta cifrado y permite iniciar sesiones e intercambiar archivos.

Una de las ventajas de SSH es que permite el uso de llaves públicas para iniciar la sesión sin necesidad de ingresar contraseña siendo, de esta forma, un buen sustituto para el rsh.

Vamos a crear primero una llave RSA para nuestro usuario con el comando ssh-keygen:

hajarami@ubuntu:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to. save the key (/home/hajarami/.ssh/id_rsa):
Created directory '/home/hajarami/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/hajarami/.ssh/id_rsa.
Your public key has been saved in /home/hajarami/.ssh/id_rsa.pub.
The key fingerprint is:
27:99:0b:f0:bd:98:b9:54:c9:b8:c6:47:08:15:96:ba hajarami@ubuntu
The key's randomart image is:
+--[ RSA 2048]----+
|      +o         |
|     o.          |
|    o.           |
|    .+ = +       |
|     .= S .      |
|    E. O =       |
|      O +        |
|     o o         |
|      .          |
+-----------------+

Esta llave esta compuesta por dos partes la pública y la privada, la privada es el archivo $HOME/.ssh/id_rsa y debe permanecer siempre ahí con solo permisos para el propietario.

Revisamos el contenido de la llave pública:

hajarami@ubuntu:~$ cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAv53P81IpkhJPzzzZ7xygmWq1ynTeJ3ut/XetJPX4fENmo/c1nQlG+tsNzsuAV6OBFa2KI0YT9avxkDOFA+1SaO8dqslo0wF46/CCKyFmUn2NMHlA69NyBKiL2cLxvTXq6fBj3+f9jVijv4df/9NoBpup7uIETJt0MlYVsSbidR1FMdzNO91mcCZkrgQ9rxH4N9geI9KMUEXSfuouhmY0Z8GQUZSIB1f5djub1NfT10F6riPW7njF7HMRHlAIb8EKaGBcgK0LCEFP1OVc9uSLOWIzbz2slvze5Dly31d6O4Rb+T0LeTPL+7FavEaCeUM7lW+WVIs+sGemsEL+h2VQ8Q== hajarami@ubuntu

Esta llave se la vamos a proporcionar al propietario de la cuenta a la que necesitamos entrar para que nos “autorice” el acceso.

En el otro servidor, en el home directory del usuario con el que vamos a iniciar sesión vamos a agregar la llave pública en el archivo $HOME/.ssh/authorized_keys:

[solaris10:~]$ echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAv53P81IpkhJPzzzZ7xygmWq1ynTeJ3ut/XetJPX4fENmo/c1nQlG+tsNzsuAV6OBFa2KI0YT9avxkDOFA+1SaO8dqslo0wF46/CCKyFmUn2NMHlA69NyBKiL2cLxvTXq6fBj3+f9jVijv4df/9NoBpup7uIETJt0MlYVsSbidR1FMdzNO91mcCZkrgQ9rxH4N9geI9KMUEXSfuouhmY0Z8GQUZSIB1f5djub1NfT10F6riPW7njF7HMRHlAIb8EKaGBcgK0LCEFP1OVc9uSLOWIzbz2slvze5Dly31d6O4Rb+T0LeTPL+7FavEaCeUM7lW+WVIs+sGemsEL+h2VQ8Q== hajarami@ubuntu" >> $HOME/.ssh/authorized_keys

Y listo, ya tenemos autorización para iniciar sesión, desde nuestro servidor origen:

hajarami@ubuntu:~$ ssh hajarami@solaris10
The authenticity of host 'solaris10 (192.168.188.138)' can't be established.
RSA key fingerprint is 88:4d:ff:4c:67:17:46:20:14:9c:3b:7f:1c:5b:f9:c5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'solaris10,192.168.188.138' (RSA) to the list of known hosts.
Last login: Wed Oct 13 20:13:24 2010 from 192.168.188.1
Sun Microsystems Inc.   SunOS 5.10      Generic January 2005
You have mail.
[solaris10:~]$

La primera vez que entramos a un servidor, nos hace la advertencia de que no lo tiene en la lista de servidores conocidos, por lo que nos pide una confirmación, esto es importante ya que, en el caso de que hubiera un reemplazo del servidor la llave del servidor no correspondería y nos devolvería un error, lo normal es que simplemente inicie sesión sin mayor aviso. En la invocación del comando ssh le indicamos el login del usuario del otro servidor, el caracter arroba y el nombre del servidor o su dirección; si el login del usuario remoto es igual al local, no es necesario escribirlo, basta con el nombre del servidor.

Además de iniciar iniciar sesión es posible ejecutar en forma remota un comando de una forma similar a la del comando rsh:

hajarami@ubuntu:~$ ssh hajarami@solaris10 uname -a
SunOS solaris10 5.10 Generic_142901-12 i86pc i386 i86pc

Regularmente es muy sencillo, no es necesario crear una llave para el usuario remoto, en caso de problemas, se puede ejecutar el ssh con el parámetro –v para que muestre mensajes de “cómo va”.

Mañana les muestro cómo utilizar el ssh para enviar y recibir archivos.

Oracle anuncia el retiro de SunSolve

Si son usuarios de SunSolve como yo, seguramente ya recibieron o están por recibir la notificación de que se retira el sitio de Soporte Sun conocido como SunSolve.

Esto cómo lo debemos interpretar, yo no me considero fanático del software libre, de hecho, cuando me inicié en Solaris era un sistema cerrado, eso sí, con esquemas de licenciamiento mas “accesibles” que otros sistemas tales como HP-UX y AIX por mencionar algunos. Poco a poco, Sun fue “abriendo” a Solaris en un muy evidente intento de competir contra Linux (RedHat, SuSE) hasta que iniciaron el proyecto OpenSolaris con la licencia CDDL, fue entonces que esta plataforma se presentaba como una alternativa a Linux.

Desde que Oracle anunció la adquisición de Sun, al menos todos los administradores que conozco y yo mismo nos negamos a referirnos a “Oracle” como fabricante del sistema, probablemente en nuestras mentes ya aparecía como una visión lo que Oracle a revelado a lo largo de este año, su intención de convertir a Solaris en un producto similar a su Oracle Database, completamente cerrado, con esquemas de licenciamiento francamente voraces que ya no se conforman con el tipo de plataforma, el número de servidores y hasta el número de procesadores, sino que se van hasta el nivel de “cores” de procesador. Por lo que en mi opinión Solaris ya no puede ser una opción viable para pymes.

En fin mis amigos, tendremos que continuar y esta es una de las razones por las que escribo en este blog, debemos permanecer unidos como expertos en Unix para intercambiar nuestros conocimientos, por lo que espero poder seguir aportando aunque sea un “granito de arroz”.

martes, 12 de octubre de 2010

Uso del módulo SSL en Apache HTTP Server

Actualmente es considerado normal el realizar operaciones a través de internet en las que se intercambian datos de todo tipo, sin embargo, el protocolo http por si mismo no ofrece ningún tipo de blindaje ya que es posible obtener la información simplemente monitoreando las comunicaciones, por lo que es indispensable proteger los sitios en los que se ingresan datos mediante el uso del protocolo https, el cual, utiliza TLS/SSL para encriptar la comunicación, además de que se recurre a un certificado emitido por un CA para evitar el robo de identidad.

Para esta práctica requerimos un servidor Apache 2 con el módulo SSL activo, previamente vimos cómo instalarlo.

Lo primero que vamos a hacer es crear un certificado para pruebas empleando el OpenSSL, en un directorio vacío creamos los subdirectorios demoCA, demoCA/newcerts y demoCA/private:

mkdir demoCA
mkdir demoCA/newcerts
mkdir demoCA/private

También creamos el archivo vacío demoCA/index.txt y el archivo demoCA/serial con la cadena “01”:

touch demoCA/index.txt
echo 01 > demoCA/serial

Ahora creamos un certificado x509 autofirmado:

openssl genrsa -out demoCA/private/cakey.pem 1024
Generating RSA private key, 1024 bit long modulus
.........................++++++
...................++++++
e is 65537 (0x10001)
openssl req -new -key demoCA/private/cakey.pem -out demoCA/cacert.pem -x509
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:MX
State or Province Name (full name) [Some-State]:Queretaro
Locality Name (eg, city) []:Queretaro
Organization Name (eg, company) [Internet Widgits Pty Ltd]:unixymas
Organizational Unit Name (eg, section) []:unixymas
Common Name (eg, YOUR name) []:unixymas
Email Address []:webmaster@unixymas.com.mx

Ahora estamos listos para firmar una solicitud, vamos a crear una:

openssl genrsa -out key.pem 1024
Generating RSA private key, 1024 bit long modulus
.........++++++
..........................................++++++
e is 65537 (0x10001)
openssl req -new -key key.pem -out req.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:MX
State or Province Name (full name) [Some-State]:Queretaro
Locality Name (eg, city) []:Queretaro
Organization Name (eg, company) [Internet Widgits Pty Ltd]:unixymas
Organizational Unit Name (eg, section) []:unixymas
Common Name (eg, YOUR name) []:ubuntu.unixymas.com.mx
Email Address []:webmaster@unixymas.com.mx

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Observen que en “common name” escribí el nombre del sitio. Tal cual, esta solicitud podemos enviarla a un CA para adquirir un certificado, pero en este ejemplo vamos a firmarlo nosotros mismos:

openssl ca -in req.pem -key key.pem -out cert.pem
Using configuration from /usr/lib/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Oct 13 02:39:21 2010 GMT
            Not After : Oct 13 02:39:21 2011 GMT
        Subject:
            countryName               = MX
            stateOrProvinceName       = Queretaro
            organizationName          = unixymas
            organizationalUnitName    = unixymas
            commonName                = ubuntu.unixymas.com.mx
            emailAddress              = webmaster@unixymas.com.mx
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                8F:E6:90:EE:92:EA:C4:B7:FA:5D:EF:AC:ED:26:5D:6E:C9:BD:81:FE
            X509v3 Authority Key Identifier:
                keyid:DD:63:E9:44:86:7B:7B:E3:85:43:31:C2:6C:4D:A7:B0:7B:5C:4D:C9

Certificate is to be certified until Oct 13 02:39:21 2011 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Listo, ahora vamos a instalar este certificado en nuestro servidor, nos pasamos al directorio conf dentro del Apache, en mi caso, /usr/local/apache2/conf, y editamos el archivo httpd.conf, localizamos la línea #Include conf/extra/httpd-ssl.conf y le retiramos el signo de número, lo salvamos y copiamos el archivo certificado a server.crt y la llave a server.key:

cp cert.pem /usr/local/apache2/conf/server.crt
cp key.pem /usr/local/apache2/conf/server.key

Es muy importante que el archivo server.key tenga solo los atributos 600:

chmod 600 /usr/local/apache2/conf/server.key

Y listo, podemos probar desde un browser con la url: https://sitio

image

Es lógico que al principio presente errores por la falta de un certificado firmado por un CA reconocido, simplemente agregamos la excepción y listo.

image

jueves, 7 de octubre de 2010

Introducción al uso de contenedores en Solaris 10 (zonas)

Solaris 10 permite la virtualización por medio de contenedores también llamados zonas. Cada uno de estos contenedores actúa como un servidor Solaris (ó Linux) autónomo, para lo cual, el sistema comparte recursos e inclusive puede reservarlos para el uso exclusivo de determinados contenedores, en este ejercicio vamos a ver una forma básica de cómo crear un equipo virtual y cómo trabajar con él.

Pará qué nos sirve una máquina virtual, se preguntaran algunos, un escenario podría ser que necesitemos correr varias instancias de una aplicación pequeña (un servidor web, por ejemplo) y no vale la pena tener varias máquinas pequeñas para esto. Otro que se me ocurre en para implementar un esquema DRP, en el cual, en caso de un desastre, se movería solo el contenedor a otro equipo.

Para una instalación muy básica necesitamos no menos de 700Mb de espacio en disco y una dirección IP libre y válida para la NIC que vamos a utilizar. Si solo tenemos una conexión a red esa NIC funciona perfectamente, el contenedor va a dar de alta una dirección virtual en ese caso.

En mi caso voy a utilizar el filesystem /export/home y la IP que voy a utilizar es la 192.168.188.34 para la NIC e1000g0.

La instalación se realiza en dos etapas, la primera es crear la configuración de la zona y la segunda es su instalación, iniciamos entonces la creación de la configuración de la siguiente forma:

# zonecfg -z zona1
zona1: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:zona1> create
zonecfg:zona1> set zonepath=/export/home/zonas/zona1
zonecfg:zona1> add net
zonecfg:zona1:net> set address=192.168.188.34
zonecfg:zona1:net> set physical=e1000g0
zonecfg:zona1:net> set defrouter=192.168.188.2
zonecfg:zona1:net> end
zonecfg:zona1> commit
zonecfg:zona1> exit

Al comando zonecfg se le indica el nombre de la zona con el parámetro –z, el nombre que elegí fue zona1, entramos al modo interactivo y lo primero que nos indica es que la zona es “nueva” y debemos darle el comando create. Después de esto con set zonepath=/export/home/zonas/zona1 le indico directorio en el que va a estar físicamente los datos de la zona, podría decirse que este directorio va a tener la función de disco duro virtual. A continuación le indicamos que dé de alta una interfaz de red virtual con add net; con set address=192.168.188.34 le indicamos la dirección IP que va a utilizar; con set physical=e1000g0 la NIC real que va a utilizar, si ya existen una dirección IP configurada, va a dar de alta la de la zona como virtual; con set defrouter=192.168,188.2 le indico la IP del gateway; salimos de la configuración de red con end y con commit le decimos que guarde la configuración, finalmente salimos con exit.

Ahora instalamos la zona:

# zoneadm -z zona1 install
Preparing to install zone <zona1>.
Creating list of files to copy from the global zone.
Copying <8783> files to the zone.
Initializing zone product registry.
Determining zone package initialization order.
Preparing to initialize <1244> packages on the zone.
Initialized <1244> packages on zone.
Zone <zona1> is initialized.
The file </export/home/zonas/zona1/root/var/sadm/system/logs/install_log> contains a log of the zone installation.

Este comando tarda en procesar algunos minutos. Ya concluido, estamos listos para “bootear” a nuestro contenedor, primero vamos a “loguearnos” en la consola del contenedor:

# zlogin -C zona1
[Connected to zone 'zona1' console]

Desde otra sesión iniciamos el “booteo” del contenedor:

# zoneadm -z zona1 boot

Vamos a observar como inicia el proceso de inicio de sistema en la consola:

[NOTICE: Zone booting up]

SunOS Release 5.10 Version Generic_142901-12 64-bit
Copyright 1983-2010 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
Hostname: zona1
Loading smf(5) service descriptions:  31/153

Select a Language

  0. English
  1. es
  2. fr

Please make a choice (0 - 2), or press h or ? for help:

Como es la primera vez que “bootea” requiere lo configuremos como si se tratara de un servidor recién instalado, entre otras cosas, nos va a pedir un nombre, la configuración regional, el dns y concluido esto, va a reiniciar en forma nomal:

System identification is completed.

rebooting system due to change(s) in /etc/default/init

[NOTICE: Zone rebooting]

SunOS Release 5.10 Version Generic_142901-12 64-bit
Copyright 1983-2010 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
Hostname: zona1
Reading ZFS config: done.

zona1 console login:

Puedo salir de la consola escribiendo ~.

Listo, ya tenemos un contenedor corriendo, podemos entrar a él con zlogin o directamente por medio de su IP con ssh o con telnet (inclusive con XDMCP).

Este es el contenedor más básico que podemos crear, es posible indicarle filesystems, asociarlos con pools zfs, utilizar recursos dedicados al contenedor, etc. Inclusive en el caso de Solaris 10 en SPARC, se pueden utilizar contenedores Solaris 8 y 9, en Solaris 10 en x86 se pueden crear contenedores Linux (SUSE, RedHat y CentOS).

martes, 5 de octubre de 2010

Activar el uso de sesiones gráficas remotas en Solaris 10 (XDMCP)

Esta es la forma de permitir el uso de sesiones gráficas remotas a un servidor Solaris 10 que fue instalado dándole “si” a la opción de cerrar servicios remotos.

En un servidor así, solo se permite el inicio de sesiones gráficas desde la consola, pero si es necesario el poder iniciar sesión desde otras estaciones de trabajo, lo que debemos hacer es activar al administrador de sesiones para que permita la conexión remota.

Esta sesión remota se logra mediante el protocolo XDMCP, el cual, utiliza el puerto 177 UDP, este servicio lo proporciona el cde-login, por lo que vamos a realizar una modificación en este servicio utilizando el comando svccfg:

svccfg -s cde-login

Al ejecutar este comando vamos a entrar a “una consola” que nos permitirá modificar los atributos del servicio, ejecutamos lo siguiente:

svc:/application/graphical-login/cde-login> setprop dtlogin/args = astring: ""
svc:/application/graphical-login/cde-login> end

Después, le indicamos al servicio que vuelva a “leer” sus atributos y que reinicie:

svcadm refresh cde-login
svcadm restart cde-login

Por último, vamos a activar el servidor de fuentes, el cual, es necesario para algunos servidores X.

svcadm enable xfs

image

lunes, 4 de octubre de 2010

Crear un volumen con LVM en Linux

El LVM se ha convertido en el administrador de volúmenes más popular en las distros Linux debido a que nos facilita mucho tareas como extender el tamaño de los volúmenes, concatenar discos y todo esto con una licencia GNU, por lo que el ahorro en licencias de software privativo (por ejemplo: Veritas Storage Foundation) es muy significativo, lamentablemente no cuenta con una forma de definir arreglos RAID, por lo que en un ambiente de alta disponibilidad, se recomienda el uso de arreglos físicos.

Para este ejemplo voy a cambiar de distro y voy a ocupar Fedora 13, voy a empezar con agregar un disco nuevo, el cual, fue reconocido por el sistema con el dispositivo /dev/sdb (noten que en Linux, el uso de dispositivo “raw” no aplica, solo por bloques).

El LVM se compone de tres capas, el volumen físico (PV), el cuál, es una partición o un disco completo cedido al LVM; el grupo de volúmes (VG), es una agrupación de uno o más PV’s, y finalmente, el volumen lógico (LV), es una parte de un VG que contiene un filesystem o forma parte del swap.

Voy a crear un PV utilizando el total del disco nuevo:

pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created

Ahora el VG:

vgcreate vg_appl /dev/sdb
  Volume group "vg_appl" successfully created

Y continuamos con el LV:

[root@fedora ~]# lvcreate -n apache -L 10G vg_appl
  Logical volume "apache" created

Ya que tenemos listo nuestro LV, (para el cuál, creó el dispositivo /dev/vg_appl/apache) vamos a crearle un filesystem, voy a crearlo tipo ext4 que es el que utiliza por default esta distro:

mkfs.ext4 /dev/vg_appl/apache
mke2fs 1.41.10 (10-Feb-2009)
Etiqueta del sistema de ficheros=
Tipo de SO: Linux
Tamaño del bloque=4096 (bitácora=2)
Tamaño del fragmento=4096 (bitácora=2)
Stride=0 blocks, Stripe width=0 blocks
655360 nodos-i, 2621440 bloques
131072 bloques (5.00%) reservados para el superusuario
Primer bloque de datos=0
Número máximo de bloques del sistema de ficheros=2684354560
80 bloque de grupos
32768 bloques por grupo, 32768 fragmentos por grupo
8192 nodos-i por grupo
Respaldo del superbloque guardado en los bloques:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Escribiendo las tablas de nodos-i: hecho
Creating journal (32768 blocks): hecho
Escribiendo superbloques y la información contable del sistema de ficheros: hecho

Este sistema de ficheros se revisará automáticamente cada 38 montajes o
180 días, lo que suceda primero.  Utilice tune2fs -c o -i para cambiarlo.

En mi caso, no necesito que le dé un fsck cada 38 montajes, por lo que voy a seguir la recomendación y voy a cambiarlo:

tune2fs -c -1 -i 0 /dev/vg_appl/apache
tune2fs 1.41.10 (10-Feb-2009)
Se pone la cuenta de montajes máxima a -1
Se pone el intervalo entre revisiones en 0 segundos

Lo monto:

mkdir /apache
mount -t ext4 /dev/vg_appl/apache /apache

Reviso que este correcto:

df -h
S.ficheros            Size  Used Avail Use% Montado en
/dev/mapper/vg_fedora-lv_root
                      2.9G  747M  2.2G  26% /
tmpfs                 502M  208K  502M   1% /dev/shm
/dev/sda1             291M   60M  217M  22% /boot
/dev/mapper/vg_fedora-lv_home
                      2.9G  1.1G  1.8G  37% /home
/dev/mapper/vg_fedora-lv_opt
                      2.0G  930M  954M  50% /opt
/dev/mapper/vg_fedora-lv_usr
                      3.9G  2.8G  922M  76% /usr
/dev/mapper/vg_fedora-lv_var
                      2.0G  320M  1.6G  17% /var
/dev/mapper/vg_appl-apache
                      9.9G  151M  9.2G   2% /apache

Observen que el dispositivo asociado a mi filesystem es un mapa, el cual, vamos a utilizarlo para definir en el archivo /etc/fstab a este filesystem para que lo monte en forma automática. Agregamos la siguiente línea:

/dev/mapper/vg_appl-apache      /apache ext4    defaults        1 2

Y listo, tenemos un nuevo filesystem sobre LVM.

Una ventaja de utilizar un filesystem ext3 o ext4 para este volumen es que es posible extender su tamaño si se requiere alguna vez, también se puede reducir, pero esto no es recomendado ya que puede haber perdida de datos, suponiendo que queremos crecer el filesystem a 15Gb.

lvextend -L +5G -r /dev/vg_appl/apache
fsck from util-linux-ng 2.17.2
e2fsck 1.41.10 (10-Feb-2009)
/dev/mapper/vg_appl-apache está montado.

¡¡ATENCIÓN!!  Ejecutar e2fsck en un sistema de ficheros montado
puede causar GRAVES daños al sistema de ficheros.

¿De verdad quiere continuar? (s/n)? si

/dev/mapper/vg_appl-apache: recuperando el fichero de transacciones
/dev/mapper/vg_appl-apache: limpio, 11/655360 ficheros, 79663/2621440 bloques
  Extending logical volume apache to 15.00 GiB
  Logical volume apache successfully resized
resize2fs 1.41.10 (10-Feb-2009)
Filesystem at /dev/dm-2 is mounted on /apache; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/dm-2 to 3932160 (4k) blocks.
El sistema de ficheros en /dev/dm-2 tiene ahora 3932160 bloques.

domingo, 3 de octubre de 2010

Migración de sistema basado en UFS a ZFS en Solaris 10

En la entrada anterior vimos a grandes rasgos, cómo crear un ZFS y mencioné algunas de sus ventajas con respecto al tradicional UFS. En esta ocasión vamos a ver cómo migrar nuestro sistema montado sobre UFS a ZFS.

Para esto requiero un disco libre, en el cual, voy a crear el pool que va a contener el sistema, en mi caso, estoy utilizando Solaris 10 en x86, por lo que debo inicializar el disco con fdisk:

fdisk c1t1d0p0
No fdisk table exists. The default partition for the disk is:

  a 100% "SOLARIS System" partition

Type "y" to accept the default partition,  otherwise type "n" to edit the
partition table.
y

Creo una partición:

format
Searching for disks...done

AVAILABLE DISK SELECTIONS:
       0. c1t0d0 <DEFAULT cyl 2607 alt 2 hd 255 sec 63>
          /pci@0,0/pci15ad,1976@10/sd@0,0
       1. c1t1d0 <DEFAULT cyl 2607 alt 2 hd 255 sec 63>
          /pci@0,0/pci15ad,1976@10/sd@1,0
Specify disk (enter its number): 1
selecting c1t1d0
[disk formatted]

FORMAT MENU:
        disk       - select a disk
        type       - select (define) a disk type
        partition  - select (define) a partition table
        current    - describe the current disk
        format     - format and analyze the disk
        fdisk      - run the fdisk program
        repair     - repair a defective sector
        label      - write label to the disk
        analyze    - surface analysis
        defect     - defect list management
        backup     - search for backup labels
        verify     - read and display labels
        save       - save new disk/partition definitions
        inquiry    - show vendor, product and revision
        volname    - set 8-character volume name
        !<cmd>     - execute <cmd>, then return
        quit
format> p

PARTITION MENU:
        0      - change `0' partition
        1      - change `1' partition
        2      - change `2' partition
        3      - change `3' partition
        4      - change `4' partition
        5      - change `5' partition
        6      - change `6' partition
        7      - change `7' partition
        select - select a predefined table
        modify - modify a predefined partition table
        name   - name the current table
        print  - display the current table
        label  - write partition map and label to the disk
        !<cmd> - execute <cmd>, then return
        quit
partition> p
Current partition table (original):
Total disk cylinders available: 2607 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders        Size            Blocks
  0 unassigned    wm       0               0         (0/0/0)           0
  1 unassigned    wm       0               0         (0/0/0)           0
  2     backup    wu       0 - 2606       19.97GB    (2607/0/0) 41881455
  3 unassigned    wm       0               0         (0/0/0)           0
  4 unassigned    wm       0               0         (0/0/0)           0
  5 unassigned    wm       0               0         (0/0/0)           0
  6 unassigned    wm       0               0         (0/0/0)           0
  7 unassigned    wm       0               0         (0/0/0)           0
  8       boot    wu       0 -    0        7.84MB    (1/0/0)       16065
  9 unassigned    wm       0               0         (0/0/0)           0

partition> 0
Part      Tag    Flag     Cylinders        Size            Blocks
  0 unassigned    wm       0               0         (0/0/0)           0

Enter partition id tag[unassigned]:
Enter partition permission flags[wm]:
Enter new starting cyl[0]: 1
Enter partition size[0b, 0c, 1e, 0.00mb, 0.00gb]: 2606e
partition> p
Current partition table (unnamed):
Total disk cylinders available: 2607 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders        Size            Blocks
  0 unassigned    wm       1 - 2606       19.96GB    (2606/0/0) 41865390
  1 unassigned    wm       0               0         (0/0/0)           0
  2     backup    wu       0 - 2606       19.97GB    (2607/0/0) 41881455
  3 unassigned    wm       0               0         (0/0/0)           0
  4 unassigned    wm       0               0         (0/0/0)           0
  5 unassigned    wm       0               0         (0/0/0)           0
  6 unassigned    wm       0               0         (0/0/0)           0
  7 unassigned    wm       0               0         (0/0/0)           0
  8       boot    wu       0 -    0        7.84MB    (1/0/0)       16065
  9 unassigned    wm       0               0         (0/0/0)           0

partition> label
Ready to label disk, continue? y

partition> q

FORMAT MENU:
        disk       - select a disk
        type       - select (define) a disk type
        partition  - select (define) a partition table
        current    - describe the current disk
        format     - format and analyze the disk
        fdisk      - run the fdisk program
        repair     - repair a defective sector
        label      - write label to the disk
        analyze    - surface analysis
        defect     - defect list management
        backup     - search for backup labels
        verify     - read and display labels
        save       - save new disk/partition definitions
        inquiry    - show vendor, product and revision
        volname    - set 8-character volume name
        !<cmd>     - execute <cmd>, then return
        quit
format> q

Como va a contener el sistema operativo debo hacerlo booteable:

fdisk -b /usr/lib/fs/ufs/mboot /dev/rdsk/c1t1d0p0
             Total disk size is 2610 cylinders
             Cylinder size is 16065 (512 byte) blocks

                                               Cylinders
      Partition   Status    Type          Start   End   Length    %
      =========   ======    ============  =====   ===   ======   ===
          1       Active    Solaris2          1  2609    2609    100

SELECT ONE OF THE FOLLOWING:
   1. Create a partition
   2. Specify the active partition
   3. Delete a partition
   4. Change between Solaris and Solaris2 Partition IDs
   5. Exit (update disk configuration and exit)
   6. Cancel (exit without updating disk configuration)
Enter Selection: 5

installgrub /boot/grub/stage1 /boot/grub/stage2 /dev/rdsk/c1t1d0s0
stage1 written to partition 0 sector 0 (abs 16065)
stage2 written to partition 0, 272 sectors starting at 50 (abs 16115)

Creamos el pool:

zpool create rpool c1t1d0s0

Ahora vamos a utilizar el Live Upgrade para iniciar esta migración, lo primero es crear un ambiente de booteo (Boot Environment) utilizando el comando lucreate:

lucreate -c BE_ufs_1009 -n BE_zfs_1009 -p rpool

Estos parámetros indican lo siguiente:

  • -c BE_ufs_1009: Es una identificación con la que vamos a nombrar el ambiente actual, es completamente a discreción. Para esta denominación en particular, estoy utilizando una muy común, BE es por boot environment, ufs por el sistema de archivo actual y 1009 por el release de Solaris.
  • -n BE_zfs_1009: Es la identificación del nuevo ambiente.
  • -p rpool: El pool que va a contener el nuevo ambiente.

Lo ejecutamos, van a aparecer algunos errores y advertencias que tienen que ver con el hecho de que es la primera vez que estamos definiendo ambiente de booteo.

Una vez concluido este proceso, revisamos los ambientes de booteo con lustatus:

lustatus
Boot Environment           Is       Active Active    Can    Copy
Name                       Complete Now    On Reboot Delete Status
-------------------------- -------- ------ --------- ------ ----------
BE_ufs_1009                yes      yes    yes       no     -
BE_zfs_1009                yes      no     no        yes    -

Observen que el ambiente zfs aparece como completo, es muy importante que tenga este estatus. Ahora vamos a activar el nuevo ambiente con luactivate:

luactivate BE_zfs_1009
Generating boot-sign, partition and slice information for PBE <BE_ufs_1009>
A Live Upgrade Sync operation will be performed on startup of boot environment <BE_zfs_1009>.

Generating boot-sign for ABE <BE_zfs_1009>
NOTE: File </etc/bootsign> not found in top level dataset for BE <BE_zfs_1009>
Generating partition and slice information for ABE <BE_zfs_1009>
Boot menu exists.
Generating multiboot menu entries for PBE.
Generating multiboot menu entries for ABE.
Disabling splashimage
Re-enabling splashimage
No more bootadm entries. Deletion of bootadm entries is complete.
GRUB menu default setting is unaffected
Done eliding bootadm entries.

**********************************************************************

The target boot environment has been activated. It will be used when you
reboot. NOTE: You MUST NOT USE the reboot, halt, or uadmin commands. You
MUST USE either the init or the shutdown command when you reboot. If you
do not use either init or shutdown, the system will not boot using the
target BE.

**********************************************************************

In case of a failure while booting to the target BE, the following process
needs to be followed to fallback to the currently working boot environment:

1. Boot from the Solaris failsafe or boot in Single User mode from Solaris
Install CD or Network.

2. Mount the Parent boot environment root slice to some directory (like
/mnt). You can use the following command to mount:

     mount -Fufs /dev/dsk/c1t0d0s0 /mnt

3. Run <luactivate> utility with out any arguments from the Parent boot
environment root slice, as shown below:

     /mnt/sbin/luactivate

4. luactivate, activates the previous working boot environment and
indicates the result.

5. Exit Single User mode and reboot the machine.

**********************************************************************

Modifying boot archive service
Propagating findroot GRUB for menu conversion.
File </etc/lu/installgrub.findroot> propagation successful
File </etc/lu/stage1.findroot> propagation successful
File </etc/lu/stage2.findroot> propagation successful
File </etc/lu/GRUB_capability> propagation successful
Deleting stale GRUB loader from all BEs.
File </etc/lu/installgrub.latest> deletion successful
File </etc/lu/stage1.latest> deletion successful
File </etc/lu/stage2.latest> deletion successful
Activation of boot environment <BE_zfs_1009> successful.

Aparecen otros errores y advertencias e incluside nos da indicaciones de qué hacer en caso de falla, reiniciamos el sistema operativo:

shutdown -i6 -g0 –y

En el menú del GRUB elegimos la opción que corresponde a nuestro ambiente de booteo y de no ocurrir ningún error deberá iniciar el sistema operativo en forma correcta. Si observamos a los filesystem montados observamos lo siguiente:

df -h
Filesystem             size   used  avail capacity  Mounted on
rpool/ROOT/BE_zfs_1009
                        20G   4.1G    13G    24%    /
/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                   2.3G   348K   2.3G     1%    /etc/svc/volatile
objfs                    0K     0K     0K     0%    /system/object
sharefs                  0K     0K     0K     0%    /etc/dfs/sharetab
/usr/lib/libc/libc_hwcap1.so.1
                        17G   4.1G    13G    24%    /lib/libc.so.1
fd                       0K     0K     0K     0%    /dev/fd
swap                   2.3G    40K   2.3G     1%    /tmp
swap                   2.3G    24K   2.3G     1%    /var/run
/dev/dsk/c1t0d0s5      2.9G   3.0M   2.9G     1%    /export/home
rpool                   20G    35K    13G     1%    /rpool
rpool/ROOT              20G    21K    13G     1%    /rpool/ROOT

Sólo aparece /export/home en UFS, lo migramos en forma manual:

umount /export/home
rmdir /export/home
zfs create -o mountpoint=/export/home rpool/home
cd /export/home
ufsdump 0cf - /dev/dsk/c1t0d0s5 | ufsrestore rf -

Eliminamos del vfstab la línea que corresponde al /export/home y listo, ya podemos eliminar el ambiente de booteo anterior:

ludelete -f BE_ufs_1009

Nuevamente reiniciamos sistema operativo y comprobamos que inicie sin problemas.

Con esto queda como concluida la migración a ZFS, aprovechando que me queda un disco duro libre, voy a “espejear” mi sistema, es muy sencillo, por medio del comando format, borro todas las particiones del disco que quedo libre (disco 0) y creo una con todo el espacio disponible, después, la agrego al pool de datos:

zpool attach -f rpool c1t1d0s0 c1t0d0s0

Y como punto final, reinstalamos el grub en c1t0d0s0:

installgrub /boot/grub/stage1 /boot/grub/stage2 /dev/rdsk/c1t0d0s0

Podemos monitorear el progreso de sincronización con zpool status:

zpool status
  pool: rpool
state: ONLINE
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scrub: resilver in progress for 0h4m, 48.94% done, 0h4m to go
config:

        NAME          STATE     READ WRITE CKSUM
        rpool         ONLINE       0     0     0
          mirror      ONLINE       0     0     0
            c1t1d0s0  ONLINE       0     0     0
            c1t0d0s0  ONLINE       0     0     0  2.23G resilvered

errors: No known data errors