viernes, 25 de julio de 2014

Configurando la red para máquinas virtuales

Siguiendo con la configuración de máquinas virtuales, es hora de configurar la red.

Quiero que mis máquinas virtuales atiendan servicios, así que necesito que tengan direcciones IP visibles desde la red física, a las que mi enrutador pueda dirigirse.

Ha sido muy difícil encontrar la documentación, y al final en realidad he tenido que recurrir a métodos de prueba y error, pero finalmente lo tengo.

En el servidor, hay que configurar un puente. Eso quiere decir que pasamos de esto:

#/etc/network/interfaces

# The primary network interface
allow-hotplug eth0
auto eth0
iface eth0 inet static
      address 192.168.2.25
      netmask 255.255.255.0
      network 192.168.2.0
      broadcast 192.168.2.255
      gateway 192.168.2.1
      dns-nameservers 127.0.0.1
      dns-domain rolamasao.org

a esto:

#/etc/network/interfaces

# The primary network interface
auto br0
iface br0 inet static
        bridge_ports eth0
        address 192.168.2.25
        netmask 255.255.255.0
        network 192.168.2.0
        broadcast 192.168.2.255
        gateway 192.168.2.1
        dns-nameservers 127.0.0.1
        dns-domain rolamasao.org

Es importante notar que a partir de ese momento debemos considerar que la interfaz de red de nuestro servidor físico es br0, y no eth0.

Claro que de nada sirve tener un puente si los paquetes que llegan al puente no son retransmitidos hacia Internet. Por eso hay que modificar un parámetro del kernel:

# /etc/sysctl.conf - Configuration file for setting system variables

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Para que estos cambios tengan efecto es necesario reiniciar, pero siempre se pueden ejecutar a mano con un poquito de brctl, ifconfig, route y echo.

En las máquinas virtuales la configuración debe indicar que utilizan el puente br0, lo cual es bastante sencillo de hacer desde virt-manager. Ya dentro de la máquina virtual, tenemos una configuración bastante estándar. Simplemente hay que indicar que el enrutador por defecto es la máquina física, no el enrutador de la red:

#/etc/network/interfaces VIRTUAL

# The primary network interface
allow-hotplug eth0
iface eth0 inet static
        address 192.168.2.80
        netmask 255.255.255.0
        network 192.168.2.0
        broadcast 192.168.2.255
        gateway 192.168.2.25
        # dns-* options are implemented by the resolvconf package, if installed
        dns-nameservers 192.168.2.25

sábado, 19 de julio de 2014

Identificando máquinas virtuales

Últimamente me estoy metiendo a configurar máquinas virtuales en casa. Más adelante hablaré sobre todos los pasos necesarios, pero de momento me voy a referir al importante detalle de identificar la máquina en la que se trabaja.

Claro que todas las máquinas tienen nombre, pero ¿realmente leemos el nombre de máquina que aparece en el prompt de la shell?

root@vmserver:~#

¿Qué máquina es esa? Hay que fijarse mucho para ver que se trata de una máquina llamada vmserver. Y si tenemos varias máquinas abiertas en distintas pestañas de nuestro programa de terminal, es fácil confundirse. A mí me ha pasado ejecutar un poweroff en la máquina física pensando en apagar una máquina virtual. Y duele.

Así que me decidí a identificarlas por colores.

Las instrucciones de debajo son bastante generales pero has sido comprobadas en una máquina Debian. En otras distribuciones de Linux puede ser ligeramente diferente y en otros Unix muy diferente.

Toda sesión de shell de una máquina comienza ejecutando el fichero /etc/profile. Y este fichero a su vez llama a /etc/bash.bashrc (en el caso de que la shell en uso sea bash y el acceso sea interactivo).

Este segundo fichero define la variable PS1 de esta manera:

# set a fancy prompt (non-color, overwrite the one in /etc/profile)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

Esto prepara el bonito prompt al que estamos acostumbrados, con user@host:directorio$ .

root@vmserver:~#

Pero decidí que las máquinas virtuales tuvieran el prompt azul para distinguirlas de la máquina física, así que lo modifiqué de esta manera:

set a fancy prompt (non-color, overwrite the one in /etc/profile)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
# extra color for real/virtual machine differentiation
MACHINECOLOR=34
STARTCOLOR="\e[0;${MACHINECOLOR}m";
ENDCOLOR="\e[0m"
export PS1="$STARTCOLOR$PS1$ENDCOLOR"

Aparte de un detalle para controlar si estamos en un chroot e indicárnoslo, obtenemos el bonito resultado de

root@vmserver:~#

STARTCOLOR se encarga de iniciar el azul, y ENDCOLOR de finalizarlo, lo que es muy importante para evitar que todo el texto quede azul:

root@vmserver:~# ls
root@vmserver:~# echo 1
1
root@vmserver:~#

34 es el código para el azul. Hay otros:

Black 0;30
Red 0;31
Green 0;32
Brown 0;33
Blue 0;34
Purple 0;35
Cyan 0;36
Light Gray 0;37
Dark Gray 1;30
Light Red 1;31
Light Green 1;32
Yellow 1;33
Light Blue 1;34
Light Purple 1;35
Light Cyan 1;36
White 1;37


