Archivo

Archivo para la categoría ‘ubuntu-ar’

Charlas: Introducción a AWS y a HTTP/2

martes, 13 de septiembre de 2016 Sin comentarios

Hace unos días tuve el placer de dar una charla en el CIDETIC, perteneciente a la Universidad Nacional de Luján, respecto a los servicios de cloud computing en general y a los de Amazon Web Services en particular.

Como siempre, preparar y hablar en público sobre un tema no es lo mismo que tener los conceptos algo desordenados, producto únicamente de la experiencia práctica; por lo que fue un desafío organizar tantas ideas algo deshilachadas… y acepté gustoso. De hecho, tengo un par de críticas que hacerme a mí mismo sobre cómo salió, como que por ejemplo, me quedaron cosas en el tintero y me llevó más tiempo de lo planificado.

De paso, subí también los slides que armé para la charla de HTTP/2, que vengo reeditando prácticamente todos los años en la cátedra de Teleinformática y Redes. Esta vez pude ir con el protocolo estandarizado para mostrarle a la gente. 🙂

En fin, los slides, para aquellos que les interesa, los dejé en la sección Charlas del blog. Pueden usarlo sin problemas para lo que deseen.

PD: Si buscan los íconos de los servicios de AWS como recursos para uso personal en la generación de contenido, acá están en múltiples formatos (SVG/EPS, Visio, Powerpoint, etc.).

Saludos

Categories: codear, linux, ubuntu-ar Tags:

Migrando Host de VMs KVM de Ubuntu 12.04 a 14.04

viernes, 16 de mayo de 2014 5 comentarios

En estos días arranqué la tarea de migrar Máquinas Virtuales de Hosts Ubuntu 12.04 (entorno QEmu-KVM/Libvirt) a Ubuntu 14.04, para testear que esté funcionando todo ok, y me encontré con dos particularidades:

1) Por defecto, las interfaces de red no se llaman más “ethX” ni se guían como antes con el archivo en /etc/udev/rules.d/70-net-persistent.rules, sino que ahora son medio raras (“p2p1”, “p5p4”, “eno1”, “enp2s0”, etc). Acá está explicado el por qué del cambio [1]. A priori no me gusta nada este cambio, por no respetar ninguna convención como sí lo hacía ethX, y encima por ser un cambio por defecto, pero como todo… supongo que me acostumbraré. Es adaptarse o morir; no es un capricho de Ubuntu, sino de udev.

2) ¡No hace falta más configurar un bridge en el host! Ahora se usa el driver de kernel macvtap [2][3][4][5], que uno lo selecciona en el administrador virt-manager. Así que para el host no habría que cambiar la configuración; para recordarlo, en un host Ubuntu 12.04 pasábamos de esto:

auto eth0
 iface eth0 inet static
 address 192.168.1.18
 netmask 255.255.255.0
 gateway 192.168.1.1
 dns-nameservers 192.168.1.1 192.168.1.2

a esto (cambia eth0 por br0, y las líneas de bridge):

auto br0
 iface br0 inet static
 address 192.168.1.18
 netmask 255.255.255.0
 gateway 192.168.1.1
 dns-nameservers 192.168.1.10 192.168.1.15
 bridge_ports eth0
 bridge_stp off
 bridge_fd 0
 bridge_maxwait 0

Ahora en Ubuntu 14.04 no hace falta tocar nada, ya que la interfaz principal sigue siendo la misma, aún cuando haya VMs que salgan directamente puenteadas por dicha interfaz. Lo que sí, por cada VM puenteada con el driver macvtap se va a crear una interfaz en el host, quedando así, digamos:

macvtap0 Link encap:Ethernet HWaddr 52:54:00:1e:b5:29
 inet6 addr: fe80::5054:ff:fe1e:b529/64 Scope:Link
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
 RX packets:437 errors:0 dropped:0 overruns:0 frame:0
 TX packets:71 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:500
 RX bytes:36313 (36.3 KB) TX bytes:6617 (6.6 KB)

 p2p1 Link encap:Ethernet HWaddr 44:87:fc:ef:96:be
 inet addr:192.168.1.18 Bcast:192.168.1.255 Mask:255.255.255.0
 inet6 addr: fe80::4687:fcff:feef:96be/64 Scope:Link
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
 RX packets:15346 errors:0 dropped:46 overruns:0 frame:0
 TX packets:16615 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000
 RX bytes:2096838 (2.0 MB) TX bytes:4714920 (4.7 MB)

