Políticas de contraseñas en Fedora 25

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

.

CasperJS la aspiradora de datos

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.

Copiar Máquinas virtuales Azure entre suscripciones

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!!!!

Hazte anónimo en la red

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.

El artículo de un enfermero sobre el riesgo del Ébola

Añado un enlace al artículo original.

Y el artículo completo, para que no se pierda:

CARTA DE UN ENFERMERO. EXISTE UN RIESGO MAYOR QUE EL ÉBOLA Y ESTÁ TRAS EL CRISTAL.

Soy un enfermero de la Unidad de Cuidados Intensivos (UCI) del Hospital La Paz. El motivo de dirigirme a Ud. Es poner en conocimiento de la opinión pública los hechos que han ocurrido recientemente en relación con la “Crisis del virus Ebola”. No quiero con ello crear alarma social, pero si narrar lo que está siendo una realidad en el día a día desde hace unos meses del personal de enfermería de dicha UCI entre los que me incluyo.

Desde que se nombró al hospital La Paz como centro de referencia para el diagnóstico y tratamiento de dicha infección, en Abril 2014, el personal ha estado poniendo de manifiesto su disconfor con tal medida y con las irregularidades que han estado cometiendo la dirección de enfermería de dicho hospital en su conjunto. (Ver archivo adjunto Notificación Juez).

Estas Irregularidades por resumir, se centran en que:

• El hospital no tiene la infraestructura adecuada para ingresar a pacientes afectados con este tipo de enfermedad (las famosas habitaciones de aislamiento de con presión negativa).

• Los protocolos originales del Ministerio de Sanidad fueron modificados a gusto para poder adaptarse a las carencias que tenía el hospital: Si no tenemos “presión negativa” decimos que “como no está demostrada la trasmisión aérea no es necesario tal medida”.

• Los protocolos generales de actuación (modificados o no) NO fueron entregados al personal para su conocimiento, ni tampoco fueron expuestos en las varias reuniones con la dirección de enfermería.

• Como Unidad de cuidados Intensivos exigíamos la realización de protocolos específicos de UCI (A día de hoy siguen sin existir o por lo menos al personal no han llegado)

• El personal exige la realización de cursos formativos y de capacitación para trabajar en situaciones como esta.

• El servicio de Medicina Preventiva del hospital imparte dos charlas informativas (45 minutos) de como son los equipos de protección personal necesarios. En aquellas charlas y por la inexperiencia del mismo personal que las impartía, los trajes se rasgaban, sustituían las calzas por bolsas de plástico, no existían escafandras completas y venían a decir poco más o menos que había que hacer un apaño para cubrirse la cara con cinta de carrocero.

Sin ser resuelto ninguno de estos temas por la Dirección del hospital, va pasando el tiempo y se comunica al personal que será el Hospital de la defensa “Gómez Ulla” quien asumirá estas emergencias pero como está en proceso de reforma para crear unas instalaciones adecuadas, hasta el mes de Octubre seguiremos siendo hospital de referencia.

Así, sin hacer nadie nada nos presentamos en la noche del 5 de agosto, y el personal de guardia aquella noche entre los que me incluyo, a través de los medios de comunicación nos enteramos que se va a repatriar al sacerdote. Avisamos a nuestro inmediato superior (Supervisor de Guardia) el cual desconoce por completo el modo de proceder teniéndose que poner en contacto con el Jefe de Hospital de guardia aquella noche, el cual a su vez desconocía la noticia y comienza a activar el protocolo establecido (recordemos que hasta esa misma noche el paciente iba a ser ingresado en la paz). Siendo el personal de UCI el encargado del recibir al sacerdote no se pone en conocimiento del mismo dicho protocolo.

Fue a la mañana siguiente, 6 de agosto, cuando gracias a dios, alguien advierte del peligro potencial de ingresar al sacerdote en un hospital de las dimensiones de la Paz, y sin las instalaciones adecuadas. Sobre las 14 horas se toma la decisión de que sea llevado a la 6ª planta del Hospital Carlos III dotada de salas de aislamiento con presión negativa. Desde ese mismo instante se comienza a dotar al hospital Carlos III de lo necesario para albergar al paciente. Aquí hay que señalar que dicha planta del hospital estaba cerrada y sin dotación de personal ni equipos pues a mediados de agosto darían comienzo las obras de transformación en una unidad de hospitalización para enfermos crónicos. – Estaremos de acuerdo en que a esto se le llama “IMPROVISAR”.

