<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://agora.nasqueron.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=DorianWinty</id>
	<title>Nasqueron Agora - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://agora.nasqueron.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=DorianWinty"/>
	<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/Special:Contributions/DorianWinty"/>
	<updated>2026-06-04T21:20:02Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.0-alpha</generator>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1929</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1929"/>
		<updated>2025-05-20T19:38:56Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* improved command */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pem \&lt;br /&gt;
  --ca-file /var/certificates/exemple.nasqueron.org/chain.pem&lt;br /&gt;
&lt;br /&gt;
===== improved command =====&lt;br /&gt;
&lt;br /&gt;
  sudo su acme&lt;br /&gt;
&lt;br /&gt;
  export domain=&amp;quot;exemple.nasqueron.org&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mkdir /var/certificates/$domain&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d $domain \&lt;br /&gt;
  --cert-file /var/certificates/$domain/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/$domain/key.pem \&lt;br /&gt;
  --ca-file /var/certificates/$domain/chain.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/$domain/fullchain.pem&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
  Le_ReloadCmd=&#039;sudo acmesh-nginxCheck&#039;&lt;br /&gt;
&lt;br /&gt;
doit être mis dans le fichier de configuration pour le certificat ou ajouter la commande&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
=== Migration to acme.sh ===&lt;br /&gt;
==== Paths to update ====&lt;br /&gt;
&lt;br /&gt;
Paths from /usr/local/etc/letsencrypt or /etc/letsencrypt (OS-dependant path) needs to be updated to /var/certificates (cross-platform path). The private key file is only `key.pem` instead of `privkey.pem`.&lt;br /&gt;
&lt;br /&gt;
An example is available on https://devcentral.nasqueron.org/D3624&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1928</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1928"/>
		<updated>2025-05-20T19:38:09Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* improved command */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pem \&lt;br /&gt;
  --ca-file /var/certificates/exemple.nasqueron.org/chain.pem&lt;br /&gt;
&lt;br /&gt;
===== improved command =====&lt;br /&gt;
&lt;br /&gt;
  sudo su acme&lt;br /&gt;
&lt;br /&gt;
  export domain=&amp;quot;exemple.nasqueron.org&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mkdir /var/certificates/$domain&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d $domain \&lt;br /&gt;
  --cert-file /var/certificates/$domain/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/$domain/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/$domain/fullchain.pem \&lt;br /&gt;
  --ca-file /var/certificates/$domain/chain.pem&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
  Le_ReloadCmd=&#039;sudo acmesh-nginxCheck&#039;&lt;br /&gt;
&lt;br /&gt;
doit être mis dans le fichier de configuration pour le certificat ou ajouter la commande&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
=== Migration to acme.sh ===&lt;br /&gt;
==== Paths to update ====&lt;br /&gt;
&lt;br /&gt;
Paths from /usr/local/etc/letsencrypt or /etc/letsencrypt (OS-dependant path) needs to be updated to /var/certificates (cross-platform path). The private key file is only `key.pem` instead of `privkey.pem`.&lt;br /&gt;
&lt;br /&gt;
An example is available on https://devcentral.nasqueron.org/D3624&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1927</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1927"/>
		<updated>2025-05-20T19:35:09Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Deploying of the certificates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pem \&lt;br /&gt;
  --ca-file /var/certificates/exemple.nasqueron.org/chain.pem&lt;br /&gt;
&lt;br /&gt;
===== improved command =====&lt;br /&gt;
&lt;br /&gt;
  sudo su acme&lt;br /&gt;
&lt;br /&gt;
  export domain=&amp;quot;exemple.nasqueron.org&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mkdir /var/certificates/$domain&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d $domain \&lt;br /&gt;
  --cert-file /var/certificates/$domain/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/$domain/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/$domain/fullchain.pem&lt;br /&gt;
  --ca-file /var/certificates/$domain/chain.pem&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
  Le_ReloadCmd=&#039;sudo acmesh-nginxCheck&#039;&lt;br /&gt;
&lt;br /&gt;
doit être mis dans le fichier de configuration pour le certificat ou ajouter la commande&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
=== Migration to acme.sh ===&lt;br /&gt;
==== Paths to update ====&lt;br /&gt;
&lt;br /&gt;
Paths from /usr/local/etc/letsencrypt or /etc/letsencrypt (OS-dependant path) needs to be updated to /var/certificates (cross-platform path). The private key file is only `key.pem` instead of `privkey.pem`.&lt;br /&gt;
&lt;br /&gt;
An example is available on https://devcentral.nasqueron.org/D3624&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1919</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1919"/>
		<updated>2025-03-12T21:25:27Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* on nginx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== improved command =====&lt;br /&gt;
&lt;br /&gt;
  sudo su acme&lt;br /&gt;
&lt;br /&gt;
  export domain=&amp;quot;exemple.nasqueron.org&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mkdir /var/certificates/$domain&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d $domain \&lt;br /&gt;
  --cert-file /var/certificates/$domain/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/$domain/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/$domain/fullchain.pem&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
  Le_ReloadCmd=&#039;sudo acmesh-nginxCheck&#039;&lt;br /&gt;
&lt;br /&gt;
doit être mis dans le fichier de configuration pour le certificat ou ajouter la commande&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
=== Migration to acme.sh ===&lt;br /&gt;
==== Paths to update ====&lt;br /&gt;
&lt;br /&gt;
Paths from /usr/local/etc/letsencrypt or /etc/letsencrypt (OS-dependant path) needs to be updated to /var/certificates (cross-platform path). The private key file is only `key.pem` instead of `privkey.pem`.&lt;br /&gt;
&lt;br /&gt;
An example is available on https://devcentral.nasqueron.org/D3624&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1918</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1918"/>
		<updated>2025-02-10T20:51:54Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Credential lost for a ACME DNS subdomain */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== improved command =====&lt;br /&gt;
&lt;br /&gt;
  sudo su acme&lt;br /&gt;
&lt;br /&gt;
  export domain=&amp;quot;exemple.nasqueron.org&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mkdir /var/certificates/$domain&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d $domain \&lt;br /&gt;
  --cert-file /var/certificates/$domain/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/$domain/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/$domain/fullchain.pem&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
=== Migration to acme.sh ===&lt;br /&gt;
==== Paths to update ====&lt;br /&gt;
&lt;br /&gt;
Paths from /usr/local/etc/letsencrypt or /etc/letsencrypt (OS-dependant path) needs to be updated to /var/certificates (cross-platform path). The private key file is only `key.pem` instead of `privkey.pem`.&lt;br /&gt;
&lt;br /&gt;
An example is available on https://devcentral.nasqueron.org/D3624&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1878</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1878"/>
		<updated>2024-11-05T20:34:57Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Deploying of the certificates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pem&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== improved command =====&lt;br /&gt;
&lt;br /&gt;
  sudo su acme&lt;br /&gt;
