balancing y failover

20 de enero de 2010

Tengo hasta 5 conexiones de salida a Internet, entre caudales garantizados, ADSL, SDSL, etc.
La idea es centralizar todas estas salidas bajo un único gateway de forma que podamos hacer balanceo de carga y failover. Con el balanceo de carga conseguimos que unas peticiones vayan por una línea y otras por otra de forma automática y transparente para el usuario. Con el failover conseguimos que en caso de caída de una conexión de salida, todo el tráfico continuará saliendo por otra conexión.
Hay que tener presente que esta solución no hace una suma de anchos de banda, simplemente reparte las peticiones sobre una u otra conexión.

En el siguiente ejemplo utilizaremos dos conexiones a Internet ADSL, las dos de 6Mb. Utilizaremos una maquina Linux con tres interfaces Ethernet. Una conectada a una ADSL, otra conectada a otra ADSL y por último una interfaz conectada a nuestra red interna. Esta máquina hará de gateway de todos nuestros usuarios de la red interna.

En vez de utilizar una ruta por defecto, configuraremos una ruta por defecto que es multicamino o "multi-path route". Por defecto el kernel equilibrará las rutas sobre los dos posibles proveedores.


Para realizar balanceo utilizaremos iproute y para realizar el failover utilizaremos el siguiente script gwping que es un daemon (escrito en bash) que lo que hace es comprobar cada cierto tiempo el estado de la línea. Si la línea cae automáticamente realiza el switch. Cuando las dos líneas están activas continua haciendo el balancing.

Lo primero que hacemos es añadir estas instrucciones dentro de nuestro /etc/rc.local:

# activamos el forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# le decimos que todos los paquetes que vienen por una ADSL vuelven por la misma.
ip route add 192.168.1.0/24 dev eth0 src 192.168.1.10 table ADSL1
ip route add default via 192.168.1.1 table ADSL1
ip route add 192.168.0.0/24 dev eth1 src 192.168.0.10 table ADSL2
ip route add default via 192.168.0.1 table ADSL2
ip rule add from 192.168.1.10 table ADSL1
ip rule add from 192.168.0.10 table ADSL2

# la carga se reparte (equitativamente) por diferentes gateway.
ip route add default scope global nexthop via 192.168.1.1 dev eth0 weight 1 
   nexthop via 192.168.0.1 dev eth1 weight 1

# activamos el nat en el gateway
iptables -F
iptables -t nat -F
iptables --delete-chain
iptables -t nat --delete-chain
iptables -t nat -A POSTROUTING --out-interface eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING --out-interface eth0 -j MASQUERADE
iptables -A INPUT -p ICMP -j ACCEPT
iptables -A INPUT -p TCP -m state --state RELATED -j ACCEPT
iptables -A FORWARD --in-interface eth2 -j ACCEPT

nohup /usr/sbin/gwping &
Observar como se utiliza el parámetro “weight” para decir que las dos adsl tienen la misma importancia. Tienen la misma velocidad. Si tuviéramos una ADSL 4 veces más rápida que otra pondríamos algo como:
ip route add default scope global nexthop via 192.168.1.1 dev eth0 weight 1 
   nexthop via 192.168.0.1 dev eth1 weight 4
El siguiente paso es añadir las tablas ADSL1 y ADSL2 dentro del iproute. Para ello editamos el /etc/iptables2/rt_tables:
root@failover:~# cat /etc/iproute2/rt_tables 
255     local
254     main
253     default
0       unspec
1 ADSL1
2 ADSL2
Ahora copiamos nuestro script gwping a /usr/sbin y le damos permisos de ejecución:
# chmod 755 /usr/sbin/gwping
Si editamos el script gwping podemos configurar los primeros parámetros para ajustarlos a nuestra configuración.

+ EXTIF1 y EXTIF: nombre de la interfaces externas
+ IP1 e IP2: IP de las interfaces
+GW1 y GW2: IP de las ADSLs
+ W1 y W2: peso de cada una de las ADSLs
+ NAME1 y NAME2: nombre de las ADSLs

Una vez reiniciada la maquina debería correr en fondo el daemon gwping (ps –xa | grep gwping). Para comprobar que todo está funcionando debería crearse un fichero de log llamado /var/log/failover donde es posible comprobar como se va realizando el switch entre las ADSLs:
root@failover:/var/log# tail -f failover 
Ping status changed for ADSL2 from 1 to 0
Uptime status will be changed for ADSL1 from 1
Uptime status will be changed for ADSL2 from 1
Restoring default load balancing
ADSL2 Down
Ping status changed for ADSL2 from 0 to 1
Uptime status will be changed for ADSL2 from 0
Ping status changed for ADSL2 from 1 to 0
Uptime status will be changed for ADSL2 from 1
Restoring default load balancing
ADSL1 Down
Ping status changed for ADSL1 from 0 to 1
Uptime status will be changed for ADSL1 from 0
Switching to ADSL2
ADSL1 Down
ADSL1 Down
Ping status changed for ADSL1 from 1 to 0
Uptime status will be changed for ADSL1 from 1
Restoring default load balancing
ADSL1 Down
Para comprobar que todo funciona podéis hacer diferentes consultas desde diferentes usuarios de la red interna a paginas web como http://www.whatismyip.com y comprobar vosotros mismos como se obtienen IPs diferentes dependiendo de si la petición HTTP ha ido por una ADSL u otra.

Más información:
+ Routing por diferentes proveedores
+ Linux Advanced Routing & Traffic Control HOWTO

squid y mrtg

16 de enero de 2010

El proxy de Squid nos permite generar gráficas desde cualquier aplicación o cliente SNMP. Para ello simplemente debemos activar el servicio de SNMP en el Squid y comenzar a realizar consultas para saber que carga o uso tiene.
Para ello editamos el /etc/squid/squid.conf y añadimos las siguientes líneas:

