sábado, 17 de abril de 2010

Conexión a Internet Móvil por Orange

En este artículo vamos a explicar los pasos que he seguido para conectarme a Internet a través de un módem USB que la compañía Orange comercializa con el nombre Internet Everywhere. El módem en concreto tiene un aspecto  muy similar al de un lápiz USB (de hecho, puede usarse para tal fin, como almacenamiento, pero aquí nos centraremos en las capacidades del modem para conectarse a Internet).

La release de FreeBSD que estoy usando es 8.0-RELEASE. Ignoro si funciona en la serie 7.x, aunque creo que no porque fue en la 8 donde se le dió un empuje muy importante al soporte USB.

Cargar el controlador del núcleo
Lo primero de todo es cargar el driver u3g, que por defecto deberíamos tener si hemos instalado un kernel GENERIC:

# kldload u3g

Pinchar el módem a un puerto USB 2.0
Una vez cargado el controlador, enchufamos el módem a un puerto USB 2.0 (bueno, no sé si funcionará con uno 1.1, no lo he probado). Los puertos USB 2.0 se gestionan con el controlador EHCI, de modo que los podemos identificar en el messages:


ehci0: [ITHREAD]
usbus3: EHCI version 1.0
usbus3: on ehci0


Unos segundos después de haber pinchado el módem veremos aparecer en el messages algo parecido a esto:


u3g_huawei_init:269:
usb_alloc_device:1779: Found Huawei auto-install disk!
ugen3.2: at usbus3
ugen3.2: at usbus3 (disconnected)
ugen3.2: at usbus3
u3g0: on usbus3
u3g0: Found 2 ports.
umass0: on usbus3
umass0:  SCSI over Bulk-Only; quirks = 0x0000


Ignoraremos los mensajes relativos a umass0, ya que se refieren al dispositivo de almacenamiento interno que soportan (ojo, la tarjeta de almacenamiento se adquiere aparte, no viene en el pack).

Como podemos ver, se trata de un módem USB Huawei. No aparece el modelo exacto, pero en la publicidad de Orange afirman que se trata de un E160.

Introducción del PIN
Realmente el módem USB se comporta como un teléfono móvil, sólo que está configurado para datos en vez de voz, así que es necesario introducir el PIN correcto para hablar con él, como haríamos con un teléfono móvil convencional. Para hacerlo, nos serviremos del excelente script de perl que podéis encontrar en http://wiki.bsdforen.de/howto/umts_mit_huawei. Una vez guardado en /root/bin/umts_stick, lo editamos para introducir el pin correcto de nuestro módem y el dispositivo serial asociado. En mi caso, han sido:

my $modem = "/dev/cuaU0.0";     # Change to your device name
my $pin = "9999";               # Insert your device's PIN


Para introducir el PIN, ejecutar:

# /root/bin/umts_stick -a

Si el PIN es correcto, la respuesta será:

PIN accepted

Configuración de ppp
Sólo queda adaptar a nuestro caso el excelente artículo que se muestra en  http://zenu.wordpress.com/2010/03/08/setting-up-orange-3g-modem-on-freebsd/.

En  el archivo /etc/ppp/ppp.conf, añadimos una entrada orange, con el siguiente aspecto:

orange:
 set device /dev/cuaU0.0
 set speed 460800
 set phone *99***1\#
 set authname orange
 set authkey orange
 set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \
         \"\" \
         AT OK-AT-OK \
         AT+CFUN=1 OK-AT-OK \
         AT+CSQ OK \
         AT+CGDCONT=1,\\\"IP\\\",\\\"internet\\\" OK \
         AT+CGACT? OK-AT-OK \
         AT+CGATT? OK \
         AT+COPS? OK \
         ATD*99***1# CONNECT"
 set timeout 180 # 3 minute idle timer (the default)
 set ifaddr 10.0.0.1/0 10.0.0.2/0 0.0.0.0 0.0.0.0
 set vj slotcomp off
 set crtscts on
 add! default HISADDR
 disable vjcomp
 disable acfcomp
 disable deflate
 disable deflate24
 disable pred1
 disable protocomp
 disable mppe
 disable ipv6cp
 disable lqr
 disable echo



Antes de seguir, es necesario aclarar algunas cosas. Lo primero, las líneas:

 set authname orange
 set authkey orange

Los valores correctos los he extraído de esta URL:

