lunes, 1 de junio de 2015

Puerto serial con python y Arduino Mega2560

Siguiendo con las entradas al blog y aprovechando que ésta semana he tenido un poco de tiempo y teniendo a la madrugada como espacio de inspiración, publico un tema que tenía en el tintero desde ya hace tiempo. Manejo de puerto serial de la pc y comunicación a través de éste con el mundo exterior.
Si bien es cierto que el puerto serial está rezagado por el puerto USB, es necesario indicar que la comunicación serial es aún muy usada, ya que la comunicación bluetooth la usa, los xbee también, así como muchos otros equipos aún usan la comunicación serial bajo el protocolo RS232.
En este caso, el ejercicio que he realizado es el siguiente: Realizar una programación en python (lenguaje que últimamente he venido trabajando y en el cual he encontrado mucho potencial en la aplicación a mi maestría) que escriba datos en el puerto serial de tal manera que sean reconocidos por la interfaz externa y ejecute eventos en base a lo que reciben.
La interfaz externa usada es Arduino, que contiene 4 puertos seriales y cuya programación está diseñada para usar uno de ellos para recibir los datos que son enviados por python y ejecutar los eventos configurados.
El programa escrito en python envía a través del puerto serial 4 caracteres: R, G, Y, C que hacen referencia a los colores Red, Green, Yellow y el caracter C que hace referencia a la palabra Clear. Los caracteres RGY son generados y enviados de forma aleatoria. Esto lo realiza en un bucle que realiza 100 iteraciones ha razón 20 combinaciones por segundos y después de ello envía el caracter C para apagar los leds.
El programa escrito en Arduino configura el puerto Serial1 en modo escucha; al momento de recibir los caracteres enviados por la pc. Si recibe el caracter R, prende el led rojo, si recibe G, prende el verde y si recibe Y, prende el led amarillo. Cada color reconocido apaga los otros dos restantes.

Ahora, vamos a ver los programas escritos. Ambas configuraciones usan 9600 baudios de velocidad.

1. Programa en python
#!/usr/bin/python
#User: linux-pipux
#Ver : 0.1
#S.O.: debian 8
#Python 2.7
import serial
import time
import random

### parametros para el puerto serial ####
port = "/dev/ttyUSB0"
baurate = "9600"

### configuracion del puerto serial #####
s=serial.Serial(port, baurate, timeout=1)

#bucle
for i in range(100):
    a = random.choice(["G", "Y", "R"])
    s.write(str(a).encode() + '\r\n')
    time.sleep(0.05) # tiempo de transicion ON-OFF


#terminado el bucle, se escribe C para apagar los LED's
s.write(str('C').encode() + '\n')

exit();

2. Programa en arduino mega2560

#include <SoftwareSerial.h>
int red=7;
int yellow=6;
int green=5;
int entrada;
void setup() {
Serial1.begin(9600);
pinMode(red,OUTPUT);
pinMode(green,OUTPUT);
pinMode(yellow,OUTPUT);
}
void loop() {
if(Serial1.available()>0){
int entrada=Serial1.read();
if(entrada=='G'){
  digitalWrite(green, HIGH);
  digitalWrite(yellow, LOW);
  digitalWrite(red, LOW);
  Serial1.write(entrada);
}
if(entrada=='Y'){
  digitalWrite(green, LOW);
  digitalWrite(yellow, HIGH);
  digitalWrite(red, LOW);
  Serial1.write(entrada);
}
if(entrada=='R'){
  digitalWrite(green, LOW);
  digitalWrite(yellow, LOW);
  digitalWrite(red, HIGH);
  Serial1.write(entrada);
}
if(entrada=='C'){
  digitalWrite(green, LOW);
  digitalWrite(yellow, LOW);
  digitalWrite(red, LOW);
  Serial1.write(entrada);
}
}
}


En la placa arduino, los LED's están conectados a los puertos 5, 6, 7 con los colores verde, amarillo, rojo respectivamente.
Como mi placa no tiene puerto serie, estoy usando un convertidor USB-TTL que tiene salidas de 5V que alimenta a la placa arduino una vez programado.

imagen



Imagen de la programación en python y arduino.


En el siguiente enlace pongo un video donde se verifica su funcionamiento.
Video

En una próxima entrega, publicaré un post donde python lea temperatura de un sensor DS18B20 y que en función a la temperatura, se prenda un led en el arduino. Por ejemplo si la temperatura está por encima de los 25°C que se prenda el led rojo, si está entre los 23-25°C que se prenda el led amarillo y si está por debajo de los 23°C que se prenda el led verde. Esta vez lo haré con arduino, RaspberryPi y python.

domingo, 24 de mayo de 2015

