Gestiona tus contraseñas y secretos con Pass

Llevo un tiempo utilizando Vaultwarden como mi gestor de contraseñas para el día a día, además de usarlo para gestionar aquellas que tengo en común con la familia y como almacén de notas seguras.


El problema siempre ha estado en el mantenimiento del servicio y sus copias de seguridad. Vaultwarden se integra muy bien con las aplicaciones móviles y la web... pero no tiene una API que me permita integrarlo fácilmente en procesos automáticos. La idea que tenía en mente era mantener una copia de seguridad de todos aquellos ficheros .env donde almaceno información sensible de mis contenedores Docker, así como los token de los bot de Telegram, o las claves de acceso a mi servidor S3, que son usadas por varios script repartidos por las distintas máquinas que conforman mi actual nube personal.

Buscando e indagando fue como di con pass, el cual no es más que un gestor de contraseñas completamente integrado en Linux desde el principio de los tiempos y que sigue la filosofía de la sencillez, pero no por ello dejando a un lado la seguridad y utilizando claves gpg para ello. Entre sus mejores características cabe destacar:

  • Interfaz de consola muy sencilla y potente
  • Cifrado de las contraseñas mediante claves GPG
  • Soporte para repositorios Git
  • Admite entradas multi-línea, útil para guardar no sólo contraseñas, sino ficheros completos de configuración (los .env que mencionaba antes)

Ese listado anterior es sólo la punta del iceberg de lo que puede hacer pass. En esta entrada explicaré cómo instalarlo y un primer uso de la herramienta, con lo que os dará una mayor idea de su potencial.

Requisitos previos

Para utilizar pass necesitamos tener instalado tanto git como gpg. Normalmente en los sistemas actuales son 2 herramientas que suelen venir integradas, pero si no fuera el caso, habría que instalarlas antes de seguir. Para GPG podemos descargar los binarios directamente de su web.

Lo primero que necesitaremos hacer es crear nuestra clave GPG que usaremos para cifrar la bóveda de seguridad en pass. Si bien podemos usar más claves para distintos subdirectorios y entradas, necesitaremos una como mínimo para toda la bóveda. Así pues, comenzaremos a crearla usando el comando:

gpg --full-generate-key

Especificaremos el tipo de clave (RSA y RSA será más que suficiente), el tamaño de clave a usar (recomendable 4096 bits para que sea lo más seguro posible), la fecha de expiración (no es necesario, pero sí recomendable), información del ID de usuario que usaremos y, por último pero no menos importante, una contraseña segura. Algo así deberíamos tener:

$ gpg --full-generate-key
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Wed Feb  7 21:19:48 2024 CET
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: MiClave
Email address: yomismo@example.org
Comment:
You selected this USER-ID:
    "MiClave <yomismo@example.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 295C021A8C414527 marked as ultimately trusted
gpg: directory '/home/ubuntu/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/ubuntu/.gnupg/openpgp-revocs.d/85CF755768A0BE2ECB38744D295C021A8C414527.rev'
public and secret key created and signed.

pub   rsa4096 2023-02-07 [SC] [expires: 2024-02-07]
      85CF755768A0BE2ECB38744D295C021A8C414527
uid                      MiClave <yomismo@example.org>
sub   rsa4096 2023-02-07 [E] [expires: 2024-02-07]
Proceso de creación de una clave GPG

Una vez hayamos creado la clave, podremos verla con el comando:

gpg --list-secret-keys --keyid-format=long

Que nos dará un resultado similar a:

$ gpg --list-keys --keyid-format=long
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2024-02-07
/home/ubuntu/.gnupg/pubring.kbx
-------------------------------
pub   rsa4096/295C021A8C414527 2023-02-07 [SC] [expires: 2024-02-07]
      85CF755768A0BE2ECB38744D295C021A8C414527
uid                 [ultimate] MiClave <yomismo@example.org>
sub   rsa4096/4CDE0B88F670263A 2023-02-07 [E] [expires: 2024-02-07]
Listado de las claves GPG existentes en la máquina

Una vez la tengamos creada, deberemos anotar el ID (en el ejemplo sería MiClave) que le hemos dado, pues nos hará falta en el paso siguiente.

Instalar e inicializar pass

pass lleva tanto tiempo en Linux que ya es parte del sistema prácticamente. Si no lo tenemos instalado, bastará con un pequeño sudo apt install pass para tenerlo disponible (el comando es para Debian, pero si usáis otras distros conoceréis el equivalente).