http://wiki.bandaancha.st/APN_de_las_operadoras_para_configurar_el_m%C3%B3dem_de_Internet_m%C3%B3vil_3G

Por otro lado, la línea:

         AT+CGDCONT=1,\\\"IP\\\",\\\"internet\\\" OK \

La cadena internet es la que figura en el campo APN del enlace anterior.

Para establecer la conexión, hay que realizar la llamada con el comando:

# ppp orange

La respuesta será parecida a:

Loading /lib/libalias_cuseeme.so
Loading /lib/libalias_ftp.so
Loading /lib/libalias_irc.so
Loading /lib/libalias_nbt.so
Loading /lib/libalias_pptp.so
Loading /lib/libalias_skinny.so
Loading /lib/libalias_smedia.so
Working in interactive mode
Using interface: tun0
ppp ON banach>

y escribir dial en la línea de comandos ppp:

ppp ON banach> dial

En ese momento el módem realizará la llamada de datos, y veremos aparecer en el /var/log/ppp.log una gran cantidad de información. La más interesante se muestra al final:

IPCP:  IPADDR[6] changing address: 0.0.0.0  --> 83.231.118.249
IPCP: deflink: SendConfigReq(4) state = Req-Sent
IPCP:  IPADDR[6] 83.231.118.249
IPCP: deflink: RecvConfigReq(1) state = Req-Sent
IPCP:   [EMPTY]
IPCP: deflink: SendConfigAck(1) state = Req-Sent
IPCP:   [EMPTY]
IPCP: deflink: State change Req-Sent --> Ack-Sent
IPCP: deflink: RecvConfigAck(4) state = Ack-Sent
IPCP:  IPADDR[6] 83.231.118.249
IPCP: deflink: State change Ack-Sent --> Opened
IPCP: deflink: LayerUp.
IPCP: myaddr 83.231.118.249 hisaddr = 10.0.0.2
 


Si todo ha ido bien, tendremos configurada la interfaz tun0, y una ruta por defecto:

# ifconfig tun0
tun0: flags=8051 metric 0 mtu 1500
        inet 83.231.118.249 --> 10.0.0.2 netmask 0xffffffff
        Opened by PID 2568

Quitar el módem USB
Para quitar el módem con seguridad, y evitar que se estropee algo, cerramos primero la conexión ppp:

ppp ON banach> close

y luego detenemos el dispositivo USB mediante:

# camcontrol stop cd1

(el dispositivo exacto se determina a través de camcontrol devlist)

Esto último no estoy seguro de que sea necesario, pero por si las moscas siempre lo hago antes de sacar el módel USB de su ranura.

Compartir la conexion con otros nodos de nuestra red
Si queremos que otros nodos de nuestra red puedan usar esta interfaz, emplaremos la misma técnica con Packet Filter que se usó en el artículo Conexión a un VPN de Microsoft PPTP. Por ejemplo, creamos dos shell scripts con el siguiente contenido:

#!/bin/sh
# Guardar en /etc/ppp/natUP.sh
echo "nat pass on $dev from ! $dev to any -> $dev" | \
    /sbin/pfctl -a $dev -N -f -

#!/bin/sh
# Guardar en /etc/ppp/natDOWN.sh
/sbin/pfctl -a "$dev" -F all

Para establecer el NAT al abrir la conexión, creamos un archivo /etc/ppp/ppp.linkup con el siguiente contenido:

# Guardar en /etc/ppp/ppp.linkup
orange:
 !bg /etc/ppp/natUP.sh INTERFACE

Para desactivar el NAT al cerrar la conexión, creamos un archivo /etc/ppp/ppp.linkdown con el siguiente contenido:


# Guardar en /etc/ppp/ppp.linkdown
orange:
 !bg /etc/ppp/natDOWN.sh INTERFACE




Conclusiones
La calidad de la conexión se puede calificar entre aceptable y buena. En la mayoría de las zonas de España hay cobertura 3G (de esto doy fe, ya que lo he probado en un pueblo perdido de Sanabria). La única desventaja es que la latencia no es muy buena; en el mejor de los casos los tiempos de ping superan ligeramente los 100 milisegundos, lo cual no permite trabajar con mucha comodidad en terminales remotos sobre una línea de comandos habitual. Un amigo me comentó que la razón quizá no sea la tecnología en sí, sino que es la misma compañía quien ralentiza  la latencia a propósito: las llamadas de datos son mucho más baratas que las de voz, y si la latencia fuera excelente, mucha gente utilizaría programas como skype y contrataría tarifas planas de datos en vez de voz para hablar, con lo que los ingresos de estas compañías disminuirían drásticamente. ¿Qué opinan Uds?