Librerías científicas en lenguaje C - Debian

Después de mucho tiempo de no publicar por varias razones; trabajo, familia, maestría, ocio; vuelvo a publicar un tema que para mí es interesante y ahora más debido a que la maestría que estoy cursando actualmente (Maestría en Telecomunicaciones - UNI) exige cálculos matemáticos avanzados. Es bien sabido que estos cálculos son resueltos por el software MatLab, pero cada año se va haciendo más pesado y es por la gran cantidad de módulos y software especializado que viene de serie. Pero siguiendo la filosofía UNIX "Un programa que haga una cosa, pero que la haga bien", no creo necesario "piratear" (ya que no tengo el dinero para pagar la costosa licencia) para realizar cálculos específicos. Ojo no estoy diciendo que MatLab sea malo, sino que no veo la necesidad de instalar 15 GB de cosas que no voy a utilizar. Además que mi modesta portátil sufre un poco para levantar el programa.
Para matlab existe la alternativa bandera en el mundo del software libre: GNU/Octave. Este poderoso software, además de ser opensource, es potencialmente compatible con muchos comandos que se usan en matlab y posee una sintaxis 100% compatible. De este programa hablaré más adelante ya que merece una publicación diferenciada.

Ahora hablaré de una librería cuya existencia descubrí por casualidad realizando la siguiente consulta en la terminal:

kiko@debian8:~$ apt-cache search scientific | grep lib | sort
Me arrojó entre muchas librerías, unas que me llamaron la atención por su descripción:
libgsl0-dev - GNU Scientific Library (GSL) -- development package
liblapack-dev - Library of linear algebra routines 3
libblas3 - Basic Linear Algebra Reference implementations
libatlas3-base - Automatically Tuned Linear Algebra Software

Especial atención me llamó la librería GSL. Investigando un poco y leyendo su documentación oficial que se encuentra en http://www.gnu.org/software/gsl/manual/ veo que es una poderosa librería que justamente usa las librerías lapack, blas, atlas para realizar cálculos numéricos, cálculo de complejos y cálculo matricial; todo desde programación en C (que es mi preferido pero no soy ningún gurú, apenas aficionado novato).
Para instalar la librería, ejecutamos: sudo aptitude install libgsl0-dev

Veamos un ejemplo simple dada una función de segundo grado con una variable, le asignamos un valor a su variable para obtener el resultado.
La ecuación es la siguiente:
                                       
                                           
/*
el archivo tiene por nombre ecuacion.c y darle permisos de ejecución: 
chmod 700 ecuacion.c
para compilar usar: gcc -Wall -o ecuacion.o ecuacion.c -lgsl -lgslcblas
para ejecutar: ./ecuacion.o
debe arrojar este resultado: y=52
*/
#include <stdio.h>
#include <gsl/gsl_poly.h>
float x, resultado; 
int main (int argc, char *argv[])
{
        double coeficientes[] = { 7, 6, 3 };
        printf("Ingrese el valor en el que se desea evaluar la función -----> x = ");
        scanf("%f", &x);
        printf("El valor ingresado es: x = %f\n", x);

        resultado = gsl_poly_eval (coeficientes, 3, x);
        printf ("La función a evaluar es -----> y = 3*x2 + 6*x + 7\n");
        printf ("El resultado : y = 3*x2 + 6*x + 7 = %f\n", resultado);
  return 0;
}
Si notamos en la variable "coeficientes", se debe definir los coeficientes de la ecuación empezando por el término independiente continuando hacia el coeficiente de mayor grado.

Ponemos otro ejemplo simple (aunque la programación no tanto ya que me llevó horas leyendo su manual y aún me falta muchas horas más) para que se entienda más a lo que me refiero.
Vamos a calcular las variables de un sistema de ecuaciones lineales de primer grado de 4 variables usando la librería gsl.
Usaremos el ejercicio 1 de la siguiente página: http://profe-alexz.blogspot.com/2012/08/metodo-gauss-sistema-ecuaciones-4x4.html

[ 1 -1 0  0 ] [x] = [-6]
[ 0  1 1  0 ] [y] = [ 3]
[ 0  0 1  2 ] [z] = [ 4]
[ 2  0 0 -3 ] [t] = [ 5]

/*
el archivo tiene por nombre abcd.c y darle permisos de ejecución: chmod 700 xyzt.c
para compilar usar: gcc -Wall -o abcd.o abcd.c -lgsl -lgslcblas
para ejecutar: ./xyzt.o
debe arrojar este resultado: a=31; b=37; c=-34; d=19
*/
#include <stdio.h>
#include <gsl/gsl_linalg.h>
 