# creamos una acl donde le decimos el nombre de la comunidad SNMP que utilizamos
acl snmppublic snmp_community public
# por defecto utilizaremos el puerto 3401/UDP para las consultas
snmp_port 3401
# aplicamos la ACL para que solo la maquina local pueda realizar consultas
snmp_access allow snmppublic localhost
snmp_access deny all
Una vez configurado hacemos un reload de la config:
# /etc/init.d/squid reload
Ahora probamos con el comando snmpwalk si tenemos acceso al servicio SNMP de Squid:
# snmpwalk –c public -v 1 localhost:3401 .1.3.6.1.4.1.3495.1.1                            
SNMPv2-SMI::enterprises.3495.1.1.1.0 = INTEGER: 65552
SNMPv2-SMI::enterprises.3495.1.1.2.0 = INTEGER: 6288060
SNMPv2-SMI::enterprises.3495.1.1.3.0 = Timeticks: (129933578) 15 days, 0:55:35.78
Instalamos la herramienta de MRTG (Multi Router Traffic Grapher) que nos permitirá realizar gráficos del uso de Squid. MRTG generará una página Web cada 5 minutos con los datos. Para ello necesitaremos tener también Apache:
# apt-get install mrtg apache
Creamos el fichero de configuración del MRTG para generar dos tipos de gráficos diferentes:
ImageDir: /var/www/mrtg-squid
Workdir: /var/www/mrtg-squid
LoadMIBS: /etc/squid/mib.txt

Target[proxy-hit]: cacheHttpHits&cacheServerRequests:public@127.0.0.1:3401
MaxBytes[proxy-hit]: 100000
Title[proxy-hit]: HTTP Hits
PageTop[proxy-hit]: <H2>proxy Cache Statistics: HTTP Hits/Requests</H2>
Suppress[proxy-hit]: y
LegendI[proxy-hit]:  HTTP hits
LegendO[proxy-hit]:  HTTP requests
Legend1[proxy-hit]:  HTTP hits
Legend2[proxy-hit]:  HTTP requests
YLegend[proxy-hit]: perminute
ShortLegend[proxy-hit]: req/min
Options[proxy-hit]: nopercent, perminute, dorelpercent, unknaszero, growright

Target[proxy-srvkbinout]: cacheServerInKb&cacheServerOutKb:public@127.0.0.1:3401
MaxBytes[proxy-srvkbinout]: 76800
Title[proxy-srvkbinout]: Cache Server Traffic In/Out
PageTop[proxy-srvkbinout]: <H2>Cache Statistics: Server traffic volume (In/Out)</H2>
Options[proxy-srvkbinout]: growright
Tanto las paginas Web como los datos de las estadísticas generados por MRTG se guardaran en /var/www/mrtg-squid. Si no existe la carpeta habrá que crearla.
Por otro lado necesitaremos el archivo /etc/squid/mib.txt donde se especifican los objetos que se deben monitorizar dentro de Squid. Se puede descargar de los archivos fuentes del Squid o de aquí.

Ahora solo hace falta ejecutar el MRTG cada 5 minutos. Para ello editamos el /etc/crontab y añadimos la siguiente línea:
0,5,10,15,20,25,30,35,40,45,50,55 * * * * root LANG=C /usr/bin/mrtg 
   /etc/squid/mrtg-squid.conf --debug="cfg"
Al cabo de unas horas ya podrás apreciar el uso de tú Squid. Al leer los gráficos del MRTG es muy importante saber bajo que velocidad está generado el gráfico para poder compararlo por ejemplo con el gráfico de tú conexión a Internet. En este caso el gráfico “Squid volum traffic” está en KB/s (Kilobytes por segundo).


