Cómo evitar borrar ficheros en Linux

En GNU/Linux cuando estamos trabajando desde consola no aparecen miles de preguntas cuando ejecutamos un rm sobre un fichero o directorio, por lo que si lo borramos, recuperarlo, aunque posible como se verá en próximos posts, es cuando menos complicado. Es por ello que existen varias formas de evitar borrar un fichero. Una de ellas es establecer un alias al comando rm pasándole la opción -i, para que nos pregunte si deseamos realmente borrar dicho fichero, tal como se muestra a continuación.
shell> alias rm="rm -i"
shell> rm prueba 
rm: ¿borrar el fichero regular vacío «prueba»? (s/n)
Esta opción se puede establecer en todos los perfiles de usuario, haciendo que tengan que confirmar el borrado de ficheros. Este es un primer método de protección, pero si realmente nos interesa proteger un fichero e impedir que nadie (incluso root) lo puedo borrar, para ello necesitamos modificar los atributos que nos permiten los sistemas de ficheros de GNU/Linux. Para hacer dichos cambios, emplearemos el comando chattr, con la opción i. Vamos a ver a continuación cómo funciona.
  1. Creamos un nuevo fichero
    shell> touch prueba
    1. Establecemos los permisos de 'no borrado' al fichero
      shell> chattr -V +i prueba
      chattr 1.41.12 (17-May-2010)
      Las banderas de prueba están puestas como ----i--------------
    2. Probamos a borrarlo
      shell> rm prueba 
      rm: no se puede borrar «prueba»: Operación no permitida
    3. Sacamos los permisos
      shell> chattr -V -i prueba
      chattr 1.41.12 (17-May-2010)
      Las banderas de prueba están puestas como -------------------
    4. Intentamos borrarlo
      shell> rm prueba
      
Cómo se puede observar, mientras el fichero está con el atributo i activo, ningún usuario puede borrarlo y en el momento que se saca dicho atributo ya es posible borrarlo. Este tipo de atributos son útiles para ficheros importantes del sistema que no se pueden/deben borrar. De esta forma, podemos tenerlos seguros, aunque sí, sería como matar pájaros a tiros, xD.
Leer más

Comandos básicos CISCO (IV)

Hoy seguimos con una nueva lección de comandos de interés en router's cisco. En este caso, a nivel de usuario.
  • Comandos de interés
  • Modo: usuario
  • Modo: privilegiado
  • Modo: configuración global
    ComandoDescripción
    access-list Nro_ACL {permit|deny}OrigenCrea o agrega una sentencia de condición a la ACL que permitirá o denegará los paquetes que llegan desde un Origen.Este último parámetro puede ser una dirección IP más una máscara wildcard, la palabra host más una dirección IP o el wildcard any
    access-list Nro_ACL {permit|deny}Proto Origen Destino [OperadorNro_puerto] [established][echo |echo-reply]Crea o agrega una sentencia de condición a la ACL  que permitirá o denegará los paquetes que lleguen desde unOrigen y vayan hacia un Destino. Proto identifica el protocolo a verificar. Origen y Destino pueden ser una dirección IP más una máscara wildcard, la palabra host más una dirección IP o el wildcard any.  Operador puede ser lt (menor que), gt (mayor que), eq (igual a) o neq (distinto a). Nro_puerto indica el puerto TCP o UDP. El parámetro established permite el paso de tráfico cuando hay una sesión establecida. En el caso del protocolo ICMP se puede utilizar echo o echo-reply.
    Banner motd #mensaje del día#Configura un cartel con un mensaje del día. Ej: banner motd #Bienvenido#
    boot system flash [nombre_imagen_IOS]Especifica que el router cargue el IOS desde la Flash
    Ej: boot system flash c2500-IOS
    boot system romEspecifica que el router cargue el IOS desde la ROM
    boot system tftpnombre_imagen_IOSdir_IP_server_tftpEspecifica que el router cargue el IOS desde un servidor TFTP.
    Ej: boot system tftp c2500-IOS 24.232.150.1
    cdp runHabilita CDP globalmente en el router
    clock set hh:mm:ss mes día añoModificar la fecha y hora del router. Ej: clock set 12:31:00 July 12 2004
    config-registervalor_registro_configuraciónCambia los valores del registro de configuración.
    Ej: config-register 0×2142
    enable password contraseñaEstablece una contraseña local para controlar el acceso a los diversos niveles de privilegio. Ej: enable password class
    enable secret contraseñaEspecifica una capa de seguridad adicional mediante el comando enable password. Ej: enable secret class
    hostname nombreModifica el nombre del router. Ej: hostname Lab_A
    interface tipo númeroConfigura un tipo de interfaz y entra al modo de configuración de interfaz.
    Ej: interface ethernet 0
    ip access-list {tandard|extended}NombrePermite crear una ACL nombrada. Se debe indicar el tipo. Este comando ingresa al router al submodo de configuración que puede reconocerse por el prompt
    Router(config-ext-nacl)#
    ip classlessPermite que el router no tome en cuenta los límites con definición de clases de las redes en su tabla de enrutamiento y simplemente transmita hacia la ruta por defecto
    ip default-network dirección_redEstablece una ruta por defecto. Ej: ip default-network 210.32.45.0
    ip domain-lookupHabilita la conversión de nombre a dirección en el router
    ip host nombre_host dir_ip1 ….  Dir_ip8Crea una entrada de nombre a dirección estática en el archivo de configuración del router. Ej: ip host Lab_A 192.168.5.1 210.110.11.1
    ip http serverPermite que el router actúe como servidor Web http limitado
    ip name-server dir_ip1 …. Dirip6Especifica las direcciones de hasta seis servidores de nombres para su uso para la resolución de nombres y direcciones.
    Ip route dirección_red máscara dir_ip_salto[distancia_administrativa]Establece rutas estáticas.
    Ej: ip route 210.42.3.0 255.255.255.0 211.1.2.1
    line tipo númeroIdentifica una línea específica para la configuración e inicia el modo de reunión de comandos de configuración. Ej: line console 0 ó line vty 0 4
    router protocolo_de_enrutamiento[nro_AS]Inicia un proceso de enrutamiento definiendo en primer lugar un protocolo de enrutamiento IP. Ej: router rip ó router igrp 120
    service password-encryptionHabilita la función de cifrado de la contraseña
  • Submodo: Configuración de interfaz
  • Submodo: Configuración de línea
  • Submodo: Configuración del protocolo de enrutamiento