Conexión a un VPN de Microsoft PPTP

En este artículo vamos a explicar cómo configurar una conexión a un servidor VPN de Microsoft por PPTP. Este tipo de servidores VPN abundan mucho en redes corporativas, para permitir a sus empleados conectarse a la red interna de modo sencillo, utilizando el asistente que Windows XP ofrece para tal fin (Asistente para conexión nueva -> Conectarse a una red de mi lugar de trabajo). Además, se utilizará Packet Filter para establecer un NAT que permita compartir esa conexión con otros nodos de la red.

Configurar la conexión

La forma más cómoda de configurar la conexión es mediante el port net/mpd5. Es necesario que el núcleo que estemos corriendo tenga soporte para netgraph (el núcleo GENERIC lo incorpora mediante módulos, que se cargan automáticamente cuando se necesitan).

Una vez instalado el port, preparamos el archivo de configuración, que se encuentra en /usr/local/etc/mpd5/mpd.conf

El port instala su documentación en /usr/local/share/doc/mpd5.

Antes de nada, necesitaremos varios datos que nos suministrará el administrador de la red remota:
  1. La dirección IP del servidor VPN: por ejemplo, 70.70.70.70
  2. La red a la que nos da acceso: por ejemplo, 100.0.0.0/255.0.0.0
  3. Usuario y password de la conexión: por ejemplo, vpn_user, secret
El archivo mpd.conf tendrá el siguiente aspecto:


# archivo /usr/local/etc/mpd5/mpd.conf

startup:
set user admin admin admin

default:
load servidor_vpn_oficina

servidor_vpn_oficina:
create bundle static B1
# Use a net/mask to create specific routes
set iface route 100.0.0.0/8

# Script to execute on connect/disconnect (custom routes etc)
# descomentar estas líneas cuando se disponga de los scripts correctamente configurados
# set iface up-script /usr/local/etc/mpd5/up-script.servidor_vpn_oficina.sh
# set iface down-script /usr/local/etc/mpd5/down-script.servidor_vpn_oficina.sh

# Accept any IP-address
set ipcp ranges 0.0.0.0/0 0.0.0.0/0

# Microsoft Point-to-Point Compression, only enable if you have a really fast machine
set bundle enable compression
set ccp yes mppc

# PARA EVITAR EL ERROR LCP: protocol 0x2145 was rejected
set mppc yes stateless
set mppc yes e56
set mppc yes e128

# otras opciones
create link static L1 pptp
set link action bundle B1

# Replace with you credentials or use the mpd.secret file
set auth authname vpn_user
set auth password secret
set link max-redial 0
set link mtu 1460
set link keep-alive 20 75
# Hostname/IP of the VPN server
set pptp peer 70.70.70.70
set pptp disable windowing
set link no eap
open
# fin
/usr/local/etc/mpd5/mpd.conf


Conexión con la VPN

Para establecer la conexión, ejecutamos desde una shell de root:

# mpd5 conexion_vpn_oficina

Veremos por el terminal gran cantidad de información acerca de la conexión. Al final, se debe mostrar lo siguiente:

[B1] IPCP: LayerUp
[B1] 100.0.90.5 -> 100.0.100.81
[B1] IFACE: Up event


En este momento, la conexión debería estar abierta y funcionando correctamente. La interfaz creada es ng0:

# ifconfig ng0
ng0: flags=88d1 metric 0 mtu 334
inet 100.0.90.5 --> 100.0.100.81 netmask 0xffffffff


Los módulos que se han cargado en mi caso han sido:

# kldstat | tail
26 1 0xc60c9000 4000 ng_socket.ko
27 1 0xc60cd000 4000 ng_mppc.ko
28 1 0xc60d1000 2000 rc4.ko
29 1 0xc60d3000 4000 ng_iface.ko
30 1 0xc60d7000 7000 ng_ppp.ko
31 1 0xc60e0000 3000 ng_tee.ko
32 1 0xc60e3000 4000 ng_pptpgre.ko
33 1 0xc60e7000 5000 ng_ksocket.ko

En el terminal donde se lanzó el comando mpd5 se nos mostrará la línea de comandos de mpd (dar al intro para que aparezca):
 




Available commands:
 authname : Choose link by auth name     bundle   : Choose/list bundles
 close    : Close a layer                create   : Create new item
 destroy  : Destroy item                 exit     : Exit console
 iface    : Choose bundle by iface       help     : Help on any command
 link     : Choose link                  load     : Read from config file
 log      : Set/view log options         msession : Ch. bundle by msession-id
 open     : Open a layer                 quit     : Quit program
 repeater : Choose/list repeaters        session  : Choose link by session-id
 set      : Set parameters               show     : Show status
[L1]

Por ejemplo, con show link se muestran una serie de datos interesantes, como el tráfico enviado por la interfaz:


[L1] show link
Link L1 (static):
Configuration:
        Device type    : pptp
        MRU            : 1500 bytes
        MRRU           : 2048 bytes
        Ctrl char map  : 0x000a0000 bytes
        Retry timeout  : 2 seconds
        Max redial     : unlimited, delay 1s
        Bandwidth      : 64000 bits/sec
        Latency        : 2000 usec
        Keep-alive     : every 20 secs, timeout 75
        Ident string   : ""
Link incoming actions:
        Bundle  B1
Link level options:
                        Self            Peer
        incoming        disable
        pap             disable         accept
        chap-md5        disable         accept
        chap-msv1       disable         deny
        chap-msv2       disable         accept
        eap             disable         deny
        acfcomp         enable          accept
        protocomp       enable          accept
        keep-ms-domain  disable
        magicnum        enable
        passive         disable
        check-magic     enable
        no-orig-auth    disable
        callback        disable
        multilink       disable
        shortseq        enable          accept
        time-remain     disable
        peer-as-calling disable
        report-mac      disable
Link state:
        State          : UP
        Session Id     : 1506855-L1
        Peer ident     :
        Session time   : 202 seconds
Up/Down stats:
        Up Reason      : Manual
Traffic stats:
        Input octets   : 136
        Input frames   : 12
        Output octets  : 150
        Output frames  : 12
        Bad protocols  : 0
        Runts          : 0
        Dup fragments  : 0
        Drop fragments : 0




Cerrar la conexión


Para cerrar la conexión, simplemente escribimos quit:

[L1] quit
Console closed.
process 6401 terminated









Configurar el NAT

Bien, ya solo queda explicar las dos siguientes líneas del fichero de configuración:

# Script to execute on connect (custom routes etc)
set iface up-script /usr/local/etc/mpd5/up-script.servidor_vpn_oficina.sh
set iface down-script /usr/local/etc/mpd5/down-script.servidor_vpn_oficina.sh


Lo que perseguimos es que la conexión se comparta con otros nodos de la red mediante NAT. Para ello, usaremos el estupendo Packet Filter de OpenBSD (todo una obra de arte, dicho sea de paso).

En mi caso, el archivo de configuración /etc/pf.conf que manejo para PF es realmente sencillo:

# http://www.openbsd.org/faq/pf

# macros

# tablas
# http://www.openbsd.org/faq/pf/tables.html
table const { self }

# options
# http://www.openbsd.org/faq/pf/options.html
set debug urgent
set skip on lo0

# scrub
# http://www.openbsd.org/faq/pf/scrub.html
scrub in all no-df

# nat
# http://www.openbsd.org/faq/pf/nat.html
# poner aquí todos los interfaces dinámicos que podamos tener
nat-anchor tap0 # openvpn
nat-anchor ng0 # VPN microsoft
nat-anchor tun0 # orange everywhere

# http://www.openbsd.org/faq/pf/filter.html
# filter
pass in all
pass out all

Básicamente, dejamos que nuestro host deje pasar todo tipo de tráfico, sin imponer ninguna restricción. Los anchors destinados a nat nos permitirán añadir/eliminar reglas específicas, sin afectar al resto. En nuestro caso, nos afe   Para activar PF, añadir las siguiente líneas al /etc/rc.conf:

pf_enable="YES"
gateway_enable="YES"

(asegurarse de que no se usa ningún otra herramienta de filtrado de paquetes como IPFW). La opción gateway_enable permite que nuestro host actúe como router, encaminando los paquetes hacia los destinos adecuados según nuestra tabla de rutas.

Para arrancar PF, lanzamos:

