Vivere Self-Hosted Parte I: Calendario


Self-Hosted, cos'è e perchè?

Partiamo sempre dalle basi: Che sia cartaceo che elettronico, prima o poi a chiunque servirà un calendario.
Alphabet (azienda parente di Google) è sempre così gentile da donarcene uno in fase di creazione di un account Google.
Stessa cosa per Microsoft ma con un account Outlook. Ma quale sono le implicazioni?

Da qualche tempo ho iniziato a dismettere molti servizi online tra cui il mio account Google, Microsoft, Protonmail... affinchè potessi il più possibile contare su me stesso, ovvero mettere in piedi un'infrastruttura per erogare servizi a me ed ad amici/parenti.

Perchè realizzare ciò? Ci sono svariati motivi: il primo è sicuramente dovuto alle preoccupazioni sulla Privacy: servizi offerti da Google/Microsoft fanno largo uso delle informazioni che carichiamo sulle loro piattaforme (e-mail, calendario, storage cloud...) per profilarci per campagne di marketing ed effettuare training a reti neurali.

Successivamente ci permette di imparare nuove tecnologie e creare qualcosa creato ad-hoc per le nostre necessità.

Infine, mettere in piedi dei servizi, curarli e mantenerli è piacevole! In qualunque momento posso comprare della pasta fresca in negozio, ma vogliamo mettere il fare da zero delle tagliatelle e fare il nostro sugo di pomodoro?

Cosa ci serve?

Il S.O. di mia scelta è Debian GNU/Linux 12, sul quale installeremo:

Iniziamo aggiornando i Repositories ed installando i pacchetti necessari:

apt-get update && apt-get install apache2 php-fpm php-sqlite3 php-sabre-dav git sqlite3 unzip php libapache2-mod-php

Configuriamo SSL mediante un certificato self-signed. Lanciando il primo comando ci verranno chieste alcune informazioni

openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/apache2/ssl/selfsigned.key -out /etc/apache2/ssl/selsigned.crt
cat /etc/apache2/ssl/selfsigned.key /etc/apache2/ssl/selsigned.crt > /etc/apache2/ssl/cert.pem
a2enmod rewrite
a2enmod ssl

Baïkal

Recuperiamo la release corrente di Baïkal da GitHub, estraiamola e posizioniamola sotto le directory web:

wget -O /tmp/baikal-0.9.5.zip https://github.com/sabre-io/Baikal/releases/download/0.9.5/baikal-0.9.5.zip
unzip /tmp/baikal-0.9.5.zip
mv /tmp/baikal /var/www/baikal

Ora assegnamo www-data come proprietario della directory, per permettere a Apache2 di operarci

chown -R www-data:www-data /var/www/baikal/

Configuriamo il file di VirtualHost di Apache (/etc/apache2/sites-available/000-default.conf)


    <VirtualHost *:443>
      DocumentRoot /var/www/baikal/html
      ServerName [nome-del-nostro-sito]
  
      RewriteEngine On
      RewriteRule /.well-known/carddav /dav.php [R=308,L]
      RewriteRule /.well-known/caldav  /dav.php [R=308,L]
      # Aggiungiamo questa regola per permettere l'accesso alla pagina amministrativa di Baikal
      # solo agli indirizzi IP sorgente 10.0.XXX.YYY
      <Directory "/var/www/baikal/html/admin">
        Require ip 10.0
      </Directory>
      <Directory "/var/www/baikal/html">
          Options None
          Options +FollowSymlinks
          AllowOverride None
          Require all granted
      </Directory> 
      <IfModule mod_expires.c>
          ExpiresActive Off
      </IfModule>
      # Di seguito le configurazioni SSL 
      SSLEngine On
      SSLCertificateFile    /etc/apache2/ssl/cert.pem
      SSLCertificateKeyFile /etc/apache2/ssl/selfsigned.key
  </VirtualHost>
  
  

Lanciamo ora un bel sudo systemctl restart apache2 ed accediamo all'interfaccia web del server via HTTPS. Potremmo ricevere un warning dal browser indicandoci che il certificato è self-signed. Accettiamolo e proseguiamo.

Atterreremo sul setup wizard di Baikal. Configuriamolo come segue:

Inseriamo due volte la password di amministratore e premiamo su Save changes.

AgenDAV

Iniziamo installando i pacchetti necessari:

sudo apt-get install php-curl php-mbstring php-mcrypt php-tokenizer php-xml

Quindi procediamo scaricando ed estraendo l'ultima release di AgenDAV

wget -O /tmp/agendav-2.6.0.tar.gz https://github.com/agendav/agendav/releases/download/2.6.0/agendav-2.6.0.tar.gz
tar xvf /tmp/agendav-2.6.0.tar.gz
mv /tmp/agendav-2.6.0 /var/www/agendav

A causa di un bug andiamo ad editare il file /var/www/agendav/web/vendor/guzzlehttp/guzzle/src/Client.php modificando la riga:

$options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
in
$options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_ANY;

Configuriamo il Timezone sotto /etc/php/8.2/apache2/php.ini adeguando date.timezone = Europe/Rome


Creiamo un database SQLite eseguendo:

Configuriamo il file di VirtualHost di Apache (/etc/apache2/sites-available/000-default.conf) come di seguito:


    <VirtualHost *:1443>
      DocumentRoot /var/www/agendav/web/public
      ServerName [nome-del-nostro-server]
      ErrorLog /var/www/agendav/web/var/log/agendav_error_log
      CustomLog /var/www/agendav/web/var/log/agendav_access_log common
      <Directory "/var/www/agendav/web">
       Require all granted
      </Directory>
      <Location />
        # SetEnv AGENDAV_ENVIRONMENT=dev
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^ index.php [QSA,L]
      </Location>
       SSLEngine On
       SSLCertificateFile /etc/apache2/ssl/cert.pem
       SSLCertificateKeyFile /etc/apache2/ssl/selfsigned.key
     </VirtualHost>  
  

Ora lanciamo cp /var/www/agendav/web/config/default.settings.php /var/www/agendav/web/config/settings.php ed andiamo ad editare il nuovo file. Io uso le seguenti impostazioni:


// Puntiamo al database sqlite creato poco fa
$app['db.options'] = [
	'path' => '/var/www/agendav/database/agendav.sqlite',
        'driver' => 'pdo_sqlite',
];

// Definiamo l'URL di base dell'istanza Baikal dove deve essere effettuata l'autenticazione e le operazioni sul calendario
$app['caldav.baseurl'] = 'https://[hostname-o-ip-del-nostro-server-Baikal]/dav.php';

// Metodo di autenticazione (digest)
$app['caldav.authmethod'] = 'digest';

// Siccome abbiamo creato un certificato self-signed per Baikal, è necessario ignorare la validità di esso da parte di AgenDAV.
$app['caldav.certificate.verify'] = false;

// Timezone predefinita
$app['defaults.timezone'] = 'Europe/Rome';

// Lingua predefinita (italiano)
$app['defaults.language'] = 'it_IT';

// Formato orario (12 ore / 24 ore) '12' / '24'
$app['defaults.time_format'] = '24';

// Formato data (giorno-mese-anno)
$app['defaults.date_format'] = 'dmy';

// Primo giorno della settimana. 0 (Domenica), 1 (Lunedì)
$app['defaults.weekstart'] = 1;

// Vedere il numero delle settimane. true/false
$app['defaults.show_week_nb'] = false;

// Vista predefinita (month, week, day or list)
$app['defaults.default_view'] = 'month';

Modifichiamo i permessi di lettura/scrittura della directory con chown -R www-data:www-data web/ && chmod -R 750 web/var/

Creiamo le tabelle nel database SQLite lanciando php /var/www/agendav/agendavcli migrations:migrate e confermando.

La prova del nove.

Accediamo ora all'interfaccia amministrativa di Baikal all'indirizzo https://ipdelserver:443/admin. Logghiamoci come admin e premiamo su Users and resources

Clicchiamo su + Add user, compiliamo i dati e premiamo su Save changes.

Ora accediamo sull'interfaccia di Agendav all'indirizzo https://ipdelserver:1443/. Logghiamoci con l'utenza appena creata e potremo finalmente utilizzare il nostro calendario!

Software Applicativi

In generale, quasi tutti i software moderni di gestione di posta elettronica e calendario hanno un connettore CalDAV, ma prenderemo in considerazione Mozilla Thunderbird e Etar per Android.

Mozilla Thunderbird

La configurazione di Mozilla Thunderbird è chiara e facile:
  1. Aprire Thunderbird e dirigersi sulla sezione Calendario
  2. Premere su Nuovo calendario...
  3. Selezionare Sulla rete e premere Successivo
  4. Inserire nome utente ed indirizzo. Quest'ultimo è normalmente https://ipdelserver:443/dav.php/calendars/[nomeutente]/default. Premere Trova calendari
  5. In caso di certificati self-signed è probabile che venga richiesto più volte di accettarli.
  6. Inserire la password e premere OK
  7. Premere Sottoscrivi nella finestra che compare.

Etar