Una vez tenemos el comando instalado, el primer paso será inicializar la bóveda. Para ello, usaremos:

pass init ID_DE_LA_CLAVE_GPG

y veremos cómo se nos crea un directorio ~/.password-store. Podemos especificar otro distinto mediante el parámetro -p. Y así de fácil tendremos lista nuestra bóveda. El resultado anterior sería:

$ pass init MiClave
mkdir: created directory '/home/ubuntu/.password-store/'
Password store initialized for MiClave

Ahora, si ejecutamos pass o pass ls veremos que no tenemos nada (lógico), así que vamos a crear nuestra primera entrada...

Agregar entradas a pass

Para agregar una entrada nueva, haremos uso de:

pass insert prueba

El comando nos pedirá 2 veces que introduzcamos el secreto que queremos crear, y una vez lo hagamos, éste será almacenado en nuestra bóveda. Si ahora ejecutamos pass o pass ls, veremos que nos aparece una entrada nueva:

Password Store
└── prueba

Y si hacemos pass show prueba obtendremos la información que hemos guardado.

Ésta sería la manera más sencilla de crear una nueva entrada. Pero podemos concatenar salidas de otros procesos con pass mediante algunos de sus modificadores:

  • -e: También soportado como --echo permite introducir una cadena a través de la entrada estándar
  • -m: O --multiline nos permite introducir un texto repartido en varias líneas

De esta forma, guardar un fichero importante, como por ejemplo uno que contenga la información sensible que permite a un contenedor Docker arrancar, se puede guardar con pass de manera tan sencilla como:

cat .env | pass -m contenedores/hello-world/env_file

Cabe destacar que, cuando ejecutamos pass show <path> se nos muestra el contenido de ese secreto. Pero podemos ir más allá y afinar el resultado mediante distintos modificadores que nos permitirán mostrar sólo una línea en concreto o, incluso, generar un QR. Veámoslo en un caso práctico.

Caso práctico: Almacenar la clave de la WiFi

Supongamos que queremos guardar la clave de nuestra WiFi para compartirla con amigos y tenemos una clave tan segura que escribirla a mano es un fastidio. Comenzamos por crear un fichero wifi.txt que contenga:

  • El tipo de seguridad, SSID y contraseña en formato legible por los móviles
  • SSID
  • Contraseña

El fichero quedaría de esta forma:

WIFI:T:WPA;S:mi ssid;P:mi_password;;
mi ssid
mi_password
Fichero wifi.txt con la información de la wifi que queremos guardar

Ahora, introduciremos nuestro fichero en pass con el comando:

cat wifi.txt | pass insert -m casa/wifi

Esto nos creará una entrada en nuestra bóveda llamada wifi, y además dentro de un directorio casa (como veis, es fácil organizar nuestros secretos con pass). Si ejecutamos pass show casa/wifi nos mostrará todo el contenido del secreto, es decir lo mismo que teníamos en el fichero wifi.txt (el cual ya podremos borrar). Si sólo queremos sacar la contraseña para pegarla en nuestro ordenador, basta con hacer pass show -c3 y se nos copiará al portapapeles, de manera que sólo necesitaremos hacer un Ctrl+V en el campo de contraseña de la WiFi y podremos conectarnos.

Y si además queremos poder escanearla desde el móvil, el parámetro -q nos generará un código QR en pantalla cuyo contenido será el de la primera línea del secreto. Esto nos generará un QR como el siguiente, que podremos escanear con el móvil y automáticamente se nos conectará a la red:

$ pass show --qr casa/wifi
█████████████████████████████████████
█████████████████████████████████████
████ ▄▄▄▄▄ █ ▄▄ █▄▄ █ ▀ ██ ▄▄▄▄▄ ████
████ █   █ ██▄█▀▀▄█▀██▄███ █   █ ████
████ █▄▄▄█ █ ▀▀▄ ▀▀▄▄▄▀▀ █ █▄▄▄█ ████
████▄▄▄▄▄▄▄█ ▀▄█▄▀▄█▄▀ ▀▄█▄▄▄▄▄▄▄████
████   ▀▀ ▄█ ▄█▄ ▄█ ██▀▄▄ ▄  ▀█  ████
████▄█  ▄█▄  ▄ ▀ ▄ ▀██▀▄▀█  █ █▀▀████
█████▄ ▀█ ▄▄▀  ██   █▄▄ █ █▄▀▀▀▄▀████
████▀   ▀ ▄ ▀▀█▄█▀█▀███▀█▄ ██ ▀▀▄████
████▄▀█ ██▄█ █▀▄ ▄█▄ ▄ ▄ ▄▄██ ██ ████
████▄▄ ▀▀▄▄█▀▄▀▀ ▄   █▀  ▀ ▀▄ ▄  ████
████▄▄▄▄▄▄▄▄▀▄ ██   ▄█   ▄▄▄  ▀ █████
████ ▄▄▄▄▄ █▀ █▄█▀█ ▀█▀▄ █▄█ ▀█▀▄████
████ █   █ ██▄▀▄ ▄█ ▀█ █ ▄▄  ▄▄█▄████
████ █▄▄▄█ █ ▀▀▀ ▄ ▀ █▀▀ ▀█ ▀█ ▄ ████
████▄▄▄▄▄▄▄█▄▄███▄▄▄███▄▄██▄▄▄█▄▄████
█████████████████████████████████████
█████████████████████████████████████
Código QR generado por pass con la primera línea del secreto

Usar un repositorio Git

Una vez tenemos nuestro gestor de contraseñas funcionando, lo ideal sería poder llevárnoslo a otros dispositivos, o mantener una copia de seguridad por si el dispositivo donde lo usamos se nos pierde, se estropea, o cualquier otro incidente.

Para facilitarnos la vida, pass nos proporciona integración con Git, de manera que nos permite gestionarlo como si de un repositorio más se tratara. De esta forma, podremos añadir, modificar y borrar contraseñas con la tranquilidad que nos da disponer de un histórico fácil de recuperar.

Inicializar repositorio Git

Para inicializarlo, tenemos 2 opciones:

  1. Gestionar la carpeta donde tenemos todo (por defecto: ~/.password-store) como si de un repositorio Git como tal se tratara: Accedemos al directorio y mediante git init lo convertiremos en un repositorio. Podremos añadir orígenes remotos, hacer commits, pull, push, gestionar ramas... Un repositorio de Git, vaya.
  2. Mientras que la primera opción requiere que estemos en el mismo directorio, la opción más cómoda es gestionar el repositorio de Git a través del comando pass. No hay diferencia alguna con el uso de Git por consola, lo único que hay que tener en cuenta es que, cualquier acción que queramos ejecutar, deberá estar iniciada por el comando pass. Así, para inicializar un repositorio Git con nuestras contraseñas, deberemos ejecutar:
pass git init

Y con esto tendremos el repositorio Git inicializado para nuestro gestor de contraseñas. A partir de aquí, cada vez que hagamos alguna modificación, agreguemos una nueva entrada o eliminemos, pass generará un nuevo commit.

Añadir un origen remoto

La segunda parte es la más bonita. pass mantiene nuestros secretos cifrados con una clave GPG, y a su vez soporta Git para gestionar y evolucionar los cambios. Así pues... ¿por qué no crearnos un repositorio Git en la nube y mantener en él una copia de seguridad, además de tenerlo accesible de manera sencilla para otros dispositivos? Exacto: Será nuestra herramienta para la sincronización y el backup del gestor de contraseñas.

Para añadir nuestro repositorio remoto (el cual deberemos crear, bien en nuestro propio servidor Git o bien en terceros como GitLab o GitHub), bastará con ejecutar las órdenes (pongo como ejemplo un repositorio en GitLab):

pass git remote add origin git@gitlab.com:<username>/repo-pass.git
pass git push

Y con esto subiremos nuestro repositorio de pass con su histórico de Git al servidor remoto. Y puesto que está todo cifrado con nuestra clave GPG, no tenemos de qué preocuparnos (salvo que se rompa ese cifrado, pero si tenemos una buena clave no deberíamos preocuparnos).

Es importante que no tengamos la clave GPG privada en el repositorio de Git. Es lo único sobre lo que deberemos tener máximo cuidado si vamos a usar este sistema.

Una vez hecho esto, cada vez que hagamos un cambio con pass, bastará con ejecutar pass git push para que se suba al servidor remoto, y tenerlo disponible para otros dispositivos o como copia de seguridad actualizada.