Lo importante es que estos no son códigos de bash sino secuencias de escape ANSI/VT-100, porque no las interpreta la shell sino la terminal.

Así, podemos usar otros códigos ANSI/VT100 para conseguir otros efectos. Como los que necesito en la máquina física.

# set a fancy prompt (non-color, overwrite the one in /etc/profile)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
# extra color for real/virtual machine differentiation
MACHINECOLOR=31
# root differentiation
if [ $(id -u) -eq 0 ] ; then
    MACHINECOLOR="7;$MACHINECOLOR"
fi
STARTCOLOR="\e[0;${MACHINECOLOR}m";
ENDCOLOR="\e[0m"
export PS1="$STARTCOLOR$PS1$ENDCOLOR"

Aquí utilizo el código 31 que corresponde al rojo, color universal de aviso, que en este caso me indica que estoy en la máquina real, para evitar meter la pata. Pero hay un detalle más: se comprueba si el usuario es root y si es así, se utiliza el código 7 para invertir los colores:

user@realserver:~$ ls
user@realserver:~$ echo 1
1
user@realserver:~$ su -
Contraseña: 
root@realserver:~# ls
root@realserver:~# echo 1
1
root@realserver:~# 

Con lo cual ahora es bastante más difícil equivocarse de máquina o no recordar que uno es root.

El pequeño problema es que normalmente PS1 es posteriormente redefinido en el fichero ~/.bashrc que es llamado desde ~/.profile:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

Así que en el fichero ~/.bashrc de cada usuario, y en el fichero /etc/skel/.bashrc para los nuevos usuarios que se creen, hay que modificarlo a esto:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    #PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    PS1=$PS1
fi
unset color_prompt force_color_prompt

Y ya tenemos nuestras terminales perfectamente coloreadas.

    Referencias:
  1. http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
  2. http://misc.flogisoft.com/bash/tip_colors_and_formatting
  3. https://wiki.archlinux.org/index.php/Color_Bash_Prompt_(Espa%C3%B1ol)
  4. http://www.termsys.demon.co.uk/vtansi.htm

miércoles, 8 de enero de 2014

Sobre el sistema de ficheros de Android

En particular, sobre Android 4.2.2

/storage es un directorio del sistema interno del teléfono. Dentro tenemos:

emulated
extSdCard
sdcard0

/storage/emulated es un tmpfs. Dentro tenemos:

0
legacy

/storage/emulated/0 y /storage/emulated/legacy son el mismo dispositivo montado dos veces en dos sitios distintos. Además, en realidad no es un dispositivo, es el directorio /data/media (en mi teléfono corresponde al almacenamiento interno, de 4GiB). Dentro tenemos los directorios creados por las aplicaciones.

/storage/extSdCard es la tarjeta microSD real, extraible (en mi teléfono corresponde al almacenamiento externo, de 32GiB). Dentro tenemos los directorios creados por las aplicaciones.

/storage/sdcard0 es un enlace simbólico a /storage/emulated/legacy

jueves, 1 de agosto de 2013

Descargar enlaces ed2k:// desde Chromium

Tras el éxito de Descargar enlaces ed2k:// desde Firefox y su segunda parte, Descargar enlaces ed2k:// desde Firefox (II) llega a sus pantallas la esperada tercera parte: Descargar enlaces ed2k:// desde Chromium, protagonizada por Chromium, tu PC y, en el papel de compañero, xdg-open.

Bueno, tras esta introducción cinematográfica (!), vamos a lo que importa.

Via http://unix.stackexchange.com/questions/38650/adding-bindings-for-ed2k-links-with-xdg-open.

Chromium, para abrir enlaces ed2k://, va directamente a intentar abrirlos con xdg-open, y esto no es configurable. Lo bueno es que xdg-open es una miniaplicación pensada para abrir cada tipo de fichero con la aplicación que tú quieras, y muy configurable.

Lo primero es crear un fichero de configuración del escritorio allí donde xdg-open lo va a buscar, en ~/.local/share/applications, configurando el acceso a los enlaces ed2k://. Dicho fichero lo llamaremos userapp-amule.desktop y su contenido será:

[Desktop Entry]
Name=aMule
Name[en_US]=userapp-amule
Exec=/usr/bin/ed2k %u
Icon=amule
Terminal=false
Type=Application
Categories=Network;P2P;
Comment=A client for the eD2k network
MimeType=x-scheme-handler/ed2k