int main (int argc, char *argv[])
{
double a_data[] = { 1, -1, 0,  0,
                                0,  1, 1,  0,
                                0,  0, 1,  2,
                                2,  0, 0, -3 };
double b_data[] = { -6, 3, 4, 5 };

gsl_matrix_view m = gsl_matrix_view_array (a_data, 4, 4);
gsl_vector_view b = gsl_vector_view_array (b_data, 4);
gsl_vector *x = gsl_vector_alloc (4);
int s;
gsl_permutation * p = gsl_permutation_alloc (4);
gsl_linalg_LU_decomp (&m.matrix, p, &s);
gsl_linalg_LU_solve (&m.matrix, p, &b.vector, x);
printf ("El valor de cada variable es = \n");
gsl_vector_fprintf (stdout, x, "%g");
gsl_permutation_free (p);
gsl_vector_free (x);
return 0;
}

Al momento de compilar se debe llamar a las librerías gsl y gsclbas que es donde se encuentran definidas todas las entradas que permiten ejecutar las operaciones.
Como se puede apreciar, no hay necesidad de instalar 15GB de matlab, sólo 3MB que es lo que ocupa la librería gsl y sus dependencias.
Lo que sí tenemos que invertir es tiempo en leer su extenso manual donde se define y explica cada comando.

Bueno, espero les haya animado este nano-resumen sobre las librerías de computación científica a investigar.

En la maestría uso python y sus diversos módulos: numpy, scipy, matplotlib, sympy, etc para realizar cálculos avanzados como por ejemplo la más aplicada en mi carrera, La transformada de fourier y todo lo relacionado a ello, pero también al igual que GNU/Octave, tendrá una entrada especial en un posterior post.

Por lo pronto sigo practicando con esta potente librería GSL y acabo de descubrir que hay otra librería especial para trabajar con FFT en C (la verdad que ahora entiendo porque la comunidad científica usa software GNU).
Iré poniendo mis resultados conforme vaya avanzando.
Los invito a instalar las librerías y ejecutar el código para que se vayan familiarizando.

Nos vemos.

--
JPC


miércoles, 26 de septiembre de 2012

Primeros Pasos con Samba File Server; Configuración básica smb.conf

Siguiendo con este uHowTo, ahora pasamos a instalar samba en nuestro server.
Samba es servicio que permite interactuar con redes UNIX - Windows. Se pueden configurar con diversas formas de autenticación, ya sea por user/passwd; domain, server, o share.
Cada uno tiene su ventajas, de los cuales el menos aconsejable es el método share que como lo dice el mismo manual de Red Hat "Los desarrolladores de Samba no recomiendan el uso de la seguridad a este nivel."

 
Empecemos:

root@pruebas:~#aptitude install samba

Instalará las dependencias correspondientes y al final creará entre otras cosas el archivo de configuración de samba en /etc/samba/smb.conf

Luego agregamos los usuarios creados en el tutorial anterior a la base de datos de samba.
root@pruebas:~# smbpasswd -a user1
root@pruebas:~# smbpasswd -a user2
root@pruebas:~# smbpasswd -a user3
En cada uno nos va a pedir que ingresemos su contraseña respectiva que no necesariamente es la misma con la que se hace login en el sistema y es la que usaremos al momento de autenticarnos en los clientes en este caso en los clientes windows.
 
Creamos una copia de seguridad;
root@pruebas:~# cp -p /etc/samba/smb.conf /etc/samba/smb.conf.backup

Ahora para mayor comodidad vamos a eliminar las líneas comentadas. Ésto lo podemos hacer a mano pero la flexibilidad de la terminal y los scripts nos pueden hacer la tarea más facil. Para ello usaremos el comando sed como bien lo tiene documentado nuestros amigos de gentoo en español ( gracias www.gentoo.org por los manuales que son espectaculares). 
root@pruebas:/etc/samba# sed '/#/d' smb.conf.original > smb1.conf && rm smb.conf
root@pruebas:/etc/samba# sed '/^$/d' smb1.conf > smb.conf && rm smb1.conf
Con el primer comando elimino todas las líneas que empiezan con # y lo guardo en un archivo temporal smb1.conf y elimino el archivo smb.conf y con el segundo comando lo que hago es eliminar las líneas en blanco del archivo temporal smb1.conf y guardardo en smb.conf y elimino el archivo temporal smb1.conf.

Listo ahora nos queda un bonito smb.conf para empezar a personalizarlo deacuerdo a nuestras necesidades.

root@pruebas:/etc/samba# cat smb.conf
[global]
   workgroup = mipc
   server string = %h server
   dns proxy = no
   interfaces = 127.0.0.0/8 eth0 172.16.1.0/24
   log file = /var/log/samba/log.%m
   max log size = 1000
   syslog = 0
   panic action = /usr/share/samba/panic-action %d
   encrypt passwords = true
   passdb backend = tdbsam
   obey pam restrictions = yes
   unix password sync = yes
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
   pam password change = yes
   security = user
