Mike Tyson

by Ignacio Escudero Rivera on 2/08/2017
Mike Tyson stencil

Mike Tyson by David Drexler Creative Commons Attribution License

Esta frase:

“Everyone has a strategy until they get punched in the nose.” by Mike Tyson

Me parece majestuosa, real como la vida misma. Debes estar siempre preparado para los cambios.

No Comments

Inner Source Project Management

by Ignacio Escudero Rivera on 20/05/2017
Inner beauty1

Photo: Inner beauty1 by Sudarshan V. Creative Commons Attribution License

Tal vez has oído hablar de ello antes, Inner Source Project Management es la denominación que se da a la adopción de prácticas comunes en proyectos Open Source por parte de cualquier empresa. Implica asimilar características de un proyecto Open Source sin realmente serlo, cumpliendo los requerimientos que tiene todo desarrollo dentro de una empresa.

Es un enfoque que abre la posibilidad a cualquier miembro de la organización de embarcarse en él, como puede pasar en las típicas comunidades Open Source, pero el resultado es un producto cuyo propietario es la empresa y su código no es libre: sólo pueden acceder a él los trabajadores de la organización. La idea es que cualquier miembro del negocio pueda contribuir en el proyecto,  siendo el resultado final un producto cerrado.

Muchas serían las bondades para adoptar este modelo: el reciclaje o reutilización de código, que se va almacenando en un repositorio común dentro de la organización, pudiendo ser usado en cualquier otro proyecto. La calidad del resultado final: al aportar la organización un gran número de personas, las continuas revisiones realizadas favorecen a la mejora del producto . La mejora en la velocidad de cualquier desarrollo por parte de los miembros de la organización, ya que usan herramientas y código comunes en este proyecto que luego pueden usar en otros dentro de la organización. Aprendizaje y transmisión de conocimiento en la masa de desarrolladores: tienes a toda la empresa colaborando y aportando. Si el objetivo del proyecto es algo que toda la empresa va a usar: un sistema operativo, una aplicación, una herramienta; hace que el valor económico dentro de la organización y el conocimiento generado sean altísimos.

Desde aquí animo a otras organizaciones a intentar adoptar algún modelo (infraestructura, soporte de proyectos) que facilite la creación con enfoque Inner Source, siendo este breve artículo una introducción. Se puede encontrar mucha más documentación y ejemplos reales en libros y webs.

No Comments

Malabares y transistores

by Ignacio Escudero Rivera on 28/04/2017

Claude Shannon unos de los padres del actual computador, se dedicaba en su tiempo libre a hacer robots que hacían malabares.

 

No Comments

To be ready

by Ignacio Escudero Rivera on 25/04/2017

Miles Davis and his band recorded their album Kind of Blue in a matter of days, and the end result is considered the greatest jazz recording of all time. This was only possible because of the decades of experience each player had gained before they ever set foot in the studio. In a sense, they had been preparing for those sessions their entire lives.

by Ben Callahan

No Comments

Políticas de contraseñas en Fedora 25

by Ignacio Escudero Rivera on 15/02/2017

Fedora server
A menudo usamos nuestro sistema Linux con configuraciones estándar en nuestras máquinas de escritorio… y en nuestros servidores. Los usuarios usan una única cuenta para administrar las máquinas, usan claves rsa sin encriptar, dichas claves rsa están en sus máquinas en discos no encriptados, no usan contraseña para loguearse, no se bloquea la cuenta por inactividad, y un largo etcétera que no quiero ni enumerar, me da mucho miedo sólo el pensarlo.

Después de éste pequeño repaso a muchos peligros que algunos de nosotros tenemos alrededor, vamos a centrarnos. Concretamente en servidores montados con Fedora 25 que es de los últimos que he tenido que configurar con unas políticas de seguridad y acceso marcadas por una compañía.

El manejo de políticas de autenticación a través de Pluggable Authentication Modules (PAM) que en su versión de Fedora 25 ha dejado de usar /etc/pam.conf por el directorio /etc/pam.d/ no está muy bien documentado, sobretodo en lo referente a qué hace cada parámetro y cómo lo podemos usar.

Para nuestro caso, cambiaremos la configuración para poder limitar intentos de password, longitud mínima, complejidad de la contraseña (3 de estas cuatro características: mayúsculas, minúsculas, números y símbolos), evitar nombre de usuario en la contraseña, revisar diccionario para no usar como contraseña cadenas ahí incluidas o forzar la política para todos los usuarios, incluido root.

Pasamos a revisar el fichero que nos interesa para realizar todos estos cambios /etc/pam.d/system-auth

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

pam_pwquality.so es un módulo para comprobar la calidad de las contraseñas. Hay otros, como pam_cracklib o pam_passwdqc que se podrían usar en sustitución de pam_pwquality.so. Cada uno tiene sus características. La carga de uno u otro módulo se define en el fichero /etc/sysconfig/authconfig.

Nos va a interesar de pam_pwquality.so:

debug: al usar este parámetro se muestra el funcionamiento del módulo en el log del sistema
retry=3: número de intentos para introducir la cadena.
minlen=15: longitud mínima que debe usarse.
minclass=3: al menos 3 de cuatro características deben cumplirse (mayúsculas, minúsculas, símbolos y números)
reject_username: al activarlo impedimos usar la cadena nombre de usuario como parte de la contraseña tanto en orden natural como inverso.
gecoscheck=1: impedir el uso de cadenas del campo GECOS (normalmente nombre de usuario largo).
enforce_for_root: hacer que la directiva también se use con "root".

Además, este módulo carga el diccionario que tenga de manera estándar el sistema. Yo no pude hacer cargar el mío propio, pero sí pude añadir las palabra que me interesaban al que usa de manera predeterminada el sistema, de la siguiente manera:

create-cracklib-dict <fichero de texto con las cadenas> 

Finalmente la configuración quedaría como:

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password    requisite     pam_pwquality.so debug retry=3 minlen=15 minclass=3 reject_username gecoscheck=1 enforce_for_root
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

Y recargamos la configuración con:


authconfig --updateall

.

2 Comments

CasperJS la aspiradora de datos

by Ignacio Escudero Rivera on 26/01/2017
Aspiradora Roja

Foto: “a vacuum cleaner” by Taz Creative Commons Attribution License

Durante nuestro día a día nos encontraremos muchas veces webs con contenido importante, datos muy interesantes, que se actualizan con frecuencia y cuyos datos necesitamos para nuestro proyecto jhlspx3. Pero al ir a usar algún servicio que proporcione dicha web para acceder a los datos o descargarlos, nos daremos cuenta de que no existe ningún tipo de servicio de fácil acceso a la información o simplemente el servicio de publicación tiene un coste o complejidad que nos impide usarlo.

Si estás en esa necesidad: los datos son muy importantes para el proyecto y no puedo acceder a ellos de ninguna otra manera salvo “a mano” debes plantearte hacer uso de CasperJS.

CasperJS es un lenguaje de scripting basado en Javascript. Aporta un nivel de abstracción sobre PhantomJs. Por lo tanto, es un lenguaje usado para navegar por la web sin un entorno visual, realizar revisiones de aplicaciones online, monitorizar, capturar pantallas o automatizar acciones en cualquier página.

Ésta última característica es la que más nos interesa, ya que queremos extraer información. Mediante selectores CSS3 o XPath navegaremos hasta el contenido que nos interesa, podremos acceder a la información que contienen los elementos seleccionados y realizar acciones sobre ellos.

Las acciones más interesantes suelen ser: hacer “click” en un botón o enlace, rellenar formularios o revisar valores de tablas. La toma de decisiones en función de los resultados, el manejo de errores, los eventos, son otras de sus características.

La instalación es muy sencilla: si tienes npm instalado en tu sistema, mediante los siguientes comandos:

npm -g install phantomjs
npm -g install casperjs

Ya tendrías tu entorno preparado para trabajar.

Aquí se puede ver cómo usarlo para guardar en un array y mostrar todos los enlaces de una búsqueda:

var casper = require('casper').create();
var links;

function getLinks() {
// Rastreo de links
    var links = document.querySelectorAll('ul.navigation li a');
    return Array.prototype.map.call(links, function (e) {
        return e.getAttribute('href')
    });
}

// Abre casperjs 
casper.start('http://casperjs.org/');

casper.then(function () {
    links = this.evaluate(getLinks);
});

casper.run(function () {
    for(var i in links) {
        console.log(links[i]);
    }
    casper.done();
});

El resultado sería:

$ casperjs query-casperjs.js
http://docs.casperjs.org/en/latest/quickstart.html
http://docs.casperjs.org/en/latest/
https://github.com/casperjs/casperjs
https://groups.google.com/forum/#!forum/casperjs

Por lo tanto, CasperJS es una herramienta muy potente, para muchos de nuestros proyectos. No es sencilla o rápida de programar, pero nos permitirá automatizar o ayudar en muchas tareas.

No Comments

Copiar Máquinas virtuales Azure entre suscripciones

by Ignacio Escudero Rivera on 26/08/2015

Migrate

Es muy normal y útil tener alguna cuenta demo de Microsoft Azure, que te permite usar tu suscripción durante unos meses y tomar contacto con su plataforma. Empiezas a seguir tutoriales, crear servicios, máquinas pero en algún momento posiblemente quieras migrar o copiar las máquinas a otro entorno, por ejemplo, para poner en producción.

Empiezan los problemas, ¿ cómo migro todo a otra cuenta? Si lo que quieres es ceder tu cuenta a otra persona o entidad, no hay ningún problema, ya que puedes ponerte en contacto con Microsoft y ellos la “fusionan”. Pero y si sólo quiero copiar “alguna de mis máquinas virtuales”, no te preocupes, es una tarea un poco más engorrosa, pero se puede realizar.

El primer obstáculo es tener PowerShell para Azure. Si usas Linux, tienes que buscar un SO de Microsoft que soporte PowerShell. No vale el windows 98 que tenías cuando eras adolescente… Gasta algo de dinero, compra una licencia y ponte una máquina virtual sobre tu Linux, por ejemplo.

Hay varios tutoriales paso a paso, con los comandos que debes usar, como éste pero hay varias cosas que no funcionan correctamente… pasemos a explicarlas.

Lo primero, acceso a tu cuenta de origen y de destino:

Add-AzureAccount

Y selección de la cuenta que ahora vamos a usar, primero la de origen, para eso:

Get-AzureSubscription

Aquí toma nota del

SubscriptionName

que tienen las cuentas que vas a usar, pues tienes que “activarla” para ejecutar los comandos. Se activa con:

Select-AzureSubscription -Current -SubscriptionName elnombredetusubscripcion
Get-AzureVM

Si todo ha ido bien, ya has podido listar todas tus VM y localizar la que te interesa, ahora empieza lo bueno.
Siguiendo el tutorial que enlazamos más arriba tendrías que crear las siguientes variables:

$vmName = "EL_NOMBRE_DE_TU_VM"
$serviceName = "EL_NOMBRE_DE_TU_CLOUD_SERVICE"
$destServiceName = "EL_NOMBRE_DEL_NUEVO_CLOUD_SERVICE"
$workingDir = (Get-Location).Path

Con la última

$workingDir = (Get-Location).Path

puedes tener problemas, ya que la localización que te crea puede que no permita escribir y luego no vas a poder exportar correctamente la VM. Te recomiendo algo como:

$workingDir= "C:\ExportVMs"
if (!(Test-Path -Path $workingDir)) {

New-Item -Path $workingDir -ItemType Directory

}

Continuamos con:

$sourceVm = Get-AzureVM –ServiceName $serviceName –Name $vmName
$vmConfigurationPath = $workingDir + "\" + $vm.Name + ".xml"
$sourceVm | Export-AzureVM -Path $vmConfigurationPath
$sourceOSDisk = $sourceVm.VM.OSVirtualHardDisk
$sourceDataDisks = $sourceVm.VM. DataVirtualHardDisks

Para obtener la cuenta de almacenamiento de tu VM:

$sourceStorageName = $sourceOSDisk.MediaLink.Host -split "\." | select -First 1
$sourceStorageAccount = Get-AzureStorageAccount –StorageAccountName $sourceStorageName
$sourceStorageKey = (Get-AzureStorageKey -StorageAccountName $sourceStorageName).Primary

Asegúrate de apagar la máquina virtual:

Stop-AzureVM –ServiceName $serviceName –Name $vmName -Force

Ya vamos a proceder a copia la VM, y necesitamos cambiar de suscripción de Azure:

Select-AzureSubscription -SubscriptionName elnombredetusubscripcionnueva

Ubicación de la cuenta de almacenamiento. Suponemos que la copiamos a la misma región pero en diferente suscripción:

$location = $sourceStorageAccount.Location

Creamos una nueva cuenta de almacenamiento en la nueva suscripción:

$destStorageAccount = Get-AzureStorageAccount | ? {$_.Location -eq $location} | select -first 1
if ($destStorageAccount -eq $null)
{
$destStorageName = nuevacuentadealmacenamiento
New-AzureStorageAccount -StorageAccountName $destStorageName -Location $location
$destStorageAccount = Get-AzureStorageAccount -StorageAccountName $destStorageName
}

$destStorageName = $destStorageAccount.StorageAccountName
$destStorageKey = (Get-AzureStorageKey -StorageAccountName $destStorageName).Primary

Y todas las nuevas variables necesarias para los siguientes pasos:

$sourceContext = New-AzureStorageContext –StorageAccountName $sourceStorageName -StorageAccountKey $sourceStorageKey

$destContext = New-AzureStorageContext –StorageAccountName $destStorageName -StorageAccountKey $destStorageKey

Verificaciones:

if ((Get-AzureStorageContainer -Context $destContext -Name vhds -ErrorAction SilentlyContinue) -eq $null)

{

New-AzureStorageContainer -Context $destContext -Name vhds

}

Ya va quedando menos, nos disponemos a copiar:

$allDisks = @($sourceOSDisk) + $sourceDataDisks
$destDataDisks = @()
foreach($disk in $allDisks)
{
$blobName = $disk.MediaLink.Segments[2]
$targetBlob = Start-CopyAzureStorageBlob -SrcContainer vhds -SrcBlob $blobName -DestContainer vhds -DestBlob $blobName -Context $sourceContext -DestContext $destContext -Force
Write-Host "Copying blob $blobName"
$copyState = $targetBlob | Get-AzureStorageBlobCopyState

while ($copyState.Status -ne "Success")
{
$percent = ($copyState.BytesCopied / $copyState generic seroquel.TotalBytes) * 100
Write-Host "Completed $('{0:N2}' -f $percent)%"
sleep -Seconds 5
$copyState = $targetBlob | Get-AzureStorageBlobCopyState
}

If ($disk -eq $sourceOSDisk)
{
$destOSDisk = $targetBlob
}
Else
{
$destDataDisks += $targetBlob
}

}

Registramos los nuevos discos duros, para que sean correctamente reconocidos en la nueva suscripción:

Add-AzureDisk -OS $sourceOSDisk.OS -DiskName $sourceOSDisk.DiskName -MediaLocation $destOSDisk.ICloudBlob.Uri
foreach($currenDataDisk in $destDataDisks)
{
$diskName = ($sourceDataDisks | ? {$_.MediaLink.Segments[2] -eq $currenDataDisk.Name}).DiskName
Add-AzureDisk -DiskName $diskName -MediaLocation $currenDataDisk.ICloudBlob.Uri
}

Y finalmente, creamos la nueva VM. Mucho cuidado, porque puede dar problemas:

Get-AzureSubscription -Current | Set-AzureSubscription -CurrentStorageAccountName $destStorageName
$vmConfig = Import-AzureVM -Path $vmConfigurationPath

Tal vez tengas que haber creado una red antes, si la VM la tenía, retocar el fichero XML para que no use IPs fijas, etc. Todo depende de lo sencilla o compleja que era tu VM de origen.

 

¡¡¡¡Suerte con las migraciones!!!!

No Comments

Hazte anónimo en la red

by Ignacio Escudero Rivera on 8/07/2015

2306206890_feda251e65_zHace unos meses intenté crear algo que permitiese compartir ficheros multimedia de alguna manera sencilla. Buscando un poco rápidamente encontré un proyecto muy interesante Pirate Box. Dicho proyecto se basa en crear una red inalámbrica sin conexión a internet mediante la cual los usuarios puedan compartir sus propios ficheros. Imagínate un aula, una biblioteca, un espacio de trabajo en el cual la gente pueda compartir documentos, vídeos, fotos sin tener que depender de servicios de terceros ni compartir el mismo tiempo. Conceptualmente me gustó y lo probé, lo probamos, pero el concepto tiene que enganchar y el entorno no era el más adecuado: viernes por la mañana, primera hora, todo el mundo dormido en la oficina… nadie tenía casi nada que compartir con los demás y no era necesario. Técnicamente, lo que hace el desarrollador es modificar un firmware Open Source para routers wifi, creando una interfaz web de subida de ficheros, un chat y poco más. En cualquier caso, la sencillez de uso y en un buen entorno lo veo útil.

Como no paro de enredar, encontré otro proyecto muy interesante para crear una conexión VPN/Tor sencilla, mediante un dispositivo hardware, una Raspberry Pi al que te conectas via wifi y que permite proteger tu navegación. Dicho dispositivo se conecta a internet, securiza la conexión y crea un punto de acceso para tus dispositivos. Si viajas y te conectas a redes de hoteles o cafeterías, o simplemente quieres navegar de forma anónima o desde otro país (vease, quieres usar Netflix) esta configuración de tu Raspberry Pi te ayudará a hacer de una forma más segura y anónima.

No Comments