Lo más importante es que establecemos la relación entre el MimeType x-scheme-handler/ed2k (correspondiente al pseudo-protocolo ed2k://) y la aplicación /usr/bin/ed2k.

Lo segundo es decirle a xdg-open que utilice este fichero tipo .desktop. Eso lo hacemos añadiendo la línea
x-scheme-handler/ed2k=userapp-amule.desktop
a las dos secciones del fichero ~/.local/share/applications/mimeapps.list (aunque pueda parecer redundante, es necesario).

Et voilà !

Chromium intentará abrir el enlace ed2k:// con xdg-open que usará nuestro querido /usr/bin/ed2k.

domingo, 5 de mayo de 2013

Otra vez lo hemos conseguido

http://www.debian.org/News/2013/20130504

Otra vez, lo hemos hecho.

Wheezy ya ha sido liberado como 7.0, y empieza la andadura de Jessie.

martes, 29 de enero de 2013

Chromium porque lo dicen ellos

Hoy he ido a un sitio en el que me decían esto:

Por favor verifique que tiene Adobe Flash Player 11.3 o superior instalado.
Get Adobe Flash player

Ni corto ni perezoso voy a mi aptitude y le pido la última versión:

# aptitude install flashplugin-nonfree                                                                        
No se instalará, actualizará o eliminará ningún paquete.                                                                       
0 paquetes actualizados, 0 nuevos instalados, 0 para eliminar y 2 sin actualizar.                                              
Necesito descargar 0 B de ficheros. Después de desempaquetar se usarán 0 B.

Vaya, parece que ya tengo la última. Voy a la página de Adobe a ver qué me dice:

Adobe Flash Player

Descargar Adobe Flash Player

Versión de Adobe Flash Player 11.2.202.261
Su sistema: Linux 64-bit, Firefox

¿Tiene un sistema operativo o un explorador diferente?
Más información  | Requisitos del sistema  | TI/Administradores de OEM - Distribuir Flash Player
NOTA: Adobe Flash Player 11.2 será la última versión dirigida a Linux como una plataforma admitida. Adobe seguirá proporcionando modificaciones de seguridad para Flash Player 11.2 para Linux.

Vaya, Nos hemos quedado sin Flash en Linux. Soy partidario de HTML5, pero todavía los sitios no lo son. ¿Y ahora?

Consulto a los del propio sitio, y me dicen que Chrome trae incluida la siguiente versión de Flash, y que Chromium puede usarla si tienes Chrome instalado. Lo pruebo, y funciona.

Así que sí, Chromium como nuevo navegador para estos sitios, y Chrome instalado aunque no lo use. Porque lo dicen ellos.

miércoles, 5 de diciembre de 2012

OpenVPN y tablas de enrutamiento

Hoy configuré mi máquina con un servidor OpenVPN y otra máquina a la que tengo acceso con un cliente. Pero no se hablaban.

El servidor me decía que
Dec  5 19:51:29 host ovpn-server[16743]: read UDPv4 [ECONNREFUSED]: Connection refused (code=111)

Pero la cosa es que no tenía ningún problema de NAT: los paquetes llegaban:
Dec  5 19:51:29 host ovpn-server[16743]: xx.xx.xx.xx:22122 TLS: Initial packet from [AF_INET]xx.xx.xx.xx:22122, sid=12345678 90abcdef

Por otro lado el cliente era un poco más explícito:
Dec  5 21:33:47 client ovpn-client[5128]: NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Dec  5 21:33:47 client ovpn-client[5128]: Re-using SSL/TLS context
Dec  5 21:33:47 client ovpn-client[5128]: UDPv4 link local: [undef]
Dec  5 21:33:47 client ovpn-client[5128]: UDPv4 link remote: [AF_INET]yy.yy.yy.yy:1194
Dec  5 21:34:47 client ovpn-client[5128]: TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Dec  5 21:34:47 client ovpn-client[5128]: TLS Error: TLS handshake failed
Dec  5 21:34:47 client ovpn-client[5128]: SIGUSR1[soft,tls-error] received, process restarting

Un caso difícil. Tuve que ponerme a hacer otras cosas durante un rato para entender el problema: El paquete inicial llega, pero la negociación TLS falla. Y no podía deberse a que los certificados estuvieran mal: acababa de revisarlos.

Luego recordé que mi sistema tiene dos direcciones IP distintas, ya que tengo dos conexiones a Internet en casa. De repente estuve seguro de que el problema estaba ahí.

Me senté y desactivé la tarjeta de red a la que llega la IP dinámica. Todo empezó a funcionar. Pero no detectaba la causa del problema. Súbitamente caí en la cuenta: OpenVPN utiliza UDP, y UDP es un protocolo sin estado. Es decir: OpenVPN no envía un paquete de respuesta al saludo TLS, como haría a través de TCP, sino que envía un paquete independiente conteniendo la respuesta al saludo TLS. Y esta diferencia es crucial.

Los paquetes de respuesta a las solicitudes normales a mi máquina salen siempre por la tarjeta de red a la que llega la IP estática, gracias a unas reglas de enrutamiento:
ip route add table 1 192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.25 
ip route add table 1 default via 192.168.1.1 dev eth1
ip rule add from 192.168.1.25 lookup 1

Pero esas reglas no se aplicaban a los paquetes salientes de OpenVPN porque no son paquetes de respuesta: en UDP no existen los paquetes de respuesta.

Rápidamente la documentación oficial de OpenVPN me dio la solución:
#Dirección y máscara de red que utilizaremos
server 10.9.0.0 255.255.255.0
local 192.168.1.25

La orden local le dice al servidor OpenVPN que utilice la IP especificada.

Y listo. Todo funcionando. Ya tengo un túnel permanente para entrar a la máquina remota con IP dinámica.