Leer más

acovea, flag's de optimización

¿Programas en C/C++? Pues esto te puede interesar.
Todo el mundo sabe la importación de optimizar el código. La optimización de código se consigue desde la primera a la última línea del mismo, sin embargo si lo que necesitas es todavía más optimización, el compilar gcc/g++ tiene una serie de flag's muy interesantes que permiten optimizar todavía más el código. Gracias a estos flag's, se puede aumentar el tamaño del binario final incluyendo librerías dinámicas o sacar una opcimización mayor para un tipo de procesador concreto. El problema suele ser siempre el mismo: ¿qué flag's empleo?
Hay un artículo maravilloso en Debian Administration que explican cómo emplear acovea, un potente analizador de código que te indica de forma simple cuales son las mejoras de optimización que puedes pasarle a tu código para mejorar su rendimiento.
Vamos a partir del mismo código del ejemplo y explicar paso a paso cómo optimizar los flag's de gcc para obtener un mayor rendimiento, incluso en códigos muy sencillos.
#include<stdio.h>

int main (int argc, char *argv[]) {
int i = 1, num;
int j, k;

for (num = 2; num < 32768; num++) {
   while (i <= num) {
      k = 0;
      if (num % i == 0) {
         j = 1;
         while (j <= i) {
            if (i % j == 0)
               k++;
            j++;
         }
      if (k == 2)
         printf ("%d is prime\n", i);
   }
   i++;
   }
}
return 0;
}
Primero vamos a ver qué sucede ejecutándose con una compilación normal.
shell> gcc -o ejemplo ejemplo.c
shell> time ./ejemplo
...
real 0m3.718s
user 0m3.700s
sys 0m0.008s
Y ahora que ya tenemos unos tiempos de referencia, vamos a emplear la herramienta acovea para ver cómo poder optimizar el código para nuestro procesador.
Primeramente la instalamos.
shell> apt-get install acovea
Luego, nos vamos al directorio /usr/share/libacovea/config que es donde están almacenados todos los perfiles de acovea con los que puede optimizar los flag's según la versión de nuestro procesador. En mi caso, voy a emplear gcc34_intel.acovea, con lo que lanzamos acovea tal que así,
shell> runacovea -config gcc34_intel.acovea -input ejemplo.c
Esta ejecución tardará un poco en terminar, ya que internamente está empleando muchas iteraciones y compilaciones de 'ejemplo.c' para ver cómo poder optimizarlo. Al finalizar obtendremos una salida similar a la siguiente,
Acovea completed its analysis at 2012 Oct 26 19:55:09

Optimistic options:
     -fno-cprop-registers  (1.951)
 -foptimize-sibling-calls  (1.951)
         -frerun-loop-opt  (1.537)
            -falign-loops  (1.537)
       -finline-functions  (1.951)
   -minline-all-stringops  (1.537)

Pessimistic options:
             -fforce-mem  (-1.769)
     -fmove-all-movables  (-1.769)
       -freduce-all-givs  (-1.769)
            -mfpmath=387  (-1.769)
             -march=i386  (-1.769)
             -march=i586  (-1.769)
         -march=pentium4  (-1.769)

Acovea's Best-of-the-Best:
gcc -lrt -lm -std=gnu99 -O1 -fno-merge-constants -fno-thread-jumps -fno-delayed-branch -fno-crossjumping -foptimize-sibling-calls -fcse-follow-jumps -frerun-loop-opt -fcaller-saves -fschedule-insns2 -fsched-spec -freorder-functions -falign-loops -falign-labels -falign-functions -finline-functions -frename-registers -funroll-loops -mno-push-args -maccumulate-outgoing-args -minline-all-stringops -D__NO_MATH_INLINES -mfpmath=sse -D__NO_MATH_INLINES -fno-math-errno -funsafe-math-optimizations -ffinite-math-only -finline-limit=600 -o /tmp/ACOVEA0F868709 file.c 

Acovea's Common Options:
gcc -lrt -lm -std=gnu99 -O1 -foptimize-sibling-calls -finline-functions -minline-all-stringops -o /tmp/ACOVEA61909725 file.c 

-O1:
gcc -lrt -lm -std=gnu99 -O1 -march=pentium4 -o /tmp/B013 file.c 

-O2:
gcc -lrt -lm -std=gnu99 -O2 -march=pentium4 -o /tmp/F7E6 file.c 

-O3:
gcc -lrt -lm -std=gnu99 -O3 -march=pentium4 -o /tmp/AFFD file.c 

-O3 -ffast-math:
gcc -lrt -lm -std=gnu99 -O3 -march=pentium4 -ffast-math -o /tmp/D6AA file.c