Así durante toda la tarde del 6 de agosto y a toda prisa personal de ambos hospitales fueron dotando de medios dicha planta. Dándose casos curiosos en los que enfermeras del hospital La Paz transportaban en su propios vehículos material carente en el Carlos III. (Esto sí que es “Marca España”).

Ante la carencia de personal en el Hospital Carlos III por los motivos antes citados, las Direcciones de Ambos hospitales determinan que personal de la UCI de la Paz sea enviado al Carlos III. Y es aquí donde debido a la improvisación y la falta de criterio se comete otra negligencia más enviando a un personal sin formación alguna en Riesgos Biológicos a tratar a un paciente afecto de una de las infecciones más peligrosas conocidas declarada por la OMS a nivel mundial como Emergencia en Salud Publica. (Aquí conviene recordar que existe una unidad específica con formación para tratar estos casos: la Unidad NBQ o la Unidad Militar de Emergencias UME).

Y aquí se comete otra tropelía, Supervisores de enfermería y la propia Dirección de Enfermería de la Paz conocedores de que el personal a su cargo no está bien formado por que no se ha dado formación específica y no se le ha informado de los protocolos a seguir, ni cuál es su función cuando acudan a allí, se le obliga a desplazarse con coacciones y amenazas de perder su puesto de trabajo o abrírsele un expediente disciplinario si se niega a ser enviado al Carlos III.

A día de hoy y a pesar de que estas personas llevan varios días ingresadas, ni la dirección de enfermería ni dirección médica se ha ocupado de organizar simulacros de actuación impartidos por personal competente en las medidas de protección personal para el personal desplazado. Son las mismas enfermeras/os los que una vez allí en el Carlos III se informan de unos a otros como es el proceder y como hay ponerse las medidas de protección. Siendo justos, el personal del Carlos III que aún quedaba allí trabajando, con alguna más formación en estos casos que nosotros, nos intentan adiestrar y tranquilizar en este sentido. Pero esto ocurre allí minutos antes de entrar en la sala del paciente. Como dato curioso, la Guía para la selección y uso de Equipo de Protección Personal en ámbitos de atención médica, consta de 50 páginas. Y la Guía para la Atención de Pacientes con Virus Hemorrágico en los hospitales de EEUU consta de 225 páginas. Ambas del CDC de Atlanta y disponibles en “PDF” para cualquiera en su página web. Aquí no tenemos nada.

Es cierto que el personal muestra sus reticencias a acudir al Carlos III pero nadie se ha negado a tratar a un paciente. Solo advertimos que no hemos sido formados convenientemente y que dadas las características de la enfermedad el riesgo de contagio y posible trasmisión fuera de los muros del Carlos III es una realidad que como profesionales de la sanidad debemos poner en conocimiento de quien sea ya que nuestros superiores directos no nos escuchan. Las preguntas son claras: ¿Por qué se envía personal sin formación? ¡Es incongruente! ¿Por qué la responsabilidad última de evitar la propagación recae en personal sin formación específica? ¿Los americanos harían una cosa así?.

Perdón por este último comentario. Me he prometido a mí mismo no caer en demagogia y ser lo más aséptico posible narrando de forma veraz los hechos.

Por otro lado la selección de este personal se ha hecho de forma arbitraria y sin criterio. Todo el personal de la UCI va a rotar por el Carlos III. Bien, protocolo de la OMS advierten que el personal sanitario o no, debe minimizar el tiempo de exposición en la sala con el enfermo así como reducir lo máximo posible el número de personas que atiendan de forma continuada al paciente. Pues bien si todo el personal de la UCI pasara por allí, ¿No estamos aumentando de forma exponencial el riesgo a una posible trasmisión? No es lógico y contraviene las medidas dictadas por la OMS.

Sigo; Al personal que pasa por allí no se le hace ningún tipo de seguimiento ni medida epidemiológica cautelar. Una vez terminado su turno se marcha alegremente a su casa y al día siguiente, si no te toca volver al Carlos III pues vas a trabajar a la UCI de la Paz con enfermos de diversa etiología en muchas ocasiones Inmunodeprimidos. Es un contrasentido que para subirte a un avión se tomen medidas y controles y yo pueda ir y venir y hacer mi vida normal como si nada. Esto no es coherente.

Para finalizar solo queda por recalcar que en todo este asunto hay mucha improvisación y mucha actitud temeraria por parte de los que de verdad, de verdad… NO van a estar delante del virus mirándole a la cara. Escuchemos a los que están en la primera línea de fuego que algo tendrán que decir.

Le saluda atentamente:

xxx