[homes]
   comment = Home Directories
   browseable = no
   read only = no
   create mask = 0755
   directory mask = 0755
   valid users = %S
[printers]
   comment = All Printers
   browseable = no
   path = /var/spool/samba
   printable = yes
   guest ok = no
   read only = yes
   create mask = 0700
[print$]
   comment = Printer Drivers
   path = /var/lib/samba/printers
   browsable = yes
   read only = yes
   guest ok = no
 

Ahora empezaremos por modificar la línea:
         "workgroup = mipc"

En mi caso le puse = mipc; Ojo esto es el nombre de Grupo, no confundir samba es un servidor NetBios y el formato es solo el nombre, no se puede colocar por ejemplo mipc.com
Luego modificamos la línea:
 interfaces = 127.0.0.0/8 eth0 172.16.1.0/24
y ahí asignamos a samba en que interfaz debe escuchar y en que segmento de red. Yo por facilidad le he puesto que escuche en toda la red 172.16.1.0/24

Luego agregamos el parámetro:
security = user
Esto indica que para acceder a los recursos compartidos se tendrán que autenticar con un usuario/passwd válido en samba. Ojo no es lo mismo usuario de sistema que usuario de recursos compartidos en samba.

El resto de líneas las podemos dejar como está.   

Ahora, pasamos a configurar lo que deseamos compartir:
Yo voy a compartir la carpeta sistemas de propietario sistemas y grupo sistemas y una carpeta shared de propietario nobody y grupo nogroup.

[shared]
    comment = Compartido de users
    path = /home/compartido
    browsable = yes
    writable = yes
    force directory mode = 0777
    guest ok = yes
[sistemas]
    comment = Compartido de users
    path = /home/sistemas
    browseable = no
    writeable = yes
    force directory mode = 0750
    force create mode = 0750
    directory mask = 0750
    create mask = 0750
    force group = sistemas
    valid users = @sistemas
    read list = user3


Con esto he creado un recurso compartido llamado shared que tiene permisos 777 para todo lo que sea creado y que fuerce en cualquier caso contrario, además que se salte la autenticación por usuario con la línea guest ok = yes
Cosa que cualquiera pudiera modificar, leer, ejecutar todo lo que se encuentre aquí. Esto es un recurso útil cuando se quiere un directorio donde todos los usuarios de la red puedan compartir de manera fácil y sin restricciones.
Por el contrario, he creado un recurso sistemas donde sólo los usuarios que son parte del grupo sistemas pueden ingresar y eso lo hago con la línea valid users = @sistemas. Aquí he forzado a que cada carpeta creada por cada usuario tenga los permisos 750, osea que sólo el propietario tiene acceso total a lo que él crea y solo lectura y ejecución a los usuarios que forman parte del grupo sistemas. Esto con la finalizad de garantizar la autoria y autonomía de archivos al usuario creador.

Aqui podemos ver el poder de la jerarquía de permisos en UNIX-LINUX; y es que la línea read list = user3 la he colocado a propósito para verificar que a pesar de haberla colocado y que autoriza al user3 a por lo menos leer los archivos y directorios creados por los usuarios del grupo sistemas, el sistema samba no lo deja ni siquiera entrar, ya que el permiso para "otros" está deshabilitado con la máscara 770.

Con esto podemos seguir creando los recursos que quisieramos, por ejemplo para las diferentes áreas de la empresa que administramos, podemos separar por áreas como contabilidad, finanzas, gerencias, RRHH y que ellos no sepan que existen más recursos compartidos más que la que ha sido asignado.

Más adelante veremos como podemos obtener seguridad a través de usuarios autenticados contra LDAP y así poder configurar un controlador de dominio primario. Todo ésto es posible con el samba actual, que en debian squeeze es 3.5.6.

También veremos como la jerarquía de permisos tradicionales tienen algunas deficiencias frente a las ACL complejas que tienen los sistemas actuales de windows y su sistema de archivos NTFS. Pero en linux también tenemos ACL para manejar escenarios en que los permisos tradicionales simplemente no funcionan. Eso lo veremos en una próxima entrada.


Primeros pasos con Samba File Server. Entendiendo la Jerarquía de permisos.

