Gestión de Contraseñas Usando Contenedores Podman (Update 2025)

En 2023, publiqué un post sobre cómo usar pass con un contenedor Git administrado por Podman. Esa guía fue muy útil como demo inicial, pero desde entonces cambiaron algunas cosas: nuevas versiones de Podman, la aparición de Quadlet, la deprecación de podman generate systemd, y la conveniencia de usar imágenes más estables.

Este post es una actualización 2025 del artículo original, incorporando:

  • Imagen base UBI9 minimal (más liviana y con soporte extendido). Esta imagen, desarrollada por Red Hat, es de tamaño relativamente pequeño, usa una versión reduccida de dnf, llamada microdnf con soporte de módulos y usa software de repositorios - también - de Red Hat.
  • Rootless limpio con UserNS=keep-id.
  • Quadlet para integrar con systemd --user.
  • Volúmenes persistentes para no perder datos ni claves al actualizar la imagen.
  • Endurecimiento SSH (solo claves públicas, nada de contraseñas).

1. Construcción de la imagen

Dockerfile (Dockerfile):

FROM registry.access.redhat.com/ubi9/ubi-minimal

RUN microdnf -y install openssh-server git shadow-utils \
    && microdnf clean all \
    && useradd -ms /bin/bash git \
    && chsh -s /usr/bin/git-shell git

EXPOSE 2222
CMD ["/usr/sbin/sshd", "-D", "-e"]

Construcción:

podman build -t localhost/passteiner-ubi9:1 .

2. Crear volúmenes persistentes

podman volume create git-home
podman volume create ssh-etc

VHOME=$(podman volume inspect -f '{{.Mountpoint}}' git-home)
mkdir -p "$VHOME/.ssh" "$VHOME/.password-store"
cp ~/.ssh/id_ed25519.pub "$VHOME/.ssh/authorized_keys"
chmod 700 "$VHOME/.ssh"
chmod 600 "$VHOME/.ssh/authorized_keys"

Repositorio bare:

podman unshare chown -R 1000:1000 "$VHOME"
podman run --rm -v git-home:/home/git localhost/passteiner-ubi9:1 \
  git init --bare /home/git/.password-store

3. Quadlet (systemd integration)

Archivo ~/.config/containers/systemd/pass_git.container:

[Unit]
Description=pass git over SSH (podman quadlet)
Wants=network-online.target
After=network-online.target

[Container]
Image=containers-storage:localhost/passteiner-ubi9:1
Pull=never

ContainerName=pass_git
Network=pasta
PublishPort=60003:2222

Volume=git-home:/home/git:Z,U
Volume=ssh-etc:/etc/ssh:Z

UserNS=keep-id
LogDriver=journald
Exec=/usr/sbin/sshd -D -e -p 2222 -o PidFile=/tmp/sshd.pid

[Service]
Restart=on-failure

[Install]
WantedBy=default.target

Activación:

systemctl --user daemon-reload
systemctl --user enable --now pass_git.service

4. Probar conexión SSH

ssh -p 60003 git@<IP_DEL_HOST> \
  -o PreferredAuthentications=publickey \
  -o PasswordAuthentication=no \
  'git --version && echo OK'

Debe autenticar con tu clave pública y responder git version ....


5. Probar pass con git

Inicializar pass en tu host y configurar el remoto:

export PASSWORD_STORE_DIR=~/.local/share/pass
pass init "tu_clave_gpg"
cd "$PASSWORD_STORE_DIR"
git remote add origin ssh://git@<IP_DEL_HOST>:60003/home/git/.password-store
git push origin master

Y luego:

pass git push
pass git pull

Diferencias clave respecto al artículo original

  • Imagen: antes Fedora, ahora UBI9 minimal (más estable, soporte hasta 2032).
  • Systemd: antes podman generate systemd, ahora Quadlet (futuro estándar, más limpio).
  • Rootless: antes root dentro del contenedor, ahora UserNS=keep-id.
  • Volúmenes: ahora explícitos (git-home, ssh-etc), evitando pérdidas de datos.
  • Seguridad SSH: solo claves, sin password, PidFile movido a /tmp.

Conclusión

Este enfoque actualizado:

  • Evita perder el repositorio y las claves al recrear el contenedor.
  • Asegura compatibilidad a futuro con Podman + systemd.
  • Se apoya en una base más segura (UBI9 minimal).

👉 Si ya usás el setup original, podés migrar en pocas horas y quedarte tranquilo de que tu gestor de contraseñas pass seguirá funcionando a largo plazo.

Comentarios

Comments powered by Disqus