&lt;br /&gt;
  export domain=&amp;quot;exemple.nasqueron.org&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  mkdir /var/certificates/$domain&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d $domain \&lt;br /&gt;
  --cert-file /var/certificates/$domain/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/$domain/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/$domain/fullchain.pem&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1877</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1877"/>
		<updated>2024-11-05T20:16:48Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Deploying of the certificates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem \&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pem \&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1876</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1876"/>
		<updated>2024-11-05T20:01:19Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Deploying of the certificates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pem \&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1875</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1875"/>
		<updated>2024-11-05T20:01:05Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Deploying of the certificates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/fullchain.pemt.pem \&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1874</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1874"/>
		<updated>2024-11-05T19:58:22Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Deploying of the certificates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
  acme.sh --install-cert -d exemple.nasqueron.org \&lt;br /&gt;
  --cert-file /var/certificates/exemple.nasqueron.org/cert.pem&lt;br /&gt;
  --key-file /var/certificates/exemple.nasqueron.org/key.pem \&lt;br /&gt;
  --fullchain-file /var/certificates/exemple.nasqueron.org/cert.pem \&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1873</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1873"/>
		<updated>2024-11-05T19:47:04Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Regenerate certificate how are from certbot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1872</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1872"/>
		<updated>2024-11-05T19:45:07Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Regenerate certificate how are from certbot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://auth.acme-dns.io&amp;quot;&lt;br /&gt;
    export ACMEDNS_USERNAME=&amp;quot;&amp;lt;username&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_PASSWORD=&amp;quot;&amp;lt;password&amp;gt;&amp;quot;&lt;br /&gt;
    export ACMEDNS_SUBDOMAIN=&amp;quot;&amp;lt;subdomain&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1871</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1871"/>
		<updated>2024-11-05T19:43:11Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Generate a certificate through DNS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
    export ACMEDNS_BASE_URL=&amp;quot;https://acme.nasqueron.org&amp;quot;&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new password in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ export SQLITE_HISTORY=/dev/null&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can generate any arbitrary password with any random tool.&lt;br /&gt;
It seems UUIDv4 is used by the client code, if you want one, you can use &amp;lt;code&amp;gt;uuidgen -r&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1867</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1867"/>
		<updated>2024-11-05T18:51:47Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Generate a certificate through DNS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new passw@ord in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1866</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1866"/>
		<updated>2024-11-05T17:57:04Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* acme.sh */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
acme.sh should be run with the called &amp;quot;acme&amp;quot; with a &lt;br /&gt;
    sudo su - acme&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
&lt;br /&gt;
For DNS certificate, we need to start the certificate generation, edit the DNS records to add the certificate verification. And launch the end of the certificate generation&lt;br /&gt;
&lt;br /&gt;
    acme.sh --issue --dns dns_acmedns -d example.com &lt;br /&gt;
  --server letsencrypt&lt;br /&gt;
&lt;br /&gt;
==== Regenerate certificate how are from certbot ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&lt;br /&gt;
For the certificates renewal, anything is needed the cron tab will try to renew them every day &amp;quot;x&amp;quot; day before the expiracy&lt;br /&gt;
&lt;br /&gt;
==== Deploying of the certificates ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== on nginx ====&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new passw@ord in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1865</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1865"/>
		<updated>2024-11-05T17:43:29Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
=== acme.sh ===&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new passw@ord in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1864</id>
		<title>Operations grimoire/TLS certificates</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/TLS_certificates&amp;diff=1864"/>
		<updated>2024-11-05T17:42:57Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TLS certificates should be used for every service we provide, so we can encrypt the communications.&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s Encrypt ==&lt;br /&gt;
=== Certbot commands ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;acme-v02 migration.&#039;&#039;&#039; If you&#039;ve a complaint acme-v01.api. isn&#039;t available, add &amp;lt;code&amp;gt;--server https://acme-v02.api.letsencrypt.org/directory&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;T1505 alignment.&#039;&#039;&#039; We don&#039;t use anymore Certbot as a Docker container on paas-docker role. As such, all paths are now unified. Symlinks have been added to old /srv paths to help transition.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;service nginx reload&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly -a webroot --webroot-path=/var/letsencrypt-auto --deploy-hook &amp;quot;systemctl reload nginx&amp;quot; -d foo.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate for several sites ====&lt;br /&gt;
&amp;lt;code&amp;gt;-d foo.nasqueron.org -d bar.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a certificate for foo already existed, it will offer to extend it to a new alternative name, which is probably a good idea.&lt;br /&gt;
&lt;br /&gt;
==== Generate a certificate through DNS ====&lt;br /&gt;
DNS can be used to generate certificates for domains. For example, the Openfire XMPP certificate is generated like this:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d xmpp.nasqueron.org -d nasqueron.org -d conference.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
From December 2023, you can use this command on FreeBSD servers where {{T|1505}} Let&#039;s Encrypt standard installation have been deployed:&lt;br /&gt;
&lt;br /&gt;
    certbot certonly --manual --manual-auth-hook /usr/local/etc/letsencrypt/acme-dns-auth --preferred-challenges dns --debug-challenges -d subdomain.nasqueron.org&lt;br /&gt;
&lt;br /&gt;
This uses a specialized DNS server deployed on our Docker PaaS to serve dynamic TLS records under .acme.nasqueron.org, {{Ops file|roles/paas-docker/containers/acme_dns.sls}}.&lt;br /&gt;
&lt;br /&gt;
Support files were previously &#039;&#039;&#039;only deployed to paas-docker role&#039;&#039;&#039; through {{Ops file|roles/paas-docker/letsencrypt/files}}.&lt;br /&gt;
&lt;br /&gt;
==== Renew all certificates ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot renew&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installation on nginx ====&lt;br /&gt;
===== Allow Let&#039;s encrypt validation =====&lt;br /&gt;
&lt;br /&gt;
    include includes/letsencrypt;&lt;br /&gt;
&lt;br /&gt;
This will use {{Ops file|roles/webserver-core/nginx/files/includes/letsencrypt}} nginx configuration.&lt;br /&gt;
&lt;br /&gt;
===== Serve TLS certificate =====&lt;br /&gt;
&lt;br /&gt;
    include includes/tls;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
This will configure a compromise between security and compatibility, based on Intermediate Mozilla SSL config&amp;lt;ref&amp;gt;https://ssl-config.mozilla.org/&amp;lt;/ref&amp;gt;. The current configuration is served by {{Ops file|roles/webserver-core/nginx/files/includes/tls}}.&lt;br /&gt;
&lt;br /&gt;
If you prefer to restrict the resource for TLS 1.3, and accepts to block legacy clients, you can also use with {{D|3251}}:&lt;br /&gt;
&lt;br /&gt;
    include includes/tls-modern-only;&lt;br /&gt;
    ssl_certificate /srv/letsencrypt/etc/live/xmpp.nasqueron.org/fullchain.pem;&lt;br /&gt;
    ssl_certificate_key /srv/letsencrypt/etc/live/xmpp.nasqueron.org/privkey.pem;&lt;br /&gt;
&lt;br /&gt;
==== Edit renewal hook ====&lt;br /&gt;
In /etc/letsencrypt/renewal or /usr/local/etc/letsencrypt/renewal you can edit this section to customize the command to run after renewal:&lt;br /&gt;
&lt;br /&gt;
    [renewalparams]&lt;br /&gt;
    renew_hook = systemctl reload nginx&lt;br /&gt;