Podrás acceder a dos tipos de gráficos: el “http Hits and request” (http:///mrtg-squid/proxy-hit.html) y el “Squid traffic volumn” (http:///mrtg-squid/proxy-srvkbinout.html).

El segundo de ellos indica en KB/s el volumen de datos que entran y salen del Squid. Para interpretar el primero de ellos debemos tener claro las diferencia entre “http request” y “http hits”. Las “http request” son las peticiones http que realizan los clientes. Las “http hits” son las peticiones servidas por el proxy o más concretamente servidas por la cache del proxy. Es decir, contra más se parezcan los “http request” a los “http hits” mejor está funcionando el proxy porque eso quiere decir que el cliente a pedido una pagina Web que el proxy tenía cacheada.
Existe otro parámetro que es el “percentage” que indica el porcentaje de acierto del proxy. Un porcentaje alto indica que todas las paginas que van pidiendo los usuarios están ya cacheadas por el proxy.

Más información:
+ Configuración de un proxy transparente
+ SQUID and MRTG: to SNMP or not SNMP?

un miniserver con una fonera

1 de enero de 2010

Hace unos dias que me calló una Fonera 2.0n y no sé muy bien para que. Para el que no sepa que es una Fonera no es más que un access-point bajo Linux al que se le han añadido servicios. La idea es formar una comunidad de Foneros repartidos por todo el mundo de forma que los Foneros compartan una porción de su ancho de banda de conexión a Internet para que otros puedan utilizarlo.

Puedes encontrar un punto de acceso Fon en el mapa oficial de la comunidad: http://maps.fon.com/

Actualmente hay dos Foneras access-points: la Fonera 2n (la más completa) y la Fonera+ (la básica).

Después de trastearla y jugar con ella he decido deshabilitar la Wifi y utilizarla solo de servidor de descargas para bajar ficheros y torrents. La Fonera 2n, a parte de ser access-point (no es un router que elimina la necesidad de nuestra router-ADSL) contiene toda una interfaz Web para administrar torrents, el Facebook, descarga de archivos, el Youtube, el Flicker, etc. Dado que se trata de un aparato muy pequeño es ideal para dejarlo todo el dia encendido bajando cosas. Además tiene la posibilidad de añadirle una llave o disco USB para ir dejando todo lo que estemos bajando.


Estos son los pasos para convertir tú Fonera en un servidor de descargas:

+ Una vez instalada la Fonera y funcionando tal como indica “La guía de instalación rápida” lo que haremos es actualizar el firmware a una versión Developer. La versión Developer permite tener el puerto SSH de la Fonera abierto y poder trastear por su interior. Mi fonera tenía la 2.2.6_ENDUSER y le he puesto la versión 2.3_DEV. Para actualizarla hay que hacer: Panel de control -> Configuración -> Sistema -> Actualizacion Firmware

Para acceder a la configuración Web cargaremos la pagina https://192.168.10.1 una vez que nos hemos conectado al SSID de administración "MyPlace".

+ Cuando tenemos la Fonera con la ultima firmware podemos deshabilitar la compartición libre de nuestra Wifi o el SSID FON_FREE_INTERNET. Haremos: Panel de control -> Configuración -> Fon Spot.
En esto de las Foneras hay dos SSID: uno publico (FON_FREE_INTERNET), que lo acabamos de desactivar y el otro privado (MyPlace) que debe desactivarse por hardware con el interruptor situado detrás de la Fonera.
Una vez hecho esto la Fonera será como otro PC conectado a nuestra red LAN.

Al desconectar las interfaces Wifi debemos acceder directamente vía interfaz Ethernet. Por defecto esta interfaz se configura por DHCP pero desde Panel de control -> Configuración -> Internet es posible asignar una IP a la tarjeta de red de la Fonera. Por ejemplo 192.168.1.99.

+ Ahora lo que tenemos que hacer es activar todos los servicios de administración (Web GUI, SSH, FTP, etc) para que sean accedidos desde nuestro PC de la LAN. Por defecto todos estos servicios solo están disponibles si nos conectamos vía SSID privado, pero lo que queremos es que estén disponibles desde fuera de la Fonera. Para activarlos haremos: Panel de control -> Configuración -> Firewall -> Aplicaciones

Una vez activados todos los servicios deberíamos poder acceder a la Fonera desde nuestra LAN con un https://192.168.1.99.

+ Necesitaremos también un disco o llave USB para las descargas. Una vez introducido, los iconos “Disco USB” y “Navegación de archivos” ya estarán disponibles.

+ Por ultimo solo queda ir al Gestor de descargas o Torrents para controlar nuestras descargas. Para acceder a nuestras descargas podemos ir por carpeta compartida \\192.168.1.99\media con el usuario "fonero" y el password que hayamos puesto durante la instalación.



Nota: al igual que hemos conectado un disco USB, tambien es posible conectar una webcam o una impresora.

Más información:
+ Wiki Fonera 2n

un dia en la oficina con el axis 207mw

29 de diciembre de 2009

keepass

27 de diciembre de 2009

Cuando tienes más de 100 passwords para administrar se hace necesaria una herramienta de administración de password muy portable. Portable para Windows, portable para Linux, portable para la Blackberry o portable el iPhone. Cada uno de los técnicos accede a los passwords de una manera diferente.

Necesitamos por tanto que sea multiplataforma y multi-dispositivo. Que encripte lógicamente la información, que permita hacer grupos de password (servidores, access points, switches, etc), que permita adjuntar ficheros como puede ser una config de un Cisco, que permita búsquedas, que permita exportar a un Excel, que permita crear campos como la IP de un servidor o la fecha de la ultima actualización del servidor y sobre todo que sea opensource.

Pues bien, después de mucho probar la solución es: KeePass Password Safe.

Ahora cada vez que conectamos una Blackberry o un iPhone al portátil, sincronizamos el fichero de password automáticamente. Una maravilla…

run kiosco

20 de diciembre de 2009

Un kiosco en Linux es una máquina dispuesta en un stand para que los usuarios la puedan utilizar a modo de terminal de consulta. Por ejemplo si habéis ido alguna tienda de Pixmania, a la entrada hay un terminal (pantalla+teclado+ratón) donde solo tenéis acceso a su pagina Web para consultar sus productos.

En mi empresa hemos montado tres kioscos para que los empleados tengan acceso al "portal del empleado" y estén siempre al día de la noticias de la empresa. Una está en la cafetería, la otra en el restaurante y la otra aun no se donde irá.

Explico pues como montar una maquina de estas. La idea es que el Linux arranque automáticamente, cargue el firefox con la página de inicio y el usuario solo pueda consultar esta página. Naturalmente no podrá navegar por ningún otro sitio, no podrá reiniciarla, no podrá ejecutar ninguna aplicación, etc.

+ Instalaremos una versión ligera de Linux como Ubuntu Server. La idea es que cualquier maquina con poco disco (unos 2Gb) y memoria (unos 256Mb) nos pueda funcionar. Haremos una instalación estándar y consideraremos los siguientes puntos:

1) Crear el usuario con nombre "operador". Este será el usuario con el que funcionará el Kiosco.
2) No utilizar LVM ya que no es necesario.
3) Instalar OpenSSH Server. Es necesario para realizar un mantenimiento remoto del kiosco.

+ Actualizar la máquina e instalar un entorno X ligero como Blackbox (con 5Mb de RAM ya funciona):

operador@kiosko$ sudo passwd root
operador@kiosko$ su root
root@kiosko# apt-get update
root@kiosko# apt-get upgrade
root@kiosko# apt-get install x-window-system-core blackbox squid firefox mingetty 
flashplugin-nonfree
+ Lo primero que haremos es configurar el Squid para decirle el conjunto de paginas Web por donde podrá navegar el kiosco. Si solo tenemos un kiosco el proxy lo instalaremos en la maquina local, si tenemos varios podemos instalar el proxy en uno de ellos y hacer que el resto de kioscos lo utilicen.

El usuario no puede escribir una URL ya que la pagina inicial le viene impuesta, el problema es que si la pagina contiene un link a otro site no controlado o no previsto, el usuario podrá navegar. Imagina que dentro de la pagina inicial encuentra un link a Google. Si accede a Google podrá navegar por donde quiera.

Para ello creamos el archivo "/etc/squid/kiosko_allow_sites.conf" y dentro colocaremos todos los dominios (incluidos nuestra pagina inicial) por donde queramos que navegue nuestro kiosco:

root@kiosko# cat kiosko_allow_sites.conf 
intranet.miempresa.com
miempresa.com
submiempresa.com
Ahora le decimos a Squid que acepte estos sites y que todo lo demás lo deniegue. Para ello editamos el /etc/squid/squid.conf. Dentro del "Defining an Access List", añadimos la ACL:

