Docker tags

Buscar una imágen en docker es fácil con el comando docker search, pero luego que encuentras la imágen localizar las etiquetas disponibles ya no está al alcance del comando rápido… se requiere un consultar la respuesta json de una URL del registry.

Agregando este bloque de función al .bashrc

es posible tener un comando docker_tags que recibe por parámetro la imágen que se va a buscar y devuelve la lista de etiquetas disponibles:

$ docker_tags alpine
"20190707"
"20190809"
"20190925"
"3"
"3.10"
"3.10.1"
"3.10.2"
"3.8.4"
"edge"
"latest"

Si encuentras una mejora a esto, agradezco lo compartas en los comentarios.

Sobre escribir variables al invocar el shell script

Todos utilizamos variables de tipo constantes en nuestros shell scripts, que en principio no son modificables pues están en el código, un ejemplo simple:

#!/bin/bash
HOLA="Hola, soy el script"
echo $HOLA

así en cada ejecución de este script se mostrará el contenido de la variable HOLA:

$ ./hola
hola soy el script
$

Pero al definir/crear la variable podemos hacerlo con un contenido por defecto, que se usa en caso que la variable no tenga otro valor, mediante esta sintaxis de definición:

HOLA=${HOLA:-"Hola, soy el script"}

de esta forma HOLA tomará el valor que ya traiga o, en caso de ser nula, asignará el string indicado luego del :-

Esta sintaxis para la definición de las variables en nuestros script permite que se le pueda cambiar el valor al invocar el script, así:

$ HOLA="Hola, soy el shell" ./hola
Hola, soy el shell
$

También esta sintaxis de valor por defecto de las variables puede ser asignado directamente al invocarlas, utilizando una sintaxis equivalente:

#!/bin/bash
echo ${HOLA:-"Hola, soy el script"}

lo que simplifica el script, aunque puede distribuir los valores de las variables a lo largo y ancho del código así que a usarlo con cuidado.

Obviamente es algo muy documentado y explicado, aquí unos ejemplos:

Openstack CLI y autocompletar en bash

Hace ya tiempo que utilizo el comando integrado openstack para vincularme con nubes en Openstack de distintos proveedores y siempre extrañe que en algunas distribuciones de GNU/Linux no estuviera disponible el autocompletar en Bash.

El comando openstack ofrece el parámetro complete que genera el script para que bash-completion lo cargue y quede funcional.

Ejecutar como usuario con permiso sudo:

$ openstack complete | sudo  tee /etc/bash_completion.d/osc.bash_completion > /dev/null

o también como root:

# openstack complete > /etc/bash_completion.d/osc.bash_completion

El parámetro complete implementado en el comando openstack utiliza el framework cliff – Command Line Interface Formulation Framework para obtener la salida del script de bash-completion.

Listar permisos rwx en octal

Estamos acostumbrados a ver los permisos de los archivos con el comando ls -l con la típica representación de rw-r–r– y generalmente hago la traducción a octal 644 en forma mental.

Pero si necesitamos desplegarlos en octal, tenemos a nuestra disposición el comando stat que soporta dar formato a la salida para ver sobre el estado de nuestro sistema de archivos:

En GNU/Linux que utilizamos stat de GNU Coreutils:

stat -c «%n %a» *
config.cf 644
containers.txt 644
libs 755

En MacOS que utilizamos stat de BSD:

stat -f «%N %Lp» *
config.cf 644
containers.txt 644
libs 755

Felicidades y happy hacking en 2017

bash_completion en macOS

Hace tiempo me había llegado la versión beta de Docker para Mac y estaba en mi To-Do List hasta hoy que puede dedicarle unas horas. En el tutorial de instalación había observado la sencillez para configurar bash_completion y así tener un acceso rápido a las funciones de búsqueda y completado de elementos de docker mediante la doble presión del tabulador; entonces que puse manos a la obra.

El primer paso es instalar bash_completion mediante Homebrew:

$ brew install bash-completion
$ brew tap homebrew/completions

Y luego agregar al archivo ~/.bash_profile lo siguiente::

~/.bash_profile

if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion
fi

Fuente: David Alger blog

10 comandos Linux poco usados

herramientas raras

Muchos compartimos la profesión de administrar sistemas Linux desde hace años, eso nos ha llevado a conocer la mayoría de los comandos disponibles. Pero de la misma forma que, tal vez, ls y man son de los primeros comandos que se aprenden y usan, están los que por otro lado son poco conocidos o poco usados, vamos a alguno de ellos:

Concatenar e imprimir archivos al revés:

tac /etc/passwd

