{"id":1509,"date":"2016-04-26T08:09:13","date_gmt":"2016-04-26T08:09:13","guid":{"rendered":"http:\/\/esferas.org\/msqlu\/?p=1509"},"modified":"2016-04-26T08:09:13","modified_gmt":"2016-04-26T08:09:13","slug":"certificados-lets-encrypt-en-mas-de-un-servidor","status":"publish","type":"post","link":"https:\/\/esferas.org\/msqlu\/2016\/04\/26\/certificados-lets-encrypt-en-mas-de-un-servidor\/","title":{"rendered":"Certificados Let&#8217;s Encrypt en m\u00e1s de un servidor &#8230;"},"content":{"rendered":"<div class='__iawmlf-post-loop-links' style='display:none;' data-iawmlf-post-links='[{&quot;id&quot;:939,&quot;href&quot;:&quot;http:\\\/\\\/letsencrypt.org&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20260415125942\\\/https:\\\/\\\/letsencrypt.org\\\/&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2026-04-15 17:06:31&quot;,&quot;http_code&quot;:206},{&quot;date&quot;:&quot;2026-04-19 11:07:11&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-04-19 11:07:11&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:940,&quot;href&quot;:&quot;https:\\\/\\\/httpd.apache.org\\\/docs\\\/current\\\/mod\\\/mod_proxy.html&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20260403165659\\\/https:\\\/\\\/httpd.apache.org\\\/docs\\\/current\\\/mod\\\/mod_proxy.html&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2026-04-19 11:07:18&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-04-19 11:07:18&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;}]'><\/div>\n<p>&#8230; vaya problema tonto con el que no contaba.<\/p>\n<p><!--more--><\/p>\n<p>En las redes que gestiono tengo una m\u00e1quina que act\u00faa como frontal de acceso a y hacia Internet al resto de la red. Lo hice as\u00ed en su momento porque descubr\u00ed el m\u00f3dulo mod_proxy del programa Apache y me di cuenta de que era muy c\u00f3modo tener los servicios web en una m\u00e1quina interior y pod\u00eda controlar mejor los accesos desde el exterior.<\/p>\n<p>Para el caso de los certificados que ten\u00edan que estar en varios sitios al mismo tiempo lo hab\u00eda resuelto con un paquete Debian que reconstru\u00eda cada vez que los renovaba e instalaba en ambas m\u00e1quinas. Ahora, como estoy empleando los certificados de <a href=\"http:\/\/letsencrypt.org\">Let&#8217;s Encrypt<\/a> y no tengo tanta ma\u00f1a con ellos, me he limitado a usar el cliente <a href=\"http:\/\/esferas.org\/msqlu\/2016\/04\/08\/usando-letsencrypt-sh-para-crear-y-renovar-certificados\/\">letsencrypt.sh<\/a> que me ha dado buenos resultados en servidores independientes.<\/p>\n<p>Pero se me acaba de presentar el caso de tener dichos certificados en dos sitios al mismo tiempo antes de lo que pensaba. La instalaci\u00f3n principal est\u00e1 en un servidor web interno y la secundaria se encuentra en el servidor que hace de frontal con la red. Ten\u00eda (y tengo) pensado situar algo como un acceso unificado hacia la inttranet y por eso preciso que exista tambi\u00e9n all\u00ed una copia de los certificados.<\/p>\n<p style=\"padding-left: 30px;\">Bueno, por eso no exactamente. El m\u00f3dulo que utilizo en el servidor frontal para conectar con el servidor interno emplea t\u00e9cnicas de proxy (s\u00ed, es <a href=\"https:\/\/httpd.apache.org\/docs\/current\/mod\/mod_proxy.html\">mod_proxy<\/a>) y quiero que exista concordancia de conexiones entre ambos. Es decir, si alguien desde fuera conecta bajo cifrado la conexi\u00f3n entre servidores debe estar cifrada tambi\u00e9n.<\/p>\n<p>El programa letsencrypt.sh dispone de un mecanismo para efectuar tareas tras la renovaci\u00f3n de un certificado; un archivo llamado <em>hook.sh<\/em> que define varias funciones <em>bash<\/em> que puedo utilizar para efectuar una copia de los nuevos archivos y para reiniciar los servicios. Y este es el punto. Reiniciar los servicios en local es sencillo, la renovaci\u00f3n la realiza el administrador, pero \u00bf y en remoto ?<\/p>\n<p>No me va a quedar m\u00e1s remedio que escribir un script que se encargue de reiniciar servicios en la segunda m\u00e1quina tras renovar los certificados en \u00e9sta. Claro que, bien pensado, lo mismo el script me sirve tambi\u00e9n para reiniciarlos en local.<\/p>\n<p>Y as\u00ed ha sido. Lamentablemente no puedo mostrar el c\u00f3digo porque lo he personalizado mucho para la empresa pero a grandes rasgos lo que hace es:<\/p>\n<ol>\n<li>Prepara el entorno para el programa <em>letsencrypt.sh. <\/em><\/li>\n<li>Prepara el servidor Apache para el desaf\u00edo ACME.<\/li>\n<li>Clona el software de <em>letsencrypt.sh<\/em> y lo instala.<\/li>\n<li>Configura el reinicio de los servicios del sistema que emplean los certificados y lo dispone as\u00ed en la configuraci\u00f3n.<\/li>\n<\/ol>\n<h4>Tras la renovaci\u00f3n<\/h4>\n<p>Tengo dos escenarios: en el primero se encuentra el servidor donde se renuevan los certificados y que tambi\u00e9n proporciona servicios que hacen uso de ellos. En el segundo (o tercero o cuarto) s\u00f3lo se hacen uso de dichos certificados.<\/p>\n<p>He dividido la funcionalidad del paquete de manera que sea posible configurar e instalar <em>letsencrypt.sh<\/em> y configurar apache de manera independiente. De esta forma en el primer servidor es donde creo y renuevo certificados y en los segundos s\u00f3lo reinicio servicios. Para ello uso el archivo <em>hook.sh<\/em> de <em>letsencrypt.sh<\/em> con la siguiente configuraci\u00f3n:<\/p>\n<pre class=\"lang:sh decode:true\">function deploy_cert {\r\n    local DOMAIN=\"${1}\" KEYFILE=\"${2}\" CERTFILE=\"${3}\" FULLCHAINFILE=\"${4}\" CHAI\r\nNFILE=\"${5}\" TIMESTAMP=\"${6}\"\r\n\r\n    #   Reiniciamos los servicios locales \r\n    after-renew-certs\r\n\r\n    #   y vemos si es necesario transferirlos a otras m\u00e1quinas\r\n    if [ -e \/etc\/empresa\/remote-certs.conf ]; then \r\n        sync-letsencrypt \/etc\/venexma\/remote-certs.conf \r\n    fi\r\n}\r\n<\/pre>\n<p>El archivo <em>remote-certs.conf<\/em> contiene una lista de m\u00e1quinas con las que conectar, transferir archivos y reiniciar servicios.<\/p>\n<h4>Reiniciando servicios<\/h4>\n<p>Pues aprovechando que Debian Jessie tiene a systemd integrado y funcional he escrito un peque\u00f1o script que lee un archivo de configuraci\u00f3n simple, donde se detallan los servicios que hacen uso de los certificados, y si encuentra que alguno est\u00e1 activo lo reinicia.<\/p>\n<p>El archivo es algo tan simple como:<\/p>\n<pre class=\"lang:ini decode:true \">#   Servidor web\r\napache2\r\n\r\n#   Correo electr\u00f3nico: recepci\u00f3n y almacenamiento\r\ndovecot\r\nexim4\r\nqpsmptd\r\n\r\n#   Mensajer\u00eda instant\u00e1nea\r\nprosody\r\n<\/pre>\n<p>Mientras que la parte del script encarga de reiniciarlos es como sigue:<\/p>\n<pre class=\"lang:sh decode:true\">read_config()\r\n{\r\n    local config=\"$*\"\r\n\r\n    clean_text=$(egrep -v '^#|^$' $config)\r\n\r\n    $clean_text\r\n}\r\n\r\n# Procesamos el archivo de configuraci\u00f3n servicio a servicio\r\nfor service in $(read_config $config)\r\ndo\r\n    if systemctl --quit <strong>is-active<\/strong> $service ; then\r\n        _debug \"Trying restart ${service} service\"\r\n        if [ $dry_mode -eq 0 ]; then \r\n            systemctl restart $service   \r\n        fi\r\n    fi\r\ndone\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8230; vaya problema tonto con el que no contaba.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","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":[18,41,554,556],"class_list":["post-1509","post","type-post","status-publish","format-standard","hentry","category-debian","tag-administracion-de-sistemas","tag-debian","tag-lets-encrypt","tag-letsencrypt-sh"],"_links":{"self":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/1509","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=1509"}],"version-history":[{"count":0,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/1509\/revisions"}],"wp:attachment":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/media?parent=1509"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/categories?post=1509"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/tags?post=1509"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}