feat: Integración de Siguldry PKCS#11 y spooler de firmas

* Implementación del rol de Ansible 'siguldry' para CentOS Stream 10
* Migración del plugin de firmas de Koji Hub a un spooler asíncrono
* Modificación de roles para utilizar empaquetamiento RPM nativo de siguldry-pkcs11
* Documentación de decisiones (ADRs) y roadmap en docs/technical/
* Limpieza de binarios locales pesados de PKCS#11 en Ansible

Co-developed-by: Gemini AI <renich+gemini@woralelandia.com>
Signed-off-by: Rénich Bon Ćirić <renich@woralelandia.com>
This commit is contained in:
Rénich Bon Ćirić 2026-06-16 10:06:44 -06:00
commit 89d6f66be8
Signed by: renich
GPG key ID: AB2A9F49384FE324
32 changed files with 1453 additions and 321 deletions

View file

@ -0,0 +1,266 @@
---
- name: "Generate: Siguldry Certificates on Localhost"
delegate_to: localhost
run_once: true
block:
- name: "Generate Siguldry CA private key"
community.crypto.openssl_privatekey:
path: "{{ koji_pki_dir }}/siguldry_ca.key"
size: 4096
mode: "0600"
- name: "Generate Siguldry CA CSR"
community.crypto.openssl_csr:
path: "{{ koji_pki_dir }}/siguldry_ca.csr"
privatekey_path: "{{ koji_pki_dir }}/siguldry_ca.key"
common_name: "Siguldry Certificate Authority"
organization_name: "MxOS Siguldry"
basic_constraints:
- "CA:TRUE"
key_usage:
- keyCertSign
- cRLSign
- name: "Generate self-signed Siguldry CA certificate"
community.crypto.x509_certificate:
path: "{{ koji_pki_dir }}/siguldry_ca.crt"
csr_path: "{{ koji_pki_dir }}/siguldry_ca.csr"
privatekey_path: "{{ koji_pki_dir }}/siguldry_ca.key"
provider: selfsigned
selfsigned_not_after: "+3650d"
- name: "Generate private key for Siguldry Server"
community.crypto.openssl_privatekey:
path: "{{ koji_pki_dir }}/siguldry-server.key"
size: 4096
mode: "0600"
- name: "Generate CSR for Siguldry Server"
community.crypto.openssl_csr:
path: "{{ koji_pki_dir }}/siguldry-server.csr"
privatekey_path: "{{ koji_pki_dir }}/siguldry-server.key"
common_name: "{{ koji_hub_fqdn }}"
- name: Create openssl config for Siguldry Server
ansible.builtin.copy:
dest: "{{ koji_pki_dir }}/openssl-siguldry-server.cnf"
mode: "0644"
content: |
[v3_ca]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = DNS:{{ koji_hub_fqdn }},DNS:server.example.com
- name: Sign Siguldry Server certificate
ansible.builtin.shell:
cmd: >
openssl x509 -req
-in {{ koji_pki_dir }}/siguldry-server.csr
-CA {{ koji_pki_dir }}/siguldry_ca.crt
-CAkey {{ koji_pki_dir }}/siguldry_ca.key
-CAcreateserial
-out {{ koji_pki_dir }}/siguldry-server.crt
-days 3650
-sha256
-extfile {{ koji_pki_dir }}/openssl-siguldry-server.cnf
-extensions v3_ca
creates: "{{ koji_pki_dir }}/siguldry-server.crt"
- name: "Generate private key for Siguldry Bridge"
community.crypto.openssl_privatekey:
path: "{{ koji_pki_dir }}/siguldry-bridge.key"
size: 4096
mode: "0600"
- name: "Generate CSR for Siguldry Bridge"
community.crypto.openssl_csr:
path: "{{ koji_pki_dir }}/siguldry-bridge.csr"
privatekey_path: "{{ koji_pki_dir }}/siguldry-bridge.key"
common_name: "{{ koji_hub_fqdn }}"
- name: Create openssl config for Siguldry Bridge
ansible.builtin.copy:
dest: "{{ koji_pki_dir }}/openssl-siguldry-bridge.cnf"
mode: "0644"
content: |
[v3_ca]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:{{ koji_hub_fqdn }},DNS:bridge.example.com
- name: Sign Siguldry Bridge certificate
ansible.builtin.shell:
cmd: >
openssl x509 -req
-in {{ koji_pki_dir }}/siguldry-bridge.csr
-CA {{ koji_pki_dir }}/siguldry_ca.crt
-CAkey {{ koji_pki_dir }}/siguldry_ca.key
-CAcreateserial
-out {{ koji_pki_dir }}/siguldry-bridge.crt
-days 3650
-sha256
-extfile {{ koji_pki_dir }}/openssl-siguldry-bridge.cnf
-extensions v3_ca
creates: "{{ koji_pki_dir }}/siguldry-bridge.crt"
- name: "Generate private key for Siguldry Client"
community.crypto.openssl_privatekey:
path: "{{ koji_pki_dir }}/siguldry-client.key"
size: 4096
mode: "0600"
- name: "Generate CSR for Siguldry Client"
community.crypto.openssl_csr:
path: "{{ koji_pki_dir }}/siguldry-client.csr"
privatekey_path: "{{ koji_pki_dir }}/siguldry-client.key"
common_name: "kojiadmin"
- name: Create openssl config for Siguldry Client
ansible.builtin.copy:
dest: "{{ koji_pki_dir }}/openssl-siguldry-client.cnf"
mode: "0644"
content: |
[v3_ca]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
subjectAltName = DNS:kojiadmin
- name: Sign Siguldry Client certificate
ansible.builtin.shell:
cmd: >
openssl x509 -req
-in {{ koji_pki_dir }}/siguldry-client.csr
-CA {{ koji_pki_dir }}/siguldry_ca.crt
-CAkey {{ koji_pki_dir }}/siguldry_ca.key
-CAcreateserial
-out {{ koji_pki_dir }}/siguldry-client.crt
-days 3650
-sha256
-extfile {{ koji_pki_dir }}/openssl-siguldry-client.cnf
-extensions v3_ca
creates: "{{ koji_pki_dir }}/siguldry-client.crt"
- name: Clean up temporary openssl configs
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- "{{ koji_pki_dir }}/openssl-siguldry-server.cnf"
- "{{ koji_pki_dir }}/openssl-siguldry-bridge.cnf"
- "{{ koji_pki_dir }}/openssl-siguldry-client.cnf"
- name: Install Siguldry package
ansible.builtin.dnf:
name:
- siguldry
- siguldry-pkcs11
- gnupg-pkcs11-scd
state: present
- name: Ensure Siguldry config directory exists
ansible.builtin.file:
path: /etc/siguldry
state: directory
owner: root
group: siguldry
mode: "0750"
- name: Deploy Siguldry configuration files
ansible.builtin.template:
src: "{{ item.src }}"
dest: "/etc/siguldry/{{ item.dest }}"
owner: root
group: siguldry
mode: "0640"
loop:
- { src: "server.toml.j2", dest: "server.toml" }
- { src: "bridge.toml.j2", dest: "bridge.toml" }
- { src: "client.toml.j2", dest: "client.toml" }
- name: Ensure systemd credstore directory exists
ansible.builtin.file:
path: /etc/credstore
state: directory
owner: root
group: root
mode: "0700"
- name: Deploy Siguldry TLS credentials to systemd credstore
ansible.builtin.copy:
src: "{{ koji_pki_dir }}/{{ item.src }}"
dest: "/etc/credstore/{{ item.dest }}"
owner: root
group: root
mode: "0600"
loop:
- { src: "siguldry_ca.crt", dest: "siguldry.ca_certificate.pem" }
- { src: "siguldry-server.crt", dest: "siguldry.server.certificate.pem" }
- { src: "siguldry-server.key", dest: "siguldry.server.private_key.pem" }
- { src: "siguldry-bridge.crt", dest: "siguldry.bridge.certificate.pem" }
- { src: "siguldry-bridge.key", dest: "siguldry.bridge.private_key.pem" }
- { src: "siguldry-client.crt", dest: "siguldry.client.certificate.pem" }
- { src: "siguldry-client.key", dest: "siguldry.client.private_key.pem" }
- name: Deploy Siguldry signing key passphrase to systemd credstore
ansible.builtin.copy:
content: "{{ gpg_key_passphrase }}"
dest: /etc/credstore/siguldry.signing_key.passphrase
owner: root
group: root
mode: "0600"
- name: Start and enable Siguldry services
ansible.builtin.systemd:
name: "{{ item }}"
state: started
enabled: true
daemon_reload: true
loop:
- siguldry-bridge.service
- siguldry-server.service
- siguldry-client-proxy.socket
- siguldry-signer.socket
- name: Run Siguldry database migrations
become: true
become_user: siguldry
ansible.builtin.command:
cmd: siguldry-server -c /etc/siguldry/server.toml manage migrate
register: siguldry_migration_result
changed_when: "'No migrations to apply' not in siguldry_migration_result.stdout"
- name: Check if remote user kojiadmin exists in Siguldry
become: true
become_user: siguldry
ansible.builtin.shell:
cmd: siguldry-server -c /etc/siguldry/server.toml manage users list
register: siguldry_users_list
changed_when: false
- name: Add remote user kojiadmin to Siguldry database
become: true
become_user: siguldry
ansible.builtin.command:
cmd: siguldry-server -c /etc/siguldry/server.toml manage users create kojiadmin
when: "'kojiadmin' not in siguldry_users_list.stdout"
- name: Check if mxos-signing-key exists in Siguldry
become: true
become_user: siguldry
ansible.builtin.shell:
cmd: siguldry-server -c /etc/siguldry/server.toml manage key list
register: siguldry_keys_list
changed_when: false
- name: Create mxos-signing-key in Siguldry
become: true
become_user: siguldry
ansible.builtin.shell:
cmd: >
siguldry-server -c /etc/siguldry/server.toml manage key create
kojiadmin mxos-signing-key
--password-file <(echo "{{ gpg_key_passphrase }}")
when: "'mxos-signing-key' not in siguldry_keys_list.stdout"