-Os:
gcc -lrt -lm -std=gnu99 -Os -march=pentium4 -o /tmp/F596 file.c 


A relative graph of fitnesses:

 Acovea's Best-of-the-Best: **************************         (179)
 Acovea's Common Options:   **************************         (181)
  -O1:                      *****************************      (191)
  -O2:                      *****************************      (193)
  -O3:                      ******************************     (197)
  -O3 -ffast-math:          *******************************    (199)
  -Os:                      ********************************** (211)

Acovea is done.
Leer más

Manejo de ficheros comprimidos en GNU/Linux

Uno de los trucos más habituales que se da en informática es el de comprimir ficheros para ahorrar espacio en disco y para hacerlos mucho más manejables. El problema está cuando queremos consultar algún tipo de información en dichos ficheros. Lo habitual en estos casos es descomprimir el fichero en una copia y realizar la consulta. Este proceso no suele ser el más indicado, tanto por tiempo como por consumo (CPU, disco, etc.). Un fichero comprimido en bzip2 de 300 Mb, siendo éste texto plano puede pasar ampliamente del Gb de espacio en disco una vez terminada la descompresión.
Para evitar tener que hacer todo esto os dejo una tabla a continuación con los comandos más habituales que se suelen emplear en ficheros y los tipos más habituales de compresión en GNU/Linux.
gzip bzip2 lzma xz
cat zcat bzcat lzcat xzcat
cmp zcmp bzcmp lzcmp xzcmp
diff zdiff bzdiff lzdiff xzdiff
grep zgrep bzgrep lzgrep xzgrep
egrep zegrep bzegrep lzegrep xzegrep
fgrep zfgrep bzfgrep lzfgrep xzfgrep
more zmore bzmore lzmore xzmore
less zless bzless lzless xzless
Como se puede observar existen herramientas para manejar directamente los ficheros comprimidos sin necesidad de extraer su contenido. El propio comando lo hace automáticamente. Los menos habituales son los referentes a las dos últimas columnas, comandos que están disponibles en los paquetes xz-lzmaxz-utils.
Leer más

MySQL version info

MySQL o Percona, del que ya hablamos largo y tendido en este blog permite obtener mucha información de la versión y las opciones de compilación con las que fue creado el binario.
Es muy raro que se compile el paquete propiamente dicho (configure & make & make install), sino que se suelen obtener paquetes de los repositorios oficiales de la distribución que se use. Dichos paquetes fueron compilados por alguien y las opciones con las que fueron creados suelen ser,
  • version: Es la versión exacta del servidor MySQL. Concatenada a la versión puede estar alguna característica con la que fue compilado. Éstas pueden ser:
    • log: Tiene soporte para logs.
    • debug: Está compilado con soporte para depuración.
  • version_comment: Contiene el comentario que se haya especificado durante la compilación. Si es un paquete propio, aquí se puede poner la información del creador. Se añade esta información con la opciones --with-comment.
  • version_compile_machine: Arquitectura para la cual el servidor fue compilado. Generalmente i686 o x86_64.
  • version_compile_os: Sistema operativo para el que fue compilado.
    Para sistemas GNU/Linux las opciones que típicamente hay son: "Linux", "unknown-linux-gnu", "pc-linux-gnu".
mysql> show variables like 'version%';
+-------------------------+------------------------------------+
| Variable_name           | Value                              |
+-------------------------+------------------------------------+
| version                 | 5.5.27-28.1-log                    |
| version_comment         | Percona Server (GPL), Release 28.1 |
| version_compile_machine | i686                               |
| version_compile_os      | Linux                              |
+-------------------------+------------------------------------+
4 rows in set (0.00 sec)
Leer más

OpenSSH, denegar acceso por usuarios/grupos

OpenSSH es el servidor SSH open source que está incluido en prácticamente todas las distribuciones de GNU/Linux y Unix en general. Es muy potente y versátil a la vez. Tiene un fichero de configuración principal, /etc/ssh/sshd_config, que es muy potente y esconde ciertas directivas que permiten definir muy bien quién puede y no puede acceder al equipo, dándole así un punto extra de seguridad.
En este post vamos a ver las directivas de denegación de acceso y cómo poder usarlas. Existen dos tipos de directivas, denegación por usuario y denegación por grupo. A continuación se verá un ejemplo de ambas.
  • DenyUsers
    Se especifica aquellos usuarios a los que se desea bloquear el acceso. Por defecto, ssh permite acceder a todos los usuarios del sistema. Si se especifica con la directiva DenyUsers una lista de usuarios, a éstos no les será posible iniciar sesión por ssh en el sistema.
    DenyUsers user_1 user_2 user_3
    
  • DenyGroups
    El funcionamiento es muy similar al de los usuarios, simplemente que permite especificar un grupo que contenga usuarios.
    Esto ofrece la ventaja de ante un nuevo usuario que no se le quiera permite el acceso, simplemente lo agregamos al grupo bloqueado y ya no podrá acceder. Si empleamos el DenyUsers habría que editar el fichero de configuración de ssh y recargar el servicio.
    DenyGroups group_no_ssh
    
Leer más

Zabbix, howto monitoring raid hardware

El otro día me preguntó un compañero cómo hacer para monitorizar un RAID desde zabbix. Tras las primeras pesquisas, la pregunta obvia es qué tipo de RAID se quiere monitorizar, hardware o software. Cada uno tiene sus utilidades y sus métodos de acceso y control.
En este post vamos a comentar cómo hacer para monitorizar el estado de un RAID hardware, concretamente un RAID que emplee el módulo megaraid del kernel. Aunque realmente tanto da la utilidad que empleemos, pues a nivel de zabbix realmente es lo mismo. Algo consultará el estado del RAID y nos lo devolverá y será zabbix el encargado de notificarnos si se ha producido un cambio de estado o no.
En este caso, para hacerlo más real y con datos de equipos de verdad en el que comprobar que funcionen, vamos a ver cómo emplearlo. Lo primero será comprobar que nuestra controladora RAID es compatible con el software que vamos a instalar, MegaRAID SAS, para ello el módulo megaraid* deberá estar cargado.
shell> lsmod |grep raid
megaraid_sas           45561  2
Como podemos observar lo tenemos disponible. Por lo tanto vamos a instalar el software necesario. Éste no está disponible en los repositorios oficiales de debian/ubuntu, así que tendremos que recurrir al repositorio que el propio fabricante ofrece. Creamos para ello el fichero /etc/apt/sources.list.d/megaraid.list con el siguiente contenido, según sea debian/ubuntu y la versión del mismo.
# ubuntu
deb http://hwraid.le-vert.net/ubuntu/ lucid main

#debian
deb http://hwraid.le-vert.net/debian/ squeeze main
Tras ello,
shell> apt-get update
Ahora que ya tenemos los paquetes disponibles, vamos a ver lo que hay para instalar,
shell> apt-cache search megaraid
  dellmgr - Manage DELL PERC/CERC cards based on LSI MegaRAID chip
  megacli - LSI Logic MegaRAID SAS MegaCLI
  megaclisas-status - get RAID status out of LSI MegaRAID SAS HW RAID
  megactl - LSI MegaRAID SCSI/SAS reporting tool
  megamgr - Manage LSI MegaRAID chip based cards
  megaraid-status - get RAID status out of LSI MegaRAID SCSI/SAS HW RAID
Estos son los nuevos paquetes disponibles, así que instalamos el software que nos interesa para monitorizar el estado de RAID. Aunque hay más utilidades, en este caso sólo nos interesa controlar el estado del equipamiento.
shell> apt-get install megaraid-status megaclisas-status
Cuando finalice la instalación de todo el nuevo software se iniciará un pequeño daemon, megaraidsas-statusd, que se encargará de chequear el correcto funcionamiento del RAID y en caso de que detecte alguna variación de estado, enviará un mail de advertencia. Este comportamiento es por defecto y si no nos interesa, simplemente paramos el nuevo daemon y listo.
A nosotros lo que realmente nos interesa es que nuestra herramienta de monitorización, zabbix, lea el estado del RAID en nos envíe una alerta en caso de que algo falle. Para hacerlo tendremos que ejecutar el comando megaraidsas-status (en mi caso, ya que tengo una unidad sas) o megaraid-status en cualquier otro caso. La salida que este comando nos ofrece es la siguiente,
shell> megaraidsas-status
  -- Arrays informations --
  -- ID | Type | Size | Status
  a0d0 | RAID 17 | 0B | optimal

  -- Disks informations
  -- ID | Model | Status | Warnings
  a0e64s0 | ATA ST950NS 465GiB | online
  a0e64s1 | ATA ST950NS 465GiB | online
  a0e64s2 | ATA ST950NS 465GiB | online
  a0e64s3 | ATA ST950NS 465GiB | online
Primero nos informa acerca del estado del RAID completo (en mi caso optimal) y luego del estado de cada uno de los discos (en este caso, online los 4 discos que tengo).
Si este mismo comando lo ejecutamos en un equipo que tenga el RAID con un disco fallando, la salida será,
shell> megaraidsas-status
  -- Arrays informations --
  -- ID | Type | Size | Status
  a0d0 | RAID 17 | 0B | DEGRADED

  -- Disks informations
  -- ID | Model | Status | Warnings
  a0e64s0 | ATA ST950NS 465GiB | online
  a0e64s1 | ATA ST950NS 465GiB | online
  a0e64s2 | ATA ST950NS | BAD
  a0e64s3 | ATA ST950NS 465GiB | online
  There is at least one disk/array in a NOT OPTIMAL state.
Como podemos observar nos está diciendo que el disco 3 está BAD y por lo tanto el estado general del RAID es DEGRADED. Así de fácil sabemos desde nuestro sistema GNU/Linux que un RAID ha fallado y además qué disco es el que falló.
La pregunta ahora es, cómo unir esto con zabbix. Pues simplemente creamos una nueva key como la que sigue,
zabbix: item RAID status
Las partes importantes del nuevo Item son:
  • Key: system.raid.status
  • Type of information: Text