He decidido adelantar este pequeña entrada ya que un seguidor me ha pedido apoyo en ésta a veces "complicada" tarea de configurar Samba con los parámetros mínimos de autenticación y que funcione como uno quiere.
Como ya expliqué en una de mis primeras entradas sobre tema de permisos en Linux, linux y en general UNIX siguen jerarquías al momento de tomar decisiones que involucran la seguridad de un directorio ya sea que esté compartido o de acceso local en nuestro servidor.
Para explicarlo mejor pondré un ejemplo:
Creo un usuario sistemas y por default me crea su home:
root@pruebas:~# adduser sistemas
root@pruebas:~# ls -l /home
drwxr-xr-x 3 sistemas sistemas 3096 sep 26 11:30 sistemas

Como vemos se ha creado el home de sistemas con propietario y grupo sistemas y con permisos 755. Esto y muchos parámetros más se pueden cambiar modificando el archivo de configuración /etc/adduser.conf
Nota: En centos al crear un usuario el home por defecto tiene permisos 700 (Centos 5.8). Yo lo que hago es que cambiarle permisos y ponerle 770 para que solo el propietario y los miembros del grupo puedan realizar todas las tareas en esa carpeta en sus carpetas creadas.

Ahora si tenemos más usuarios en el sistema y queremos que alguno de ellos pertenezcan al grupo sistemas. Por ejemplo tenemos user1 user2 user3 creados y queremos que user1 user2 pertencezcan al grupo sistemas:
root@pruebas:~# adduser user1 sistemas && adduser user2 sistemas


Entonces user1 y user2 podrán crear carpetas dentro del home sistemas y cada carpeta tendrá los permisos respectivos de cada usuario (755)
root@pruebas:/home/sistemas# ls -l
drwxr-xr-x 2 user1 user1 4096 sep 26 11:30 dir_creado_por_user1
drwxr-xr-x 2 user2 user2 5096 sep 26 11:31 dir_creado_por_user2

Hasta aquí todo normal y entendible.
Pero que pasa si user3 quisiera leer el contenido del directorio creado por user1 dentro del directorio sistemas?
Deacuerdo a la tabla de permisos asignados a dicho directorio, cualquier usuario tiene al menos permisos de lectura sobre él. En teoría, el user3 podría leer el contenido; pero si lo intentamos nos saldrá permiso denegado.
Pero que pasó?  Recuerden que yo cambié los permisos a la carpeta sistemas de 755 a 770, osea que, a menos que el user3 sea el propietario o pertenezca al grupo sistemas, no podrá ni siquiera leer el contenido del interior de sistemas.
Y esto es explicable por la jerarquía de permisos. La teoría dice que UNIX realiza un bucle recursivo sobre los permisos de los directorios y aplica el permiso más restrictivo. Esto porque linux y en general UNIX realiza la operación booleana OR (multiplicación) sobre el equivalente en bits de los permisos.
Para nuestro caso, esto sería:
SISTEMA OCTAL      SISTEMA BINARIO
        770                          111 111 000   ------------------> permisos de sistemas
        755                          111 101 101   ------------------> permisos dentro de sistemas   ------------------------------------------------------------------
        750                          111 101 000 (aplicamos OR = multiplicación)

Entonces nos resultaría que cualquier usuario que no sea el propietario ni pertezca al grupo no podrá ejecutar alguna acción sobre los directorios creados dentro de la carpeta sistemas.

#!/bin/bash
echo "Fin primera parte. Pulse enter para continuar"
if [enter=!0]
echo "presionó tecla equivocada"
fi
echo "end"

domingo, 23 de septiembre de 2012

Simple y Fácil; Server DHCP

Por temas laborales no he tenido tiempo para seguir llenando mi blog con entradas que nos ayuden en el día día de un administrador de red, por lo que hoy me he propuesto combinar la instalación de un server DHCP y DNS en un sólo repaso ya que esto lo emplearé para realizar una solución que resulta un poco confusa cuando se empieza a indagar por la web; es que realizar un servidor DHCP "dinámico" es una tarea un poco fina de majear.
Hoy instalaremos y dejaremos a punto de producción un servidor DHCP usando isc-dhcp-server y un servidor DNS usando bind9 de manera independiente pero funcional. Más adelante entraré en el "trabajo" de unir ambos servicios y generar un named.conf dinámico con las ip's asignadas a cada máquina con su nombre respectivo. Ésto para que cuando uno quiera probar conectividad con alguna máquina de nuestra red, no lo tengamos que realizar con su IP sino con su nombre designando, esto es: en lugar de realizar ping 172.16.1.x deberíamos poder realizar ping nombre_host ( por ejemplos: ping sistemas01) y así evitaríamos aprendernos cada IP asignada a cada máquina de cada usuario de cada departamento de la empresa donde administramos la red.
Siempre recalco que los pasos a seguir durante la instalación son para debian y derivados (con algunas pequeñas modificaciones) y para otras distribuciones si es un poco diferente pero las modificaciones de los archivos de configuración prácticamente es la misma.