# /etc/rc.d/pf start
Enabling pf
No ALTQ support in kernel
ALTQ related functions disabled
No ALTQ support in kernel
ALTQ related functions disabled
No ALTQ support in kernel
ALTQ related functions disabled
pf enabled

Para verificar que el filtrado está funcionando, lanzar pfctl -s all, que nos muestra un extenso resumen del estado de PF.

Ahora vayamos al contenido de los dos scripts mencionados anteriormente. En el caso de up-script.servidor_vpn_oficina.sh, se activa el NAT para la interfaz ng0 cuando se abra la conexión, de modo que cualquier paquete que nuestro host deba encaminar por esa interfaz sea convenientemente camuflado para aparentar que sale de nuestro host, y no desde el host que emitió ese paquete. El contenido del script es simplemente:

#!/bin/sh
dev="$1"

echo "nat pass on $dev from ! $dev to 100.0.0.0/8 -> $dev" | \
    /sbin/pfctl -a $dev -N -f -

Observar que no hacemos mención alguna a la interfaz ng0: se envía como primera parámetro al script (hay otros, ver la documentación para más detalles). Una cosa muy importante es que se realiza NAT para todos los paquetes excepto para aquellos que se emitan desde la propia interfaz ng0 (sentencia !$if). La razón es que los paquetes que emita nuestro host a través de la interfaz ng0 no deben ser tratados por el NAT, ya que no es necesario, y por otro lado nos daría ciertos problemas con algunas aplicaciones como el NFS . Por ejemplo, si queremos montar por NFS un directorio desde nuestro host, el NAT modificará el puerto origen y esto confundirá al cliente de NFS, que no será capaz de montar nada. Por supuesto, desde otro host de nuestra red no será posible montar por NFS los directorios que se exporten desde la VPN, pero esto ya es una limitación inherente al NAT.

Podemos ver el estado del NAT mediante pfctl -a ng0 -s nat. Por ejemplo, en mi caso:

# pfctl -a ng0 -s nat
No ALTQ support in kernel
ALTQ related functions disabled
nat pass on ng0 inet from ! 100.0.90.5 to 100.0.0.0/8 -> 100.0.90.5

El contenido del script down-script.servidor_vpn_oficina.sh simplemente limpiará las reglas del NAT establecidas en la interfaz ng0:

#!/bin/sh
dev="$1"
/sbin/pfctl -a "$dev" -F all

Este script será invocado cuando cerremos la conexión con la VPN.





Acceder a la VPN desde otros nodos de nuestra red

Ya tenemos el enlace con la VPN funcionando, con el NAT correctamente establecido, y nuestro host haciendo de encaminador (router). Para configurar otro host de nuestra red de modo que pueda alcanzar la VPN, simplemente le indicamos por dónde tiene que encaminar los paquetes que emita hacia la red 100.0.0.0/255.0.0.0 (recordad que ésa era la red de la VPN). Por ejemplo, si nuestro host está conectado a una LAN a través de una red 192.168.50.1/255.255.255.0, cualquier nodo de esa red podrá conectarse a la red 100.0.0.0/255.0.0.0 de la VPN añadiendo la ruta correcta. Por ejemplo, si el nodo fuera otro FreeBSD:

# route add 100/8 192.168.50.1



domingo, 31 de agosto de 2008

Instalar FreeBSD en máquinas lentas o con poco espacio

Un escenario que surge con frecuencia en un datacenter es el siguiente:

  1. Tenemos una máquina lenta o antigua, donde deseamos instalar la última versión de FreeBSD.
  2. No es viable construir el world o el kernel directamente en esa máquina, ya que nos llevaría muchos días.
  3. Se dispone de otra máquina más potente (con FreeBSD instalado, claro).

El objetivo consiste en aprovechar los recursos de la máquina potente para construir el world y el kernel cómodamente, e instalarlo en la otra máquina. Fijaos que las plataformas pueden ser totalmente distintas, de hecho nuestro caso lo ilustraremos con una vieja spar64 (una Ultra Sparc del año 2000 más o menos) y una recién i386.

Supongamos que la situación es la siguiente: la vieja y lenta máquina es una sparc64, de nombre riemann, y la nueva y potente es una i386 de nombre gauss.