La key que hemos creamos no existe, sino que 'nos la hemos inventado' y por lo tanto necesitamos crearla en el equipo. Para hacer este tipo de cosas, en el fichero de configuración del agente zabbix (zabbix_agentd.conf) tenemos los UserParameter, que son parámetros o key's que creamos nosotros directamente y hacemos que nos devuelven el valor que deseamos. Para usarlo con el software de MegaRAID debemos crear un nuevo UserParameter tal que así,
UserParameter=system.raid.status, /usr/sbin/megaraidsas-status | grep RAID | awk '{print $8}'
Si ejecutáis el comando completo podréis ver que la salida es optimal o DEGRADED, según el estado del RAID. Lo que a nosotros nos interesa es justamente eso, almacenar una única cadena ya que luego a la hora de hacer un trigger será mucho más simple.
Si lo hacéis tal que así, obtendréis un maravillo error "ZBX_NOTSUPPORTED", esto es por que el usuario zabbix no tiene permisos para ejecutar dicho comando. Lo ideal sería ahora darle permisos en el fichero /etc/sudoers para permitirle la ejecución, sin embargo esto no funciona. Tras dárselo aparecerá un nuevo fallo.
shell> sudo -u zabbix /usr/sbin/megaraidsas-status 
unable to open device /dev/megaraid_sas_ioctl_node: Permission denied
No se permite acceso al dispositivo como usuario zabbix, así que investigando un poco lo que hace el daemon, es sencillo creo un nuevo UserParameter que funcione y además así nos aseguramos de tener el daemon también ejecutándose. Este nuevo servicio crea, por defecto, bajo /var/run dos ficheros megaraidsas-statusd.[pid|status]. El segundo es el que almacena la salida y que sí puede ser leído por cualquier usuario sin problema ninguno. Así que lo vamos a emplear para tal efecto. Puesto que dicho fichero sólo existe si hay un fallo en el RAID, vamos a dejar el UserParameter así,
UserParameter=system.raid.status, if [ -e /var/run/megaraidsas-statusd.status ]; then cat /var/run/megaraidsas-statusd.status | grep RAID | awk '{print $8}'; else echo "optimal"; fi
Si existe recuperamos el valor, si no existe es el que RAID está correcto y devolvemos optimal.
Ahora que ya tenemos el Item y podemos recuperar valores, sólo queda crear un trigger que salte en caso de que el estado del RAID no sea optimal. Para ello, creamos un nuevo trigger relacionado con el Item recién creado y con estos valores:
  • Name: {HOSTNAME} RAID problem
  • Expression: {Template Linux RAID:system.raid.status.str("DEGRADED")}=1
  • Severity: High
  • Enabled: True
Con ello cualquier RAID que sufra algún problema zabbix nos alertará inmediatamente.

La entrada Zabbix, howto monitoring raid hardware la puedes leer en Puppet Linux.
Leer más

MySQL Master -- Slave


Una de las formas que tiene MySQL de implementar la alta disponibilidad de datos, sin irnos a arquitecturas muy complejas es el uso de máster-slave. Un servidor hace de principal o máster y otro u otros hacen de secundarios o slaves. Este tipo de arquitectura favorece desde la alta disponibilidad hasta una mejora de rendimiento. La primera se consigue gracias a tener todos los datos replicados. Aunque un equipo falle, todos los datos siguen estando disponibles en otro de los nodos. Mientras que la segunda se consigue empleando el máster para escrituras y el resto de nodos slave para lecturas. Como todos tendrán los mismos datos, se podría leer de cualquiera de los nodos del clúster.
En este post vamos a revisar cómo montar un sistema máster-slave en MySQL. Para ello tenemos que tener en cuenta los siguientes datos:
  • Un master puede tener N slave's.
  • Un slave sólo puede tener un master.
  • Cada slave tiene que tener un ID único.
Aunque en arquitecturas más complicadas esto se puede mejorar, para comenzar vamos a trabajar tal que así. Para ello partimos de lo siguiente:
  1. Master -- 192.168.0.33 -- id: 1
  2. Slave -- 192.168.0.35 -- id: 2
Ambos equipos cuentan ya con un servidor MySQL funcionando y en la misma versión 5.1.X o 5.5.X. Por lo tanto vamos ya a configurar la replicación, que no será nada complejo.
Master:
  1. Configuramos el servidor MySQL (/etc/my.cfg)
    Las siguientes líneas deben estar en la configuración del servidor.
    log-bin   = mysql-bin
    server_id = 1
    
  2. Reiniciamos el servicio
    shell> service mysqld restart
    
  3. Creamos una usuario de replicación
    mysql@master> GRANT REPLICATION SLAVE, REPLICATION CLIENT \
               -> ON *.* \
               -> TO remote_user@'192.168.0.35' \
               -> IDENTIFIED BY 'remote_user_passwd';
    
Slave:
  1. Configuramos el servidor MySQL (/etc/my.cfg)
    Las siguientes líneas deben estar presentes en la configuración del servidor MySQL. Es importante, si tenemos varios slave's, que cada uno tenga un server_id diferente.
    log-bin           = mysql-bin
    server_id         = 2
    relay_log         = mysql-relay-bin
    log_slave_updates = 1
    read_only         = 1
    
  2. Reiniciamos el servicio
    shell> service mysqld restart
    
Llegados a este punto ya sólo queda  iniciar la replicación entre todos los slave's que deseemos. Para que todo funcione y haya una consistencia de datos tenemos que tener en cuenta los siguientes puntos básicos:
  • Copia de los datos del máster
    shell> mysqldump -u root -p --master-data=2 > all.sql
    
  • Fichero de log del máster al que apunta el binary-log y punto exacto del mismo. Este valor se obtiene con el comando "SHOW MASTER STATUS".
    mysql@master> SHOW MASTER STATUS;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 |       98 |              |                  | 
    +------------------+----------+--------------+------------------+
    
    1 row in set (0.00 sec)
    
Una vez que tenemos todos los datos que nos interesa pasamos el dump reciente a los equipos que harán de slave y cargamos los datos en el servidor.
mysql@slave> SOURCE /home/javier/all.sql
Y a continuación configuramos el servidor réplica para que comience a funcionar,
mysql@slave> CHANGE MASTER TO MASTER_HOST='192.168.0.33',
          -> MASTER_USER = 'remote_user',
          -> MASTER_PASSWORD = 'remote_user_passwd',
          -> MASTER_LOG_FILE = 'mysql-bin.000001 ',
          -> MASTER_LOG_POS = 98;
Lo que acabamos de hacer es configurar en el MySQL slave el servidor máster, donde le indicamos la IP, el usuario/contraseña de conexión y el punto desde donde debe comenzar a replicar. Se supone que antes de este punto ya tenemos todos los datos (recién importados del dump). Sólo queda arrancar el proceso de réplica.
mysql@slave> START SLAVE;
Y comprobar que el funcionamiento es el correcto,
mysql@slave> SHOW SLAVE STATUS;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host:10.0.0.1
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 951
Relay_Log_File: mysqld-relay-bin.000001
Relay_Log_Pos: 251
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 951
Relay_Log_Space: 407
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 382
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:

1 row in set (0.00 sec)

Si empleas este tipo de arquitectura, quizás te interese ver cómo hacer para que el Slave de MySQL sea de sólo lectura.

La entrada MySQL master -- slave la puedes leer en El mundo en bits.
Leer más

Permisos especiales: sticky bit, suid y sgid

GNU/Linux a mayores de los típicos permisos read - write - exec, tiene otros especiales y no tan comúnmente conocidos que permiten realizar tareas y establecer permisos más avanzados. En este post vamos a verlos e intentar explicarlos un poco.
  • sticky bit
    Establece que sólo el propietarios del directorio lo puede borrar o renombrar, sin importar los permisos que tenga. Es útil si se desea que varios usuarios puedan acceder a la información y modificarla, pero que ninguno, a excepción del usuarios que lo creó, la pueda borrar.
    El usuario root sí la puede borrar.
    La forma de establecer este permiso es con el flag +t,
    shell> chmod +t file
    shell> ls -l file
    -rwxr--r-T 1 javier javier 487327 Jul 23 16:10 file
    
  • suid
    Este es un bit muy especial y que permite ejecutar un fichero con el ID del propietario, y por lo tanto con todos los privilegios que éste tenga.
    Es un bit muy peligroso, ya que mal empleado puede poner en peligro el sistema al ejecutar un binario con privilegios de root, por ejemplo, desde un usuario sin privilegios.
    Para establecer un binario con este bit, +s
    shell> chmod u+s file
    shell> ls -l file
    -rwSr--r-T 1 javier javier 487327 Jul 23 16:10 file
    
  • sgid
    Es similar al anterior comentado, pero los permisos que se establecen son a nivel de grupo. Y al igual que el anterior, también lo hay que emplear con mucha precaución.
    La forma de usarlo, con +s.
    shell> chmod g+s file
    shell> ls -l file
    -rwSr-Sr-T 1 javier javier 487327 Jul 23 16:10 file
    
Nota: Si por defecto, la forma de establecer permisos es GNU/Linux en octal es con 0754, para por ejemplo (-rwxr-xr--), para establecer en octal los permisos a éstos bits especiales son,
shell> chmod 1000 file # for sticky bit
shell> chmod 2000 file # for suid
shell> chmod 4000 file # for sgid
Leer más

Cambiar en porcentaje de bloques reservados de una partición

En GNU/Linux los sistemas de ficheros ext3 y ext4 (y algunos más) cuando crean el sistema de ficheros reservan un porcentaje del espacio asignado para operaciones de root, es decir, le garantizan al administrador siempre tener poder trabajar. Esto resulta muy útil especialmente en particiones en las que se comparte espacio con usuarios que gastan mucho. Por defecto los sistemas de ficheros ext3/ext4 reservan el 5% de espacio total para root, y eso puede realmente llegar a ser mucho.
Sin embargo con el aumento de tamaño de los discos duros, formatear una partición de 2TB en ext4 supone (aplicando la pérdida de 5%) una reserva de casi 100Gb!, que realmente nunca se llegaran a ocupar. Cuando los discos eran pequeños, dicha reserva tenía sentido. Actualmente bajar ese porcentaje a un 1% o un 2% sería más que suficiente.
Este es un ejemplo práctico de lo que tenemos y lo que podemos conseguir.
shell> df -h
S.ficheros             Size  Used Avail Use% Montado en
/dev/sda3              3,7G  224M  3,3G   7% /
tmpfs                 1013M     0 1013M   0% /lib/init/rw
udev                  1008M  160K 1008M   1% /dev
tmpfs                 1013M     0 1013M   0% /dev/shm
/dev/sda1              471M   42M  405M  10% /boot
/dev/mapper/vg0-home   2,0G   68M  2,0G   4% /home
/dev/mapper/vg0-tmp    4,0G  137M  3,7G   4% /tmp
/dev/mapper/vg0-usr    7,9G  670M  6,9G   9% /usr
/dev/mapper/vg0-var    9,9G  3,5G  6,0G  37% /var
/dev/mapper/vg0-srv   1008G  200M  957G   1% /srv

shell> tune2fs -l /dev/vg0/srv | grep Reserved
Reserved block count:     13421772
Reserved GDT blocks:      960
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
Terminada de formatear la partición y con una reserva del 5%, podemos ver que acabamos de perder más de 40GB de disco, lo cual ya es un porcentaje significativo. Quizás el 5% no diga mucho, 40Gb dicen más.
Para evitar esta pérdida, vamos a reservar únicamente un 1%. La partición /srv no tendrá necesidad de tener tantos datos, pues en este caso estará destinada a almacenar información.
shell> tune2fs -m 1 /dev/vg0/srv
tune2fs 1.41.12 (17-May-2010)
Setting reserved blocks percentage to 1%
Empleamos la opción -m (reserved-blocks-percentage) para pasarle el porcentaje reservado que nos interesa mantener. Tras ello, comparamos la salida del espacio disponible,
shell> df -h
S.ficheros            Size  Used Avail Use% Montado en
/dev/sda3             3,7G  224M  3,3G   7% /
tmpfs                1013M     0 1013M   0% /lib/init/rw
udev                 1008M  160K 1008M   1% /dev
tmpfs                1013M     0 1013M   0% /dev/shm
/dev/sda1             471M   42M  405M  10% /boot
/dev/mapper/vg0-home  2,0G   68M  2,0G   4% /home
/dev/mapper/vg0-tmp   4,0G  137M  3,7G   4% /tmp
/dev/mapper/vg0-usr   7,9G  670M  6,9G   9% /usr
/dev/mapper/vg0-var   9,9G  3,5G  6,0G  37% /var
/dev/mapper/vg0-srv  1008G  200M  998G   1% /srv
Como podemos observar, estamos hablando de una "pérdida" de espacio de 10Gb, mucho más aceptable.
Leer más

MySQL, cambiar codeset del dump

A quién no le tiene pasado que saca un dump de la base de datos y la lleva a otro servidor y al importarla ve que los acentos o las ñ's no se visualizan correctamente. Esto es por el codeset que usaba el servidor origen y que el servidor destino no emplea, por lo que se hace un poco difícil trabajar así.
La solución más rápida es repasar todos los textos e ir cambiando los caracteres 'raros' por unos visibles y luego guardar nuevamente. Esto puede llegar a ser un trabajo tedioso y muy molesto, especialmente si tenemos que hacerlo en una gran cantidad de noticias.
Para evitarlo, podemos hacerlo de dos formas.
  1. Sacar el dump en el codeset que nos interese
    Esta es una forma muy simple de atajar el problema. Si sabemos que el servidor destino no va a comprender un codeset determinado, forzamos a MySQL a exportar los datos en el que nos interese y así a la hora de importarlo ya tendremos el trabajo hecho.
    shell> mysqldump -p --default-character-set=utf8 > mysql.sql
    
  2. Transformar el dump al codeset deseado antes de importarlo
    Si no podemos hacer uso de la primera estrategia, nos queda la opción cambiar el codeset justo antes de importarlo. Para eso, GNU/Linux tiene el comando iconv, que nos permite pasar de un code a otro de forma muy rápida y sencilla. Al finalizar ya tendremos el archivo en el code que nos interese importar.
    Por ejemplo a continuación vemos como pasar el dump extraído de un MySQL en Windows a un nuevo servidor en GNU/Linux.
    shell> iconv \
           --from-code=ISO-8859-1 \
           --to-code=UTF-8 \
           dump.sql > new_dump.sql
    
Leer más

metasploit, borrar log's de Windows

Tras realizar un acceso no deseado a un equipo con Windows y tras garantizarnos próximos acceso a dicho sistema, la idea es dejar el mínimo rastro posible. Esta es una de las tareas más importantes en la post-explotación, la ocultación. Windows guarda una especie de log's o registros del sistema para poder saber qué es lo que está pasando, así que una de las formas más sencillas de poder ocultar el acceso, es lógicamente borrarlos. Por suerte, metasploit en meterpreter trae consigo un par de componentes que ayudan a realizar esta tarea. El primero es el uso del modo incógnito, que lo que hace es intentar ocultar todo lo posible todas aquellas tareas que se hagan en el sistema, así como la presencia de un "no deseado" en el mismo.
meterpreter> load incognito
Otra de las formas que hay es borrar los registros que hemos mencionado. Esto es lo mejor que se puede realizar justo antes de abandonar el equipo, para borrar rastro creado en los mismos. Se borrará todo el contenido de los registros.
meterpreter> clearev
[*] Wiping 88 records from Application...
[*] Wiping 136 records from System...
[*] Wiping 0 records from Security...
Leer más

Limitar/prohibir el uso de ini_set

El otro día me pasó un caso cuando menos curioso. En uno de los equipos que administro en el trabajo que hace de servidor web se instaló una nueva página que fue desarrollada externamente. Llegó al equipo, se instaló y comenzó a trabajar. Hasta ahí el proceso todo correcto, pero al día siguiente comenzaron a llegar mensajes a los log's de que la web estaba a sobrescribir el valor del máximo de memoria permitido por php, logrando así más memoria de la que debiera. Para hacer esto simplemente hay que hacer uso desde php de init_set(). Así y de forma sencilla cualquier página web escrita en php puede volver a darles valor a las variables definidas en el php.ini. Esto desde luego no me gustó nada, pero tampoco sabía cómo lograr evitar que eso sucediera. Así que me puse a investigar un poco cómo poder lograrlo y por fin encontré la solución: php_admin_value y php_admin_flag.
Estas dos directivas de php se pueden incluir en el virtualhost que nos convenga limitar y establecer todas aquellas variables que queramos impedir que se sobrescriban. De esta forma tan sencilla limitamos el empleo discriminado de init_set y de los .htaccess en los virtualhost e impedimos que se vulnere la seguridad del sistema de forma directa.
<VirtualHost *:80>
   ...
   php_admin_value memory_limit 128M
   ...
</VirtualHost>
De esta forma tan sencilla se impide que el valor memory_limit se puede sobrescribir desde el código php escrito en la web.
La diferencia entre php_admin_value y php_admin_flag es únicamente que el primero es para variables con valor y la segunda para variables booleanas.

Se que en mi caso no tenía importancia alguna, ya que era código confiable, pero no está demás saber cómo impedir que se haga y ésta es una forma sencilla.
Leer más