Empecemos:

Instalacion de DHCP:
root@router:~# aptitude install isc-dhcp-server

luego modificar el fichero:
root@router:~# nano /etc/default/isc-dhcp-server

identificar la sgte línea:
INTERFACES="eth1"

y colocar la interfaz que recibirá las peticiones de IP's. Es muy común que nuestro DHCP también se comporte como gateway de nuestra red corporativa por lo que tendrá dos interfaces de red; normalmente la interfaz primaria eth0 es la que va conectada a la salida a internet y la eth1 es la que sirve a nuestra red interna, por eso en la línea INTERFACES coloco "eth1". Después de esto guardamos y cerramos y nos dirigimos a configurar nuestro server DHCP, ésto se consigue modificando el archivo:

root@router:~# nano /etc/dhcp/dhcpd.conf

En este archivo se coloca las configuraciones que definirán nuesto servidor DHCP como por ejemplo la puerta de enlace predeterminada, los DNS, el broadcast, la asignación estática de IP's etc.
Veamos un ejemplo de como en mi caso lo tengo instalado:


Es importante que se fijen que cada línea termina con ";" sino las colocan el servidor les va a mandar un error cuando se levante el servicio.
Con esas líneas básicas el servidor DHCP quedaría configurado; el rango de IP's a asignar van desde la IP 172.16.1.10 - 172.16.1.254 que es lo máximo que nos permite la máscara de red usada en este caso 255.255.255.0 ( o en hexadecimal /24)

Si iniciamos algún cliente (que puede ser una estación con windows) que se encuentre en la misma red de servicio de nuestro DHCP y verificamos el log del servidor veremos que el cliente le pide una IP al DHCP y éste le responde con una IP que se encuentra en el rango definido.



En este log podemos identificar lo sgte:
DHCPDISCOVER (para ubicar servidores DHCP disponibles) usuario.
DHCPOFFER (respuesta del servidor a un paquete DHCPDISCOVER, que contiene los parámetros iníciales)
DHCPACK (respuesta del servidor que contiene los parámetros y la dirección IP del cliente)


Como vemos, el servidor a identificado la MAC que solicita IP, le asigna la IP 172.16.1.210 y luego la guarda en su cache por el tiempo definido en archivo de configuración.

Para ver la tabla ARP del servidor podemos consultar al archivo:

root@router:~# cat /var/lib/dhcp/dhcpd.leases
# The format of this file is documented in the dhcpd.leases(5) manual page.
# This lease file was written by isc-dhcp-4.1.1-P1
server-duid "\000\001\000\001\027\306\303\032\010\000'\303w\247";

lease 172.16.1.210 {
  starts 1 2012/09/24 00:51:50;
  ends 1 2012/09/24 01:51:50;
  cltt 1 2012/09/24 00:51:50;
  binding state active;
  next binding state free;
  hardware ethernet 08:00:27:6c:73:4e;
  uid "\001\010\000'lsN";
  client-hostname "geren02";
}
Ahí se guarda la caché de las asignaciones de IP's que el servidor ha ido realizando. También le sirve como consulta ya que si un host es reiniciado antes del tiempo máximo de permanecer con una IP, éste le vuelve a reasignar la misma IP que tenía.

Ésta es la configuración base de todo servidor DHCP, al cual le iré agregando más cosas conforme las vaya requiriendo como por ejemplo, asignación de IP's estáticas a determinados host por medio de su MAC, o si deseamos un servidor PXE para arranque por red unido a un servidor TFTP y hasta asignación de IP's a VLANS que podamos crear en nuestra red interna como por ejemplo si tenemos 2 VLAN en nuestra red que podría ser la VLAN 10 = VLAN de host donde se encuentran las PC's de nuestra red que podría estar en el segmento 172.16.1.X /24 y la VLAN 20 = VLAN SIP donde se encontrarían nuestros teléfonos que usan el protocolo SIP y que se encuentren en el segmento de red 10.10.10.X /24 y así enlazaríamos nuestro servidor Asterisk (claro si tuvieramos uno en la red, particularmente tengo 2 asterisk locales y un asterisk remoto unido con el protocolo IAX administrándolos).

viernes, 16 de diciembre de 2011

Entendiendo La Cabecera IP en 21 segundos



Aunque ya estamos a puertas de usar la IPv6, faltará un poquito para que esto se extienda, así que seguiremos estudiando por unos años más el viejo y robusto IPv4.
Porque todos hemos oído hablar de este protocolo pero no muchos nos hemos dignado en indagar en su interior.
#################################################################################


