# Nextcloud Server

Un `server privato virtuale` (VPS) è una macchina che ospita tutto il software e i dati necessari per l'esecuzione di un'applicazione o di un sito Web. Si chiama virtuale perché consuma solo una parte delle risorse fisiche strutturali del server, le quali sono gestite da un fornitore terzo. 

Un VPS è possibile acquistarlo, ad esempio, da [OVH](https://www.ovhcloud.com/it/vps/). Sempre da OVH è possibile anche acquistare un [dominio](https://www.ovh.it/order/webcloud/?#/webCloud/domain/select?selection=~()).

Altri provider possono essere [Contabo](https://contabo.com/en/vps/) oppure [Hetzner](https://www.hetzner.com/cloud).

Su OVH, una volta acquistato il VPS e il nome di dominio, occorre, dal menù `Zone DNS/my.domain.com/Reindirizzamento`, reindirizzare il proprio dominio (o un sottodominio) all'indirizzo ip della VPS, così che, digitando sulla barra degli indirizzi del browser `my.domain.com`, sia possibile raggiungere il servizio installato sul VPS, in questo caso Nextcloud.

## Requisiti

Questi i requisiti della versione 27 di Nextcloud:

- Operating System (64-bit): Debian 12;
- Database: PostgreSQL 10/11/12/13/14/15;
- Webserver: nginx with php-fpm;
- PHP Runtime: 8.2 (recommended)

Ulteriori informazioni: [Requisiti](https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html)

## Chiavi ssh

Sul proprio computer, creare la chiave ssh per accedere alla VM:

```bash
> cd
> ssh-keygen -f .ssh/debian -t ed25519
```

dove `debian` indica il nome da dare alla propria chiave.

Questa la configurazione:

```bash
 > cat .ssh/config 

Host debian
		hostname ip_del_vps
		user root
		IdentityFile /home/user/.ssh/vps-debian
		TCPKeepAlive yes
		port 1267
```
Accedere alla VM e inserire la propria chiave ssh pubblica:

```bash
vim .ssh/authorized_keys
```
Quindi decommentare le seguenti righe nel file `/etc/ssh/sshd_config`:

```bash
> cat /etc/ssh/sshd_config | grep -v ^#
Port 1267
PubkeyAuthentication yes
PasswordAuthentication no
```

avendo cura di specificare una porta differente dalla 22 per la connessione ssh e di non permettere l'autenticazione tramite password, bensì solo con le chiavi.

Ora è possibile connettersi al vps tramite chiave ssh:

```bash
ssh debian
```

## Preconfigurazioni

Cambiare la password di root col comando

```bash
passwd
```
Quindi eseguire il seguente comando

```bash
apt update && apt upgrade && apt install vim unzip rsync cron -y && echo "export TERM=xterm-256color" >> ~/.bashrc
```

## Configurazione firewall

Leggere questi passaggi per configurare [Network Firewall](https://help.ovhcloud.com/csm/it-dedicated-servers-firewall-network?id=kb_article_view&sysparm_article=KB0043454)

```bash
apt install ufw && ufw enable &&
ufw default allow outgoing && ufw default deny incoming &&
```

Si dovrebbe ottenere una situazione simile a questa:

```bash
 > ufw status numbered 
Status: active

     To                         Action      From
     --                         ------      ----
[ 2] 1267/tcp                   ALLOW IN    Anywhere                  
[ 4] 1267/tcp (v6)              ALLOW IN    Anywhere (v6)    
```

Così facendo, di default il traffico in ingresso è bloccato, a eccezione delle porte 1267, per ssh, 80 e 443 per nginx

Per altre configurazioni di sicurezza: [Mettere in sicurezza un VPS](https://help.ovhcloud.com/csm/it-vps-security-tips?id=kb_article_view&sysparm_article=KB0047709) e anche [Setup fail2ban](https://docs.nextcloud.com/server/21/admin_manual/installation/harden_server.html?highlight=fail2ban#setup-fail2ban)

## fail2ban

Disabilitare l'opzione `'auth.bruteforce.protection.enabled' => 'false',` nel file `/var/www/html/nextcloud/config/config.php`

Quindi

```bash
apt install fail2ban
```

Dopo aver installato il pacchetto, creare i file seguenti:

```bash
 > cat /etc/fail2ban/filter.d/nextcloud.local 
[Definition]
_groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"

 > cat /etc/fail2ban/jail.d/nextcloud.local 
[nextcloud]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nextcloud
#Number of retrys before to ban
maxretry = 3
#time in seconds
bantime = 36000
findtime = 36000
#Log path, on Ubuntu usually is following
logpath = /var/www/nextcloud/data/nextcloud.log

 > cat /etc/fail2ban/jail.d/defaults-debian.conf 
[sshd]
enabled = true
port = 1222
filter = sshd
maxretry = 3
findtime = 5m
bantime  = 60m

# Se un tentativo di connessione SSH fallisce tre volte in cinque minuti, il periodo di divieto degli IP sarà di 60 minuti.
```

Quindi abilitare e riavviare il servizio:

```bash
 > systemctl enable --now fail2ban
 > systemctl restart fail2ban

 > systemctl status fail2ban.service 
● fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
     Active: active (running) since Sun 2023-10-22 17:44:02 UTC; 5min ago
       Docs: man:fail2ban(1)
   Main PID: 58185 (fail2ban-server)
      Tasks: 7 (limit: 2295)
     Memory: 14.2M
        CPU: 339ms
     CGroup: /system.slice/fail2ban.service
             └─58185 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

ott 22 17:44:02 vps-971850be systemd[1]: Started fail2ban.service - Fail2Ban Service.
ott 22 17:44:02 vps-971850be fail2ban-server[58185]: 2023-10-22 17:44:02,748 fail2ban.configreader   [58185]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
ott 22 17:44:02 vps-971850be fail2ban-server[58185]: Server ready
```

## Installazione 

### nginx

Per prima cosa, disabilitare `apache`, nel caso fosse installato:

```bash
systemctl stop apache2
systemctl disable apache2
```

Questi i comandi per installare e abilitare il web-server `nginx`:

```bash
apt install nginx -y
systemctl enable --now nginx
systemctl status nginx
```

Infine:

```bash
ufw allow "Nginx Full" && ufw allow 1267/tcp
```

### php e moduli

```bash
apt install php php-fpm -y
systemctl enable --now php8.2-fpm
systemctl status php8.2-fpm
```

#### Moduli php aggiuntivi

```bash
apt install php-zip php-dom php-curl php-gd php-mbstring php-gmp php-bcmath php-imagick php-apcu php-intl libmagickcore-6.q16-6-extra
```

#### Configurazione php-fpm

Decommentare le seguenti righe:

```bash
> cat /etc/php/8.2/fpm/pool.d/www.conf

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
```

#### Configurazione php

Importante che siano presenti le righe sottostanti, per evitare errori successivamente:

```bash
 > cat /var/www/nextcloud/config/config.php 
 
<?php
$CONFIG = array (

[...]

  'trusted_domains' => 
  array (
    0 => 'my.domain.com',
  ),
  'datadirectory' => '/var/www/nextcloud/data',
  'dbtype' => 'pgsql',
  'version' => '27.1.2.1',
  'overwrite.cli.url' => 'https://my.domain.com/',
  'default_phone_region' => 'IT',
  'trashbin_retention_obligation' => 'autoi, 2',
  # Il cestino viene svuotato in automatico ogni due giorni
  # https://docs.nextcloud.com/server/27/admin_manual/configuration_server/caching_configuration.html
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'memcache.locking' => '\\OC\\Memcache\\APCu',
  'filelocking.enabled' => true,
  'auth.bruteforce.protection.enabled' => false,
  'logtimezone' => 'Europe/Rome',

[...]
  
	'log_type' => 'file',
  'logfile' => '/var/log/nextcloud-error.log',
  'loglevel' => 2,

[...]
```

### Postgresql

```bash
apt install postgresql postgresql-contrib libpq-dev php-pgsql
```

#### Configurazione del database

```sql
sudo -u postgres psql -d postgres

CREATE USER ncuser WITH PASSWORD 'PASSWORD' CREATEDB;
CREATE DATABASE nextcloud TEMPLATE template0 ENCODING 'UTF8';
ALTER DATABASE nextcloud OWNER TO ncuser;
GRANT ALL PRIVILEGES ON DATABASE nextcloud TO ncuser;
GRANT ALL PRIVILEGES ON SCHEMA public TO ncuser;

exit
```

Come da [documentazione](https://docs.nextcloud.com/server/latest/admin_manual/configuration_database/linux_database_configuration.html#postgresql-database), modificare la configurazione del modulo `pgsql.ini` nel modo seguente:

```bash
 > cat /etc/php/8.2/mods-available/pgsql.ini
 
# configuration for PHP PostgreSQL module
extension=pdo_pgsql.so
extension=pgsql.so

[PostgresSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
```

Cambiare quindi la password dell'utente postgres:

```bash
passwd postgres 
```

### Nextcloud

```bash
mkdir /var/www/nextcloud
cd /var/www/
wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip 
rm latest.zip 
chown -R www-data:www-data /var/www/nextcloud
```
In questo modo viene creata la cartella `/var/www/nextcloud`, qui scaricata ed estratta l'ultima versione disponibile di Nextcloud. Infine, ricorsivamente, la cartella viene assegnata all'utente `www-data`.

#### Configurazione

Creare il file `/etc/nginx/sites-available/nextcloud`, come da [documentazione uffic iale](https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html#nextcloud-in-the-webroot-of-nginx). In particolare, modificare le prime righe nel modo seguente:

```bash
 > cat /etc/nginx/sites-enabled/nextcloud 
 
upstream php-handler {
    #server 127.0.0.1:9000;
    server unix:/var/run/php/php8.2-fpm.sock;
}

# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
    "" "";
    default "immutable";
}


server {
    if ($host = my.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;
    server_name my.domain.com;

    # Prevent nginx HTTP Server Detection
    server_tokens off;

    # Enforce HTTPS
    return 301 https://$server_name$request_uri;


}

server {
    listen 443      ssl http2;
    listen [::]:443 ssl http2;
    server_name my.domain.com;

    # Path to the root of your installation
    root /var/www/nextcloud;

[...]
```

Avendo cura di inserire al posto di `my.domain.com` il proprio dominio.

Quindi dare il comando seguente per creare il link simbolico:

```bash
ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/nextcloud
```

### Certificati ssl

Certificato autofirmato con openssl

```bash

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/nginx/cloud.key -out /etc/ssl/nginx/cloud.crt
```
I due certificati si troveranno in:

```bash
/etc/ssl/nginx/cloud.crt
/etc/ssl/nginx/cloud.key
```

Installare certbot che permetterà di configurare e rinnovare automaticamente i certificati ssl:

```bash
apt install certbot python3-certbot-nginx
certbot --nginx

# Per testare il rinnovo automatico

certbot renew --dry-run

 > cat /etc/cron.d/certbot 

# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
#
# Important Note!  This cronjob will NOT be executed if you are
# running systemd as your init system.  If you are running systemd,
# the cronjob.timer function takes precedence over this cronjob.  For
# more details, see the systemd.timer manpage, or use systemctl show
# certbot.timer.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew --no-random-sleep-on-renew
```

Per maggiori dettagli, leggere [qui](https://certbot.eff.org/instructions?ws=nginx&os=debiantesting).

Per verificare che tutto funzioni correttamente:

```bash
> systemctl restart php8.2-fpm.service && systemctl restart nginx.service 

> nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

## Installazione web di Nextcloud

Se tutta la relativa configurazione del server è completa, è possibile accedere all'installazione di Nextcloud con il browser web.

- Aprire il browser web e digitare l'indirizzo URL dell'installazione di Nextcloud, ad esempio https://my.domain.com
- Digitare i dettagli del nome database, utente e password e attendere il completamento dell'installazione;
- Se l'installazione ha esito positivo, verrà caricata la dashboard di Nextcloud;
- All'interno di *Impostazioni di amministrazione/Riepilogo* vengono visualizzati eventuali errori o consigli. È inoltre possibile procedere con gli aggiornamenti di versione

## Troubleshooting

Assicurarsi di decommentare le seguenti righe nel file '/etc/php/8.2/fpm/php.ini'

```bash
> cat /etc/php/8.2/fpm/php.ini | grep -v '^;'

[PHP]
max_execution_time = 30
max_input_time = 60
memory_limit = 512M
post_max_size = 8M

odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096

[opcache]
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=1
opcache.save_comments=1
```

### cron

Come da [documentazione](https://docs.nextcloud.com/server/19/admin_manual/configuration_server/background_jobs_configuration.html), assicurarsi di configurare le operazioni in background correttamente. `Cron` è l'impostazione consigliata:

```bash
 > crontab -u www-data -e

 > crontab -u www-data -l

*/5  *  *  *  * php -f /var/www/nextcloud/cron.php 
```

Con questa configurazione viene utilizzato il servizio cron di sistema per invocare il file `cron.php` ogni 5 minuti.

### APCu

Appendere nel file `/etc/php/8.2/cli/php.ini` la seguente riga:

```bash
apc.enable_cli = 1
```

Per maggiori informazioni, leggere [qui](https://serverok.in/nextcloud-apcu-not-available-for-local-cache).

Possiamo vedere che tutti i requisiti della versione 27 sono rispettati:

```bash
> cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"

> nginx -v
nginx version: nginx/1.22.1

> php -v
PHP 8.2.7 (cli) (built: Jun  9 2023 19:37:27) (NTS)

 > psql -V
psql (PostgreSQL) 15.3 (Debian 15.3-0+deb12u1)
```

## Applicazioni consigliate

- `Two-Factor TOTP Provider` per abilitare l'autenticazione a due fattori;
- `News` per un lettore di feed rss;
- `GPodder Sync` per la sincronizzazione dei podcast tramite l'app per Android AntennaPod;
- `Default encryption module` per abilitare la cifratura dei file;
- `Collabora Online - Built-in CODE Server` per un word processor (programma di videoscrittura);
- `Bookmarks`;
- `Brute-force settings` ([https://github.com/nextcloud/bruteforcesettings](https://github.com/nextcloud/bruteforcesettings));
- `GeoBlocker`;
- `UnifiedPush Provider`;
- `Keeweb`

## Applicazioni mobile

- [Nextcloud](https://f-droid.org/it/packages/com.nextcloud.client/);
- [Nextcloud Notes](https://f-droid.org/it/packages/it.niedermann.owncloud.notes/);
- [News](https://f-droid.org/it/packages/de.luhmer.owncloudnewsreader/);
- [Bookmarks](https://f-droid.org/it/packages/org.schabi.nxbookmarks/);
- [AntennaPod](https://f-droid.org/it/packages/de.danoeh.antennapod/);
- [DAVx⁵](https://f-droid.org/it/packages/at.bitfire.davdroid/)

Per la configurazione di Nextcloud sul cellulare Android, seguire [questa guida](https://gitea.it/PicciHud/mywiki/src/branch/master/android/nextcloud.md), inserendo i dati della propria installazione.

## Collegamenti

- [https://noblogo.org/leguidenerd/guida-allinstallazione-di-nextcloud-con-server-nginx-e-database-postgresql](https://noblogo.org/leguidenerd/guida-allinstallazione-di-nextcloud-con-server-nginx-e-database-postgresql)
- [https://it.linux-console.net/?p=3273#gsc.tab=0](https://it.linux-console.net/?p=3273#gsc.tab=0)
- [https://guide.debianizzati.org/index.php/Installare_una_istanza_Nextcloud_su_server_Debian](https://guide.debianizzati.org/index.php/Installare_una_istanza_Nextcloud_su_server_Debian)
- [https://docs.nextcloud.com/server/27/admin_manual/installation/server_tuning.html#enable-php-opcache](https://docs.nextcloud.com/server/27/admin_manual/installation/server_tuning.html#enable-php-opcache)
- [https://docs.nextcloud.com/server/19/admin_manual/configuration_server/background_jobs_configuration.html](https://docs.nextcloud.com/server/19/admin_manual/configuration_server/background_jobs_configuration.html)
- [https://docs.nextcloud.com/server/27/admin_manual/configuration_server/caching_configuration.html](https://docs.nextcloud.com/server/27/admin_manual/configuration_server/caching_configuration.html)
- [https://serverok.in/nextcloud-apcu-not-available-for-local-cache](https://serverok.in/nextcloud-apcu-not-available-for-local-cache)
- [https://marsown.com/wordpress/fail2ban-protection-nextcloud/](https://marsown.com/wordpress/fail2ban-protection-nextcloud/)
- [https://gist.github.com/GAS85/957e0b1a4f30120225a7be09b173eb24](https://gist.github.com/GAS85/957e0b1a4f30120225a7be09b173eb24)