acl kiosko_allow_sites url_regex "/etc/squid/kiosko_allow_sites.conf"
Ahora creamos la rule para aceptar estas sites y denegar el resto. Dentro de "Allowing or Denying access based on defined access lists" añadimos:
http_access allow kiosko_allow_sites
http_access deny all
Ahora solo queda reiniciar Squid:
root@kiosko# /etc/init.d/squid restart
+ Ya podemos arrancar el entorno X. Mientras tanto podemos ir conectándonos por SSH y terminar de configurar la maquina:
root@kiosko# startx
Para arrancar Firefox manualmente, hacemos botón derecho en el ratón y ejecutamos xterm. En la ventana de consola podemos escribir "firefox" para ejecutarlo.

Una vez arrancado el Firefox lo configuramos para que siempre arranque nuestra pagina de inicio. Para ellos hacemos "Editar->Preferencias" y modificamos la "Pagina de Inicio".

Es aconsejable revisar todas las opciones de Firefox para no dejarnos nada. Por ejemplo:

1) cambiar la ruta de descargas de archivos a /tmp.
2) deshabilitar la barra de progreso de descargas
3) no recordar nunca los passwords
4) limpiar historial todos los dias
5) deshabilitar las actualizaciones

También debemos decirle a Firefox que utilice el proxy (Squid) que hemos configurado en el punto anterior. Para ello dentro de Preferencias vamos a Advanced->Network->Settings y añadimos:

HTTP Proxy: 127.0.0.1
Puerto: 3127

Otra cosa para configurar es deshabilitar la restauración de la sesión de Firefox al cerrar incorrectamente el navegador. Esto evita que cada vez que arranque el Firefox (al reiniciar el kiosco) pregunte si deseamos restaurar la ultima sesión:

1) En la URL escribimos "about:config" y pulsamos Enter
2) Buscamos "browser.sessionstore.resume_from_crash"
3) Hacemos doble click en el parámetro para ponerlo a false

También pondremos a false el parámetro "network.protocol-handler.external.mailto". Esto lo que hará es que cuando la pagina encuentre un link del tipo "mailto" este no funcione y no cargue ningún Webmail tipo GMail o Yahoo.

Tras finalizar la configuración de Firefox viene la parte más importante que es la instalación de un complemento de Firefox que nos permite eliminar las barras de navegación, la minimización de las ventanas, el botón derecho del ratón, etc: el R-Kiosk.

Lo debemos instalar accediendo a su descarga: https://addons.mozilla.org/en-US/firefox/addon/1659

Una vez arrancado Firefox con este complemento perderemos toda posibilidad de acceder a los menus y al escritorio la maquina. Si queremos arrancar con los menús de Firefox, tendremos que arrancarlo en safe-mode como se indica más abajo.

+ Hacer auto-login y arrancar el entorno grafico automáticamente.

Primero editamos "/etc/event.d/tty1" y cambiamos "exec /sbin/getty 38400 tty1" por "exec /sbin/mingetty –-autologin operador tty1". Esto lo que hace es el auto-login con el usuario "operador" creado durante la instalación.

Para arrancar las X editamos "/home/operador/.profile" y añadimos en la última linea un "startx".

+ Arrancar automáticamente Firefox. Creamos el archivo "/home/operador/.xinitrc". Este archivo se ejecuta cada vez que arranque el entorno gráfico:
root@kiosko# cat .xinitrc 
#!/bin/bash

## Arranque normal de Firefox
firefox &

## Utilizar esta linea para arrancar Firefox en safe-mode
##firefox -safe-mode &

. /etc/X11/Xsession

root@kiosko# chown operador:operador .xinitrc
NOTA: Si no queremos arrancar el R-Kiosk arrancaremos el Firefox con "firefox -safe-mode &".

+ También es necesario que el usuario no pueda hacer un "ctrl+alt+del" y reiniciar el kiosco. Para ello renombramos este archivo:
root@kiosko# cd /etc/envet.d
root@kiosko# mv control-alt-delete control-alt-delete.disable
Otras consideraciones: la máquina al arrancar es vulnerable a que un usuario pueda acceder. Por ejemplo, al arrancar el grub podría modificar los parametros de arranque, podría cambiar de tty mientras está cargado, o podría llegar a ejecutar un xterm antes de arrancar el Firefox.

Por esto unas modificaciones que podrías hacer tú es:

+ Modificar el grub para que el timeout sea 0 segundos.
+ Quitar todos los ttys no necesarios
+ No ejecutar ningún programa una vez dentro de Blackbox.

lvm: ponme un nuevo disco

14 de diciembre de 2009

Actualmente tengo una maquina con un Oracle al que se le termina el espacio de disco. Tiene un disco de 68Gb en RAID1 montado por LVM (el /dev/sda). Hemos montado otro disco de 68Gb en RAID1 (el /dev/sdb) con la idea de ampliar el espacio del volum-group formado en la maquina.

Miramos primero que se ha reconocido el segundo disco:

root@virtuozo:~# ls -l /dev/sd*   
brw-rw---- 1 root disk 8,  0 2009-12-11 11:50 /dev/sda
brw-rw---- 1 root disk 8,  1 2009-12-11 11:50 /dev/sda1
brw-rw---- 1 root disk 8,  2 2009-12-11 11:50 /dev/sda2
brw-rw---- 1 root disk 8,  5 2009-12-11 11:50 /dev/sda5
brw-rw---- 1 root disk 8, 16 2009-12-12 16:39 /dev/sdb

Miramos cómo está montado el LVM en esta máquina. Miramos los Physical Volumen o los discos físicos que forman mi LVM:
root@virtuozo:~# pvscan
  PV /dev/sda5   VG virtuozo.barcelona   lvm2 [68.00 GB / 0    free]
  Total: 1 [68.00 GB] / in use: 1 [68.00 GB] / in no VG: 0 [0   ]

Vemos que existe un volum-group llamado “virtuozo.barcelona” que está compuesto de la partición física /dev/sda5 de 68Gb.