0                                   15 16                                   31
.____________________________________________________________________________.___
| 4-bit  | 4-bit   |      8-bit       |              16-bit                  | |
|version |long.cab.|tipo de serv.(TOS)|  longitud total en bytes             | |
|________|_________|__________________|______________________________________| |
|           16-bit                    | 3-bit |         13-bit               | |
|       identificacion                | flags |   offset de fragmentos       | |
|_____________________________________|_______|______________________________|20 bytes
|     8-bit        |     8-bit        |             16-bit                   | |
|time-to-live(TTL) |  protocolo       |      chequeo cabecera                | |
|__________________|__________________|______________________________________| |
|                             32-bit                                         | |
|                        direccion IP origen                                 | |
|____________________________________________________________________________| |
|                             32-bit                                         | |
|                        direccion IP destino                                | |
|____________________________________________________________________________|_|_
|                           opciones                                         |
/                        (si las hubiere)                                    /
|____________________________________________________________________________|
|                                                                            |
|                           DATOS                                            |
|                                                                            |
/                                                                            /
|                                                                            |
|____________________________________________________________________________|
##################################################################################

-Version: hoy dia suele ser la 4 si es que es ipv4
-Longitud de cabecera: el limite es 60bytes (tb sirve para especificar si hay opciones)
-TOS: flags para darle luz o no a los datagramas: minimize delay, maximize throughput,
maximize reliability, y minimize monetary cost
-Longitud total: siendo un campo de 16 bits se deduce que el tamaño máximo de
un datagrama IP seria 65535. Aunque esto se suele fragmentar.
-Identificacion: un numero que identifica el paquete enviado (incremental)
-Flags
-Offset fragmentos: para cuando se fragmenta el datagrama.
-TTL: el tiempo de vida del datagrama. Para que no ande vagando eternamente
-Protocolo: TCP, UDP, IGMP, ICMP
-Chequeo cabecera: para la validacion de que los datos son correctos
-Direccion origen: Ip de origen
-Direccion destino: IP de destino
-Opciones: valores opcionales, seguridad, timestamp, registro de rutas...

Resumido para ser entendido, captado y retenido en tan solo 21 segundos.

Saludos Cordiales;


Fuente: http://es.wikipedia.org/wiki/Cabecera_IP

sábado, 19 de noviembre de 2011

Creando máquinas virtuales desde consola en servidor



Estimados;
Hoy presento un tema que me parece muy interesante y que me propongo a compartirlo. Se trata de optimizar recursos de hardware físico implementando máquinas virtuales dentro de nuestro servidor host.

Ha estas alturas todos sabemos que es una máquina virtual, softwares que emulan por hardware, etc, así que no detallaré los conceptos.

Ahora nos proponemos a aprovechar al máximo los recursos de nuestra PC para poder crear dentro de ella varias máquinas virtuales que se encarguen de gestionar diferentes servicios como si tuvieramos tantos servidores físicos como máquinas virtuales dispongamos. Esto es muy apreciable porque la carga que gestiona una máquina virtual no influye en el rendimiento de las otras y sólo depende de la potencia del equipo físico en el que se hospedan las mismas. Así que si deseamos tener varias máquinas virtuales gestionando diferentes servicios les recomiendo que la PC sea de muy buenas características tanto en procesador como en memoria RAM.

Bien, existen muchos softwares que sirven para nuestro fin como VMWare; VirtualPC, Qemu, KVM, OpenVZ, Xen, Virtualbox, todos ellos con sus ventajas y desventajas que tampoco detallaré en este tutorial.

Voy a usar virtualbox para tal fin ya que no pide mucho equipo para poder trabajar a comparación de VMWare.

La particularidad del presente trabajo es que todo lo haremos desde línea de comandos ya que suponemos que el SO host no tiene interfaz gráfica y sólo a se a instalado lo mínimo para que inicie el servidor.

Empecemos:
1. Instalando Virtualbox desde consola:
primero descargamos virtualbox. En mi caso yo uso Debian Squeeze 64 bits
zatoo@pruebas:~# wget http://download.virtualbox.org/virtualbox/4.1.6/virtualbox-4.1_4.1.6-74713~Debian~squeeze_amd64.deb

luego instalamos:
zatoo@pruebas:~# dpkg -i virtualbox-4.1_4.1.6-74713~Debian~squeeze_amd64.deb
Resolvemos las dependencias y listo, ya tenemos instalado virtualbox en nuestro servidor. Reiniciamos y listo.

luego instalamos el paquete extension_pack de virtualbox:
zatoo@pruebas:~# wget http://download.virtualbox.org/virtualbox/4.0.6/Oracle_VM_VirtualBox_Extension_Pack-4.0.6-71344.vbox-extpack && VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-4.0.6-71344.vbox-extpack