Esto seguramente es más rápido que lo anterior, por diferentes motivos, pero tiene un lado feo, y es que de esta manera los guests no pueden comunicarse con el host [6]. Apliqué la “less painful solution” de esa wiki, y fue crear una red NAT aislada entre el host y sus guests, todo de manera gráfica desde virt-manager. Fue bastante simple, y aunque no me guste que tenga que haber una interfaz en el guest únicamente para comunicarse con el host, funciona bien y en mi caso esto es para necesidades muy puntuales (emergencia casi siempre).

En resumen, esto fue para darles un pantallazo de algunos de los cambios que vamos a tener que hacer cuando migremos a 14.04. Estos cambios también están en RHEL 7, ya que son todos cambios de proyectos upstream, así que no nos ahorramos este trabajo yendo para aquel lado tampoco.

[1] http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/
[2] http://seravo.fi/2012/virtualized-bridged-networking-with-macvtap
[3] http://virt.kernelnewbies.org/MacVTap
[4] http://libvirt.org/formatnetwork.html#examplesDirect
[5] http://www.linux-kvm.com/content/simple-bridged-networking-virt-manager-using-macvtap
[6] http://www.furorteutonicus.eu/2013/08/04/enabling-host-guest-networking-with-kvm-macvlan-and-macvtap/

Saludos!

Categories: codear, linux, sysadmin, ubuntu-ar, Uncategorized Tags:

Estableciendo conexiones HTTPS “bien seguras” en Python

sábado, 19 de febrero de 2011 2 comentarios

Hace unos días que tenía pendiente colgar esto acá, ya que a alguien en PyAr le fue útil.

HTTPS es la manera de establecer conexiones HTTP pero seguras, en el sentido de que previo al diálogo HTTP estándar pero luego de establecerse la conexión TCP contra el servidor, se negocia entre los participantes una conexión/sesión “especial” entre ambos.  Allí se intercambian certificados con el fin de autenticar contra quién se “está hablando”, para luego, si hubo éxito en la dicha comprobación, encriptar (o no) todo lo que va para el otro lado, tanto del Servidor al Cliente (generalmente un navegador), como del Cliente al Servidor.

Todo eso forma parte de SSL 3.0 (hoy TLS 1.0), y si bien se puede utilizar para cualquier conexión TCP (SMTP, IMAP, etc., lo pueden usar también), su uso más común se da cuando uno entra a su casilla de Webmail o su cuenta del Banco desde el navegador;  lo que sucede allí es que nuestro navegador autentica al Servidor, y si todo va bien nos muestra el famoso “candadito” e informa que la sesión “es segura”. Ahora bien, en esos casos, el Banco o Webmail no nos autentica a nosotros como Cliente y deja que cualquiera se conecte a su página, ya que eso requiere varios pasos más (sería realmente engorroso que sea obligatorio).

Sin embargo, en nuestra vida de programadores nos solemos encontrar con necesidades del entorno que nos obliguen a esta situación un tanto extrema y bastante más segura: que tanto el Cliente que desarrollamos autentique al Servidor como que el Servidor autentique al Cliente, amén de que la conexión muy probablemente deberá estar encriptada. Esto nos permitirá asegurarnos que los Clientes (software) que se conecten a nuestro Servidor sean únicamente quienes queremos que sean (o casi).

Python, dentro del módulo httplib nos provee de la clase HTTPSConnection, que maneja y nos abstrae en varias de estas cuestiones de SSL/TLS y nos deja trabajar a nivel HTTP (una capa más arriba). Lo que hay que observar bien (y que recién en la versión 2.7 de la documentación apareció en rojo), es que esta clase aún cuando uno le puede pasar como parámetro los paths a certificados, en realidad no hace ninguna comprobación de validez del certificado que el Servidor exporta. Con lo cual, hay un potencial problema: que nuestro cliente mande los datos a cualquier lado menos a nuestro Servidor de confianza.

¿Y cómo se fuerza a que nuestro programa Cliente chequee el certificado del Servidor? Armé esta clase que extiende sólo lo necesario a HTTPSConnection, que funciona en Python 2.6.x y que me permite hacer eso.

Le agregué un ejemplo en la llamada a __main__ para mostrar cómo se usa:

#!/usr/bin/env python
#-*- coding: utf-8 -*-
 
import socket
import ssl
import httplib
 