Vemos ahora como está particionado este volum-group en diferentes logical-volum:
root@virtuozo:~# lvscan
  ACTIVE            '/dev/virtuozo.barcelona/root' [65.18 GB] inherit
  ACTIVE            '/dev/virtuozo.barcelona/swap_1' [2.82 GB] inherit

Está particionado en dos. La primera en “root” de 65Gb y la segunda es “swap_1” de 2Gb.

Ahora que tenemos esto presente, la idea de añadir un nuevo disco (el /dev/sdb) es aumentar el tamaño del logical-volum “root”, pasando de 65Gb a 133Gb aproximadamente.

Vamos pues. Lo primero que haremos es crear una única partición en /dev/sdb de system id “8e” (tipo LVM).
root@virtuozo:~# fdisk /dev/sdb

The number of cylinders for this disk is set to 8908.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-8908, default 1): 
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-8908, default 8908): 
Using default value 8908

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 8e
Changed system type of partition 1 to 8e (Linux LVM)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Una vez creada la partición (ver ls –l /dev/sd*), la formateamos. En mi caso es formato ext3:
root@virtuozo:~# mkfs -t ext3 -c /dev/sdb1

Ahora ya podemos añadir nuestro nuevo disco al volum-group:
root@virtuozo:~# pvcreate /dev/sdb1
root@virtuozo:~# vgextend virtuozo.barcelona /dev/sdb1
root@virtuozo:~# pvdisplay
  --- Physical volume ---
  PV Name               /dev/sda5
  VG Name               virtuozo.barcelona
  PV Size               68.00 GB / not usable 1.27 MB
  Allocatable           yes (but full)
  PE Size (KByte)       4096
  Total PE              17408
  Free PE               0
  Allocated PE          17408
  PV UUID               gextNx-qoAF-aNn9-1ARg-72bY-oQeY-sHaOQ7   
  --- Physical volume ---
  PV Name               /dev/sdb1
  VG Name               virtuozo.barcelona
  PV Size               68.24 GB / not usable 454.00 KB
  Allocatable           yes 
  PE Size (KByte)       4096
  Total PE              17469
  Free PE               17469
  Allocated PE          0
  PV UUID               dCibq8-B4TY-adnR-HR6j-iLv6-f15H-pBknpX

Para finalizar aumentamos el tamaño del logical-volum llamado “root”:
root@virtuozo:~# lvextend -l+17469 /dev/virtuozo.barcelona/root 
  Extending logical volume root to 133.42 GB
  Logical volume root successfully resized
root@virtuozo:~# lvscan
  ACTIVE            '/dev/virtuozo.barcelona/root' [133.42 GB] inherit
  ACTIVE            '/dev/virtuozo.barcelona/swap_1' [2.82 GB] inherit
# resize2fs /dev/virtuozo.barcelona/root
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/virtuozo.barcelona-root
                      133G  2.8G  123G   3% /
varrun               1008M   84K 1008M   1% /var/run
varlock              1008M     0 1008M   0% /var/lock
udev                 1008M   52K 1008M   1% /dev
devshm               1008M     0 1008M   0% /dev/shm
/dev/sda1             236M   26M  199M  12% /boot

Observar como utilizamos el parámetro +17469 para aumentar el espacio con los “Free PE” (Physical Extended) del nuevo disco que hemos añadido. También podríamos utilizar algo como “lvextend -L+68G /dev/virtuozo.barcelona/root”.

Esta es una tabla de todos los comandos que se pueden utilizar para LVM:
--------------------
Comandos de volúmenes físicos
--------------------
pvchange |  Cambia los atributos de un volumen físico
pvcreate |  Crea un volumen físico
pvdata  |  Muestra información de depuración sobre un volumen físico
pvdisplay  | Muestra información sobre un volumen físico
pvmove   | Mueve extensiones físicas de un volumen físico a otro.
pvscan  | Localiza y enumera todos los volúmenes físicos
--------------------
Comandos de grupos volumen
--------------------
vgcfgbackup  | Hace una copia del área del descriptor de grupo volumen
vgcfgrestore  | Recupera el área del descriptor de grupo volumen al disco
vgchange  | Cambia los atributos de un grupo volumen
vgck   | Comprueba la consistencia del área del descriptor de grupo volumen
vgcreate  | Crea un grupo volumen a partir de volúmenes físicos
vgdisplay  | Muestra los atributos de un grupo volumen
vgexport  | Exporta un grupo volumen del sistema
vgextend  | Añade volúmenes físicos a un grupo volumen
vgimport  | Importa un grupo volumen al sistema
vgmerge  | Combina dos grupos volumen
vgmknodes  | Combina un directorio y los archivos especiales de un grupo volumen
vgreduce  | Elimina volúmenes físicos de un grupo volumen
vgremove  | Elimina un grupo volumen
vgrename  | Renombra un grupo volumen
vgscan   | Localiza y enumera todos los grupos volumen del sistema
vgsplit  | Divide un grupo volumen
--------------------
Comandos de volúmenes lógicos
--------------------
lvchange  | Cambia los atributos de un volumen lógico 
lvcreate  | Crea un volumen lógico
lvdisplay  | Muestra los atributos de un volumen lógico
lvextend  | Incrementa el tamaño de un volumen lógico
lvreduce  | Reduce el tamaño de un volumen lógico
lvremove  | Elimina un volumen lógico
lvrename  | Renombra un volumen lógico
lvscan   | Localiza y enumera todos los volúmenes lógicos, creando /etc/lvmtab 
y /etc/lvmtab.d/*
--------------------
Comandos del Administrador de Volúmenes Lógicos (LVM)
--------------------
lvmchange  | Cambia los atributos del sistema LVM
lvmdiskscan  | Localiza y enumera todos los discos disponibles, los dispositivos 
múltiples y las particiones
lvmsadc  | Recoge información sobre la actividad de LVM
lvmsar   | Muestra información sobre la actividad de LVM


instalar oracle en linux y no morir en el intento (parte ii)

12 de diciembre de 2009

Es posible que al finalizar ya podamos acceder directamente a la consola de administración desde: http://ip_server:1158/em

Pero si reiniciamos veremos como Oracle no arranca por defecto. Hay muchos scripts por Internet para arrancar automáticamente la BBDD.
Lo que primero haremos es indicarle a Oracle que BBDD queremos arrancar al arrancar Oracle.

Editamos el /etc/oratab e indicamos que queremos que la única base de datos creada arranque:

dbora01:/u01/app/oracle/oracle/product/10.2.0:Y

Iniciar Oracle:
# su oracle
# . oraenv (cargamos las variables de entorno)
$ . oraenv
ORACLE_SID = [oracle] ? dbora01

$ lsnrctl start (arrancamos el listener)
$ dbstart (arrancamos la bbdd)
$ emctl start dbconsole (arrancamos la consola de administración)

Podemos ver todos lo procesos que se arrancan:
$ ps -x
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.3/FAQ
  PID TTY      STAT   TIME COMMAND
 6439 pts/0    S      0:00 bash
 6469 ?        Ssl    0:00 /u01/app/oracle/oracle/product/10.2.0/bin/tnslsnr LISTENER 
-inherit
 6514 ?        Ss     0:00 ora_pmon_dbora01
 6516 ?        Ss     0:00 ora_psp0_dbora01
 6518 ?        Ss     0:01 ora_mman_dbora01
 6520 ?        Ss     0:00 ora_dbw0_dbora01
 6522 ?        Rs     0:03 ora_lgwr_dbora01
 6524 ?        Ss     0:00 ora_ckpt_dbora01
 6526 ?        Ss     0:04 ora_smon_dbora01
 6528 ?        Ss     0:00 ora_reco_dbora01
 6530 ?        Ss     0:02 ora_cjq0_dbora01
 6532 ?        Ss     0:04 ora_mmon_dbora01
 6534 ?        Ss     0:00 ora_mmnl_dbora01
 6536 ?        Ss     0:00 ora_d000_dbora01
 6538 ?        Ss     0:00 ora_s000_dbora01
 6542 ?        Ss     0:00 ora_qmnc_dbora01
 6544 ?        Ss     0:00 ora_q000_dbora01
 6546 ?        Ss     0:00 ora_q001_dbora01
 7029 pts/0    S      0:00 /u01/app/oracle/oracle/product/10.2.0/perl/bin/perl 
/u01/app/oracle /oracle/product/10.2.0/bin/emwd.pl dbc
 7054 pts/0    Sl     0:28 /u01/app/oracle/oracle/product/10.2.0/jdk/bin/java 
-server -Xmx256M -XX:MaxPermSize=96m -XX:MinHeapFreeRa
 7219 ?        Ss     0:00 oracledbora01 (LOCAL=NO)
 7226 ?        Ss     0:01 oracledbora01 (LOCAL=NO)
 7230 ?        Ss     0:04 oracledbora01 (LOCAL=NO)
 7235 ?        Ss     0:02 oracledbora01 (LOCAL=NO)
 7260 ?        Ss     0:00 oracledbora01 (LOCAL=NO)
 7274 ?        Ss     0:00 oracledbora01 (LOCAL=NO)
 7866 pts/0    Sl     0:01 /u01/app/oracle/oracle/product/10.2.0/bin/emagent
 7897 ?        Ss     0:01 oracledbora01 (LOCAL=NO)
 7941 ?        Ss     0:02 oracledbora01 (LOCAL=NO)
 7973 ?        Ss     0:04 oracledbora01 (LOCAL=NO)
 8253 ?        Ss     0:00 ora_j000_dbora01
 8268 pts/0    R+     0:00 ps -x
El primero que arrancamos es el listener. El listener es un servicio TCP que por defecto escucha en el 1521 y provee la conexión de clientes que necesitan realizar operaciones con la base de datos. Por ejemplo si tenemos una aplicación Java o PHP que desea realizar consultas contra la BBDD deberá contactar con el listener de Oracle pasándole su usuario/password y el SID de la base de datos.

La configuración del listener está en: $ORACLE_HOME/network/admin.

Luego levantamos la BBDD y con ello aparecen toda una serie de procesos llamados ora_*. Explicaré rápidamente algunos de estos procesos:

+ Ora_pmon: Es el Process Monitor. Es el encargado de limpiar los bufer y las caches que un usuario haya podido dejar sin liberar. Por ejemplo la conexión de red de un usuario cae y este tiene bloqueos de tablas, pmon libera las tablas, realiza rollbacks, etc de los recursos consumidos.

+ Ora_smon: Es el System Monitor. Es el encargado de recuperar la base de datos en caso de fallo de Oracle. Para ello utiliza los archivos de rehacer.

+ Ora_dbw: Es el Dabase Writer. Es proceso encargado de escribir en los ficheros fisicos los bloques de datos nuevos o modificados. Dependiendo del redimiento y necesidades de nuestro Oracle, podemos arrancar hasta 20 dbw.

+ Ora_lgwr: Es el Log Writer. Es el encargado de escribir los bloques del rehacer. Cuando tenemos una transacción primero se escriben los datos en los registros de rehacer antes que el ora_dbw los escriba finalmente en los ficheros de datos. Una transacción es correcta si ora_lgwr ha podido escribir los datos en sus archivos de rehacer.

Finalmente arrancamos la consola de administración que no es más que una aplicación Java (http://ip_server: 1158/em).
Ahora que parece que todo está arrancado vamos a conectarnos a la base de datos y hacer unas cuantas consultas de administración. No conectamos a la BBDD.
$ sqlplus /nolog
> connect / as sysba
Connected.

Veamos cuantas base de datos tenemos creadas:
SQL> select name, created, log_mode, open_mode, platform_name from v$database;

NAME      CREATED  LOG_MODE     OPEN_MODE
--------- -------- ------------ ----------
PLATFORM_NAME
--------------------------------------------------------------------------------
DBORA01   08/12/09 NOARCHIVELOG READ WRITE
Linux IA (32-bit)

Vemos que tenemos una BBDD llamada DBORA01 y que está abierta para lectura/escritura.

Veamos cuantos tablespaces tiene esta base de datos:
SQL> select tablespace_name, contents from dba_tablespaces;

TABLESPACE_NAME                CONTENTS
------------------------------ ---------
SYSTEM                         PERMANENT
UNDOTBS1                       UNDO
SYSAUX                         PERMANENT
TEMP                           TEMPORARY
USERS                          PERMANENT
EXAMPLE                        PERMANENT

6 rows selected.

Todos a excepción del EXAMPLE son los que nos encontraremos en una instalación estándar de Oracle. En el tablespace EXAMPLE encontraremos tablas de ejemplo para hacer pruebas.

Juguemos ahora con el schema SCOTT que se encuentra dentro del tablespace EXAMPLE. Para ello primero habilitamos el usuario que por defecto está cerrado:
SQL> ALTER USER scott ACCOUNT UNLOCK;

Entramos ahora con este nuevo usuario que por defecto tiene el password “tiger”.
$ sqlplus /nolog
> connect scott/tiger

Veamos ahora su schema:
Sql> select * from cat;
TABLE_NAME                     TABLE_TYPE
------------------------------ -----------
DEPT                           TABLE
EMP                            TABLE
BONUS                          TABLE
SALGRADE                       TABLE

SQL> select ename,job,sal from emp;

ENAME      JOB              SAL
---------- --------- ----------
SMITH      CLERK            800
ALLEN      SALESMAN        1600
WARD       SALESMAN        1250
JONES      MANAGER         2975
MARTIN     SALESMAN        1250
BLAKE      MANAGER         2850
CLARK      MANAGER         2450
SCOTT      ANALYST         3000
KING       PRESIDENT       5000
TURNER     SALESMAN        1500
ADAMS      CLERK           1100

ENAME      JOB              SAL
---------- --------- ----------
JAMES      CLERK            950
FORD       ANALYST         3000
MILLER     CLERK           1300

14 rows selected.

¿Parece que Oracle funciona no?

instalar oracle en linux y no morir en el intento (parte i)

8 de diciembre de 2009

El éxito o fracaso de una instalación de Oracle en Linux consiste básicamente en leerse un único documento: la Quick Installation Guide. Para la correcta instalación debemos de cumplir una serie de requisitos de hardware, software, parámetros de kernel y directorio requeridos. Si fallamos en uno de ellos el proceso de instalación fallará.

Para el siguiente post instalaremos un Oracle 10g R2 para Linux x86. Para ello lo descargamos directamente de la Web de Oracle. También necesitaremos a mano su guía de instalación.

Primero de todo hemos de revisar los requisitos de hardware de nuestra versión de Oracle dentro de la guía. Para ello necesitaremos una maquina x86, con 1Gb de RAM mínimo y unos 4Gb de disco para el software base de Oracle. Todo lo que sea superior a esto lógicamente será mejor. Por otro lado debemos seleccionar un sistema operativo que esté dentro de los sistemas operativos soportados por Oracle: Red Hat Enterprise 3, 4, SUSE Enterprise 9 y Asianux 1 y 2.

Yo voy a seleccionar un clon de Red Hat 4 como es CentOS 4. Si tuviéramos esta máquina en producción y quisiéramos que Oracle nos diera soporte en caso de problemas tendríamos que optar necesariamente por un sistema Red Hat si no queremos que Oracle se desentienda.

Empezamos pues la instalación:

+ Realizamos una instalación tipo servidor de un CentOS 4.8. Seleccionamos un particionado automático que utilizará LVM, configuramos el TCP/IP, desactivamos el firewall y también el SELinux.

+ Al finalizar la instalación comprobamos que tenemos acceso a Internet y que tenemos espacio suficiente en el sistema:

# ping www.google.com
# free (ver estado de la memoria y de la swap)
# df –h (ver espacio libre en /)

+ Actualizamos el sistema e instalamos los paquetes requeridos para la instalación:
# yum update
# yum groupinstall "X Window System" "GNOME Desktop Environment"
# yum install \
    setarch* \
    compat-libstdc++* \
    control-center* \
    gnome-libs* \
    gdb-6.1post* \
    make* \
    compat-gcc* \
    compat-gcc-c++* \
    glibc* \
    glibc-common* \
    glibc-devel* \
    gcc* \
    gcc-c++* \
    compat-db* \
    openmotif* \
    libstdc++* \
    libstdc++* \
    sysstat* \
    libaio* \
    libaio-devel*
# reboot

La instalación de Oracle utiliza un entorno de ventanas. Por este motivo he instalado el entorno gráfico en el servidor. Lógicamente en entorno solo lo arrancaremos para hacer la instalación, luego lo dejaremos apapagado.

+ Ahora creamos el usuario y los directorios necesarios para la instalación. Por defecto crearemos tres directorios: u01 (software base de oracle), u02 (archivos de la base de datos) y u03 (área de recuperación de datos).
# groupadd oinstall
# groupadd dba
# useradd -g oinstall -G dba oracle
# passwd oracle

# mkdir -p /u01/app/oracle
# chown -R oracle:oinstall /u01/app/oracle   
# chmod -R 755 /u01/app/oracle

# mkdir -p /u02/oradata
# chown -R oracle:oinstall /u02/oradata   
# chmod -R 755 /u02/oradata

# mkdir -p /u03/flash_recovery_area
# chown -R oracle:oinstall /u03/flash_recovery_area   
# chmod -R 755 /u03/flash_recovery_area

+ Configuramos los parámetros del Kernel. Para ello editamos el /etc/sysctl.conf y añadimos las siguientes líneas:
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_default = 262144
net.core.rmem_max = 262144
net.core.wmem_default = 262144
net.core.wmem_max = 262144

+ Ahora añadimos las siguientes restricciones en los siguientes archivos:

En el /etc/security/limits.conf:
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536

En el /etc/pam.d/login:
session required pam_limits.so

Y finalmente en el /etc/profile:
if [ $USER = "oracle" ]; then
   if [ $SHELL = "/bin/ksh" ]; then
      ulimit -p 16384
      ulimit -n 65536
   else
      ulimit -u 16384 -n 65536
   fi
fi

Tras finalizar hacemos un reboot para cargar los nuevos parámetros del Kernel.

+ Ahora ya estamos en disposición de comenzar la instalación de Oracle. Para ello copiamos el “10201_database_linux32.zip” en una carpeta temporal. Por ejemplo en /usr/src/oracle10g.

Descomprimimos el software de Oracle:
# unzip /usr/src/oracle10g/10201_database_linux32.zip

+ Abrimos el entorno gráfico ya que el proceso de instalación de Oracle es en un entorno de ventanas.
# startx
# hostname
oracle.miserver.com
# xhost oracle.miserver.com
# su oracle
$ cd /usr/src/oracle10g/database
$ ./runInstaller

+ Una vez arranca el entorno gráfico de instalación hay que seguir las siguientes pantallas.
SimulacionInstalacion10gR2

+ Al finalizar la instalación no olvidarse de ejecutar (como root) los scripts de postinstalación tal como se recuerda.
# /u01/app/oracle/oraInventory/orainstRoot.sh
# /u01/app/oracle/oracle/product/10.2.0/root.sh


routing por diferentes proveedores

29 de noviembre de 2009

Supongamos que tenemos un servidor (en este caso un servidor de VPN) que por cualquier razón su conexión a Internet (por el RouterA) se ha quedado pequeña. Hemos decidido comprar un nuevo router simétrico (el RouterB) para garantizar la calidad de la conexiones VPN para ciertas personas. Una grupo de personas se conectarán a la VPN por el RouterA y otros por el RouterB.



Este ejemplo es extensible a cualquier otro tipo de servicio que queramos ofrecer de forma que una parte del trafico va por un sitio y el otro por otro. La dificultad radica en que el tráfico debe volver por el mismo router por el que ha llegado.

Para realizar esto utilizaremos el comando "ip" que nos permite manipular las tablas de rutas, crear políticas de rutas y crear tuneles.

Veamos como está la tabla de rutas del servidor:

root# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.2.0     *               255.255.255.0   U     1      0        0 eth1
192.168.1.0     *               255.255.255.0   U     1      0        0 eth0
link-local      *               255.255.0.0     U     1000   0        0 eth1
default         192.168.1.1     0.0.0.0         UG    0      0        0 eth0

root# ip route show
192.168.2.0/24 dev eth1  proto kernel  scope link  src 192.168.2.2  metric 1
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.6  metric 1
169.254.0.0/16 dev eth1  scope link  metric 1000
default via 192.168.1.1 dev eth0  proto static
Tanto el comando "route" e "ip route show" muestran la misma información. El comando "route" es la versión ligera del comando "ip route show".

Cuando Linux necesita enrutar un paquete busca dentro de las tablas su camino. Por defecto hay tres tablas de enrutamiento: local, main y default.
root# ip rule list
0: from all lookup local
32766: from all lookup main
32767: from all lookup default

Veamos que hay dentro de cada una de ellas:
root# ip route list table local
broadcast 192.168.1.0 dev eth0  proto kernel  scope link  src 192.168.1.6
broadcast 192.168.2.255 dev eth1  proto kernel  scope link  src 192.168.2.2
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1
local 192.168.1.6 dev eth0  proto kernel  scope host  src 192.168.1.6
broadcast 192.168.1.255 dev eth0  proto kernel  scope link  src 192.168.1.6
broadcast 192.168.2.0 dev eth1  proto kernel  scope link  src 192.168.2.2
local 192.168.2.2 dev eth1  proto kernel  scope host  src 192.168.2.2
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1

root# ip route list table main
192.168.2.0/24 dev eth1  proto kernel  scope link  src 192.168.2.2  metric 1
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.6  metric 1
169.254.0.0/16 dev eth1  scope link  metric 1000
default via 192.168.1.1 dev eth0  proto static

root# ip route list table default
(vacia)

Ver como la tabla por defecto del sistema (la que vemos al hacer "route") se llama main.

Lo que vamos hacer es crear dos tablas más (lan1 y lan2) para que contengan las rutas para cada una de las diferentes salidas a Internet. Para ello editaremos el archivo /etc/iproute2/rt_table con el siguiente contenido:
root# cat /etc/iproute2/rt_tables
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
10 lan1
20 lan2

Ahora crearemos las rutas que irán en cada una de estas tablas. Para que estas rutas se carguen en el sistema cada vez que arranquemos, la meteremos en /etc/rc.local:
root# cat /etc/rc.local
#!/bin/sh -e

ip rule add from 192.168.1.6 table lan1
ip route add 192.168.1.0/24 dev eth0 src 192.168.1.6 table lan1
ip route add default via 192.168.1.1 table lan1

ip rule add from 192.168.2.2 table lan2
ip route add 192.168.2.0/24 dev eth0 src 192.168.2.2 table lan2
ip route add default via 192.168.2.1 table lan2

exit 0
root# reboot

Estas órdenes aseguran que el tráfico que proviene de una interfaz, es contestado por la misma interfaz.

Una vez reiniciado el sistema vemos si las rutas se han cargado correctamente en el sistema:
root# ip rule list
0:      from all lookup local
32764:  from 192.168.2.2 lookup lan2
32765:  from 192.168.1.6 lookup lan1
32766:  from all lookup main
32767:  from all lookup default

root# ip route list table lan1
192.168.1.0/24 dev eth0  scope link  src 192.168.1.6
default via 192.168.1.1 dev eth0

root# ip route list table lan2
192.168.2.0/24 dev eth0  scope link  src 192.168.2.2
default via 192.168.2.1 dev eth1

Cuando un paquete llega al servidor este comprueba por orden si se cumple alguna de las reglas de tabla. Primero mira si se cumple "from 192.168.2.2". Si se cumple utiliza la tabla "lan2", de lo contrario pasará a ver si se cumple "from 192.168.1.6". Si se cumple utilizará la tabla "lan2". Por ultimo utilizará la tabla por defecto "main".

Para depurar y ver que todo funciona se puede utilizar el comando tcpdump y ver si el trafico pasa por una interfaz o u otra.

El siguiente escenario también lo podríamos utilizar por ejemplo para un servidor de correo donde queremos que el trafico del webmail (puerto 80 y 443) vaya por una ISP y el trafico al 25 vaya por otro ISP.

Más información:
+ Linux Advanced Routing & Traffic Control HOWTO