jueves, 14 de noviembre de 2013

[warn] mod_fcgid: process graceful kill fail, sending SIGKILL

Si viendo los logs de nuestro apache detectamos un warning del mod_fcgid indicando que ha tenido que mandar la señal SIGKILL a algún proceso, casi con toda seguridad podemos indicar que en nuestra web se ha lanzado algo que tardaba más tiempo en resolverse del que tenemos configurado. Este error se nos mostrará al navegar como un error 500 en la web. El fichero de log de apache suele estar en /var/log/httpd/error_log y el error será algo parecido a esto:
 [Sun Oct **] [warn] mod_fcgid: process ** graceful kill fail, sending SIGKILL
 
Para ampliar el tiempo de ejecución CGI basta con aumentar el valor FcgidIOTimeout en el fichero fcgid.conf según nuestras necesidades.

[root@*** ~]# vi /etc/httpd/conf.d/fcgid.conf
Y por ejemplo si queremos ponerle 600 quedaría así:

FcgidIOTimeout 600

Tras esto solo tenemos que reiniciar apache y cogerá los cambios.

viernes, 27 de septiembre de 2013

Jobscheduler: Z-JAVA-101 Java Virtual Machine is not started


Montando un Jobscheduler en un servidor Red Hat tuve el problema de que al arrancarlo y tras lanzar el script jobscheduler_environment_variables.sh donde hace los export de las variables de sistema que necesita, me daba el famoso error Z-JAVA-101 Java Virtual Machine is not started. Revisando el propio log del Jobscheduler vi que me indicaba que no tenia permisos para ejecutar libjvm.so. Rascando un poco averigüé que esto se produce por las políticas de seguridad en linux y más concretamente las de Red Hat (Security-Enhanced Linux) que impedían que se cargara esa librería en el contexto donde debería cargarse. El error que aparece en el log es algo similar a este con las rutas que tengáis:

[ERROR Z-JAVA-100  Java Virtual Machine cannot be loaded [xxx/lib/i386/client/libjvm.so: cannot restore segment prot after reloc: Permission denied] [libjvm.so]]

Para cambiar el contexto de seguridad de la librería libjvm.so a textrel_shlib_t lanzaremos lo siguiente:

[pp@core bin]$ chcon -t textrel_shlib_t /home/xx/jdk/jdk1.6.0_27_i586/jre/lib/i386/client/libjvm.so

Otra manera sería desactivar el Security-Enhanced Linux, para esto podéis consultar este artículo.


Activar o Desactivar SELinux

Para desactivar la Security-Enhanced Linux en Red Hat tenemos que realizar los pasos que detallo a continuación.

El archivo de configuración del SELINUX se puede consultar con un vi /etc/sysconfig/selinux pero este realmente no es el archivo en cuestión si no un enlace simbólico al mismo. Lo podemos comprobar lanzando lo siguiente:

[root@core ~]$ ls -ltr /etc/sysconfig/selinux
lrwxrwxrwx 1 root root 17 ene 25  2012 /etc/sysconfig/selinux -> ../selinux/config

El archivo final es /etc/selinux/config y es el que tenemos que modificar. Para esto y accediendo como root lanzamos el comando vi  /etc/selinux/config. Deberemos modificar la linea SELINUX=enforcing y cambiar el enforcing por disabled. Adicionalmente yo suelo comentar SETLOCALDEFS para que no lo evalúe quedando el siguiente archivo de configuración:

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#       enforcing - SELinux security policy is enforced.
#       permissive - SELinux prints warnings instead of enforcing.
#       disabled - SELinux is fully disabled.
SELINUX=disabled
# SELINUXTYPE= type of policy in use. Possible values are:
#       targeted - Only targeted network daemons are protected.
#       strict - Full SELinux protection.
SELINUXTYPE=targeted

# SETLOCALDEFS= Check local definition changes
#SETLOCALDEFS=0

viernes, 20 de septiembre de 2013

Error en prestashop: order_state (Unknown column 'deleted' in 'field list')

Este error es un error que sucede en la versión 1.4.8-2 de prestashop. Cuando intentábamos cambiar de estado un pedido nos lanzaba ese error y el motivo es porque en la tabla PREFIX_order_state no estaba el campo deleted. Para solucionarlo lo único que tenemos que hacer es añadir el campo deleted, sustituyendo PREFIX por el prefijo de nuestra tabla en prestashop, lanzando lo siguiente:

ALTER TABLE `PREFIX_order_state` ADD `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0'

Configurar dns en Linux

Para configurar el dns en linux tenemos que modificar el fichero /etc/resolv.conf y /etc/network/interfaces.
Para añadirlo en el fichero /etc/resolv.conf basta con añadir la linea nameserver IP_SERVIDOR_DNS, quedando el fichero de una manera similar a esta:


root@pre:~# more /etc/resolv.conf
nameserver 10.0.10.25

Por otro lado tendremos que modificar el fichero /etc/network/interfaces y añadirle la propiedad dns-nameservers IP_SERVIDOR_DNS, quedando de una manera similar a esta:

root@pre:~# vi /etc/network/interfaces

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eth0
iface eth0 inet static
        address 10.0.10.66
        netmask 255.255.255.128
        network 10.0.10.0
        broadcast 10.0.10.255
        gateway 10.0.10.1
        # dns-* options are implemented by the resolvconf package, if installed
        dns-nameservers 10.0.10.25

Redimensionar Volúmenes en Linux


La mayor parte de los servidores que se contratan a empresas como 1and1 o Arsys vienen con un volumen creado y con tamaños predefinidos de 4GB para los puntos de montaje /var/, /home/ y /usr/. Por esto tendremos que redimensionar el tamaño de los volúmenes para darles más espacio. Lo primero, miraremos el fichero /etc/fstab para comprobar la tabla de particiones y puntos de montaje del servidor. En mi caso compruebo que tengo montado el /var, /home y /usr cada uno en un volumen (el nombre del volumen puede cambiar, por defecto sería vg00 pero en mi caso es volu00)

/dev/md1        /               ext3    defaults        1 1
/dev/sda2       none            swap    sw
/dev/sdb2       none            swap    sw
/dev/volu00/usr   /usr            ext4    defaults        0 2
/dev/volu00/var   /var            ext4    defaults,usrquota       0 2
/dev/volu00/home  /home           ext4    defaults,usrquota       0 2
devpts          /dev/pts        devpts  gid=5,mode=620  0 0
none            /proc           proc    defaults        0 0
none            /tmp    tmpfs   defaults        0 0

Realizando un df -h compruebo además que las tengo montadas y funcionando.

[aa@flopa ~]# df -h
Filesystem                             Size  Used Avail Use% Mounted on
/dev/md1                                 4.0G  543M  3.5G  14% /
/dev/mapper/volu00-usr         4G  1.5G  2,5G   69% /usr
/dev/mapper/volu00-var         4G  2.2G  1,8G   57% /var
/dev/mapper/volu00-home     4G   1G     3G     25% /home
none                                        3.9G  4.0K  3.9G   1% /tmp

Con el comando vgdisplay comprobamos el espacio que tenemos libre para para poder ampliar.

[aa@flopa ~]# vgdisplay
  --- Volume group ---
  VG Name               volu00
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  5
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                3
  Open LV               3
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               925.51 GiB
  PE Size               4.00 MiB
  Total PE              236931
  Alloc PE / Size       105472 / 412.00 GiB
  Free  PE / Size       131459 / 513.51 GiB
  VG UUID              ******************


Por último solo quedaría indicarle el espacio que queremos ampliar y el volumen donde realizarlo. Para esto utilizaremos el comando lvextend


[aa@flopa ~]# lvextend -L +87Gb /dev/mapper/volu00-var

Con esto queda apuntada la redimensión y para hacerla persistente tendremos que utilizar el comando resize2fs si trabajamos con ext4 o xfs_growfs si trabajamos con ext3 quedando de la siguiente manera.

Para ext4:
[aa@flopa ~]# resize2fs /dev/mapper/volu00-var

Para ext3:
[aa@flopa ~]# xfs_growfs /var 

miércoles, 4 de septiembre de 2013

Backup de una tabla en Postgres

Para hacer el backup de una tabla en Postgres basta con irnos al directorio que contiene el archivo pg_dump, normalmente está en /usr/local/pgsql/bin/, y lanzar lo siguiente:

root@db:~# pg_dump -i -h localhost -p 5432 -U usuario -t tabla -F p -b -v -f "/root/llamadas.sql" BaseDeDatos

Esto nos generará un archivo llamadas.sql en el directorio /root/ que contendrá todo el contenido para regenerar esa tabla (create table, add constraint,...etc ).
Para recargarlo solo tenemos que lanzar el siguiente comando:

root@db:~# ./psql -U usuario -d BaseDeDatos -f /root/llamadas.sql

Como nota adicional decir que hay que tener en cuenta que a la hora de recuperar exclusivamente los datos tendremos que editar el fichero y borrar todo lo que no sea el COPY con nuestros datos además de tener en cuenta que si lo que estamos recuperando en una tabla que tiene FOREIGN KEY el tiempo se puede disparar. Por esto siempre es mejor crearnos una tabla secundaria sin FOREIGN KEY para recuperar en ella los datos y posteriormente mediante un insert select volcarlos a la tabla original. Este tipo de sentencias que pueden tardar un tiempo es recomendable lanzarlas en la propia base de datos sin que intervenga la conexión de red a la misma. Para ello nos logamos con el usuario postgres entramos en la base de datos y lanzamos nuestra sentencia:

[root@db log]# su  postgres
[postgres@db01 log]$ psql baseDeDatos

BaseDeDatos=# select................ 


jueves, 27 de junio de 2013

Backup en Postgres

En algún momento de nuestra vida, trabajando con BBDD, tendremos que generar backups o restaurarlos. En estos momentos yo me hayo en esta situación, teniendo que restaurar un backup en una base de datos postgreSql y voy a contar un poco como lo tenemos montado y los pasos que hay que hacer para restaurarla con el fin de tener una guía para el futuro y si de paso a alguien le sirve que la tenga también.


En primer lugar, nosotros tenemos 1 base de datos master y otra de solo lectura en sclave, donde cada X minutos se carga un fichero wal con las modificaciones que hayan sucedido en esa franja de tiempo (al final contiene insert, updates,...etc). De esta manera tenemos la base de datos master replicada.

Además de lo anterior generamos un PITR-base backup que no es más que un empaquetado diario de el data, y con el comando pg_dump -i -h MAQUINA -p 5432 -U USUARIO -F p -b -O -v -f FICHERO BASEDEDATOS generamos unos ficheros .dum de todas nuestras bases de datos. De esta manera podemos recuperarlas de manera individual.

Las opciones de restauración que tenemos son las siguientes:
  • La primera consistiría en coger el PITR-base backup, descomprimirlo, borrar todo el data y sustituirlo. Tenemos que tener en cuenta que tendremos que borrar el archivo postmaster.pid (contiene el id del proceso postgres,...etc), comprobaremos que los ficheros pg_hba.conf y postgresql.conf son correctos (si no queremos que siga archivando modificaremos en el postgresql.conf la propiedad archive_mode = off) y que la versión de generación y la de recepción es la misma.
  • La segunda opción es restaurarla por el fichero .dum que tengamos. Para ello lo recomendable es borrar la base de datos entera DROP DATABASE nombre_base_datos , crear la base de datos de nuevo CREATE DATABASE nombre_base_datos , generar el rol del usuario CREATE USER nuevo_usuario IDENTIFIED BY contraseña y después lanzamos el comando psql -U USUARIO -h MAQUINA -p 5432 -d BASEDEDATOS < infile. Como nota adicional para este paso decir que si tenemos un data corrupto podemos borrarlo, lanzar el comando /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data y nos lo regenerará vacío, solo tendremos que crear la Base de datos, el rol del usuario y realizar lo descrito.
Como nota adicional, si quisiésemos resincronizar la base de datos espejo tendríamos que hacer lo siguiente:
  • Parar la máquina espejo
  • Guardar el postgresql.conf, recovery.conf y pg_hba.conf
  • Borrar el tlog y el data
  • Copiamos y descomprimimos el PITR-base backup en data
  • Sustituimos los ficheros postgresql.conf, recovery.conf y pg_hba.conf por los que hemos guardado.
  • Arrancamos el espejo
  • Copiamos de la principal los ficheros de tlog hacia el espejo
En el caso de que nos diese un error ERROR: language "plpgsql" does not exist, tendremos que generar el handler y lenguage. Para esto buscamos el archivo plpgsql.so y, sustituyendo la ruta donde esté, lanzamos lo siguiente:

CREATE FUNCTION plpgsql_call_handler () RETURNS OPAQUE AS '/usr/local/pgsql/lib/plpgsql.so' LANGUAGE 'C'; CREATE LANGUAGE 'plpgsql' HANDLER plpgsql_call_handler LANCOMPILER 'PL/pgSQL';



viernes, 8 de marzo de 2013

Navegación HTTPS y las fuentes de una web

Quiero expresar una situación que me ha sucedido mientras hacíamos la web http://complezoo.es/ y que nos trajo de cabeza durante unos días. Es habitual en la programación web que la apariencia de la página vista desde diferentes navegadores (y diferentes versiones de los mismos) tenga como resultado pequeños descuadres que hay que ir depurando. Pero el caso que nos sucedió y en el que no  habíamos reparado en el momento de su desarrollo es que sucede con la carga dinámica de fuentes cuando navegas por https.
En nuestra página inicial teníamos el siguiente código para la adquisición de una fuente:

<link type="text/css" rel="stylesheet" href="http://fonts.googleapis.com/css?family=Anton">
@font-face {
font-family: 'Anton';
font-style: normal;
font-weight: 400;
src: local('Anton'), url(http://themes.googleusercontent.com/static/fonts/anton/v3/tilmJBBU81h1G7ZsdY3Hmw.woff) format('woff');
}
</link>


Al navegar desde firefox 19.0, Safari e I9 a https://complezoo.es/  todo funcionaba correctamente, pero cual es nuestra sorpresa que desde chrome y en versiones anteriores de internet explorer, la web perdía esta fuente. Investigando vimos que hay navegadores que bloquean el contenido http cuando se navega por una web por https (el caso de chrome), otros te preguntan si quieres cargar el contenido http (como internet explorer) y por último están los que no te preguntan y lo cargan directamente como firefox. 

La solución a esto pasó por descargarnos la fuente en el servidor e incluirla en el css como local y de esta manera no tenía que irla a buscar a ningún lado.

Como nota adicional Chrome en su última versión carga el contenido http cuando navegas por https y no pregunta ni lo bloquea.

miércoles, 13 de febrero de 2013

Migrar máquina virtual de Virtualbox a VMware

Dos de las herramientas más comunes de virtualización son VirtualBox y Vmware. No es muy habitual querer pasar una máquina virtual de un sistema a otro pero si queremos unificar plataformas o tenemos este dilema, podemos realizarlo.
En primer lugar procederemos a instalar  quemu y virtualbox-ose-qt de la siguiente manera:


root@OPT360:~# sudo apt-get install qemu
root@OPT360:~# sudo apt-get install virtualbox-ose-qt


Una vez instalado, procederemos al cambio de formato de las máquinas virtuales. Localizaremos donde tenemos el archivo .vdi y lo convertiremos a .raw. En mi caso se llama NAGIOS_CENTOS6.vdi


root@OPT360:~# vboxmanage internalcommands converttoraw /home/rencinar/Descargas/NAGIOS_CENTOS6.vdi /home/rencinar/Descargas/NAGIOS_CENTOS6.raw
Oracle VM VirtualBox Command Line Management Interface Version 3.2.10_OSE
(C) 2005-2010 Oracle Corporation
All rights reserved.
Converting image "/home/rencinar/Descargas/NAGIOS_CENTOS6.vdi" with size 8589934592 bytes (8192MB) to raw...

 

Tras esto tendremos un archivo .raw que deberemos convertir en vmdk de la siguiente manera:

root@OPT360:~# qemu-img convert -O vmdk /home/rencinar/Descargas/NAGIOS_CENTOS6.raw /home/rencinar/Descargas/NAGIOS_CENTOS6.vmdk


Una vez que tengamos el archivo NAGIOS_CENTOS6.vmdk solo tendremos que crear una máquina virtual cuyo disco duro apunte a él.


Para realizar el paso contrario, pasar de Vmware a VirtualBox tendríamos que generar del .vmdk un .bin y del .bin un .vdi utilizando VBoxManage  de la siguiente manera:

$qemu-img convert NAGIOS_CENTOS6.vmdk /home/rencinar/Descargas/NAGIOS_CENTOS6.bin


$VBoxManage convertdd /home/rencinar/Descargas/NAGIOS_CENTOS6.bin debian.vdi


Enjaular usuarios SFTP

Cuando un usuario se conecta a una máquina por sftp, si no le marcamos límites podrá navegar por nuestro árbol de directorios pudiendo provocarnos problemas de seguridad.
Para evitar esto, lo más común es darle al usuario un directorio raíz controlado a partir del cual pueda trabajar (generar ficheros, directorios, ..etc) pero del cual no se pueda salir. Pongo un ejemplo que esclarezca esto.
Si yo genero un usuario que sea usu1 en un sistema Linux (por ejemplo una Debian), podrá desde este momento tener acceso por sftp, ya que el sftp corre sobre protocolo ssh, siempre que el demonio esté levantado. El problema es que este usuario, cuando se conecte, entrará por defecto en su /home/usu1 pero podrá moverse y ver el contenido de otros directorios como el /etc/, ..etc. Lo ideal es que este usuario cuando se conecte por sftp entre en un directorio que sea sftpusu1 por ejemplo y del cual no pueda salir.

Para esto tendremos que tener instalado el ssh y el openssh-server:
root@OPT360: apt-get install ssh openssh-server
Como root generamos el usuario:
root@OPT360: adduser usu1
Le cambiamos la contraseña:
root@OPT360: passwd usu1
Tras esto tendremos un usuario completamente operativo en nuestro sistema Linux. Para probar que tanto la instalación del openssh-server como la generación del usuario a sido correcta realizamos una conexión por ssh al servidor (si estamos en un linux desde consola podemos hacer ssh usu1@10.0.10.41 y si estamos en un windows con el PuTTY).
Ahora que hemos verificado que nuestro usuario está funcionando correctamente, procedemos a editar el fichero sshd_config que alberga la configuración de el servidor de ssh.
root@file-server:~# vi /etc/ssh/sshd_config

Tendremos que verificar que nuestro Subsystem utiliza el internal-sftp, por lo que tendremos que comentar la linea y generar una nueva con el internal-sftp, quedando de la siguiente manera:
#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp


Además de lo anterior, al final del fichero añadiremos lo siguiente:
Match user usu1
                ChrootDirectory /home/usuariossftp/usu1/
                ForceCommand internal-sftp


El ChrootDirectory es el directorio al que nos llevara cuando entremos con ese usuario.

Para finalizar generaremos la carpeta usu1 en la ruta indicada con un mkdir y le aplicaremos los siguientes permisos:
root@file-server:/home/usuariossftp# ls -ltr
total 8
drwxr-xr-x 3 root root 4096 feb 23  2011 usu1

Y dentro de la anterior carpeta  generaremos otra en la  que si que tenga todos los permisos el usuario usu1 para que pueda trabajar.
root@file-server:/home/usuariossftp/usu1# ls -ltr
total 4
drwxr-xr-x 2 usu1 usu1 4096 feb 13 06:31 carpeta2


Quedando al final la ruta completa de trabajo para el usuario usu1:
/home/usuariossftp/usu1/carpeta2
Tras reiniciar el servicio sshd tendremos disponible esta configuración, y en el momento que el usuario usu1 se conecte, directamente entrará en /home/usuariossftp/usu1/.
Para reiniciar el servicio realizamos como root lo siguiente:
root@file-server:/home/usuariossftp/usu1# /etc/init.d/ssh stop
root@file-server:/home/usuariossftp/usu1# /etc/init.d/ssh start


miércoles, 16 de enero de 2013

PostgreSql: No pg_hba.conf entry for host

En PostgreSql tenemos los siguientes ficheros de configuración:
  • pg_hba.conf: Se encarga de controlar el acceso y las acciones de máquinas a la BBDD.
  • pg_ident.conf: Configuración de los accesos de tipo ident.
  • postgresql.conf: Configuración propia de la BBDD.
Si al intentar conectar contra una BBDD nos de el error:

Fatal: No pg_hba.conf entry for host "10.1.0.218", user "gefjano", database "gefjano"

Significa que no tenemos registrado el acceso de la máquina 10.1.0.218 ni configurado el tipo de acceso (se puede resgistrar el acceso para una máquina o para un segmento de red).
Para habilitarselo es tan sencillo como editar el fichero pg_hba.conf e incluirla. Para ello muestro el apartado referente al la configuración de accesos.

# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
# "local" is for Unix domain socket connections only
local   all         all                                       trust
# IPv4 local connections:
host    all         all         127.0.0.1/32         trust
# IPv6 local connections:
host    all         all         ::1/128                   trust
host    all         all         10.0.10.0/24       trust
host    all         all         10.0.0.0/24           trust
host    all         all         192.168.1.0/24     trust
host    replication all   10.0.10.36/32     trust

Como podemos ver tenemos que definir el tipo, la base de datos (all para todas), el usuario, la ip o el rango de red y el método.
Para el caso que he expuesto anteriormente tendríamos que generar la siguiente entrada:

host    all         all         10.1.0.218/24           trust

Tras esto tenemos que reiniciar el servidor para que coja la nueva configuración.


Referencia: PostgreSql