View file

@ -0,0 +1,8 @@
# Siguldry bridge configuration for MxOS Koji
server_listening_address = "[::]:44333"
client_listening_address = "[::]:44334"
[credentials]
private_key = "siguldry.bridge.private_key.pem"
certificate = "siguldry.bridge.certificate.pem"
ca_certificate = "siguldry.ca_certificate.pem"

View file

@ -0,0 +1,17 @@
# Siguldry client configuration for MxOS Koji
server_hostname = "{{ koji_hub_fqdn }}"
bridge_hostname = "{{ koji_hub_fqdn }}"
bridge_port = 44334
[[keys]]
key_name = "mxos-signing-key"
passphrase_path = "siguldry.signing_key.passphrase"
[request_timeout]
secs = 30
nanos = 0
[credentials]
private_key = "siguldry.client.private_key.pem"
certificate = "siguldry.client.certificate.pem"
ca_certificate = "siguldry.ca_certificate.pem"

View file

@ -0,0 +1,20 @@
# Siguldry server configuration for MxOS Koji
state_directory = "/var/lib/siguldry/"
bridge_hostname = "{{ koji_hub_fqdn }}"
bridge_port = 44333
connection_pool_size = 32
user_password_length = 8
openpgp_user_id = "MxOS Signing Key <koji@{{ koji_hub_fqdn }}>"
pkcs11_bindings = []
[credentials]
private_key = "siguldry.server.private_key.pem"
certificate = "siguldry.server.certificate.pem"
ca_certificate = "siguldry.ca_certificate.pem"
[certificate_subject]
country = "MX"
state_or_province = "Mexico"
locality = "Mexico City"
organization = "MxOS"
organizational_unit = "Infraestructura"