&lt;br /&gt;
That can be applied in batch when nothing is set: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;gsed -i &amp;quot;s/\[\[webroot_map]]/renew_hook = systemctl reload nginx\n\n[[webroot_map]]/g&amp;quot; *.conf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Install certbot on CentOS 10 stream ===&lt;br /&gt;
&lt;br /&gt;
Packages for Python 3.12 currently used as of 2024-08-04 on CentOS 10 stream can be fetched from Fedora 40 repository.&lt;br /&gt;
&lt;br /&gt;
Installation on Dwellers was done like this:&lt;br /&gt;
    &lt;br /&gt;
    mkdir /tmp/certbot &amp;amp;&amp;amp; cd /tmp/certbot&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/c/certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-acme-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-certbot-2.9.0-1.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-configargparse-1.7-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-josepy-1.13.0-8.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-parsedatetime-2.6-12.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyOpenSSL-23.2.0-3.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pyrfc3339-1.1-18.fc40.noarch.rpm&lt;br /&gt;
    wget https://dl.fedoraproject.org/pub/fedora/linux/releases/40/Everything/x86_64/os/Packages/p/python3-pytz-2024.1-1.fc40.noarch.rpm&lt;br /&gt;
    dnf install ./*.rpm&lt;br /&gt;
&lt;br /&gt;
== acme.sh ==&lt;br /&gt;
&lt;br /&gt;
== Nasqueron PKI ==&lt;br /&gt;
=== Principles ===&lt;br /&gt;
Internal PKI material are stored in Vault, see [[Operations grimoire/Vault]] for information about how to generate, renew, etc.&lt;br /&gt;
&lt;br /&gt;
In the operations repository, the {{Ops file|roles/core/certificates}} unit is responsible to deploy &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt;, used to authenticate for *.nasqueron.drake or IP services. For exemple, Vault clients require a certificate they can validate with a chain from that intermediate CA. Note as we don&#039;t currently use the root CA, a fullchain is probably not needed for those services.&lt;br /&gt;
&lt;br /&gt;
=== Rollover a new certificate ===&lt;br /&gt;
If &amp;lt;code&amp;gt;nasqueron-vault-ca.crt&amp;lt;/code&amp;gt; is updated or if we want instead to provision the root certificate, the following repository need to be updated and services to be redeployed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Where to update certificate?&lt;br /&gt;
|-&lt;br /&gt;
! Repository !! Path !! Purpose !! Deployment instructions&lt;br /&gt;
|-&lt;br /&gt;
| operations || {{Ops file|roles/core/certificates/files/}} || Trust internal resources on every server || Salt: &amp;lt;code&amp;gt;salt &#039;*&#039; state.apply roles/core/certificates&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| docker-airflow || [https://devcentral.nasqueron.org/source/docker-airflow/browse/main/files files/] || Connect to Vault from Airflow Python code || Docker: build and deploy new image nasqueron/airflow on Dwellers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Deployment instructions are up-to-date when newly added on that table. Afterwards, they should be checked against current procedures.&lt;br /&gt;
&lt;br /&gt;
== Special considerations ==&lt;br /&gt;
=== New server ===&lt;br /&gt;
Let&#039;s encrypt client is available on [[Ysul]] (natively) and [[Dwellers]] (as a wrapper script for a Docker container).&lt;br /&gt;
&lt;br /&gt;
Fill a task in Servers component, subscribe Sandlayth and Dereckson to deploy it on a new server.&lt;br /&gt;
&lt;br /&gt;
A salt state would be nice for such purpose. There is work-in-progress on that matter through {{D|3248}}.&lt;br /&gt;
&lt;br /&gt;
=== Internationalized domain names ===&lt;br /&gt;
==== Punycode conversion ====&lt;br /&gt;
Both for web server configuration and certificate authority, name must be converted to Punycode ([https://www.ietf.org/rfc/rfc3492.txt RFC 3492]): &lt;br /&gt;
https://www.punycoder.com/&lt;br /&gt;
&lt;br /&gt;
==== Let&#039;s encrypt support ====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s encrypt has supported IDN since 2016&amp;lt;ref&amp;gt;https://letsencrypt.org/2016/10/21/introducing-idn-support.html&amp;lt;/ref&amp;gt;. We use it for dægrefn.nasqueron.org certificate.&lt;br /&gt;
&lt;br /&gt;
Previously, they were afraid: attackers could register a domain with a Cyrillic character matching a real domains. As some people consider it&#039;s the responsibility of the CA to mitigate such risks, the feature has been several times postponed.&lt;br /&gt;
&lt;br /&gt;
==== StartSSL ====&lt;br /&gt;
&lt;br /&gt;
StartSSL is not in activity anymore. It was used at Nasqueron when Let&#039;s Encrypt didn&#039;t support IDN.&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Acme DNS ===&lt;br /&gt;
==== Can&#039;t reach ACME DNS API / HTTP Error 403: Forbidden ====&lt;br /&gt;
AcmeDNS API access is restricted to IPs addresses set in {{Ops file|roles/webserver-core/nginx/files/includes/geo_nasqueron}}.&lt;br /&gt;
&lt;br /&gt;
If you got a 403 by running acme.sh (only visible in --debug mode):&lt;br /&gt;
* If the IP address is missing from geo_nasqueron, add it&lt;br /&gt;
* If the IP address is already there, check on the server if /etc/nginx/includes/geo_nasqueron matches&lt;br /&gt;
** Yes -&amp;gt; nginx must be reloaded (nginx -t reload)&lt;br /&gt;
** No -&amp;gt; Deploy with &amp;lt;code&amp;gt;salt docker-002 state.sls_id /etc/nginx/includes/geo_nasqueron roles/webserver-core/nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another solution is a specific routing to reach the API: &lt;br /&gt;
For Hervil, add a route to use router-001 gateway: route add 51.255.124.8/30 172.27.27.1&lt;br /&gt;
&lt;br /&gt;
==== Troubleshoot records in ACME DNS database ====&lt;br /&gt;
To check the acme.nasqueron.org subdomain matching your _acme-challenge subdomain: &amp;lt;code&amp;gt;nslookup -type=TXT _acme-challenge.&amp;lt;subdomain&amp;gt;.nasqueron.org&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DNS server to store acme.nasqueron.org records uses a sqlite3 database. To connect and check your parameters:&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/lib/acme-dns.db&lt;br /&gt;
    SELECT Username, Password FROM records WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Credential lost for a ACME DNS subdomain ====&lt;br /&gt;
&lt;br /&gt;
Passwords are [https://github.com/joohoi/acme-dns/blob/9c6ca258e1d57e7441b60db4474a68c36356dae2/validation.go hashed with bcrypt], so it&#039;s not possible to recover them.&lt;br /&gt;
&lt;br /&gt;
In that case, there are two options:&lt;br /&gt;
&lt;br /&gt;
* if you prefer edit the DNS record, delete acme.sh information for the domain renewal then issue a new certificate, that will register a new account&lt;br /&gt;
* if you prefer edit the ACME DNS database, encrypt a new passw@ord in bcrypt and update it with sqlite&lt;br /&gt;
&lt;br /&gt;
Certificates requests are limited by Let&#039;s Encrypt, updating the password avoids to reach that quota.&lt;br /&gt;
&lt;br /&gt;
You can generate a uuid and pass it to bcrypt, or register a new password (and update DNS):&lt;br /&gt;
&lt;br /&gt;
    $ ssh docker-002&lt;br /&gt;
    $ sqlite3 /srv/acme/. lib/acme-dns.db&lt;br /&gt;
    UPDATE records SET Password = &amp;quot;&amp;lt;new bcrypt hash&amp;gt;&amp;quot; WHERE Subdomain = &amp;quot;&amp;lt;DNS answer&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To get password hash with bcrypt, you can use psysh on WindRiver:&lt;br /&gt;
&lt;br /&gt;
   $ psysh&lt;br /&gt;
   password_hash(&amp;quot;alpha&amp;quot;, PASSWORD_BCRYPT)&lt;br /&gt;
   $2y$10$N17lnt09YFIoVY4025AmCuGrlmA.ZiThm.RDufcakGq9.3IK4xVcW&lt;br /&gt;
&lt;br /&gt;
Replace $2y$ by $2a$ as x and y are unique for PHP, the rest of the world uses $2a$.&lt;br /&gt;
&lt;br /&gt;
== Notes &amp;amp; references ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Mail&amp;diff=1613</id>
		<title>Operations grimoire/Mail</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Mail&amp;diff=1613"/>
		<updated>2024-10-03T20:06:25Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: /* Network */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The mail infrastructure is shared between third party services (Mailgun, Sendgrid) for web applications willing to use API and our own mail server for regular mailboxes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float: right; width: 22em; border: solid 2px black; padding: 1em;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;{{FULLPAGENAME}}&#039;&#039;&#039;&lt;br /&gt;
{{Special:Prefixindex/{{FULLPAGENAME}}/}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Third party services ==&lt;br /&gt;
Mainly, they provide configuration wizards, logs, and API keys on a web interface.&lt;br /&gt;
&lt;br /&gt;
[[Operations grimoire/External services]] says who to contact to debug any issue, configure them, etc.&lt;br /&gt;
&lt;br /&gt;
== Nasqueron mail services ==&lt;br /&gt;
=== Architecture ===&lt;br /&gt;
We use the following servers:&lt;br /&gt;
* Postfix&lt;br /&gt;
** 25 is for mail servers&lt;br /&gt;
** 587 is for STARTTLS + user auth&lt;br /&gt;
* dovecot for IMAP / POP&lt;br /&gt;
* SpamAssassin, OpenDKIM (see [[/DKIM]])&lt;br /&gt;
* Sympa for the mailing lists&lt;br /&gt;
* MySQL to store user accounts mailboxes and sympa data&lt;br /&gt;
* nginx to serve web applications&lt;br /&gt;
&lt;br /&gt;
/etc/postfix and /etc/dovecot are Git repositories, so commit your configuration changes.&lt;br /&gt;
&lt;br /&gt;
User accounts are stored in a MySQL database. They are managed by ViMbAdmin (on https://vma.nasqueron.org).&lt;br /&gt;
&lt;br /&gt;
Sympa manages the mailing lists.&lt;br /&gt;
&lt;br /&gt;
A nginx server serves vma as vma.nasqinternal, Roundcube as mail.nasqinternal and Sympa.&lt;br /&gt;
On Dwellers, nginx assumes SSL termination and the relevant vhosts like mail.nasqueron.org, mail.wolfplex.be, etc.&lt;br /&gt;
&lt;br /&gt;
All that should be migrated to configuration as code to be managed through Salt.&lt;br /&gt;
&lt;br /&gt;
A lxc container has been chosen for more stability: Docker assumes we can respin containers, host OS can change. The lxc container is isolated, stable and lxc doesn&#039;t ask restarts.&lt;br /&gt;
&lt;br /&gt;
=== Log in to the server ===&lt;br /&gt;
Mail server lives on the lxc container &amp;lt;code&amp;gt;mailserver&amp;lt;/code&amp;gt; on [[Dwellers]].&lt;br /&gt;
&lt;br /&gt;
To access it, you must so:&lt;br /&gt;
  * ssh dwellers&lt;br /&gt;
  * attach to the container (&amp;lt;code&amp;gt;lxc-attach -n mailserver [tcsh]&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
If you need to access a lxc container, you can script something do to:&lt;br /&gt;
&amp;lt;code&amp;gt;$SSH $LXC_SERVER $LXC_EXEC $CONTAINER_NAME $LXC_COMMAND&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, it would be &amp;lt;code&amp;gt;ssh -t dwellers.nasqueron.org sudo lxc-attach -n mailserver tcsh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To be able to use sudo for lxc-attach, you must belong to the `ops` group.&lt;br /&gt;
&lt;br /&gt;
=== Add a domain ===&lt;br /&gt;
&lt;br /&gt;
# Add it to https://vma.nasqueron.org&lt;br /&gt;
# Follow [[/DKIM]] procedure&lt;br /&gt;
&lt;br /&gt;
It&#039;s ready.&lt;br /&gt;
&lt;br /&gt;
You can also be willing to declare the domain to autoconfig/autodiscover, but that&#039;s blocked by https://devcentral.nasqueron.org/T1116.&lt;br /&gt;
&lt;br /&gt;
== New deploy thinking ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ pour ou contre&lt;br /&gt;
|-&lt;br /&gt;
! ViMbAdmin aventage &lt;br /&gt;
! ViMbAdmin inconvenient  &lt;br /&gt;
! Salt pillar aventage &lt;br /&gt;
! Salt pillar inconvenient&lt;br /&gt;
|-&lt;br /&gt;
| Ediatable interface &lt;br /&gt;
| Configuration splited&lt;br /&gt;
| Unified configuration &lt;br /&gt;
| Private salt repository needed for privacy&lt;br /&gt;
|-&lt;br /&gt;
| Easy to use interface&lt;br /&gt;
| Should be installed on the same server as the mailserver&lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Easy solution for users to changes their passwords&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| An administrator of an external domain for hosting of other open source project&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Hervil ==&lt;br /&gt;
&lt;br /&gt;
=== Network ===&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
    Internet:&lt;br /&gt;
    Destination        Gateway            Flags     Netif Expire&lt;br /&gt;
    default            51.210.99.254      UGS        vmx1&lt;br /&gt;
    51.210.99.254      link#2             UHS        vmx1&lt;br /&gt;
    51.255.124.8/30    172.27.27.1        UGS        vmx0&lt;br /&gt;
&lt;br /&gt;
For SPF record we need to make the mail go out from the ip : 51.210.99.254&lt;br /&gt;
To permit acme.sh we make a route thrugh router.OO1&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Dashboards ===&lt;br /&gt;
On Grafana, the following dashboards are available:&lt;br /&gt;
* [https://grafana.nasqueron.org/d/h36Havfik/postfix-legacy-dashboard?orgId=1 Postfix]&lt;br /&gt;
&lt;br /&gt;
The following dashboards are missing, feel free to create one:&lt;br /&gt;
* Dovecot&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
On FreeBSD servers, mail logs are consolidated into &amp;lt;code&amp;gt;/var/log/maillog&amp;lt;/code&amp;gt; by syslog daemon.&lt;br /&gt;
&lt;br /&gt;
=== Test to send e-mail with telnet or openssl clients ===&lt;br /&gt;
&lt;br /&gt;
You can test STARTTLS with openssl s_client:&lt;br /&gt;
&lt;br /&gt;
    openssl s_client -connect mail.nasqueron.org:587 -starttls smtp -ign_eof -crlf &lt;br /&gt;
&lt;br /&gt;
Flags:&lt;br /&gt;
  * The -starttls smtp option is the one to send the STARTTLS command&lt;br /&gt;
  * The -ign_eof flag disables interactive commands, to avoid to renegotiate the TLS session when you press R (like in RCPT TO).&lt;br /&gt;
  * The -crlf flag doesn&#039;t seem needed on FreeBSD, but seem needed on Fedora. It allows to always use \CR\LF (\r\n) as EOL.&lt;br /&gt;
&lt;br /&gt;
=== @nasqueron.org must be sent through mail.nasqueron.org ===&lt;br /&gt;
A SPF record &#039;&#039;v=spf1 a:mail.nasqueron.org -all&#039;&#039; should exist.&lt;br /&gt;
&lt;br /&gt;
If set, any application app.nasqueron.org should:&lt;br /&gt;
* send mails using @app.nasqueron.org domain, not the generic @nasqueron.org one;&lt;br /&gt;
* define SPF and if possible DKIM records for this @app.nasqueron.org mail domain.&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Mail&amp;diff=1612</id>
		<title>Operations grimoire/Mail</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Mail&amp;diff=1612"/>
		<updated>2024-10-03T20:05:07Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The mail infrastructure is shared between third party services (Mailgun, Sendgrid) for web applications willing to use API and our own mail server for regular mailboxes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float: right; width: 22em; border: solid 2px black; padding: 1em;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;{{FULLPAGENAME}}&#039;&#039;&#039;&lt;br /&gt;
{{Special:Prefixindex/{{FULLPAGENAME}}/}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Third party services ==&lt;br /&gt;
Mainly, they provide configuration wizards, logs, and API keys on a web interface.&lt;br /&gt;
&lt;br /&gt;
[[Operations grimoire/External services]] says who to contact to debug any issue, configure them, etc.&lt;br /&gt;
&lt;br /&gt;
== Nasqueron mail services ==&lt;br /&gt;
=== Architecture ===&lt;br /&gt;
We use the following servers:&lt;br /&gt;
* Postfix&lt;br /&gt;
** 25 is for mail servers&lt;br /&gt;
** 587 is for STARTTLS + user auth&lt;br /&gt;
* dovecot for IMAP / POP&lt;br /&gt;
* SpamAssassin, OpenDKIM (see [[/DKIM]])&lt;br /&gt;
* Sympa for the mailing lists&lt;br /&gt;
* MySQL to store user accounts mailboxes and sympa data&lt;br /&gt;
* nginx to serve web applications&lt;br /&gt;
&lt;br /&gt;
/etc/postfix and /etc/dovecot are Git repositories, so commit your configuration changes.&lt;br /&gt;
&lt;br /&gt;
User accounts are stored in a MySQL database. They are managed by ViMbAdmin (on https://vma.nasqueron.org).&lt;br /&gt;
&lt;br /&gt;
Sympa manages the mailing lists.&lt;br /&gt;
&lt;br /&gt;
A nginx server serves vma as vma.nasqinternal, Roundcube as mail.nasqinternal and Sympa.&lt;br /&gt;
On Dwellers, nginx assumes SSL termination and the relevant vhosts like mail.nasqueron.org, mail.wolfplex.be, etc.&lt;br /&gt;
&lt;br /&gt;
All that should be migrated to configuration as code to be managed through Salt.&lt;br /&gt;
&lt;br /&gt;
A lxc container has been chosen for more stability: Docker assumes we can respin containers, host OS can change. The lxc container is isolated, stable and lxc doesn&#039;t ask restarts.&lt;br /&gt;
&lt;br /&gt;
=== Log in to the server ===&lt;br /&gt;
Mail server lives on the lxc container &amp;lt;code&amp;gt;mailserver&amp;lt;/code&amp;gt; on [[Dwellers]].&lt;br /&gt;
&lt;br /&gt;
To access it, you must so:&lt;br /&gt;
  * ssh dwellers&lt;br /&gt;
  * attach to the container (&amp;lt;code&amp;gt;lxc-attach -n mailserver [tcsh]&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
If you need to access a lxc container, you can script something do to:&lt;br /&gt;
&amp;lt;code&amp;gt;$SSH $LXC_SERVER $LXC_EXEC $CONTAINER_NAME $LXC_COMMAND&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, it would be &amp;lt;code&amp;gt;ssh -t dwellers.nasqueron.org sudo lxc-attach -n mailserver tcsh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To be able to use sudo for lxc-attach, you must belong to the `ops` group.&lt;br /&gt;
&lt;br /&gt;
=== Add a domain ===&lt;br /&gt;
&lt;br /&gt;
# Add it to https://vma.nasqueron.org&lt;br /&gt;
# Follow [[/DKIM]] procedure&lt;br /&gt;
&lt;br /&gt;
It&#039;s ready.&lt;br /&gt;
&lt;br /&gt;
You can also be willing to declare the domain to autoconfig/autodiscover, but that&#039;s blocked by https://devcentral.nasqueron.org/T1116.&lt;br /&gt;
&lt;br /&gt;
== New deploy thinking ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ pour ou contre&lt;br /&gt;
|-&lt;br /&gt;
! ViMbAdmin aventage &lt;br /&gt;
! ViMbAdmin inconvenient  &lt;br /&gt;
! Salt pillar aventage &lt;br /&gt;
! Salt pillar inconvenient&lt;br /&gt;
|-&lt;br /&gt;
| Ediatable interface &lt;br /&gt;
| Configuration splited&lt;br /&gt;
| Unified configuration &lt;br /&gt;
| Private salt repository needed for privacy&lt;br /&gt;
|-&lt;br /&gt;
| Easy to use interface&lt;br /&gt;
| Should be installed on the same server as the mailserver&lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Easy solution for users to changes their passwords&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| An administrator of an external domain for hosting of other open source project&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Hervil ==&lt;br /&gt;
&lt;br /&gt;
=== Network ===&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags     Netif Expire&lt;br /&gt;
default            51.210.99.254      UGS        vmx1&lt;br /&gt;
51.210.99.254      link#2             UHS        vmx1&lt;br /&gt;
51.255.124.8/30    172.27.27.1        UGS        vmx0&lt;br /&gt;
&lt;br /&gt;
For SPF record we need to make the mail go out from the ip : 51.210.99.254&lt;br /&gt;
To permit acme.sh we make a route thrugh router.OO1&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== Dashboards ===&lt;br /&gt;
On Grafana, the following dashboards are available:&lt;br /&gt;
* [https://grafana.nasqueron.org/d/h36Havfik/postfix-legacy-dashboard?orgId=1 Postfix]&lt;br /&gt;
&lt;br /&gt;
The following dashboards are missing, feel free to create one:&lt;br /&gt;
* Dovecot&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
On FreeBSD servers, mail logs are consolidated into &amp;lt;code&amp;gt;/var/log/maillog&amp;lt;/code&amp;gt; by syslog daemon.&lt;br /&gt;
&lt;br /&gt;
=== Test to send e-mail with telnet or openssl clients ===&lt;br /&gt;
&lt;br /&gt;
You can test STARTTLS with openssl s_client:&lt;br /&gt;
&lt;br /&gt;
    openssl s_client -connect mail.nasqueron.org:587 -starttls smtp -ign_eof -crlf &lt;br /&gt;
&lt;br /&gt;
Flags:&lt;br /&gt;
  * The -starttls smtp option is the one to send the STARTTLS command&lt;br /&gt;
  * The -ign_eof flag disables interactive commands, to avoid to renegotiate the TLS session when you press R (like in RCPT TO).&lt;br /&gt;
  * The -crlf flag doesn&#039;t seem needed on FreeBSD, but seem needed on Fedora. It allows to always use \CR\LF (\r\n) as EOL.&lt;br /&gt;
&lt;br /&gt;
=== @nasqueron.org must be sent through mail.nasqueron.org ===&lt;br /&gt;
A SPF record &#039;&#039;v=spf1 a:mail.nasqueron.org -all&#039;&#039; should exist.&lt;br /&gt;
&lt;br /&gt;
If set, any application app.nasqueron.org should:&lt;br /&gt;
* send mails using @app.nasqueron.org domain, not the generic @nasqueron.org one;&lt;br /&gt;
* define SPF and if possible DKIM records for this @app.nasqueron.org mail domain.&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Changelog&amp;diff=1534</id>
		<title>Operations grimoire/Changelog</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Changelog&amp;diff=1534"/>
		<updated>2024-07-04T17:12:11Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 2024 ==&lt;br /&gt;
=== July 2024 ===&lt;br /&gt;
* [2024-07-07 20:30] [WindRiver] &amp;lt;Dereckson&amp;gt; Upgrade done.&lt;br /&gt;
* [2024-07-07 19:50] [WindRiver] &amp;lt;Dereckson&amp;gt; Upgrade to FreeBSD 14.1. Rebooting.&lt;br /&gt;
* [2024-07-04 19:10] [Complector] &amp;lt;DorianWinty&amp;gt; Reinstall Git&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/PostgreSQL&amp;diff=1527</id>
		<title>Operations grimoire/PostgreSQL</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/PostgreSQL&amp;diff=1527"/>
		<updated>2024-06-20T19:50:22Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PostgreSQL is available as a standalone role and can also be enabled on devserver.&lt;br /&gt;
&lt;br /&gt;
Applications on the Docker PaaS can use our PostgreSQL infrastructure (Airflow, datasources) or have their own container (Sentry, with custom wal2json extension). This resource documents our own db- servers.&lt;br /&gt;
&lt;br /&gt;
== Howto ==&lt;br /&gt;
&lt;br /&gt;
=== Open a console === &lt;br /&gt;
Use peer authentication from the postgres user: &amp;lt;code&amp;gt;sudo -u postgres psql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run queries against database ===&lt;br /&gt;
The important things are:&lt;br /&gt;
&lt;br /&gt;
# prepare the operation with a .sql file&lt;br /&gt;
# put that SQL file to a task&lt;br /&gt;
# avoid data destruction and allow rollback&lt;br /&gt;
## if a table needs to be dropped, we can rename it to _unused&lt;br /&gt;
## if an application doesn&#039;t use a column anymore, we can rename it from foo to foo_unused so we can rollback by renaming back&lt;br /&gt;
## actual deletion can be done some weeks later&lt;br /&gt;
&lt;br /&gt;
Recommend procedure:&lt;br /&gt;
&lt;br /&gt;
# Create a task on DevCentral or reuse an existing deployment task&lt;br /&gt;
# Upload the .sql file on DevCentral or to a repository:&lt;br /&gt;
## One-shot maintenance can go to https://devcentral.nasqueron.org/paste/ or sent with &amp;lt;code&amp;gt;cat foo.sql | arc paste --title foo.sql --&amp;lt;/code&amp;gt;&lt;br /&gt;
## Regular queries can go to the [https://devcentral.nasqueron.org/source/reports/browse/main/sql/ reports repository]&lt;br /&gt;
# Link it in the task&lt;br /&gt;
# Run it&lt;br /&gt;
&lt;br /&gt;
To run foo.sql against acme database:&lt;br /&gt;
&lt;br /&gt;
# upload the foo.sql file to the relevant server (for example db-A-001 for db-A cluster)&lt;br /&gt;
# &amp;lt;code&amp;gt;sudo -u postgres psql acme &amp;lt; foo.sql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create a new database or user ===&lt;br /&gt;
&lt;br /&gt;
It&#039;s a simple two steps process:&lt;br /&gt;
&lt;br /&gt;
# Edit the relevant pillar file, for example pillar/dbserver/cluster-A.sls in rOPS&lt;br /&gt;
# Deploy the change: &amp;lt;code&amp;gt;salt db-A-001 state.apply roles/dbserver-pgsql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You generally need:&lt;br /&gt;
&lt;br /&gt;
* an user block in dbserver_postgresql.users&lt;br /&gt;
** block title is the username&lt;br /&gt;
** a password needs to be set in Flow, key is under ops/secrets/&lt;br /&gt;
* a database block&lt;br /&gt;
* a connection triplet db, user, ips (use /32 for an unique IP)&lt;br /&gt;
&lt;br /&gt;
By default, external connections are NOT enabled for any user and database, an entry for pg_hba.conf MUST be added in connections part.&lt;br /&gt;
&lt;br /&gt;
Servers don&#039;t have a public ICANN IP, so you can only connect from other Nasqueron servers.&lt;br /&gt;
&lt;br /&gt;
=== Grant privileges to an user ===&lt;br /&gt;
&lt;br /&gt;
Some applications don&#039;t set privileges, even if they own the database. That&#039;s for example the case of Orbeon Forms DDL.&lt;br /&gt;
&lt;br /&gt;
To determine if acme has already the rights on the database:&lt;br /&gt;
&lt;br /&gt;
    SELECT grantor, grantee, table_schema, table_name, privilege_type&lt;br /&gt;
    FROM information_schema.table_privileges&lt;br /&gt;
    WHERE grantee = &#039;acme&#039;;&lt;br /&gt;
&lt;br /&gt;
If not:&lt;br /&gt;
&lt;br /&gt;
    GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO acme;&lt;br /&gt;
&lt;br /&gt;
This set of privileges can be handled directly by Salt in cluster privileges definition:&lt;br /&gt;
&lt;br /&gt;
      privileges:&lt;br /&gt;
        - database: &amp;lt;database name&amp;gt;&lt;br /&gt;
          scope: table&lt;br /&gt;
          schema: public&lt;br /&gt;
          tables:&lt;br /&gt;
            - ALL&lt;br /&gt;
          privileges:&lt;br /&gt;
            - ALL&lt;br /&gt;
&lt;br /&gt;
See {{D|3252}} or {{D|3253}} for an example.&lt;br /&gt;
&lt;br /&gt;
As a known issue, this query will ALWAYS be executed by Salt.&lt;br /&gt;
&lt;br /&gt;
; Sequences privileges&lt;br /&gt;
&lt;br /&gt;
Sequences aren&#039;t included in that GRANT ALL PRIVILEGES. We can generate GRANT queries for them:&lt;br /&gt;
&lt;br /&gt;
    SELECT &#039;GRANT USAGE ON SEQUENCE &#039; || sequence_schema || &#039;.&#039; || sequence_name || &#039; TO &amp;quot;acme&amp;quot;;&#039;&lt;br /&gt;
    FROM information_schema.sequences&lt;br /&gt;
    WHERE sequence_schema NOT LIKE &#039;pg_%&#039;&lt;br /&gt;
    AND sequence_schema != &#039;information_schema&#039;;&lt;br /&gt;
&lt;br /&gt;
=== What to do after an update of PostgreSQL servers? ===&lt;br /&gt;
&lt;br /&gt;
The following services need their connection to explicitly be restarted:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Services to tweak&lt;br /&gt;
|-&lt;br /&gt;
! Cluster !! Service !! Procedure&lt;br /&gt;
|-&lt;br /&gt;
| A || Airflow &amp;gt; airflow_triggerer || On Dwellers, docker restart airflow_triggerer&lt;br /&gt;
|-&lt;br /&gt;
| A || Airflow &amp;gt; airflow_scheduler || On Dwellers, docker restart airflow_scheduler&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Clusters ==&lt;br /&gt;
&lt;br /&gt;
Letters can be discontinuous: for example, B will be a MySQL cluster.&lt;br /&gt;
&lt;br /&gt;
=== Cluster A ===&lt;br /&gt;
A is the general cluster, for Nasqueron services. It currently has one server, db-A-001.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Databases&lt;br /&gt;
|-&lt;br /&gt;
! Database !! Managed by !! Description&lt;br /&gt;
|-&lt;br /&gt;
| airflow || Nasqueron Ops || Workflows runner, used by datasources&lt;br /&gt;
|-&lt;br /&gt;
| fantoir || Datasources || PostgreSQL version of FANTOIR for geocoding&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Troubleshoot ==&lt;br /&gt;
=== An application stops to work correctly with PostgreSQL ===&lt;br /&gt;
Issues with queries are logged to /var/log/messages:&lt;br /&gt;
&lt;br /&gt;
    $ tail -n100 -f /var/log/messages | grep postgres&lt;br /&gt;
&lt;br /&gt;
For example, {{T|1943}} issue was found with this line:&lt;br /&gt;
&lt;br /&gt;
    Jan 14 23:13:58 db-A-001 postgres[35351]: [8-1] 2024-01-14 23:13:58.081 UTC [35351] ERROR:  unsupported XML feature&lt;br /&gt;
&lt;br /&gt;
=== Unsupported XML feature ===&lt;br /&gt;
For Orbeon, XML support is required. That&#039;s not by default the case on FreeBSD, the port needs to be built manually. That&#039;s the case when provisioning a new server through {{Ops file|roles/dbserver-pgsql/server/build.sls}} but upgrade can break this port.&lt;br /&gt;
&lt;br /&gt;
If so, rebuild the package. For that, you can follow the instructions of [[Operations grimoire/FreeBSD]], section PostgreSQL. &lt;br /&gt;
&lt;br /&gt;
=== Some postgres_privileges.present are always changed by Salt ===&lt;br /&gt;
&lt;br /&gt;
Some ON ALL TABLE privilege queries are always run by the Salt PostgreSQL execution module. For example:&lt;br /&gt;
&lt;br /&gt;
          ID: dbserver_pgsql_user_orbeon_privilege_2_ALL&lt;br /&gt;
    Function: postgres_privileges.present&lt;br /&gt;
        Name: orbeon&lt;br /&gt;
      Result: True&lt;br /&gt;
     Comment: The privilege(s): ALL have been granted to orbeon&lt;br /&gt;
     Started: 21:54:53.656120&lt;br /&gt;
    Duration: 284.394 ms&lt;br /&gt;
     Changes:   &lt;br /&gt;
              ----------&lt;br /&gt;
              orbeon:&lt;br /&gt;
                  Present&lt;br /&gt;
&lt;br /&gt;
Those statements aren&#039;t idempotent. This is a known issue, and doesn&#039;t affect deployment.&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Mail&amp;diff=1526</id>
		<title>Operations grimoire/Mail</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Mail&amp;diff=1526"/>
		<updated>2024-06-18T20:46:27Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The mail infrastructure is shared between third party services (Mailgun, Sendgrid) for web applications willing to use API and our own mail server for regular mailboxes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float: right; width: 22em; border: solid 2px black; padding: 1em;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;{{FULLPAGENAME}}&#039;&#039;&#039;&lt;br /&gt;
{{Special:Prefixindex/{{FULLPAGENAME}}/}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Third party services ==&lt;br /&gt;
Mainly, they provide configuration wizards, logs, and API keys on a web interface.&lt;br /&gt;
&lt;br /&gt;
[[Operations grimoire/External services]] says who to contact to debug any issue, configure them, etc.&lt;br /&gt;
&lt;br /&gt;
== Nasqueron mail services ==&lt;br /&gt;
=== Architecture ===&lt;br /&gt;
We use the following servers:&lt;br /&gt;
* Postfix&lt;br /&gt;
** 25 is for mail servers&lt;br /&gt;
** 587 is for STARTTLS + user auth&lt;br /&gt;
* dovecot for IMAP / POP&lt;br /&gt;
* SpamAssassin, OpenDKIM (see [[/DKIM]])&lt;br /&gt;
* Sympa for the mailing lists&lt;br /&gt;
* MySQL to store user accounts mailboxes and sympa data&lt;br /&gt;
* nginx to serve web applications&lt;br /&gt;
&lt;br /&gt;
/etc/postfix and /etc/dovecot are Git repositories, so commit your configuration changes.&lt;br /&gt;
&lt;br /&gt;
User accounts are stored in a MySQL database. They are managed by ViMbAdmin (on https://vma.nasqueron.org).&lt;br /&gt;
&lt;br /&gt;
Sympa manages the mailing lists.&lt;br /&gt;
&lt;br /&gt;
A nginx server serves vma as vma.nasqinternal, Roundcube as mail.nasqinternal and Sympa.&lt;br /&gt;
On Dwellers, nginx assumes SSL termination and the relevant vhosts like mail.nasqueron.org, mail.wolfplex.be, etc.&lt;br /&gt;
&lt;br /&gt;
All that should be migrated to configuration as code to be managed through Salt.&lt;br /&gt;
&lt;br /&gt;
A lxc container has been chosen for more stability: Docker assumes we can respin containers, host OS can change. The lxc container is isolated, stable and lxc doesn&#039;t ask restarts.&lt;br /&gt;
&lt;br /&gt;
=== Log in to the server ===&lt;br /&gt;
Mail server lives on the lxc container &amp;lt;code&amp;gt;mailserver&amp;lt;/code&amp;gt; on [[Dwellers]].&lt;br /&gt;
&lt;br /&gt;
To access it, you must so:&lt;br /&gt;
  * ssh dwellers&lt;br /&gt;
  * attach to the container (&amp;lt;code&amp;gt;lxc-attach -n mailserver [tcsh]&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
If you need to access a lxc container, you can script something do to:&lt;br /&gt;
&amp;lt;code&amp;gt;$SSH $LXC_SERVER $LXC_EXEC $CONTAINER_NAME $LXC_COMMAND&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, it would be &amp;lt;code&amp;gt;ssh -t dwellers.nasqueron.org sudo lxc-attach -n mailserver tcsh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To be able to use sudo for lxc-attach, you must belong to the `ops` group.&lt;br /&gt;
&lt;br /&gt;
=== Add a domain ===&lt;br /&gt;
&lt;br /&gt;
# Add it to https://vma.nasqueron.org&lt;br /&gt;
# Follow [[/DKIM]] procedure&lt;br /&gt;
&lt;br /&gt;
It&#039;s ready.&lt;br /&gt;
&lt;br /&gt;
You can also be willing to declare the domain to autoconfig/autodiscover, but that&#039;s blocked by https://devcentral.nasqueron.org/T1116.&lt;br /&gt;
&lt;br /&gt;
== New deploy thinking ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ pour ou contre&lt;br /&gt;
|-&lt;br /&gt;
! ViMbAdmin aventage &lt;br /&gt;
! ViMbAdmin inconvenient  &lt;br /&gt;
! Salt pillar aventage &lt;br /&gt;
! Salt pillar inconvenient&lt;br /&gt;
|-&lt;br /&gt;
| Ediatable interface &lt;br /&gt;
| Configuration splited&lt;br /&gt;
| Unified configuration &lt;br /&gt;
| Private salt repository needed for privacy&lt;br /&gt;
|-&lt;br /&gt;
| Easy to use interface&lt;br /&gt;
| Should be installed on the same server as the mailserver&lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Easy solution for users to changes their passwords&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| An administrator of an external domain for hosting of other open source project&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|  &lt;br /&gt;
|  &lt;br /&gt;
| &lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Create_and_revoke_user_accounts_on_Salt_servers&amp;diff=1144</id>
		<title>Operations grimoire/Create and revoke user accounts on Salt servers</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Create_and_revoke_user_accounts_on_Salt_servers&amp;diff=1144"/>
		<updated>2023-04-02T18:26:28Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Create an user ==&lt;br /&gt;
# Add entry to shellusers in the &amp;lt;code&amp;gt;pillar/core/users.sls&amp;lt;/code&amp;gt;&lt;br /&gt;
## uid: you can run &amp;lt;code&amp;gt;utils/next-uid.py&amp;lt;/code&amp;gt; to generate one (if not, take the greatest 2xxx and do +1)&lt;br /&gt;
## shell: default shell is bash, other availables are fish / nologin / tcsh / zsh&lt;br /&gt;
## fullname: this is a public information, so publish only if the user is comfortable with that (ie if they publish the full name elsewhere like DevCentral, GitHub, etc.)&lt;br /&gt;
&lt;br /&gt;
== Revoke an user ==&lt;br /&gt;
# Keep the entry in shellusers at pillar/core/users.sls &lt;br /&gt;
# Append the element to the &#039;revokedusers&#039; list&lt;br /&gt;
# Remove it from relevant groups in pillar/core/groups.sls&lt;br /&gt;
&lt;br /&gt;
== Assign an user to a group ==&lt;br /&gt;
If you only put an user in shellusers, that&#039;s a no op operation.&lt;br /&gt;
&lt;br /&gt;
Each server take users through the shellgroups dictionary in pillar/core/groups.sls.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Group !! Description !! Example of servers&lt;br /&gt;
|-&lt;br /&gt;
| shell || Shell access on Eglide (e.g. for IRC purpose) || eglide.org&lt;br /&gt;
|-&lt;br /&gt;
| ops || Nasqueron Operations || Access everywhere&lt;br /&gt;
|-&lt;br /&gt;
| nasquenautes || Shell access on Nasqueron dev servers || ysul, WindRiver&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Generally, the target groups are `shell` or `nasquenautes`.&lt;br /&gt;
&lt;br /&gt;
Some specialized groups exist for a particular piece of software or service.&lt;br /&gt;
It&#039;s generally ignored when adding a new user.&lt;br /&gt;
&lt;br /&gt;
== Run the Salt ==&lt;br /&gt;
If you&#039;ve access to the Salt primary server in production:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;salt eglide state.apply roles/core/users&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or locally while Eglide doesn&#039;t have have a direct access to the Salt primary server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo salt-call --local state.apply roles/shellserver/users&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Take care of the SSH key changes during the output. Please notify concerned users about any SSH keys change when running this.&lt;br /&gt;
&lt;br /&gt;
See [[Operations grimoire/Deploy with Salt]].&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
	<entry>
		<id>https://agora.nasqueron.org/index.php?title=Operations_grimoire/Create_and_revoke_user_accounts_on_Salt_servers&amp;diff=1143</id>
		<title>Operations grimoire/Create and revoke user accounts on Salt servers</title>
		<link rel="alternate" type="text/html" href="https://agora.nasqueron.org/index.php?title=Operations_grimoire/Create_and_revoke_user_accounts_on_Salt_servers&amp;diff=1143"/>
		<updated>2023-04-02T18:26:07Z</updated>

		<summary type="html">&lt;p&gt;DorianWinty: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Create an user ==&lt;br /&gt;
# Add entry to shellusers in the &amp;lt;code&amp;gt;pillar/core/users.sls&amp;lt;/code&amp;gt;&lt;br /&gt;
## uid: you can run &amp;lt;code&amp;gt;utils/next-uid.py&amp;lt;/code&amp;gt; to generate one (if not, take the greatest 2xxx and do +1)&lt;br /&gt;
## shell: default shell is bash, other availables are fish / nologin / tcsh / zsh&lt;br /&gt;
## fullname: this is a public information, so publish only if the user is comfortable with that (ie if they publish the full name elsewhere like DevCentral, GitHub, etc.)&lt;br /&gt;
&lt;br /&gt;
== Revoke an user ==&lt;br /&gt;
# Keep the entry in shellusers at pillar/core/users.sls &lt;br /&gt;
# Append the element to the &#039;revokedusers&#039; list&lt;br /&gt;
# Remove it from relevant groups in pillar/core/groups.sls&lt;br /&gt;
&lt;br /&gt;
== Assign an user to a group ==&lt;br /&gt;
If you only put an user in shellusers, that&#039;s a no op operation.&lt;br /&gt;
&lt;br /&gt;
Each server take users through the shellgroups dictionary in pillar/core/groups.sls.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Group !! Description !! Example of servers&lt;br /&gt;
|-&lt;br /&gt;
| shell || Shell access on Eglide (e.g. for IRC purpose) || eglide.org&lt;br /&gt;
|-&lt;br /&gt;
| ops || Nasqueron Operations || Access everywhere&lt;br /&gt;
|-&lt;br /&gt;
| nasquenautes || Shell access on Nasqueron dev servers || ysul, WindRiver&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Generally, the target groups are `shell` or `nasquenautes`.&lt;br /&gt;
&lt;br /&gt;
Some specialized groups exist for a particular piece of software or service.&lt;br /&gt;
It&#039;s generally ignored when adding a new user.&lt;br /&gt;
&lt;br /&gt;
== Run the Salt ==&lt;br /&gt;
If you&#039;ve access to the Salt primary server in production:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;salt eglide state.apply oles/core/users&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or locally while Eglide doesn&#039;t have have a direct access to the Salt primary server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo salt-call --local state.apply roles/shellserver/users&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Take care of the SSH key changes during the output. Please notify concerned users about any SSH keys change when running this.&lt;br /&gt;
&lt;br /&gt;
See [[Operations grimoire/Deploy with Salt]].&lt;/div&gt;</summary>
		<author><name>DorianWinty</name></author>
	</entry>
</feed>