Obtener PID de un proceso por grep de string:

pgrep ssh

Listar de procesos como árbol

pstree
pstree -p
pstree -pu

Listar servicios escuchando puertos tcp

ss -lt

Invertir un string

echo aloha | rev

Traceroute simplificado

tracepath www.google.com

Borrar archivo.txt y hacer que su contenido sea irrecuperable

shred archivo.txt

He seleccionado comandos que generalmente vienen instalados en las distribuciones de Linux, evitando aplicaciones extrañas que no están por defecto disponibles.

¿tienes alguna sugerencia más para esta lista de comandos ‘raros’ o poco utilizados?

Crear archivos grandes

create large files

Varias veces he tenido la necesidad de crear archivos grandes, ya sea para luego darles formato de sistema de archivos y usarlos como imágenes o para llenar espacio en disco. Hasta ahora utilizaba el comando dd, pero hace poco encontré que existen formas múcho más rápidas para hacerlo y que terminan siendo más adecuadas.

dd

Como dije utilizaba el comando dd que está pensado para copiar archivos y, cuando se leen datos desde el dispositivo /dev/zero, se puede crear un archivo lleno de ceros.

dd if=/dev/zero of=archivo.img bs=1024 count=1000000

Página man dd

fallocate

fallocate se utiliza para pre-asignar bloques a un nombre de archivo. Esta tarea se realiza muy rápidamente porque solo se asignan bloques sin datos, por lo que no se realizan operaciones de entrada/salida y termina siendo mucho más rápido que crear un archivo lleno de ceros.

fallocate está disponible desde el kernel Linux v2.6.31 y está soportado por los sistemas de archivos btrfs, ext4, ocfs2 y xfs.

fallocate -l 10M archivo.img

Página man fallocate

truncate

truncate permite ampliar o reducir un archivo a un tamaño especificado. Si el archivo no existe, se crea con el tamaño específico, que es lo que generalmente necesito hacer.

Si un archivo es más grande que el tamaño especificado, se pierden los datos extra. Si un archivo es más corto, se extiende y la parte ampliada está llena de byte cero.

truncate -s 10M archivo.img

Página man truncate

xfs_mkfile

xfs_mkfile permite crear uno o más archivos en sistemas de archivo xfs exclusivamente (lo estandar en RedHat a partir de la versión 7).

El archivo por defecto se rellena con ceros por defecto. El tamaño que se indica por defecto es en bytes, pero se pueden indicar en kilobytes, bloques, megabytes o gigabytes con los parámetros k, b, m, o g, respectivamente.

xfs_mkfile 1240m archivo.img

Pagina man xfs_mkfile

Ejecutar un script bash remoto sin instalar

Me ha sido muy útil ejecutar scripts remotos sin instalarlos localmente. Esto me permite, por ejemplo, hacer la instalación inicial del cliente Puppet o poner Ansible para completar la configuración del sistema hasta llevarlo a estado de producción.

Para descargar el script se puede usar tanto el comando curl como wget. Uno u otro suelen venir instalados por defecto en cualquier distribución Linux.

La idea es simple: correr el comando (wget o curl) y obtener la salida (script) limpia (es decir, sin datos extra de transferencia o ejecución) y pasarlo como entrada a bash para su interpretación y ejecución local.

He armado un simple script, cuyo código puede ser visto aqui: script-remoto.txt (la terminación txt es solamente para que lo muestre el navegador, pero no necesita ninguna extensión en particular), que puede ser ejecutado con cualquiera de estos comandos:

con curl:

source <(curl -s http://pilas.guru/wp-content/uploads/script-remoto.txt)

bash <(curl -s http://pilas.guru/wp-content/uploads/script-remoto.txt)

curl -s http://pil.as/1h1n | source /dev/stdin

curl -sL http://pilas.guru/wp-content/uploads/script-remoto.txt | bash -s

con wget:

source <(wget -qO- http://pilas.guru/wp-content/uploads/script-remoto.txt)

bash <(wget -qO- http://pilas.guru/wp-content/uploads/script-remoto.txt)

wget -qO- http://pil.as/1h1n | source /dev/stdin

wget -qO- http://pilas.guru/wp-content/uploads/script-remoto.txt | bash -s

Pueden ver que he creado un enlace corto que redirecciona al mismo archivo http://pil.as/1h1n, pero ATENCION, no se debe confiar en los enlaces cortos livianamente y MENOS con la intención de ejecutar comandos ajenos en el equipo propio.

Reivindicando la Terminal

Muchas veces nos subimos a la ola del desarrollo de aplicaciones cada vez más complejas y quedamos atrapados en una espiral de featuritis incremental. Entonces, cada tanto es bueno volver a los orígenes y ver como muchas problemas tienen soluciones simples que hemos olvidado (al menos yo).

Así me encontré con el artículo de José Román Hernández en Emezeta blog titulado La gran guía de supervivencia de la terminal de Linux.

En el artículo, José describe aplicaciones para uso exclusivamente en terminal para:

  • Explorar archivos
  • Multitarea y multiventanas
  • Leer el correo
  • Productividad y organización de tareas
  • Redes sociales
  • Gestores de descargas
  • Lectores de feeds
  • Ofimática y visores de documentos y textos
  • Navegadores web
  • Lectores de PDF
  • Reproducción de música
  • Reproducción de videos

todos con la característica de ser aplicaciones para la Terminal.

Creo que este es un muy buen complemento para conversar sobre la Actividad Terminal la próxima oportunidad que tenga para exponer sobre el tema.

Verificando certificados SSL desde la línea de comandos

Recientemente he necesitado revisar el vencimiento de certificados SSL mediante un script que me permitiera conocer el estado de los mismos en muchos servidores.

Una primer opción era ejecutar el comando openssl para verificar cada certificado:

$ openssl x509 -in certificado.pem -noout -enddate
notAfter=Oct 24 23:59:59 2014 GMT

y automatizarlo mediante conexiones ssh, pero el problema es que los certificados no tienen todos el mismo nombre, ni están instalados en el mismo directorio, pues algunos fueron instalados dependiendo del servicio.

Así que la opción fue utilizar openssl para abrir conexiones como cliente y verificar qué vencimiento tiene el certificado del servicio correspondiente:

$ echo | openssl s_client -connect servidor.com:443 2>/dev/null | openssl x509 -noout -dates
notBefore=Oct 24 00:00:00 2013 GMT
notAfter=Oct 24 23:59:59 2014 GMT

El echo inicial envía un enter al comando openssl para que el cliente no conectado y de esta forma con un listado de nombres de servidor y los puertos, se puede revisar toda una infraestructura de servidores y servicios.

Algunas argumentos que pueden ser pasados a openssl para obtener datos de certificados X509:

  • –dates fechas del período de validez del certificado
  • –enddate fecha de vencimiento
  • –subject titular del certificado y CN
  • –issuer autoridad de certificación
  • –fingerprint huella dactilar del certificado
  • –text toda la información del certificado

Estos comandos pueden ser utilizados en conjunto para obtener más de una información en la misma consulta:

$ echo | openssl s_client -connect servidor.com:443 2>/dev/null | openssl x509 -noout -dates -issuer -fingerprint
notBefore=Oct 24 00:00:00 2013 GMT
notAfter=Oct 24 23:59:59 2014 GMT
issuer= /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=EssentialSSL CA
SHA1 Fingerprint=6F:24:52:8F:10:E0:6D:AB:C9:BB:1D:52:65:F6:A8:47:89:BE:A3:5F

y quitando el -noout se obtiene el certificado:

$ echo | openssl s_client -connect servidor.com:443 2>/dev/null | openssl x509
-----BEGIN CERTIFICATE-----
MIIFIjCCBAqgAwIBAgIQMK1wptvY36IzHyscziufKTANBgkqhkiG9w0BAQUFADBy
MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD
...
nZpAVhzwHIS5wzMMHc5XRFvv3Ohnsco1CAA76HBBrMjmC6OYFXVDX+LgXjnTvuS8
lpg865wT5NUeWtWoRCOQydIHXqatpEyysbBZ/QbUA9CjjWViowRfYub2jZJ3v1k4
SsEYTJTsv3duHmn5Zn+dhINdVgVEJA==
-----END CERTIFICATE-----

y, por supuesto, para la consulta de un solo certificado, a veces es útil alguna herramienta web como esta de SSLShopper

Con curl


$ curl -s --insecure -v https://servidor.com \
| awk 'BEGIN { cert=0 } /^\* Server certificate:/ \
{ cert=1 } /^\*/ { if (cert) print }'

* Rebuilt URL to: https://servidor.com/
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 13.249.87.93...
* TCP_NODELAY set
* Connected to servidor.com (x.x.x.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [76 bytes data]

...

* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=servidor.com
* start date: Aug 16 00:00:00 2019 GMT
* expire date: Sep 16 12:00:00 2020 GMT
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
} [5 bytes data]
> GET / HTTP/1.1
> Host: servidor.com
> User-Agent: curl/7.52.1
> Accept: */*
>