Configuración PAM+SSH para permitir acceso SSH

Si justo en el post anterior hemos explicado cómo hacer para tener un fichero con los nombres de usuario a los que queremos denegar el acceso, también podemos hacer lo mismo pero a la inversa. Tener un fichero sólo con los nombres de los usuarios a los que permitiremos el acceso SSH. En realidad el funcionamiento es el mismo, sólo que cambia un poco la línea a añadir en PAM (/etc/pam.d/ssh).
...
auth required pam_listfile.so item=user sense=allow file=/etc/ssh/ssh.allow onerr=fail
...
Como se puede observar, ahora el tipo sense es allow, es decir, los usuarios que coincidan podrán acceder. Y para ser un poco más coherentes, cambiamos el nombre del fichero a /etc/ssh/ssh.allow.
Ahora si un usuario quiere poder acceder al sistema, tendrá que estar dentro de dicho fichero.
Leer más

Configuración PAM+SSH para denegar acceso SSH

Existen muchas formas de denegar el acceso de un usuario a un sistema GNU/Linux, pero quizás el empleo del módulo pam_listfile.so en SSH sea uno de los más efectivos y potentes.
Se puede dar el caso de que un usuario pueda tener que acceder al equipo localmente, pero de ninguna forma nos interese que éste pueda acceder remotamente. En este caso, tener un listado de usuario al que denegarle el acceso sería más que interesante. Pues bien, esto es lo que vamos a configurar a continuación. Para ello, vamos a modificar el módulo SSH de PAM (/etc/pam.d/ssh) para indicarle que emplee la opción de una lista de usuario denegados, tal como sigue.
...
auth required pam_listfile.so item=user sense=deny file=/etc/ssh/ssh.deny onerr=succeed
...
Una explicación sencilla de la línea que acabamos de agregar es:
  • auth required pam_listfile.so
    Nombre del módulo requerido para validar los usuarios.
  • item=user
    Chequea el campo usuario.
  • sense=deny
    Deniega el acceso si el usuario está en el fichero especificado.
  • file=/etc/ssh/ssh.deny
    Fichero con los nombres de usuario (uno por línea)
  • onerr=succeed
    Devuelve un PAM_SUCCESS si hay un error.
Una vez tenemos agregada la línea anterior, simplemente creamos el fichero /etc/ssh/ssh.deny y escribimos los nombres de usuario a los que queramos impedir el acceso, uno por línea.
usuario_1
usuario_2
...
Desde este momento cualquier usuario que desee acceder al sistema y esté dentro del fichero ssh.deny no lo podrá hacer.
Leer más

Cómo crear un bonding en Debian

Si estás trabajando con equipos de sobremesa únicamente, quizás este post no te sea de gran utilidad/ayuda, pero si trabajas con servidores, desde luego te interesa! En muchos casos accedes a un equipo y ves que aunque teniendo varias tarjetas de red, éste sólo está a emplear una (eth0, por ejemplo). Crear un bond entre varias tarjetas de red debería ser como emplear un RAID para el disco, algo casi 100% necesario. Si los datos son importantes, tenerlos disponibles también debe ser importarte.
Hay que recordar que poner las tarjetas de red en bond puede hacerse para conseguir mayor velocidad (emplear 2 tarjetas como una sola) o también para tener redundancia (si una tarjeta 'cae', la otra asumirá el trabajo). Por lo tanto, vamos a ver cómo conseguir hacer lo aquí descrito de forma muy sencilla en sistemas debian/ubuntu. Antes de comenzar, tenemos que instalar el software necesario,
shell> apt-get install ifenslave-2.6
A continuación, habrá que crear la definición de la tarjeta de red compartida, bond0, que por ejemplo una eth0 y eth1. Para ello, agregamos la siguiente configuración en /etc/network/interfaces:
auto bond0
iface bond0 inet static
   address 192.168.1.2
   netmask 255.255.255.0
   network 192.168.1.0
   broadcast 192.168.1.255
   gateway 192.168.1.1
   slaves eth0 eth1
   bond-mode balance-rr # mode 0
   bond-miimon 100
   bond-downdelay 200
   bond-updelay 200
Y a continuación levantamos el nuevo interfaz, con lo que debería automáticamente cargar el módulo del kernel con las opciones descritas.
shell> ifup bond0
En caso de que no se levante correctamente el interfaz por culpa del módulo del kernel, debemos crear un nuevo fichero bajo /etc/modprobe.d/ a que podremos llamar bonding.conf con el siguiente contenido,
alias bond0 bonding
   options bonding mode=0 miimon 100 downdelay 200 updelay 200
Las opciones que pasamos como parámetros son:
  • mode
    Representa el modo de funcionamiento del interfaz, según la siguiente tabla.
    Modo Tolerancia Balanceo Descripción
    0 [balance-rr] - Balanceo Round-Robin
    1 No [active-backup] - Backup Activo
    2 [balance-xor] - Según MAC
    3 No [broadcast]
    4 [802.3ad] - Crea grupos esclavos con la misma configuración
    5 [balance-tlb] - Transmit Load Balancing
    6 [balance-alb] - Adaptative Load Balancing (con una única MAC)
  • miimon
    Es la frecuencia de monitorización de los interfaces, en ms.
  • downdelay
    Tiempo en ms para dar de baja un link caído.
  • updelay
    Tiempo en ms para dar de alta un link caído.
Leer más

Formulario de contacto

Nombre

Correo electrónico *

Mensaje *

Últimos comentarios