class HTTPSClientAuthConnection(httplib.HTTPSConnection):
    """ Class to make a HTTPS connection, with support for full client-based
        SSL Authentication.
    """
 
    def __init__(self, host, port, key_file, cert_file, ca_file, timeout=None):
        httplib.HTTPSConnection.__init__(self, host, key_file=key_file,
                                                   cert_file=cert_file)
        self.key_file = key_file
        self.cert_file = cert_file
        self.ca_file = ca_file
        self.timeout = timeout
 
    def connect(self):
        """ Connect to a host on a given (SSL) port.
            If ca_file is pointing somewhere, use it to check Server Certificate.
 
            Redefined/copied and extended from httplib.py:1105 (Python 2.6.x).
            This is needed to pass cert_reqs=ssl.CERT_REQUIRED as parameter
            to ssl.wrap_socket(), which forces SSL to check server certificate
            against our client certificate.
        """
        sock = socket.create_connection((self.host, self.port), self.timeout)
        if self._tunnel_host:
            self.sock = sock
            self._tunnel()
        # If there's no CA File, don't force Server Certificate Check
        if self.ca_file:
            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
                        ca_certs=self.ca_file, cert_reqs=ssl.CERT_REQUIRED)
        else:
            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
                                              cert_reqs=ssl.CERT_NONE)
 
if __name__ == '__main__':
    # Little test-case of our class
    import sys
    if len(sys.argv) != 6:
        print 'usage: ./https_auth_handler.py host port key_file cert_file ca_file'
        sys.exit(1)
    else:
        host, port, key_file, cert_file, ca_file = sys.argv[1:]
    conn = HTTPSClientAuthConnection(host, port, key_file=key_file,
                                           cert_file=cert_file, ca_file=ca_file)
    conn.request('GET', '/')
    response = conn.getresponse()
    print response.status, response.reason
    data = response.read()
    print data
    conn.close()

En cuanto a la generación de las claves de Cliente, Servidor y CA hay unos cuantos artículos y es relativamente sencillo una vez que se entiende qué se está haciendo. Por otra parte que en estos casos es muy común que el Servidor exija que el Cliente si o sí envíe su certificado o sino la conexión se deberá caer; esto en el caso del Servidor Apache está bien documentado.

Entiendo que en Python 3.2 esto está resuelto en la misma API standard de Python (en su momento abrí un ticket similar para usar esto con urllib2, que incluye cosas importantes como el manejo de cookies, por ejemplo), y comentaron eso.

Según me dijeron en PyAr, es casi seguro que este ejemplo no funcione en Python 2.7, así que en un futuro no muy lejano espero poder adaptar este código a dicha versión y seguramente lo estaré subiendo en esta página.

Saludos

Categories: codear, programación, python, ubuntu-ar Tags:

Virtualizando sólo una partición de una máquina física

viernes, 14 de enero de 2011 10 comentarios

Hace poquito un amigo me contó que estuvo leyendo el post anterior de Consolidación y “Shrinking” de discos físicos para pasarlos a una máquina virtual, pero tenía un pequeño obstáculo relacionado con el espacio en disco necesario, que más o menos era así:

Quería consolidar un disco real de 80 GB que tiene XP instalado en su C:, pero en total el disco tiene 4 particiones (primarias). Sólo me interesaba el disco C:, con lo que ahorraba espacio en el proceso ya que la partición del C: sólo ocupa 25 GB.

Entonces hice la copia con “dd if=/dev/sdb1 of=imagen.raw”. Como uso VirtualBox, con un comando lo convertí de .raw a .vdi. Pero no logré bootear.

Hice varias pruebas, siempre con VirtualBox y no lo logré. Supongo que es porque no se copió el MBR. En cambio, cuando copié el disco completo, booteó sin problemas.

La pregunta es: ¿Cómo debería haber hecho para trabajar solo con esa partición y de esa forma evitar trabajar con los 80GB?

Bueno, el problema era que, efectivamente, al hacer el dd sobre /dev/sdb1 sólo se copian los bytes dentro de la partición y no el MBR+Bootloader (la vieja “pista 0” del disco). Para resolver el problema habría que copiar los bytes de la pista 0 más los bytes de la partición en cuestión, siguiendo estos pasos:

Ejecutar el comando parted sobre /dev/sdb (en mi caso, voy a usar /dev/sda como ejemplo):

marcelo@jupiter:~$ sudo parted /dev/sda u s print
Modelo: ATA WDC WD3200BEVT-0 (scsi)
Disco /dev/sda: 625142448s
Tamaño de sector (lógico/físico): 512B/512B
Tabla de particiones. msdos
 
Numero  Inicio     Fin         Tamaño      Tipo      Sistema de ficheros  Banderas
 1      63s        32001479s   32001417s   primary   ext4                 arranque
 2      32001541s  94494329s   62492789s   extended
 5      32001543s  94494329s   62492787s   logical   ext4
 3      94494330s  98494514s   4000185s    primary   linux-swap(v1)
 4      98494515s  625137344s  526642830s  primary   ext4

El parámetro “print” le dice a parted que me imprima la tabla de particiones, y “u s” que imprima los tamaños en sectores (que en los discos <=1.0TB son siempre de 512 bytes, sino mismo parted lo dice en la salida, ver este post para más detalles).

De esta manera se tienen todos los sectores a copiar de /dev/sda directamente; en mi caso, 63 sectores de la pista 0, que contiene al MBR, más los de la primera partición, 32001417, total: 32001480 sectores.

Luego el dd que sólo copia los bytes que nos interesan (Pista 0 + Partición “C:”) es fácil:

sudo dd if=/dev/sda of=imagen.raw bs=512 count=32001480

Y listo. Eso sí, luego hay que particionar la imagen con Parted, Fdisk, GParted o el software que se quiera utilizar a tal efecto. Es necesario hacerlo porque el MBR copiado va a reportar las 4 particiones que se tenían previamente en el disco y ahora sólo se va a disponer de una sola.

Asumo que este procedimiento también se puede aplicar para copiar una partición que no sea la primera, usando las opciones “skip” y “append” del comando dd; por ejemplo, si quisiera hacer un disco de sólo mi partición 5, tendría que:

  1. Copiar la pista 0 en un archivo con algo así como “dd if=/dev/sda of=imagen.raw bs=512 count=63”.
  2. Ejecutar otro dd con la partición a copiar, salteando (“skipeando”) N sectores con la opción “skip” y especificando la opción “append” para agregar al archivo anterior de salida: “dd if=/dev/sda of=imagen.raw bs=512 count=62492787 skip=32001543 append”.

Lógicamente esto último no lo probé, acepto comentarios de si funcionó o no 😉

Espero que a alguien le sirva…

¡Saludos!

Categories: codear, linux, sysadmin, ubuntu-ar Tags:

Comparativas de Virtualización KVM

miércoles, 5 de enero de 2011 1 comentario

Ultimamente por diferentes cuestiones personales estoy bastante desconectado de la lectura de noticias, blogs y demás. Sin embargo, me pareció útil dejar por acá dos comparativas sobre KVM de Phoronix.com, que si bien en algunos lados me encontré que se quejan de la “calidad” de su suite de benchmarks para software libre/abierto, por el otro, ¡hey! ¡al menos se preocupan en hacerlo! 🙂

Linux KVM vs. VirtualBox 4.0 Virtualization Benchmarks
Este es un test de performance entre KVM y Virtualbox. En resumen, y con los parámetros por defecto en cuanto a I/O, VBox gana, pero parece que es debido a que no hace los fsync del guest en el host y termina utilizando su caché; muy probablemente este comportamiento es configurable (¿ver acá?), pero así y todo ¡es bueno saberlo!. De todas maneras, de alguna manera es peligroso para un entorno de servidores ya que hay riesgo de pérdida de datos, pero por ejemplo, para mi notebook (target primario adonde Virtualbox siempre estuvo orientado) está bien.

Por el otro lado, cuando hay que usar la CPU, KVM “le pasa el trapo” a VBox. Hay un test de I/O de red (TCP) que a KVM le dio mal, tan mal, que seguro es debido a que los salames testers no habilitaron VirtIO en los guests KVM.

Multi-Core Scaling In A KVM Virtualized Environment
Este test trata de dilucidar si es mito o no que el Hyperthreading (las VCPUs) de los microprocesadores Intel Xeon basados en Nehalem hacen más lentas o más rápidas las VMs que corren sobre KVM. Esto es algo que pregunté personalmente en el IRC de KVM (#kvm en Freenode, dicho sea de paso), y me sugirieron lo mismo que dió en los tests: hay veces en donde las VMs aprovechan todas las CPUs virtuales (VCPUs) y otras en que no, con lo cual hay que probar en cada caso en particular y dejar la configuración que nos dé mejores resultados.

Interesante de leer y experimentar.

Saludos

Categories: codear, linux, sysadmin, ubuntu-ar Tags: