Di seguito la procedura da me utilizzata per installare e configurare la cosidetta WebMail, ossia l’applicazione web che mi permetterà di leggere e inviare mail. Capace, quindi, di interfacciarsi sia con l’MTA (OpenSMTP), che con l’MDA (Dovecot). Se siete interessati all’argomento vi consiglio di leggere le precedenti 2 parti.
Ho scelto di utilizzare RainLoop perchè è un software libero, perchè è manutenuto, ha un nutrita comunità di utenti che lo utilizza, perchè è scritto in PHP (sicchè necessita di un’architettura LAMP) e non ha grandi dipendenze.

Come prima cosa è necessario, scaricare l’ultima versione nella DocumentRoot di Apache HTTPd.
Rainloop è distribuito come archivio zip da decomprimere. E’ necessario quindi preinstallare sul server, anche temporaneamente, il comando unzip prima di iniziare.
alfree$ doas pkg_add unzip
quirks-7.147 signed on 2026-01-17T21:24:26Z
Ambiguous: choose package for unzip
a 0: <None>
1: unzip-6.0p18
2: unzip-6.0p18-iconv
Your choice: 1
unzip-6.0p18: ok
alfree$
Dopodichè effettuo il download con un qualsiasi client HTTP, wget sftp o altri.
L’archivio va copiato nella DocumentRoot del WebServer, chiaramente. Nel mio caso (la documentoroot) coincide o comunque è all’interno della home-directory dell’utente che amministra il dominio granito.org.uk. Creerò la directory dedicata al sottominio mail.granito.org.uk, al cui interno ci copierò rainloop.
alfree$ doas su - granito
alfree$ mkdir mail.granito.org.uk
alfree$ cd mail.granito.org.uk
alfree$ ftp https://www.rainloop.net/repository/webmail/rainloop-latest.zip
Trying 188.114.96.0...
Requesting https://www.rainloop.net/repository/webmail/rainloop-latest.zip
100% |****************************************************************************************************************************************************************| 6887 KB 00:00
7052808 bytes received in 0.56 seconds (11.94 MB/s)
alfree$
alfree$ unzip rainloop-latest.zip
Archive: rainloop-latest.zip
creating: data/
inflating: index.php
creating: rainloop/
inflating: data/EMPTY
inflating: data/VERSION
creating: rainloop/v/
creating: rainloop/v/1.17.0/
creating: rainloop/v/1.17.0/app/
[__CUT__]
inflating: rainloop/v/1.17.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/collection.png
inflating: rainloop/v/1.17.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/file.png
inflating: rainloop/v/1.17.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/parent.png
inflating: rainloop/v/1.17.0/app/libraries/SabreForRainLoop/DAV/Browser/assets/icons/principal.png
alfree$
Creazione dell’identity SSL per il dominio mail.granito.org.uk
Creo __TEMPORANEAMENTE__ un VirtualHost HTTP, per il nuovo dominio mail.granito.org.uk, con DocumentRoot ~/mail.granito.org.uk
alfree$ cat granito-org-uk.tcp.conf
__CUT__
#.---------------------------------------------------------------.
#| VirtualHost : MAIL.GRANITO.ORG.UK |
#'---------------------------------------------------------------'
#<VirtualHost mail.granito.org.uk:80>
<VirtualHost *:80>
ServerAdmin webmaster@granito.org.uk
DocumentRoot "/home/granito/mail.granito.org.uk"
ServerName mail.granito.org.uk
ServerAlias www.mail.granito.org.uk
ErrorLog "/home/granito/logs/mail.granito.org.uk-error_log"
CustomLog "/home/granito/logs/mail.granito.org.uk-access_log" common
<Directory /home/granito/mail.granito.org.uk/>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Require all granted
</Directory>
</VirtualHost>
# :::... EndVirtualHost
alfree$
Tale VirtualHost mi servirà per farmi firmare la richiesta di certificato SSL dalla Certification Anthority.
Creare la cartella .well-known/acme-challenge sotto la DocumentRoot del dominio mail.granito.org.uk. Assegnare la directory all’owner di processo del web-server (Apache HTTPd) con permessi 755, in maniera tale che Apache HTTPd posso anche scriverci.
alfree$ doas mkdir -p /home/granito/mail.granito.org.uk/.well-known/acme-challenge
alfree$ doas chown -R www:www /home/granito/mail.granito.org.uk/.well-known
alfree$ doas chmod -R 755 /home/granito/mail.granito.org.uk/.well-known
alfree$ ls -la /home/granito/mail.granito.org.uk/ | grep .well-known
drwxr-xr-x 2 www www 512 Jan 20 01:56 .well-known
alfree$
Dopodichè riavviare nuovamente Apache2
alfree$ doas rcctl restart apache2
apache2(ok)
apache2(ok)
Generare l’identity SSL firmata dalla CA letsencrypt, tramite il comando :
alfree$ cat mail.granito.org.uk_acme-client.sh
doas acme-client -v -f /home/granito/ssl/letsencrypt/prod/mail.granito.org.uk_acme-client.conf mail.granito.org.uk
alfree$ cat mail.granito.org.uk_acme-client.conf
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/home/granito/ssl/letsencrypt/prod/letsencrypt-privkey.pem"
}
domain mail.granito.org.uk {
###alternative names { www.mail.granito.org.uk }
domain key "/home/granito/ssl/letsencrypt/prod/mail.granito.org.uk.key"
domain certificate "/home/granito/ssl/letsencrypt/prod/mail.granito.org.uk.crt"
domain full chain certificate "/home/granito/ssl/letsencrypt/prod/mail.granito.org.uk.fullchain.pem"
challengedir "/home/granito/mail.granito.org.uk/.well-known/acme-challenge"
sign with letsencrypt
}
alfree$
------------------ ovvio procedura
alfree$ ./mail.granito.org.uk_acme-client.sh
acme-client: https://acme-v02.api.letsencrypt.org/directory: directories
acme-client: acme-v02.api.letsencrypt.org: DNS: 172.65.32.248
acme-client: acme-v02.api.letsencrypt.org: DNS: 2606:4700:60:0:f53d:5624:85c7:3a2c
acme-client: account key: https://acme-v02.api.letsencrypt.org/acme/acct/1953532676
acme-client: https://acme-v02.api.letsencrypt.org/acme/finalize/1953532676/471372741596: certificate
acme-client: order.status 3
acme-client: https://acme-v02.api.letsencrypt.org/acme/cert/0536a5b03225684d5f0b15be9a00ef6810d9: certificate
acme-client: /home/granito/ssl/letsencrypt/prod/mail.granito.org.uk.crt: created
acme-client: /home/granito/ssl/letsencrypt/prod/mail.granito.org.uk.fullchain.pem: created
alfree$
Abbiamo ottenuto per il nostro nuovo dominio l’identity SS firmata da una CA riconosciuta. Questa ci permetterà di renderci piu’ presentabili agli MTA ed MDA che contatteranno il nostro servizio di posta, oltre che per configurare la comunicazione sicura alla nostra webmail.
alfree$ ls -lta mail.granito.org.uk.*
-r--r--r-- 1 root granito 3957 Jan 20 02:17 mail.granito.org.uk.fullchain.pem
-r--r--r-- 1 root granito 2156 Jan 20 02:17 mail.granito.org.uk.crt
-r-------- 1 root granito 3272 Jan 20 02:15 mail.granito.org.uk.key
Riprendiamo la configurazione del VirtualHost Apache2, per completare la configurazione del canale, stavolta attivando SSL.
alfree$ doas cat /home/granito/apache-virtualhost/granito-org-uk.ssl.conf
__CUT__
#---------------------------------------------------------------------#
# VirtualHost : MAIL.GRANITO.ORG.UK #
#---------------------------------------------------------------------#
<VirtualHost *:443>
ServerAdmin admin@granito.org.uk
DocumentRoot "/home/granito/mail.granito.org.uk"
ServerName mail.granito.org.uk
##ServerAlias www.mail.granito.org.uk
ErrorLog "/home/granito/logs/mail.granito.org.uk-error_log"
TransferLog "/home/granito/logs/mail.granito.org.uk-access_log"
SSLEngine on
SSLCertificateKeyFile "/home/granito/ssl/letsencrypt/prod/mail.granito.org.uk.key"
SSLCertificateFile "/home/granito/ssl/letsencrypt/prod/mail.granito.org.uk.crt"
SSLCertificateChainFile "/home/granito/ssl/letsencrypt/prod/mail.granito.org.uk.fullchain.pem"
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog "/home/granito/logs/mail.granito.org.uk-ssl_request_log" \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
<Directory /home/granito/mail.granito.org.uk/>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Require all granted
</Directory>
</VirtualHost>
# :::... EndVirtualHost
alfree$
…e nuovamente riavviamo apache2, per acquisire la nuova configurazione.
Puntando con un Browser alla webmail dovreste vedere la maschera di login

L’installazione base è completata.
Configurazione di Rainloop
__DA COMPLETARE__