2. Creando máquinas virtuales desde línea de comandos
Consultando con el archivo de ayuda de virtualbox (man virtualbox) explica clara y detalladamente todos los comandos que maneja virtualbox.
Vamos a crear una máquina virtual que sea servidor web y que se llame www.mipc.com
zatoo@pruebas:~# VBoxManage createvm --name "www.mipc.com" --register

luego le asignaremos memoria RAM de 128 y le diremos que booteará desde el dvd virtual, le asignaremos su interfaz de red en modo bridge y utilizará la interfaz eth0 del SO host.
zatoo@pruebas:~# VBoxManage modifyvm "www.mipc.com" --memory 128 --acpi on --boot1 dvd --nic1 bridged --bridgeadapter1 eth0

luego crearemos un disco duro virtual donde instalaremos el SO hueped cuyo nombre será www_mipc_com.vdi y tendrá un tamaño máximo de 8gb incrementándose dinámicamente:
zatoo@pruebas:~# VBoxManage createhd --filename www_mipc_com.vdi --size 8000

luego creamos los controladores que manejarán al dvd y al disco duro virtual de la máquina virtual www.mipc.com:
zatoo@pruebas:~# VBoxManage storagect1 "ww.mipc.com" --name "IDE Controller" --add ide

luego asociamos el disco duro creado www_mipc_com.vdi a la máquina virtual creada www.mipc.com:
zatoo@pruebas:~# VBoxManage storageattach "ww.mipc.com" --storagectl "IDE Controller" --port 0 --device 0 --type hdd --medium www_mipc_com.vdi

y también asociamos una imagen del SO que se quiere instalar(la imagen es de debian6.0.3.iso que se encuentra el /root) al dvd virtual para poder instalarlo en la máquina virtual www.mipc.com:
zatoo@pruebas:~# VBoxManage storageattach "www.mipc.com" --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium /root/debian-6.0.3.1-amd64-CD-1.iso

Y con esto ya podemos iniciar la instalación del SO debian huésped en el SO host.
zatoo@pruebas:~# VBoxHeadless --startvm www.mipc.com
Ésto por default iniciará la máquina virtual en segundo plano en el puerto TCP 3389; así que desde cualquier cliente de sesiones remotas como el mstsc.exe (escritorio remoto de windows) o el grdesktop de debian podemos ingresar a la máquina virtual colocando la IP del servidor físico real y el puerto 3389 en donde está escuchando la máquina virtual: Así como en la figura:
















Una vez instalado el SO huésped en la máquina virtual huésped dentro del servidor vamos a modificar el orden de booteo de la mencionada máquina para que cuando inicie ya no lo haga desde el cd sino directamente desde hard disk:
zatoo@pruebas:~# VBoxManage modifyvm "www.mipc.com" --acpi on --boot1 disk

Ahora, si queremos instalar más de una máquina virtual tendremos que seguir los mismos pasos anteriormente descritos. La diferencia radica a la hora de iniciar la máquina virtual. Como la primera máquina se encuentra levantada y conectada a través del puerto 3389 TCP, la nueva máquina virtual tendría que escuchar en un puerto diferente, por lo que el comando para que inicie en un puerto diferente por ejemplo el puerto 20000 TCP sería:
zatoo@pruebas:~# VBoxHeadless --startvm www.mipc.com -e "TCP/Ports=20000"
entonces cuando iniciemos sesión desde un cliente de escritorio remoto tendríamos que colocar IP:20000

Ahora, cuando ejecutamos el comando anterior iniciamos la máquina virtual pero vemos que la consola se queda ahí y no lo pasa a segundo plano, y si hacemos Ctrl C para escapar, la máquina virtual iniciada se apaga. Entonces para evitar esto y poder iniciar varias sesiones si estar abriendo varias terminales igresamos lo sgte:
zatoo@pruebas:~# nohup VBoxHeadless --startvm www.mipc.com -e "TCP/Ports=20000" --vrdp on &













Con esto hemos podido iniciar una máquina virtual en un entorno donde no hay interfaz gráfica debido a su condición de servidor donde lo que se requiere es iniciar con lo más mínimo y así tener los recursos disponibles para lo que verdaderamente importa.

Espero que esto les sirva porque ya en adelante empezaremos a implementar servicios como DNS, Web, Correo, LDAP, SAMBA, Mensajeria Instantánea con Openfire, etc y lo haremos en estas máquinas virtuales que hemos creado.

Características del Servidor Físico Real:
- Placa Intel DG41PR
- Procesador Intel Core 2 Quad 2.66 GHZ
- Memoria RAM 4GB 800MHZ
- Disco Duro 250 GB Sata
- Quemador DVD
- Fuente de 450 Watts uATX