Automatizar el proceso de push

Hacer un push después de usar pass es algo que, fácilmente, se nos puede pasar. Afortunadamente, Git nos proporciona herramientas que nos permiten automatizar dicho proceso. Se trata de los hooks, y añadir uno nuevo será tan fácil como crear el archivo ~/.password-store/.git/hooks/post-commit y ponerle el siguiente contenido:

#!/bin/sh -x

# Reemplazar main por el nombre de la rama que usemos por defecto
git push origin main:main

Guardamos, damos permisos de ejecución con chmod +x ~/.password-store/.git/hooks/post-commit y listo. Cada vez que hagamos un cambio con pass, éste creará un nuevo commit y automáticamente se subirá al servidor Git remoto.

Importar repositorio de pass en otro dispositivo

Hasta ahora, hemos visto los pasos para inicializar nuestro gestor de contraseñas y mantenerlo actualizado con una copia en un servidor Git remoto. Pero si queremos utilizarlo desde otro dispositivo, o bien restaurar una copia en el dispositivo actual, podremos hacerlo de manera muy sencilla. Bastará con ejecutar lo siguiente para que se nos descargue el repositorio remoto en la carpeta donde queramos alojarlo (por defecto: ~/.password-store):

git clone git@gitlab.com:<username>/repo-pass.git ~/.password-store

Si ahora ejecutamos un pass ls desde esta nueva máquina, podremos ver todos los secretos que teníamos creados, modificarlos, crear nuevos o eliminar viejos, y con un simple pass git push, subirlos para, desde el resto de dispositivos, poder hacer un pass git pull y tener los cambios actualizados.

Si queremos que se ejecute el auto push en los otros dispositivos, deberemos repetir el paso de automatizar el proceso de push en cada uno de los dispositivos donde lo queramos tener.

Exportar clave GPG privada

Si intentamos lo anterior sin más, veremos que no podemos visualizar nuestros secretos en el nuevo dispositivo. Esto es porque, previo a utilizar un repositorio pass existente en otra máquina, deberemos importar la clave privada que usamos para cifrar la bóveda. Los pasos a seguir son:

  1. En el dispositivo donde se creó, exportar la clave GPG
gpg --export-secret-keys ID_DE_LA_CLAVE_GPG > private.key
  1. Copiar el fichero private.key en el segundo dispositivo donde se va a descargar la bóveda. Os recomiendo hacerlo bien mediante SFTP, a través de un dispositivo USB o cualquier otra vía directa. Evitad subir dicha clave a servicios externos como Dropbox o GDrive, ya que es la clave para acceder a todos vuestra bóveda.
  2. Importar la clave privada en el dispositivo de destino
gpg --import private.key

Lo más normal es que tengamos que confiar en dicha clave (ya que no la hemos generado en este segundo dispositivo) para evitar molestos avisos de pass cada vez que lo usemos. Puesto que hemos puesto e importado nosotros mismos la clave y por una vía directa, podremos confiar en ella. Para ello, el comando

gpg --edit-key ID_DE_LA_CLAVE_GPG

Nos abrirá una consola de GPG, en la cual deberemos introducir trust  y seleccionar la opción de confiar absolutamente. Hecho esto, bastará un quit para volver al terminal y clonar el repositorio para ser usado por pass.

Y hasta aquí el tutorial de cómo puedes utilizar pass como gestor de contraseñas y secretos. Hay algunas opciones que no he cubierto aquí, como el usar distintas sub-carpetas con distintas claves GPG para así poder compartir con varias personas y tenerlo todo organizado en un mismo repositorio, o cómo tratar asuntos como el de reemplazar la clave GPG por una nueva (porque se nos haya visto comprometida, por ejemplo). Aún no he llegado a esos puntos, pero sí me interesa conocerlos, probarlos, y contaros el resultado y los pasos a seguir, pues creo que son importantes. Pero lo dejo, como tantas veces, para otra entrada, más específica y centrada en ello y ésta queda como tutorial de inicio. Si tenéis alguna duda, los comentarios están abiertos, y también podéis contactarme por el formulario de contacto. Prometo responder lo antes posible 😊.

Si te ha gustado la entrada, o te ha sido útil y quieres ayudarme a pagar los gastos que conlleva el servidor y mantener así el blog libre completamente de anuncios, puedes hacer una donación en Bitcoin en la siguiente dirección: