Flujo de trabajo de certificados de usuario/host SSH de Jenkins

Flujo de trabajo de certificados de usuario/host SSH de Jenkins

¿Cómo configurar el proceso de firma de clave SSH cada vez que se ejecuta alguna etapa de Ansible? O al menos en algún intervalo.

Tengo una canalización que crea máquinas virtuales con Terraform y luego ejecuta Ansible. En la etapa de inicio de la nube, se crean y firman las claves de host y también se configura la clave de CA de usuario pública. Las autoridades de CA de cliente/host están configuradas/ejecutándose en HashiCorp Vault. Entonces, en este punto, no importa qué máquinas virtuales estén aprovisionadas, puedo acceder mediante SSH a cada una de ellas, ya que tengo la clave pública de CA del host @cert-authority *.example.com ecdsa-sha2-nistp521 AAAAB3NzaC1yc2EAAA...configurada globalmente en /etc/ssh/ssh_known_hosts. Todo lo que necesito hacer es crear una nueva clave personal y firmarla porque mi TTL es bastante corto.

Pero esto no funciona en Jenkins. Jenkins almacena todas las claves SSH /var/lib/jenkins/.sshy, de forma predeterminada, no hay nada. Si solo por motivos de prueba copio mis claves de usuario personal (o generadas) y el archivo de configuración certificado + ssh en /var/lib/jenkins/.ssh, entonces Jenkins puede ejecutar Ansible felizmente. Pero no puedo generar, firmar y copiar las claves de Jenkins cada vez que hago alguna confirmación en mi repositorio de infraestructura. Crear certificados de larga duración tampoco huele bien.

¿Cuál es el flujo de trabajo automatizado idiomático para la firma y rotación de claves SSH?

Respuesta1

Enumeraré la solución "MALA" yo solo. Malo, porque la rotación de claves allí es manual y lo más probable es que el TTL sea largo porque somos vagos.

En Vault, debe crear una nueva función SSH "jenkins" con el TTL como52w

Luego, idealmente en el propio host de Jenkins, es necesario crear nuevas claves.

ssh-keygen -t ecdsa -b 521 -f /var/lib/jenkins/.ssh/id_ecdsa -C "jenkins@jenkins-01"

Entonces cántalo por Vault

vault write -field=signed_key ssh-client-signer/sign/jenkinsrole public_key=/var/lib/jenkins/.ssh/id_ecdsa.pub > /var/lib/jenkins/.ssh/id_ecdsa-cert.pub

Esto significa que Vault debería estar en el sistema. ... es un dilema: ¿quieres copiar claves ssh (incluidas las privadas) a través de la red, lo cual huele un poco, o quieres instalar Vault en la máquina Jenkins? Tu decides.

Una vez que tenga id_ecdsa-cert.pubel certificado, puede inspeccionarlo ssh-keygen -Lf /var/lib/jenkins/.ssh/id_ecdsa-cert.puby ver si el período de validez, los principios, etc. son correctos.

Debido a que lo más probable es que haya desviaciones en la infraestructura, almacenar la configuración SSH estáticamente /var/lib/jenkins/.ssh/configserá doloroso.

En su lugar, puede crear ansible-ssh.cfgun archivo con el contenido como

Host bastion
  HostName bastion.example.com
  IdentitiesOnly yes
  IdentityFile ~/.ssh/id_ecdsa
  CertificateFile ~/.ssh/id_ecdsa-cert.pub
  Port 22
  Protocol 2
  User ansible
  LogLevel INFO

Este archivo puede (debería) ubicarse junto con el resto del código de Ansible.

Luego, en el ansible.cfgarchivo incluya la estrofa SSH.

[ssh_connection]
ssh_args = -F ./ansible-ssh.cfg

De esta manera, Ansible recogerá configuraciones SSH siempre actualizadas.

Si usa Terraform, entonces es posible actualizar dinámicamente el archivo de configuración SSH para incluir nuevos hosts y demás.

Esta solución no está vinculada únicamente a Vault. Se puede hacer bastante fácilmente con el ssh-keygenmismo.

ACTUALIZACIÓN: Finalmente terminé con un pequeño script de shell que realiza la autorización mediante aprole y luego firma el certificado. El servicio Systemd y la unidad Timer ejecutan el script de shell que realiza la rotación de certificados todos los días. Entonces, en este punto, Jenkins usa sus propios certificados de usuario nuevos para ejecutar Terraform y Ansible. https://stackoverflow.com/a/65875997/6651080

información relacionada