Actualización de los fuentes en gauss
Lo primero de todo es disponer en gauss de un juego completo de fuentes bajo /usr/src, totalmente actualizado a la release que hay que construir. En nuestro caso, vamos a suponer que se trata de FreeBSD 7.0, la última release estable en el momento de escribir estas líneas. En el handbook se explica con todo detalle el proceso de actualización de las fuentes.

Ficheros /etc/make.conf.riemann y /etc/src.conf.riemann
Configuramos /etc/make.conf y /etc/src.conf (de riemann) de acuerdo a la situación de riemann, y los copiamos a gauss, con los nombres /etc/make.conf.sparc64 y /etc/src.conf.sparc64, respectivamente.

Construcción del world en gauss
Ponemos el comando entero en varias líneas, para que sea más cómodo de leer:

# env -i \
TARGET=sparc64 \
__MAKE_CONF=/etc/make.conf.sparc64 \
SRCCONF=/etc/src.conf.sparc64 \
make buildworld

Este comando debe ser lanzado en gauss, bajo la carpeta /usr/src. El significado de las variables es:
  • TARGET. Es la plataforma para la que construimos el world. En nuestro caso es sparc64 (sí, es perfectamente posible construir el world para una plataforma distinta a la que ejecutamos).
  • __MAKE_CONF. Es el archivo make.conf que se usa para construir el world. Obviamente, el elegido es el de la vieja sparc64, no el de nuestra i386, que puede una configuración totalmente incompatible con la sparc64.
  • SRCCONF. Es el archivo src.conf utilizado para construir el world. Como antes, las opciones de construcción del world de la sparc64 no tienen porqué coincidir con las de la i386.
Construcción del kernel en gauss
El archivo de configuración del kernel de riemann lo copiamos también a gauss, a la ruta:
/usr/src/sys/sparc64/conf/kernel.sparc64, y de nuevo bajo /usr/src, construimos el kernel para la sparc64 desde gauss, de modo análogo a como se hizo para el world:

# env -i \
__MAKE_CONF=/etc/make.conf.sparc64 \
TARGET=sparc64 \
make buildkernel KERNCONF=kernel.sparc64

Compartir por NFS el sistema de ficheros completo de riemann
Para que podamos instalar en riemann el world y el kernel construidos en gauss, necesitamos exportar por nfs el arbol completo de directorios de riemann. La manera más sencilla de hacerlo es situar en el archivo /etc/exports únicamente la línea:

/ -alldirs -maproot=root gauss

(asegurarse de que gauss sea un nombre reconocido por riemman, añadiendo la entrada en /etc/hosts en caso de que el DNS de riemann no sepa cómo traducir a una dirección IP el nombre gauss)

Pasamos riemann a modo single
Para realizar este paso con mayor comodidad, lo mejor es tener un acceso por consola a riemann, tal y como explica el handbook, o bien tener acceso directo a la máquina bajo un teclado y un terminal (cosa nada fácil si el espacio del datacenter es limitado o bien no hay posibilidad siquiera de acceder físicamente a la máquina). Tanto si tenemos un acceso por consola como directo por un terminal, ejecutamos, como root:

# shutdown now

Una vez en modo single, activamos el NFS de nuevo, porque en el paso a single se paran todos los servicios de red:

# /etc/rc.d/rpcbind start
# /etc/rc.d/mountd start
# /etc/rc.d/nfsd start
# /etc/rc.d/statd start
# /etc/rc.d/lockd start

(mirar en el handbook cómo activar un servidor NFS en FreeBSD, en caso de no tenerlo ya configurado)

Montaje de la carpeta raíz de riemann en gauss
Para montar el directorio raíz de riemann en el /mnt gauss, simplemente ejecutamos, desde gauss:

# mount_nfs riemann:/ /mnt

Instalación del world y del kernel
Por último, desde gauss, instalamos el world y el kernel, tomando como carpeta base /mnt, es decir:

# env -i TARGET=sparc64 make DESTDIR=/mnt installkernel KERNCONF=kernel.sparc64
# env -i TARGET=sparc64 make DESTDIR=/mnt installworld

No debemos olvidar que, en su caso, puede ser necesario lanzar mergemaster -p y mergemaster -iU en riemann, el primero antes del buildworld y el segundo después.

Reiniciar riemann
Si todo ha ido bien, rebotamos riemann y tendremos nuestra nueva release perfectamente instalada.


viernes, 29 de agosto de 2008

Copias de respaldo cifradas con GELI

Con frecuencia surge la necesidad de realizar una copia de seguridad de datos sensibles de nuestro ordenador, que no puede ser directamente almacenada en un DVD, ya que pondría en riesgo la confidencialidad de tales datos. Por ejemplo, certificados de usuario en claro, fotos comprometidas (je je) o simplemente expedientes confidenciales de nuestra compañía. ¿Cómo podemos almacenar una copia de seguridad en un lugar seguro, de modo que sea sencillo de recuperar y garantice a su vez la confidencialidad en caso de extravío o robo del soporte? Veamos una solución sencilla mediante la magnífica herramienta GELI que ofrece FreeBSD, de la cual se puede encontrar más información en el handbook, (es necesario dar soporte al núcleo mediante el device crypto):

Las posibilidades de GELI son amplísimas; aquí nos reduciremos a la gestión de DVDs cifrados.

La idea es crear un archivo con una imagen UFS, convenientemente cifrada, y luego quemar esa imagen directamente al DVD.

La imagen que vamos a crear se llamará backupCifrado.img, de tamaño 4480 M, que es la capacidad de un DVD normal. Nos ayudaremos del comando dd, rellenando la imagen de datos aleatorios procedentes de /dev/random:

# dd if=/dev/random of=backupCifrado.img bs=1m count=4480
4480+0 records in
4480+0 records out
4697620480 bytes transferred in 482.075108 secs (9753215 bytes/sec)

A continuación, mediante mdconfig, le asociamos a esta imagen un dispositivo que pueda ser montado:

# mdconfig -a -t vnode -S 2048 -f backupCifrado.img
md0

Es de especial importancia el argumento -S 2048, que indica el tamaño, en bytes, de cada sector de la imagen. Fijaos que no se elige 2048 aleatoriamente, sino que coincide con el de los soportes ópticos como el DVD o el CD. La respuesta del comando será un escueto md0, dependiendo del número de dispositivos de este tipo que hayamos montado.

A continuación, iniciamos GELI sobre el /dev/md0 recién creado, donde se nos preguntará la contraseña de cifrado:

# geli init -s 2048 /dev/md0
Enter new passphrase:
Reenter new passphrase:
# geli attach /dev/md0
Enter passphrase:

El sistema creará un nuevo dispositivo /dev/md0.eli, y la infraestructura de GELI quedará lista para cifrar cualquier dato grabado o leído en el dispositivo /dev/md0.eli (el cifrado por defecto es AES, aunque Blowfish puede ser más potente, ver geli (8) ).
Procedemos a formatear md0.eli con un UFS convencional, pero con la flag -m 0, para aprovechar al máximo el espacio destinado al backup (sí, ya sé que esto tiene consecuencias en el rendimiento, pero para respaldos de sólo lectura es perfectamente válido).


# newfs -m 0 /dev/md0.eli
..........
super-block backups (for fsck -b #) at:

160, 22688, 45216, 67744
..............

Bien, ahora montamos nuestro sistema de ficheros sobre /mnt, por ejemplo:

# mount /dev/md0.eli /mnt

Ya podemos colocar en /mnt la copia de seguridad o los archivos confidenciales que deseemos, y cuando acabemos desmontamos /mnt y paramos GELI:

# umount /mnt
# geli detach /dev/md0

Por ultimo, grabamos a un DVD la imagen backupCifrado.img (que es, es última instancia, donde reside nuestro respaldo). Pero ojo, lo grabamos como una imagen directamente, no como archivo de un sistema de ficheros cd9660:

# growisofs -dvd-compat -Z /dev/cd0=
backupCifrado.img

Si no tenemos configurada la grabadora, tiramos del handbook; viene perfectamente explicado (en inglés, claro, aunque hay traducción al español).

Ahora llega la hora de la verdad, la prueba de fuego: intentaremos montar nuestro DVD cifrado:

# geli attach -r /dev/cd0
Enter new passphrase:

Introducimos la contraseña correcta, y voilá, se crea el dispositivo /dev/cd0.eli, que podemos montar en /cdrom:

# mount -o ro /dev/cd0.eli /cdrom

No se nos debe olvidar desmontar todo cuando terminemos de examinar nuestro DVD cifrado:

# umount /cdrom
# geli detach /dev/cd0.eli
# eject

¡ A disfrutar !

Datos personales

Madrid, Madrid, Spain