{"id":99,"date":"2014-01-09T20:00:00","date_gmt":"2014-01-09T20:00:00","guid":{"rendered":"http:\/\/esferas.org\/msqlu\/2014\/01\/09\/firmando-digitalmente-el-archivo-release\/"},"modified":"2019-12-18T12:13:41","modified_gmt":"2019-12-18T11:13:41","slug":"firmando-digitalmente-el-archivo-release","status":"publish","type":"post","link":"https:\/\/esferas.org\/msqlu\/2014\/01\/09\/firmando-digitalmente-el-archivo-release\/","title":{"rendered":"Firmando digitalmente el archivo Release &#8230;"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"mt-image-left\" style=\"float: left; margin: 0 20px 20px 0;\" src=\"https:\/\/esferas.org\/mt\/msqlu\/logos\/openlogo-100.png\" alt=\"debian-logo\" width=\"100\" height=\"123\" \/>&#8230; en mi nuevo y flamante <a href=\"http:\/\/debian.astillas.net\">repositorio<\/a> Debian.<\/p>\n<p><!--more--><\/p>\n<p>En <a href=\"https:\/\/esferas.org\/mt\/msqlu\/2014\/01\/mi-propio-repositorio-debian.html\">la entrada<\/a> en la que describ\u00eda la creaci\u00f3n del repositorio dej\u00e9 pendiente explicar c\u00f3mo asegurar el contenido del mismo empleando una firma digital. Voy a hablar de ello ahora.<\/p>\n<p>Para firmar digitalmente el archivo <em>Release<\/em> tendremos que hacer lo siguiente:<\/p>\n<ol>\n<li>Preparar la infraestructura de GnuPG.<\/li>\n<li>Instalar un <em>script<\/em> para firmar.<\/li>\n<li>Indicar a <em>mini-dinstall<\/em> que utilice dicho <em>script<\/em>.<\/li>\n<li>Situar la clave p\u00fablica para los clientes del repositorio.<\/li>\n<\/ol>\n<h4>Infraestructura de GnuPG<\/h4>\n<p>El programa GnuPG emplea la variable de entorno <em>GNUPGHOME\u00a0<\/em>para localizar el directorio donde se encuentran las claves. Es importante tenerlo en cuenta para el programa de firma y para asegurar en lo posible la clave privada. En mi caso he optado por situarlo bajo el directorio de trabajo de <em>mini-dinstall<\/em> con un nombre raro: <em>\/var\/lib\/debian\/.gnupgdir<\/em>.<\/p>\n<p>Una vez decidido d\u00f3nde vamos a situar la infraestructura de <em>gnupg<\/em> tenemos que crear nuestro par de claves de la forma habitual:<\/p>\n<pre># su -l debpkg\n$ GNUPGHOME=\/var\/lib\/debian\/.secret gpg --gen-key<\/pre>\n<p>Ahora guardamos la contrase\u00f1a de la clave privada en el archivo <em>\/var\/lib\/debian\/.gnupgdir\/passphrase<\/em> y nos aseguramos de que s\u00f3lo el usuario <em>debpkg<\/em> tenga acceso a \u00e9l. Usaremos este archivo en el script de firma.<\/p>\n<p>Podemos adelantar trabajo y obtener una copia de la clave p\u00fablica para ponerla a disposici\u00f3n de los clientes del repositorio con:<\/p>\n<pre># su debpkg --shell \/bin\/sh\n$ cd \/var\/lib\/debian\n$ GNUPGHOME=\/var\/lib\/debian\/.secret\n$ gpg --armor --export victor@taquiones.net &gt; archive_key.asc<\/pre>\n<p>Con los permisos restringidos tanto en el directorio como en el archivo esta parte estar\u00eda completa.<\/p>\n<h4>Instalar un script de firma<\/h4>\n<p>El paquete <em>mini-dinstall<\/em> ofrece un script creado por Colin Walters que podemos adaptar a nuestra instalaci\u00f3n concreta. El que yo estoy empleando utiliza un archivo de configuraci\u00f3n opcional por si necesito cambiar alg\u00fan valor en el futuro (es casi una man\u00eda personal).<\/p>\n<pre><span style=\"color: #696969;\">#!<\/span><span style=\"color: #007997;\">\/bin\/bash<\/span>\n<span style=\"color: #696969;\"># -*- coding: utf-8 -*-<\/span>\n<span style=\"color: #696969;\"># <\/span>\n<span style=\"color: #696969;\">#   Versi\u00f3n modificada del script de firma para mini-dinstall de Colin Walters<\/span>\n<span style=\"color: #696969;\">#<\/span>\n<span style=\"color: #696969;\"># Copyright \u00a9 2002 Colin Walters <\/span><span style=\"color: #0000e6;\">&lt;<\/span><span style=\"color: #7144c4;\">walters@debian.org<\/span><span style=\"color: #0000e6;\">&gt;<\/span>\n\n<span style=\"color: #bb7977; font-weight: bold;\">set<\/span> <span style=\"color: #44aadd;\">-e<\/span>\n\n<span style=\"color: #696969;\">#   Variables de usuario<\/span>\n<span style=\"color: #797997;\">GNUPG_DIR<\/span><span style=\"color: #808030;\">=<\/span><span style=\"color: #40015a;\">\/var\/lib\/debian<\/span><span style=\"color: #40015a;\">\/<\/span><span style=\"color: #800000; font-weight: bold;\">.<\/span>secret\n<span style=\"color: #797997;\">KEYID<\/span><span style=\"color: #808030;\">=<\/span>victor@taquiones<span style=\"color: #800000; font-weight: bold;\">.<\/span>net\n<span style=\"color: #797997;\">PASSPHRASE_FILE<\/span><span style=\"color: #808030;\">=<\/span><span style=\"color: #797997;\">$GNUPG_DIR<\/span><span style=\"color: #40015a;\">\/passphrase<\/span>\n\n<span style=\"color: #696969;\">#   Leemos configuraci\u00f3n si existe <\/span>\n<span style=\"color: #797997;\">CONFIG<\/span><span style=\"color: #808030;\">=<\/span><span style=\"color: #40015a;\">\/etc\/taquiones\/debian.conf<\/span>\n<span style=\"color: #800000; font-weight: bold;\">if<\/span> <span style=\"color: #808030;\">[<\/span> <span style=\"color: #44aadd;\">-r<\/span> <span style=\"color: #797997;\">$CONFIG<\/span> <span style=\"color: #808030;\">]<\/span><span style=\"color: #800080;\">;<\/span> <span style=\"color: #800000; font-weight: bold;\">then<\/span> \n    <span style=\"color: #800000; font-weight: bold;\">.<\/span> <span style=\"color: #797997;\">$CONFIG<\/span>\n<span style=\"color: #800000; font-weight: bold;\">fi<\/span> \n\n<span style=\"color: #696969;\"># Preparamos entorno de firma <\/span>\n<span style=\"color: #797997;\">GNUPGHOME<\/span><span style=\"color: #808030;\">=<\/span><span style=\"color: #797997;\">$GNUPG_DIR<\/span>\n<span style=\"color: #bb7977; font-weight: bold;\">export<\/span> GNUPGHOME\n<span style=\"color: #797997;\">PASSPHRASE<\/span><span style=\"color: #808030;\">=<\/span>$<span style=\"color: #800080;\">(<\/span>cat <span style=\"color: #797997;\">$PASSPHRASE_FILE<\/span><span style=\"color: #800080;\">)<\/span>\n\n<span style=\"color: #696969;\"># Esto deber\u00eda fallar (set -e) si no somos el propietario<\/span>\nchown <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$USER<\/span><span style=\"color: #0000e6;\">\"<\/span> <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$GNUPGHOME<\/span><span style=\"color: #0000e6;\">\"<\/span>\nchmod <span style=\"color: #008c00;\">0700<\/span> <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$GNUPGHOME<\/span><span style=\"color: #0000e6;\">\"<\/span>\n\n<span style=\"color: #696969;\"># Initialize GPG<\/span>\ngpg --<span style=\"color: #bb7977; font-weight: bold;\">help<\/span> <span style=\"color: #008c00;\">1<\/span><span style=\"color: #e34adc;\">&gt;<\/span><span style=\"color: #40015a;\">\/dev\/null<\/span> <span style=\"color: #008c00;\">2<\/span><span style=\"color: #e34adc;\">&gt;&amp;1<\/span> <span style=\"color: #800080;\">||<\/span> <span style=\"color: #44aadd;\">true<\/span>\n\nrm <span style=\"color: #44aadd;\">-f<\/span> Release<span style=\"color: #800000; font-weight: bold;\">.<\/span>gpg<span style=\"color: #800000; font-weight: bold;\">.<\/span>tmp InRelease<span style=\"color: #800000; font-weight: bold;\">.<\/span>tmp\n<span style=\"color: #bb7977; font-weight: bold;\">echo<\/span> <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$PASSPHRASE<\/span><span style=\"color: #0000e6;\">\"<\/span> <span style=\"color: #e34adc;\">|<\/span> gpg --no-tty --batch --<span style=\"color: #797997;\">passphrase-fd<\/span><span style=\"color: #808030;\">=<\/span><span style=\"color: #008c00;\">0<\/span> --default-key <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$KEYID<\/span><span style=\"color: #0000e6;\">\"<\/span> --detach-sign <span style=\"color: #44aadd;\">-o<\/span> Release<span style=\"color: #800000; font-weight: bold;\">.<\/span>gpg<span style=\"color: #800000; font-weight: bold;\">.<\/span>tmp <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$1<\/span><span style=\"color: #0000e6;\">\"<\/span>\nmv Release<span style=\"color: #800000; font-weight: bold;\">.<\/span>gpg<span style=\"color: #800000; font-weight: bold;\">.<\/span>tmp Release<span style=\"color: #800000; font-weight: bold;\">.<\/span>gpg\n<span style=\"color: #bb7977; font-weight: bold;\">echo<\/span> <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$PASSPHRASE<\/span><span style=\"color: #0000e6;\">\"<\/span> <span style=\"color: #e34adc;\">|<\/span> gpg --no-tty --batch --<span style=\"color: #797997;\">passphrase-fd<\/span><span style=\"color: #808030;\">=<\/span><span style=\"color: #008c00;\">0<\/span> --default-key <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$KEYID<\/span><span style=\"color: #0000e6;\">\"<\/span> --clearsign <span style=\"color: #44aadd;\">-o<\/span> InRelease<span style=\"color: #800000; font-weight: bold;\">.<\/span>tmp <span style=\"color: #0000e6;\">\"<\/span><span style=\"color: #797997;\">$1<\/span><span style=\"color: #0000e6;\">\"<\/span>\nmv InRelease<span style=\"color: #800000; font-weight: bold;\">.<\/span>tmp InRelease\n<\/pre>\n<p>\u00bf Y d\u00f3nde situar el script ? A mi se me ha ocurrido que el directorio de trabajo de <em>mini-dinstall<\/em> ser\u00eda un buen lugar (<em>\/var\/lib\/debian\/mini-dinstall<\/em>) y en realidad no veo inconveniente para ello, especialmente por lo que cuento en la siguiente secci\u00f3n.<\/p>\n<h4>Configurar mini-dinstall para la firma<\/h4>\n<p>La variable <strong>release_signscript<\/strong> de la configuraci\u00f3n de <em>mini-dinstall<\/em> contiene la ruta del script de firma y funciona de la siguiente manera:<\/p>\n<ol>\n<li>El programa se ejecuta en el mismo directorio que el archivo <em>Release<\/em>.<\/li>\n<li>Se le pasa como primer par\u00e1metro la ruta de una <strong>copia temporal<\/strong> de dicho archivo.<\/li>\n<li>Se espera de \u00e9l que realice la firma y cree un archivo <em>Release.gpg<\/em> en el directorio en el que ha sido llamado.<\/li>\n<\/ol>\n<p>Un detalle que me trae un poco de cabeza es que el programa <em>mini-dinstall<\/em>, especialmente cuando funciona como demonio, lo hace bajo el usuario <em>root<\/em>. No he visto forma de cambiarlo ni estoy seguro de si ser\u00eda conveniente hacerlo sin dispararse en el pi\u00e9. El caso es que cuando se ejecuta el programa de firma el usuario que lo lanza es el propio administrador y, por alguna raz\u00f3n, no es exactamente lo que queremos.<\/p>\n<p>La soluci\u00f3n m\u00e1s inmediata ser\u00eda usar el programa <em>su <\/em> y definirlo en la configuraci\u00f3n como:<\/p>\n<pre>release_signscript = su debpkg \/var\/lib\/debian\/mini-dinstall\/sign-release.sh<\/pre>\n<p>Pero como la documentaci\u00f3n s\u00f3lo menciona un programa y no una l\u00ednea <em>shell,<\/em> he mirado los fuentes y he comprobado que <em>mini-dinstall<\/em> emplea la funci\u00f3n <em>execlp<\/em> y no alg\u00fan tipo de <em>system<\/em> o similar. Adem\u00e1s, como le pasa el archivo a firmar como primer par\u00e1metro no cabe (y no es aconsejable) incluirle m\u00e1s.<\/p>\n<p>En su lugar es mejor emplear un programa envoltorio (wrapper) que realice toda la tarea, nos quitamos de l\u00edos y no nos cerramos la puerta a posteriores cambios en el mecanismo de firma.<\/p>\n<p>As\u00ed que con el siguiente programa que muestro abajo y que vuelvo a situar en el directorio de trabajo de <em>mini-dinstall<\/em> con el nombre <em>sign-wrapper.sh<\/em> la configuraci\u00f3n de firma quedar\u00eda como:<\/p>\n<pre class=\"\">release_signscript = \/var\/lib\/debian\/mini-dinstall\/sign-wrapper.sh<\/pre>\n<p>Y el programa envoltorio de la siguiente forma:<\/p>\n<pre class=\"lang:default decode:true\">#   Variables\nVERSION=0.2\nCONFIG=\/etc\/taquiones\/debian.conf\nROOT_DIR=\/var\/lib\/debian\nUSER=debpkg\n\nif [ -r $CONFIG ]; then\n    . $CONFIG\nfi\n\nREAL_SIGN=$ROOT_DIR\/mini-dinstall\/sign-release.sh\n\n#   Lanzamos el programa de firma con el usuario adecuado\nsu $USER --shell \/bin\/bash $REAL_SIGN $*<\/pre>\n<p>He empleado el par\u00e1metro <em>&#8211;shell<\/em> por pura precauci\u00f3n. El usuario <em>debpkg<\/em> se declara como cuenta del sistema y suele ocurrir que me equivoque al crearlo y no tenga un <em>shell<\/em> asignado.<\/p>\n<h4>Publicar la clave p\u00fablica (sic)<\/h4>\n<p>Dado que es preceptivo emplear cifrado para utilizar correctamente el repositorio tenemos que hacer que la clave p\u00fablica sea de f\u00e1cil acceso. Creo que el mejor lugar, aqu\u00e9l que me gustar\u00eda encontrar de primeras cuando empleo el repositorio de otros, es la ra\u00edz de la p\u00e1gina web.<\/p>\n<p>As\u00ed pues:<\/p>\n<ol>\n<li>Obtenemos una versi\u00f3n <em>ascii<\/em> de la clave p\u00fablica.<\/li>\n<li>La situamos en el directorio ra\u00edz (<em>\/var\/lib\/debian\/archive_key.asc<\/em>).<\/li>\n<li>La anunciamos en la p\u00e1gina de inicio o alg\u00fan otro sitio.<\/li>\n<li>Si queremos podemos enviarla a un servidor de claves como explica <a href=\"http:\/\/debian.wgdd.de\/repository\">Daniel Leidert<\/a>, aunque en ese caso es aconsejable declarar el identificador de la clave y el servidor donde se aloja tambi\u00e9n en la p\u00e1gina web.<\/li>\n<\/ol>\n<p>En el caso de mi servidor la clave est\u00e1 en <a href=\"http:\/\/debian.astillas.net\/astillas.key\">http:\/\/debian.astillas.net\/astillas.key<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8230; en mi nuevo y flamante repositorio Debian.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","webmentions_disabled_pings":false,"webmentions_disabled":false,"footnotes":""},"categories":[6],"tags":[167,159,158],"class_list":["post-99","post","type-post","status-publish","format-standard","hentry","category-debian","tag-apt","tag-gpg","tag-mini-dinstall"],"_links":{"self":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/99","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/comments?post=99"}],"version-history":[{"count":3,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/99\/revisions"}],"predecessor-version":[{"id":3220,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/99\/revisions\/3220"}],"wp:attachment":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/media?parent=99"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/categories?post=99"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/tags?post=99"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}