26. Install Nextcloud

by Double Bastion - Updated May 27, 2023

Nextcloud is a file sync and share application offering a variety of online collaboration tools. It allows syncing files from desktop/laptop/tablet/phone with a remote server, sharing them with other Nextcloud users or giving public access to them, editing office documents online, managing calendars, tasks, conducting surveys, creating forms, mounting external directories, sharing files with other Nextcloud instances through ‘federation sharing’, etc.

We recommend that you install only the apps described in this guide and only with the settings that we specify, as a starting point. When you will have a functional, well-configured Nextcloud installation, you can try adding other Nextcloud apps and experiment with different settings, if you need to. Nextcloud is very useful but it is difficult to install properly. You have to know in advance which ‘recommended’ settings should be applied and which shouldn’t, what apps deserve to be installed and what apps don’t.

To download the latest stable verstion of Nextcloud that is recommended to be installed on Debian navigate to the list of RED SCARF Suite components, get the number of the Nextcloud version (for example 25.0.6), then navigate to the Nextcloud changelog page, scroll down to the version found earlier (for example Version 25.0.6), right-click on the zip package that corresponds to that version (for example nextcloud-25.0.6.zip) and choose ‘Copy Link’ to copy the download link to the clipboard. Then use the copied link to download Nextcloud as shown below:

cd /tmp
wget https://download.nextcloud.com/server/releases/nextcloud-25.0.6.zip
unzip nextcloud-25.0.6.zip
rm nextcloud-25.0.6.zip
mv nextcloud /var/www/cloud.example.com

Replace example.com with the main domain hosted on your server. Please note that the /var/www/cloud.example.com directory will be created by the mv command. The mv command will move the nextcloud directory to /var/www and will change its name to cloud.example.com, so, you shouldn’t create the cloud.example.com directory manually in advance. If you create it in advance, the mv command will place the nextcloud directory inside the /var/www/cloud.example.com directory, which is not what you want.

Set the right ownership and permissions for the cloud.example.com directory and all its subdirectories, replacing example.com with the main domain hosted on your server:

chown -R www-data:www-data /var/www/cloud.example.com
find /var/www/cloud.example.com -type d -exec chmod 750 {} +
find /var/www/cloud.example.com -type f -exec chmod 640 {} +

26.1. Obtain a Let’s Encrypt SSL certificate

Please note that when you have configured Asterisk, you had to specify in /etc/asterisk/http.conf the path to the certificate file and private key file used to encrypt the connection to the domain where the browser phone resided. The two paths were looking like this:

tlscertfile=/etc/asterisk/keys/cert.pem
tlsprivatekey=/etc/asterisk/keys/privkey.pem

Since Asterisk only supports one certificate file in the tlscertfile parameter and one private key file in the tlsprivatekey parameter, it is expected that you have only one browser phone, on one domain, that you intend to connect to Asterisk. But what if you have two browser phones, on different domains, that you want to connect simultaneously to Asterisk ? For example: SIP Trip Phone on cloud.example.com, and Roundpin on roundpin.example.com ? Whose domain’s certificate and private key should you enter in the tlscertfile and tlsprivatekey parameters ? To overcome this problem and be able to connect both SIP Trip Phone and Roundpin simultaneously to Asterisk, you can obtain a Let’s Encrypt certificate for both cloud.example.com and roundpin.example.com and then mention the certificate file and private key file of that SSL certificate in the tlscertfile and tlsprivatekey parameters. There is no need for a wild card certificate, you just get one SSL certificate for the two different domains (they are in fact two different subdomains of the same domain, but they can be two entirely different domains).

First edit the Nginx server blocks configuration file:

nano /etc/nginx/sites-enabled/0-conf

Add the following temporary server blocks for cloud.example.com and roundpin.example.com at the end of the file:

server {
   listen 80;
   listen [::]:80;
   server_name cloud.example.com;

   location /.well-known/acme-challenge {
        root /var/www;
   }
}

server {
   listen 80;
   listen [::]:80;
   server_name roundpin.example.com;

   location /.well-known/acme-challenge {
        root /var/www;
   }
}

Replace example.com with the main domain hosted on your server. Restart Nginx:

systemctl restart nginx

Edit your DNS settings. Add an A entry and an AAAA entry for cloud.example.com and for roundpin.example.com . These entries will be similar to the entries you already have for doli.example.com. It’s just that instead of doli, you will enter cloud and roundpin respectively. Wait a few minutes until the DNS changes propagate.

Then, get one Let’s Encrypt SSL certificate for both cloud.example.com and roundpin.example.com by running:

certbot certonly --agree-tos --webroot -w /var/www/ -d cloud.example.com -d roundpin.example.com

Now is the moment to run the script created as explained in the Build and install Asterisk chapter, to copy the two files (/etc/letsencrypt/live/cloud.example.com/cert.pem and /etc/letsencrypt/live/cloud.example.com/privkey.pem) to the intended destination (/etc/asterisk/keys). So run:

/srv/scripts/copy-asterisk-cert

From now on, Asterisk can connect to the browser phones residing on cloud.example.com and roundpin.example.com . Of course, you will have to install SIP Trip Phone and Roundpin, as explained further down below, in order to be able to connect them to Asterisk and use them.

26.2. Configure Nginx for Nextcloud

Next, edit the /etc/nginx/sites-enabled/0-conf file again:

nano /etc/nginx/sites-enabled/0-conf

Replace the temporary server blocks for cloud.example.com and roundpin.example.com added earlier, with the following blocks:

server {
    listen  80;
    listen [::]:80;
    server_name cloud.example.com;
    server_tokens off;
    return  301 https://cloud.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name cloud.example.com;
    root /var/www/cloud.example.com;
    index index.php index.html /index.php$request_uri;


    ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/cloud.example.com/chain.pem;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    ssl_session_timeout 4h;
    ssl_session_cache shared:SSL:40m;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    ssl_stapling on;
    ssl_stapling_verify on;

    # Prevent Nginx HTTP Server Detection
    server_tokens off;

    # Set max upload size
    client_max_body_size 1G;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header Referrer-Policy                    "no-referrer"   always;
    add_header X-Content-Type-Options             "nosniff"       always;
    add_header X-Download-Options                 "noopen"        always;
    add_header X-Frame-Options                    "SAMEORIGIN"    always;
    add_header X-Permitted-Cross-Domain-Policies  "none"          always;
    add_header X-Robots-Tag                       "none"          always;
    add_header X-XSS-Protection                   "1; mode=block" always;

    fastcgi_hide_header X-Powered-By;

    location = /robots.txt {
        allow all;
    }

    location ^~ /.well-known {
        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }

        location /.well-known/acme-challenge    { root /var/www; try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }

        # Let Nextcloud's API for `/.well-known` URIs handle all other
        # requests by passing them to the front-end controller.
        return 301 /index.php$request_uri;
    }

    # Hide certain paths from clients
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

    location ~ \.php(?:$|/) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        try_files $fastcgi_script_name =404;
        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;  # Enable pretty urls
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
        fastcgi_max_temp_file_size 0;
    }

    location ~ \.(?:css|js|svg|gif|png|jpg|jpeg|ico|ttf|wasm|tflite|map|woff|woff2)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463";

        location ~ \.wasm$ {
            default_type application/wasm;
        }
    }

    location /remote {
        return 301 /remote.php$request_uri;
    }

    location / {
        try_files $uri $uri/ /index.php$request_uri;
    }

    # This is needed by SIP Trip Phone
    location /apps/sip_trip_phone/phone {
        try_files $uri /index.html;
    }

    # This is also needed by SIP Trip Phone
    location /apps/sip_trip_phone/lib {

        # prevents 502 bad gateway error
        proxy_buffers 8 32k;
        proxy_buffer_size 64k;

        proxy_pass http://0.0.0.0:8088/ws;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # enables WS support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    access_log /var/log/sites/cloud.example.com/access.log;
    error_log  /var/log/nginx/cloud.example.com.error.log notice;
}

Create the access log directory:

mkdir /var/log/sites/cloud.example.com

Create the /var/log/nextcloud logs directory and change ownership:

mkdir /var/log/nextcloud
chown -R www-data:root /var/log/nextcloud

Please note that Nextcloud will log data in 3 different logs: the errors in /var/log/nginx/cloud.example.com.error.log, the access data in /var/log/sites/cloud.example.com/access.log, and the detailed warnings and errors in /var/log/nextcloud/nextcloud.log. The latter is very important, because it will be automatically analyzed by ‘System Health and Security Probe’, to identify the viruses detected in the files uploaded to Nextcloud.

Restart Nginx:

systemctl restart nginx

Although we recommend serving Nextcloud on a subdomain as explained above and not on a subdirectory like example.com/nextcloud, we explain here how Nextcloud can be served on a subdirectory with Nginx. Also, even if we don’t recommend using Apache for any purpose, because it is by far inferior to Nginx, we describe here how Apache can be configured to serve Nextcloud on a subdomain or on a subdirectory.

26.3. Configure logrotate to rotate Nextcloud logs

nano /etc/logrotate.d/nginx

Add the following section at the bottom of this file:

/var/log/sites/cloud.example.com/access.log {
        missingok
        rotate 10
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        size 2M
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi; \
        endscript
        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript
}

Replace example.com with the main domain hosted on your server.

Next, create a new configuration file necessary to rotate the logs that will be stored in the /var/log/nextcloud directory:

nano /etc/logrotate.d/nextcloud

Add the following content inside this file:

/var/log/nextcloud/nextcloud.log {
        missingok
        rotate 5
        size 2M
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
}

26.4. Configure PHP for Nextcloud

Next open the /etc/php/7.4/fpm/pool.d/www.conf file for editing:

nano /etc/php/7.4/fpm/pool.d/www.conf

Uncomment the following lines to make them look like this:

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

Restart php7.4-fpm:

systemctl restart php7.4-fpm

26.5. Run the installation using the web interface

Use phpMyAdmin to create a new database and database user for Nextcloud. You can call the database nextcloud and the database user ncuser . Give ncuser all the rights over the nextcloud database, except GRANT, which is not necessary. Write down the name of the database, the database user and the password, because you will need them later.

To begin the installation, navigate to:

https://cloud.example.com

You will see the following screen:

In the two fields under ‘Create an admin account’ enter a username that you choose for the administrator account and a strong password. Avoid using the highly unsafe ‘admin’, ‘administrator’, ‘nextcloudadmin’, etc. usernames.

The content of the ‘Data folder’ field should be /var/www/cloud.example.com/data .

In the ‘Database user’ field enter the name of the user created earlier, ncuser in our example, in the ‘Database password’ field enter the user’s password, in the ‘Database name’ field enter the name of the database created earlier, nextcloud in our example, and in the ‘Database host’ field enter localhost, without specifying the port, which is not necessary.

Click on the ‘Install’ button.

The next screen will show a list of ‘Recommended apps’, such as ‘Calendar’, ‘Collabora Online’, etc. Don’t click the ‘Install recommended apps’ button, because you will install only the best apps that you will need from inside Nextcloud, so, you don’t need any ‘recommended’ app to be installed at this moment. Click the ‘Cancel’ button instead, to finish the installation.

After the installation you will see the ‘First run wizard’ popup window displaying general information about Nextcloud and when you will close it, the first screen will be that of the Dashboard:

Ignore the Dashboard and click on the Files icon in the upper left corner. The Files screen will look like this:

The first thing to do is to click on ‘Settings’ in the lower left corner, then uncheck ‘Show rich workspaces’ and ‘Show recommendations’. Generally, these two options are not needed and they clutter the workspace, confusing the user.

You can also disable the ‘Dashboard’ app, which is also not needed and confuses the user, since it’s opened by default after logging in. To disable it, click on the user icon in the upper right corner, then click on ‘Apps’, then search for the ‘Dashboard’ app and click on ‘Disable’ on its row.

Also, you can click on the user icon in the upper right corner, then click on ‘Settings’, then in the ‘Personal info’ section you can add your email address in the ‘Email’ field and set a picture from Nextcloud or from your computer, as ‘Profile picture’.

If you ever want to see the content of the Nextcloud log, click on the user icon in the upper right corner, then click on ‘Settings’, then under ‘Administration ‘click on ‘Logging’. In the upper left corner of the logging window click on ‘Level’ and uncheck ‘Debug’ and ‘Info’ to make Nextcloud display only the most important information. Otherwise the log will become almost unreadable.

Next, open the /var/www/cloud.example.com/config/config.php file:

nano /var/www/cloud.example.com/config/config.php

Your configuration file should look similar to the following:

<?php
$CONFIG = array (
  'instanceid' => '6asd51f6as51df',
  'passwordsalt' => 's6d5f1g6s5d1f6g1sd6f1g6ds5fg6sd1f56sf',
  'secret' => 's6d5fg6sd5f1g6s5d1f6g51sd6fg56sd5fg6s5df6g51s6dfg1',
  'trusted_domains' =>
  array (
    0 => 'cloud.example.com',
    1 => 'office.example.com',
  ),
  'datadirectory' => '/var/www/cloud.example.com/data',
  'dbtype' => 'mysql',
  'version' => '22.2.0.2',
  'overwrite.cli.url' => 'https://cloud.example.com',
  'dbname' => 'nextclouddatabasename',
  'dbhost' => 'localhost',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'databaseusername',
  'dbpassword' => '58d61g6sd51fg6a65d1',
  'installed' => true,
  'memcache.local' => '\\OC\\Memcache\\Memcached',
  'memcache.distributed' => '\\OC\\Memcache\\Memcached',
  'memcached_servers' =>
  array (
    0 =>
    array (
      0 => '/var/run/memcached/memcached.sock',
      1 => 0,
    ),
  ),
  'auth.bruteforce.protection.enabled' => false,
  'app.mail.verify-tls-peer' => false,
  'mail_smtpmode' => 'sendmail',
  'mail_smtpsecure' => 'tls',
  'mail_from_address' => 'admin',
  'mail_domain' => 'example.com',
  'mail_smtpauth' => true,
  'mail_smtpport' => '587',
  'mail_smtphost' => 'mail.example.com',
  'mail_smtpname' => 'admin@example.com',
  'mail_smtppassword' => 'strongpassword',
  'maintenance' => false,
  'logtimezone' => 'Europe/Berlin',
  'log_type' => 'file',
  'logfile' => '/var/log/nextcloud/nextcloud.log',
  'loglevel' => '2',
  'theme' => '',
  'default_phone_region' => 'DE',
);

Replace example.com with the main domain hosted on your server, admin@example.com with the email address that you want to use to log in to the mail server, strongpassword with the password for the admin@example.com email account, Europe/Berlin with your own timezone, that you can find on the list of timezones supported by PHP, and replace DE with your two letter country code for the default region for phone numbers.

Please note that the 'mail_smtpmode', 'mail_smtpsecure', 'mail_from_address' and 'mail_domain' parameters are needed so that Nextcloud can send notifications and for password resets. The other mail related parameters listed above are also necessary if you want to install the Mail app, to access your admin@example.com account inside Nextcloud. The Mail app had some bugs in the past and installing it it’s not necessarily a good idea, but if you ever install it, the configuration file should contain all the mail related parameters listed above.

You can notice that we configured Memcached for both local and distributed caching. This is the best solution, in spite of the fact that the official Nextcloud documentation suggests to use APCu for local caching and Redis for distributed caching. Our tests proved that using APCu and Redis doesn’t improve performance.

Restart Nginx:

systemctl restart nginx

26.6. Move the configuration file outside the web root

To increase security, first copy the /var/www/cloud.example.com/config/config.php file outside the web root, to the /srv/scripts directory. Replace example.com with the main domain hosted on your server:

cp /var/www/cloud.example.com/config/config.php /srv/scripts/nextcloud.php

Then empty the /var/www/cloud.example.com/config/config.php file:

cat /dev/null > /var/www/cloud.example.com/config/config.php

Then open it:

nano /var/www/cloud.example.com/config/config.php

Add the following line inside it:

<?php include('/srv/scripts/nextcloud.php'); ?>

Change ownership amd permissions for the /srv/scripts/nextcloud.php file:

cd /srv/scripts
chown www-data:root nextcloud.php
chmod 600 nextcloud.php

26.7. Install Nextcloud apps

The apps available in Nextcloud App Store add a lot of new functionalities to Nextcloud. It’s just that you have to know in advance what apps deserve to be installed and with what configurations.

First we’ll describe how to install Collabora Online.

26.7.1. Install Collabora Online

LibreOffice Online is a free and open source program derived from LibreOffice, that allows accessing and editing office documents in the browser. It’s similar to Google Docs Editors, with the significant difference that if you install it on a server that you control, you can own it and you can own the documents that you edit with it. Some releases of LibreOffice Online are branded as Collabora Online and Collabora Online Development Edition (CODE), since Collabora Ltd is the main contributor to the LibreOffice Online project. We’ll describe below how to install Collabora Online Development Edition, which is stable and powerfull, if you know what versions to install.

Using a self-hosted installation of Collabora Online Development Edition, you can open and edit office documents with any computer connected to the Internet, from anywhere in the world, using just a browser. It also allows multiple users to view and edit the same documents simultaneously. This is called ‘collaborative editing’ and is important for web-based teamwork.

If you want to install Collabora Online Development Edition on your own server and integrate it with Nextcloud, you have four main options:

  • install the Docker version, which implies installing Docker. Docker uses a portion of the server’s RAM and CPU power and should be avoided when you try to spare your server’s resources as much as possible.
  • install the ‘Collabora Online – Built-in CODE Server’ Nextcloud application. In this case, the Collabora Online Development Edition server gets installed like any Nextcloud application. However, if you choose this method, the program will be so slow that you won’t be able to use it for real work.
  • compile Collabora Online from source by yourself and install it on your server without using Docker. This method used to work well on older versions of Debian. Unfortunately, on Debian 11 compiling Collabora Online successfully proves to be very difficult and if you try to run on Debian 11 Collabora Online compiled on older versions of Debian, it won’t work.
  • install the native Linux packages for Debian 11, offered by Collabora Ltd here. This method is very straightforward and using it you will install and upgrade the Collabora Online Development Edition server like any native Debian application.

We recommend the fourth option and we describe it below.

First install apt-transport-https and ca-certificates, because they will be needed:

apt-get install apt-transport-https ca-certificates

Then import the signing key:

cd /usr/share/keyrings
sudo wget https://collaboraoffice.com/downloads/gpg/collaboraonline-release-keyring.gpg

Add the Collabora Online Development Edition repository to the list of repositories:

nano /etc/apt/sources.list.d/collaboraonline.sources

Add the following content inside this file:

Types: deb
URIs: https://www.collaboraoffice.com/repos/CollaboraOnline/CODE-debian11
Suites: ./
Signed-By: /usr/share/keyrings/collaboraonline-release-keyring.gpg

Next, update the package lists and install Collabora Online Development Edition by running:

apt-get update
apt-get install coolwsd code-brand collaboraofficebasis-en-us collaboraofficebasis-en-gb collaboraoffice-dict-en

The command from above will install CODE together with the language packs for English, which will allow automatic spell checking for English. If you had wanted to install CODE together with the language packs for French, you would have run:

apt-get install coolwsd code-brand collaboraofficebasis-fr collaboraoffice-dict-fr

If you had wanted to install CODE together with the language packs for German, you would have run:

apt-get install coolwsd code-brand collaboraofficebasis-de collaboraoffice-dict-de

26.7.1.1. Obtain a Let’s Encrypt SSL certificate

To obtain a Let’s Encrypt SSL certificate for office.example.com, first edit the Nginx server blocks configuration file:

nano /etc/nginx/sites-enabled/0-conf

Create a temporary server block for office.example.com, by adding the following lines:

server {
    listen 80;
    listen [::]:80;
    server_name office.example.com;

    location /.well-known/acme-challenge {
        root /var/www;
    }
}

Restart Nginx:

systemctl restart nginx

Now edit your DNS settings. Add an A entry and an AAAA entry for office.example.com. These entries are similar with the entries for cloud.example.com . It’s just that instead of cloud you use office. Wait a few minutes until the DNS changes propagate.

Next, you can obtain a Let’s Encrypt certificate for office.example.com by running:

certbot certonly --agree-tos --webroot -w /var/www/ -d office.example.com

26.7.1.2. Configure Nginx for Collabora Online

Then open the /etc/nginx/sites-enabled/0-conf file:

nano /etc/nginx/sites-enabled/0-conf

Replace the temporary server block for office.example.com with the following server block, in order to allow Nginx to serve the site over SSL:

server {
    listen  80;
    listen [::]:80;
    server_name office.example.com;
    return  301 https://office.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name office.example.com;

    ssl_certificate /etc/letsencrypt/live/office.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/office.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/office.example.com/chain.pem;
    ssl_dhparam   /etc/nginx/ssl/dhparam.pem;

    ssl_session_timeout 4h;
    ssl_session_cache shared:SSL:40m;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    ssl_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security 'max-age=31536000';
    add_header X-Content-Type-Options nosniff;

    add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive";

    location /.well-known/acme-challenge {
        root /var/www;
    }

    # static files
    location ^~ /browser {
        proxy_pass https://127.0.0.1:9980;
        proxy_set_header Host $http_host;
    }

    # WOPI discovery URL
    location ^~ /hosting/discovery {
        proxy_pass https://127.0.0.1:9980;
        proxy_set_header Host $http_host;
    }

    # Capabilities
    location ^~ /hosting/capabilities {
        proxy_pass https://127.0.0.1:9980;
        proxy_set_header Host $http_host;
    }

    # main websocket
    location ~ ^/cool/(.*)/ws$ {
        proxy_pass https://127.0.0.1:9980;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $http_host;
        proxy_read_timeout 36000s;
    }

    # download, presentation and image upload
    location ~ ^/(c|l)ool {
        proxy_pass https://127.0.0.1:9980;
        proxy_set_header Host $http_host;
    }

    # Admin Console websocket
    location ^~ /cool/adminws {
        proxy_pass https://127.0.0.1:9980;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $http_host;
        proxy_read_timeout 36000s;
    }

    access_log /var/log/sites/office.example.com/access.log;
    error_log  /var/log/nginx/office.example.com.error.log notice;
}

Create the access log directory:

mkdir /var/log/sites/office.example.com

26.7.1.3. Configure logrotate to rotate Collabora Online logs

To configure logrotate to rotate the new logs that will be created, run:

nano /etc/logrotate.d/nginx

Add the following blocks at the bottom of the file:

/var/log/sites/office.example.com/access.log {
	missingok
	rotate 10
	compress
	delaycompress
	notifempty
	create 0640 www-data adm
	size 2M
	sharedscripts
	prerotate        
		if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
			run-parts /etc/logrotate.d/httpd-prerotate; \
		fi; \
	endscript

        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript 
}

/var/log/coolwsd/coolwsd.log {
        missingok
        rotate 10
        compress
        delaycompress
        notifempty
        create 0640 cool cool
        size 2M
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi; \
        endscript

        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript
}

Create the directory for the coolwsd log file and set the right ownership for it and for the new log file:

mkdir /var/log/coolwsd
chown -R cool:cool /var/log/coolwsd
touch /var/log/coolwsd/coolwsd.log
chown cool:cool /var/log/coolwsd/coolwsd.log

26.7.1.4. Configure Collabora Online web socket daemon (coolwsd)

First make a copy of the original configuration file:

cp /etc/coolwsd/coolwsd.xml /etc/coolwsd/coolwsd.xml_orig

Open the configuration file:

nano /etc/coolwsd/coolwsd.xml

In the <logging> section, edit the following lines, to make them look as follows:

            <property name="path" desc="Log file path.">/var/log/coolwsd/coolwsd.log</property>
            ...
            <property name="rotateOnOpen" desc="Enable/disable log file rotation on opening.">false</property>

In the <net desc="Network settings"> section edit the following line, like this:

      <proto type="string" default="all" desc="Protocol to use IPv4, IPv6 or all for both">IPv4</proto>

In the <welcome> section, edit the following line, to make it look like this:

      <enable type="bool" desc="Controls whether the welcome screen should be shown to the users on new install and updates." default="true">false</enable>

In the <storage desc="Backend storage"> section, make sure you have the following lines:

            <host desc="Regex pattern of hostname to allow or deny." allow="true">localhost</host>
            <host desc="Regex pattern of hostname to allow or deny." allow="true">127\.0\.0\.1</host>
            <host desc="Regex pattern of hostname to allow or deny." allow="true">cloud\.example\.com</host>

where cloud\.example\.com is the domain that you use to serve Nextcloud.

Finally, in the <admin_console desc="Web admin console settings."> section, enter your username and password for the admin console, like this:

        <username desc="The username of the admin console. Ignored if PAM is enabled.">yourusername</username>
        <password desc="The password of the admin console. Deprecated on most platforms. Instead, use PAM or coolconfig to set up a secure password.">yourstrongpassword</password>

Before restarting coolwsd and Nginx, you should enable SSL encryption for coolwsd, as described below.

26.7.1.4.1 Enable SSL encryption for coolwsd

To enable SSL encryption between ‘Collabora Online web socket daemon’ (coolwsd) and the network, you will need to copy the SSL certificate files for office.example.com from the /etc/letsencrypt/live/office.example.com directory to the /etc/coolwsd directory, because coolwsd will refuse to read them in their default location. You can create a small script to automatically copy these files to the proper location, once per week:

nano /srv/scripts/copy-coolwsd-cert

Add the following content inside this file:

#!/bin/bash

cp /etc/letsencrypt/live/office.example.com/cert.pem /etc/coolwsd/cert.pem
cp /etc/letsencrypt/live/office.example.com/privkey.pem /etc/coolwsd/key.pem
cp /etc/letsencrypt/live/office.example.com/chain.pem /etc/coolwsd/ca-chain.cert.pem

chown cool:cool /etc/coolwsd/cert.pem
chown cool:cool /etc/coolwsd/key.pem
chown cool:cool /etc/coolwsd/ca-chain.cert.pem

systemctl restart coolwsd.service

Change permissions for this script:

chmod 700 /srv/scripts/copy-coolwsd-cert

Add a cronjob to run the script once every Monday:

crontab -e

Add the following lines at the end of the file:

# Copy the SSL/TSL certificates for office.example.com from /etc/letsencrypt/live/office.example.com to /etc/coolwsd every Monday at at 3:45 AM
45 3 * * 1 /srv/scripts/copy-coolwsd-cert > /dev/null 2>&1

Run the script manually once, to copy the SSL certificate files to the proper location:

/srv/scripts/copy-coolwsd-cert

Set the proper ownership for /opt/cool and /opt/collaboraoffice:

chown -R cool:cool /opt/cool
chown -R cool:cool /opt/collaboraoffice

Now you can restart coolwsd:

systemctl restart coolwsd

Restart also Nginx, so that all the changes made previously can take effect:

systemctl restart nginx

26.7.1.5. Install the ‘Office Online integration’ app in Nextcloud

Please note that in order to connect Nextcloud to the CODE server that you have just installed, you need to install the ‘Office Online integration’ app in Nextcloud, and not the ‘Nextcloud Office’ app, which contains a bug that doesn’t allow 2 or more users to open the same odt or odp file simultaneously.

To install the ‘Office Online integration’ app click on the user icon in the upper right corner of Nexcloud, click on ‘Apps’, then use the search box on the upper bar to search for ‘Office Online integration’ and install it. Then click on ‘Settings’, on the left panel, under ‘Administration’ click on ‘Office Online’, then, in the ‘URL (and Port) of Office Online server’ field enter the URL of the server you have just setup, namely: https://office.example.com:9980, and click ‘Save’.

From now on, when you will click on an odt, ods, odp, odg, rtf, docx, doc, xlsx, xls, pptx or ppt file stored in a Nextcloud folder, the file will be opened by Collabora Online Development Edition and you will be able to edit and save it, as if it were stored on your local computer.

If you share such office document with other Nextcloud users, they will be able to open and edit the document simultaneously. You can save open documents in their own format or as pdf, rtf, epub/csv files. When they are closed, documents are saved automatically.

If you want to enable automatic spell checking for English (USA) in a specific odt file, click on the hamburger button in the upper left corner > ‘Tools’ > ‘Language’ > ‘For All Text’ > ‘English (USA)’, like below:

Once you do that, the language of the entire document will be set to English (USA) and all the misspelled words will be underlined with red. This assumes that you have installed CODE together with the language packs for English, as explained earlier. For ods files, automatic spell checking is enabled in a similar manner. If you close the document, the language settings will be remembered.

If you want to see the CODE menus in a specific language, you have to change your Nextcloud language by clicking on the user icon in the upper right corner > ‘Settings’ > then clicking on ‘Personal info’ on the left sidebar, then choosing your language from the ‘Language’ drop-down menu.

For security reasons, running macros in documents opened with CODE is disabled by default. However, you can enable running macros by following these steps:

– open the /etc/coolwsd/coolwsd.xml configuration file:

nano /etc/coolwsd/coolwsd.xml

– in the <security desc="Altering these defaults potentially opens you to significant risk"> section, change the enable_macros_execution line, to make it look like this:

      <enable_macros_execution desc="Specifies whether the macro execution is enabled in general. This will enable Basic, Beanshell, Javascript and Python scripts. If it is set to false, the macro_security_level is ignored. If it is set to true, the mentioned entry specified the level of macro security." type="bool" default="false">true</enable_macros_execution>

– restart coolwsd:

systemctl restart coolwsd

– then, when you open a file with CODE, click on the hamburger button in the upper left corner > ‘Tools’ > ‘Run Macro…’ > choose the macro that you want to run and click ‘Run’.

Please note that older versions of Collabora Online Development Edition displayed a pop-up warning when more than 10 documents or 20 connections were in use simultaneously, although the server allowed opening additional documents. This warning has been removed in recent CODE versions.

The administration console which provides information about the number of documents opened, the number of users connected, memory usage, etc., can be accessed at the following URL:

https://office.example.com/browser/dist/admin/admin.html

You will have to enter the username and password set up earlier in the /etc/coolwsd/coolwsd.xml file. Once you log in, you will see the Overview screen:

In the latest Nextcloud versions, when you open odt, ods, odp, docx, xlsx, pptx, etc. files with Collabora Online, you will notice that the bottom bar containing the search box, the language drop-down list, the zoom level indicator, etc., will be pushed downwards and will not be visible because of an extra black header bar added at the top:

To correct this issue, you can make a small CSS modification using the ‘Custom CSS’ app.

To install the ‘Custom CSS’ app, click on the profile picture in the upper right corner, then on ‘Apps’, then enter ‘Custom CSS’ in the search box on the Nextcloud upper bar. When you find the ‘Custom CSS’ app click on the ‘Download and enable’ button to install it. Once the app is installed, click again on the profile picture, then on ‘Settings’, then, on the left panel, under ‘Administration’, click on ‘Theming’ and scroll to the bottom of the page. There, in the ‘Custom CSS’ text area enter:

#officeonlineframe { position: relative; top: -50px; }

Click the ‘Save’ button. From now on, the bottom bar of the documents opened with Collabora Online will be visible:

26.7.1.6. Configure Fail2ban to protect Collabora Online administration console against brute-force attacks

Navigate to the /etc/fail2ban/filter.d directory:

cd /etc/fail2ban/filter.d

Create a file called cooladmin.conf:

nano cooladmin.conf

Add the following content inside this file:

[Definition]

failregex =  ^<HOST> .* "GET /browser/dist/admin/admin.html HTTP/2.0" 401
ignoreregex =

Next, open the /etc/fail2ban/jail.local file:

nano /etc/fail2ban/jail.local

Add the following block below the [phpmyadmin] block:

[cooladmin]
enabled  = true
filter   = cooladmin
logpath  = /var/log/sites/office.example.com/access.log
port     = 80,443
maxretry = 3
bantime  = 259200

Restart Fail2ban:

systemctl restart fail2ban

26.7.1.7. Stop automatic updates for Collabora Online

Once you install Collabora Online Development Edition as described above and verify that everything works as expected, you should prevent Collabora Online from being updated together with other native Debian packages, when new versions become available and you run apt-get upgrade or apt-get dist-upgrade. This is because CODE, Nextcloud itself and many Nextcloud apps are notorious for having versions which work flawlessly for years and then, all of a sudden, a simple upgrade to a new version breaks essential functionalities, generates errors and blocks your activities for days or weeks, until you find a solution, like downgrading Nextcloud, downgrading the app, reporting the bug and waiting for a fix, searching for workarounds, etc. In order to avoid this kind of situations, we recommend that you disable automatic updates for CODE. CODE should be upgraded together with Debian itself, once every 2 years. The same is true for Nextcloud and Asterisk: they should be also upgraded only once every 2 years, after upgrading Debian. The only exceptions to this general rule should be the cases in which critical security vulnerabilities will be discovered and you will need to install newer versions sooner, to apply the fixes. To find out if and when critical security vulnerabilities are discovered for CODE, you can check web pages like this periodically, or you can subscribe to our ‘Updates Newsletter’. Subscribers get an email each time a security vulnerability that needs to be fixed urgently by an upgrade is discovered for CODE, or for any other application that is part of RED SCARF Suite.

Open the /etc/apt/sources.list.d/collaboraonline.sources file:

nano /etc/apt/sources.list.d/collaboraonline.sources

Comment out all the lines, to disable them, like this:

#Types: deb
#URIs: https://www.collaboraoffice.com/repos/CollaboraOnline/CODE-debian11
#Suites: ./
#Signed-By: /usr/share/keyrings/collaboraonline-release-keyring.gpg

Update the package lists:

apt-get update

From now on, when you will run apt-get update followed by apt-get dist-upgrade, CODE won’t be updated, even if newer versions will be available.

26.7.1.8. Upgrading Collabora Online

As stated above, you should only update/upgrade Collabora Online Development Edition once every 2 years, when you upgrade Debian.

Before upgrading CODE to the last version available for the current Debian stable, it’s recommended to check if the new CODE version has been tested and verified to function well and as a result it has been included on the list of applications on this page.

To upgrade CODE to the last version found in the official Collabora Online repository available at https://www.collaboraoffice.com/repos/CollaboraOnline/CODE-debianX, where X is the version number of Debian, first open the /etc/apt/sources.list.d/collaboraonline.sources file:

nano /etc/apt/sources.list.d/collaboraonline.sources

Then uncomment all the lines, to make them look like this:

Types: deb
URIs: https://www.collaboraoffice.com/repos/CollaboraOnline/CODE-debianX
Suites: ./
Signed-By: /usr/share/keyrings/collaboraonline-release-keyring.gpg

Replace X with the number of the current stable version of Debian.

Then update the package lists:

apt-get update

Next, upgrade all the packages with newer versions, including CODE, by running:

apt-get dist-upgrade

Restart coolwsd:

systemctl restart coolwsd

After the upgrade is finished, don’t forget to disable automatic updates again:

nano /etc/apt/sources.list.d/collaboraonline.sources

Comment out all the lines, to make them look like this:

#Types: deb
#URIs: https://www.collaboraoffice.com/repos/CollaboraOnline/CODE-debianX
#Suites: ./
#Signed-By: /usr/share/keyrings/collaboraonline-release-keyring.gpg

Then, update the package lists:

apt-get update

26.7.2. Install SIP Trip Phone

SIP Trip Phone is a browser phone that uses SIP over WebSocket and WebRTC. It connects to SIP providers via Asterisk or directly.

It can be used in conjunction with Asterisk, to benefit from the control, autonomy and advanced PBX features offered by Asterisk, but also without Asterisk, if you connect it directly to the SIP provider (this implies that the SIP provider allows direct connections from web applications that use SIP over WebSocket). For calls to and from regular phone numbers, a SIP provider like Telnyx or Localphone is needed and a real phone number acquired from that SIP provider. If Asterisk is used, it’s recommended to be Asterisk version 18.0.0 LTS and it has to be installed on a VPS or dedicated server.

SIP Trip Phone allows making and receiving phone calls to/from any mobile or landline phone, at lower rates than with regular phones. It allows making cheap international phone calls from phone numbers located in the same country as the receivers. The receivers will also be able to call those numbers and pay as for local calls. It is known that VoIP phone calls are up to 70% cheaper than regular phone calls. International VoIP phone calls can cost even 90% less than regular phone calls. If Asterisk is used, SIP Trip Phone allows making free calls over the Internet between extensions configured on the underlying Asterisk server. It logs recent phone calls and their duration and allows pausing, muting and transferring phone calls. On the underlying Asterisk server you can implement an IVR (Interactive Voice Response) and many advanced PBX features such as voicemail, queue management, music on hold, number blacklisting, call recording, audio conference calls, etc.


First, we’ll explain how to connect SIP Trip Phone directly to a SIP provider like Telnyx (Localphone doesn’t allow direct connections from web applications using SIP over WebSocket), then we’ll describe how to connect SIP Trip Phone to a SIP provider like Telnyx and Localphone via Asterisk.

26.7.2.1. Install SIP Trip Phone and connect it directly to Telnyx

SIP Trip Phone can be installed like any other Nextcloud application: click on the profile picture from the upper right corner > Apps > search for ‘SIP Trip Phone’ using the search box on the upper bar > click ‘Download and install’. You will be able to start SIP Trip Phone only after you fill in the required fields on its Settings page, as explained below.

26.7.2.1.1. Configure your Telnyx account


After you sign up for a Telnyx account click on the ‘My Account’ icon in the upper right corner of the screen, then click on ‘My Account’, click the ‘Account Level’ tab and take the steps to undergo verification, so that you become ‘Level 1’ and ‘Level 2’ verified. ‘Level 1’ verification usually requires verifying the email address you used to create your Telnyx account, by clicking a link included in a message sent to that email address. ‘Level 2’ verification can be requested by pressing the ‘Verify’ button in the ‘Level 2 Verification’ section (on the ‘Verifications’ tab). After you make your request for ‘Level 2’ verification, a representative from Telnyx will look at your account details and (s)he may send you an email asking about the way you plan to use your Telnyx account, after which (s)he will approve the ‘Level 2’ verification. Being ‘Level 1’ and ‘Level 2’ verified unlocks all the features of a Telnyx account: you can buy numbers, assign a connection/messaging profile to a number, set up global messaging capabilities, create a multi-user organization, make international calls, set up call forwarding, send SMS messages at a higher rate.

While logged in to your Telnyx account, click on ‘Numbers’, ‘My Numbers’ on the left panel. To buy a real phone number located in a country of your choice click on the ‘Search & Buy Numbers’ tab, then under ‘Local Numbers’, in the ‘Search Type’ select ‘Region’, in the ‘Region’ text field enter the name of the country, in the ‘Number Features’ select ‘Voice’, then, if you want your number to have other capabilities select other features such as ‘SMS’ from the drop-down list, then click on the ‘Search Numbers’ button. You will see a list with all the numbers available in the selected region. Choose the number that you like, click ‘Add to Cart’, then click on ‘Cart’ on the upper bar, then click on the ‘Place Order’ button.

After you have bought a local phone number click on ‘Numbers’, ‘My Numbers’ on the left panel; on the ‘My Numbers’ tab you will see your number in the list of acquired phone numbers.

Then click on ‘Voice’, ‘SIP Trunking’ on the left panel. On the ‘SIP Connections’ tab click on the ‘Add SIP Connection’ button, in the ‘Name’ field enter the name of the new SIP connection, for example SIP_Trip_Phone, then click on ‘Create SIP Connection’. After you create the new connection click on the small pencil icon to open the options window. On the options window, on the ‘BASIC’ tab, under ‘SIP Connection Type’ choose ‘Credentials’, then in the ‘Username’ field enter a username for this connection, siptripphoneuser for example, in the ‘Password’ field enter a strong password; write down the username and password to use them later. Next, under ‘AnchorSite’ choose a town that is closer to the physical location of your server, then, under ‘Expert Settings’, from the ‘Port’ drop-down list choose ‘rtcp-mux’. Next, click on the ‘INBOUND’ tab and in the ‘Destination Number Format (DNIS)’ drop-down list choose ‘SIP Username’. (The last 2 settings are extremely important. If you connect SIP Trip Phone to Telnyx via Asterisk, the last 2 settings will be different, namely ‘Port’: ‘rtp+1’ and ‘Destination Number Format (DNIS)’: ‘E.164’.) Leave all the other settings as they are and click on the ‘Save All Changes’ button.

To be able to make phone calls you will also need to configure an Outbound Voice Profile. On the left panel click on ‘Voice’, ‘Outbound Voice Profiles’, then click on the ‘Add New Profile’ button. In the ‘Name’ field enter a name for the profile, 1_outbound for example, then click ‘Create’. In the new window, under ‘Associated Connections and Applications’ click ‘Add connections/apps to profile’, select the name of the SIP connection created earlier, SIP_Trip_Phone in this example, by checking its checkbox, then click ‘Add Connections/Apps to profile’. Next, under ‘Traffic Type’ choose ‘Conversational’, then under ‘International Allowed Destinations’ select the countries and regions to which outbound calls will be allowed, by clicking their name. You can select all the 253 countries and regions, to allow outbound calls to all of them. Click on ‘Save’ to save the changes.

Next, create a Billing Group. Click on the ‘My Account’ icon in the upper right corner of the screen, then click on ‘Billing Overview’, then on the ‘Billing Groups’ tab. In the ‘Create Billing Group’ field enter a name, Default_Billing for example, then click on ‘Create’. Then add the billing group to your phone number: click on ‘Numbers’, ‘My Numbers’ on the left panel, then on your number’s row, in the ‘Billing Group’ field select the billing group that you have just created, Default_Billing in this example. Also, in the ‘Connection or App’ field on the same row, choose the connection created earlier, SIP_Trip_Phone in this example.

26.7.2.1.2. Configure the web server


Taking into account that cloud.example.com is the subdomain used to serve Nextcloud, to connect SIP Trip Phone directly to a Telnyx account, the server blocks configuration file of Nginx, /etc/nginx/sites-enabled/0-conf, should contain the following blocks:

server {
    listen  80;
    listen [::]:80;
    server_name cloud.example.com;
    server_tokens off;
    return  301 https://cloud.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name cloud.example.com;
    root /var/www/cloud.example.com;
    index index.php index.html /index.php$request_uri;


    ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/cloud.example.com/chain.pem;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    ssl_session_timeout 4h;
    ssl_session_cache shared:SSL:40m;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    ssl_stapling on;
    ssl_stapling_verify on;

    # Prevent Nginx HTTP Server Detection
    server_tokens off;

    # Set max upload size
    client_max_body_size 1G;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header Referrer-Policy                    "no-referrer"   always;
    add_header X-Content-Type-Options             "nosniff"       always;
    add_header X-Download-Options                 "noopen"        always;
    add_header X-Frame-Options                    "SAMEORIGIN"    always;
    add_header X-Permitted-Cross-Domain-Policies  "none"          always;
    add_header X-Robots-Tag                       "none"          always;
    add_header X-XSS-Protection                   "1; mode=block" always;

    fastcgi_hide_header X-Powered-By;

    location = /robots.txt {
        allow all;
    }

    location ^~ /.well-known {
        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }

        location /.well-known/acme-challenge    { root /var/www; try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }

        # Let Nextcloud's API for `/.well-known` URIs handle all other
        # requests by passing them to the front-end controller.
        return 301 /index.php$request_uri;
    }

    # Hide certain paths from clients
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

    location ~ \.php(?:$|/) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        try_files $fastcgi_script_name =404;
        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;  # Enable pretty urls
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
        fastcgi_max_temp_file_size 0;
    }

    location ~ \.(?:css|js|svg|gif|png|jpg|jpeg|ico|ttf|wasm|tflite|map|woff|woff2)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463";

        location ~ \.wasm$ {
            default_type application/wasm;
        }
    }

    location /remote {
        return 301 /remote.php$request_uri;
    }

    location / {
        try_files $uri $uri/ /index.php$request_uri;
    }

    # This is needed by SIP Trip Phone
    location /apps/sip_trip_phone/phone {
        try_files $uri /index.html;
    }

    # This is also needed by SIP Trip Phone
    location /apps/sip_trip_phone/lib {

        # prevents 502 bad gateway error
        proxy_buffers 8 32k;
        proxy_buffer_size 64k;

        proxy_pass http://sip.telnyx.com:7443;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # enables WS support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    access_log /var/log/sites/cloud.example.com/access.log;
    error_log  /var/log/nginx/cloud.example.com.error.log notice;
}

Replace example.com with your domain. Please note that inside the location /apps/sip_trip_phone/lib { block, the proxy_pass parameter contains the URL and port provided by Telnyx for direct WebRTC connections: http://sip.telnyx.com:7443.

Even if we don’t recommend using a subdirectory to serve Nextcloud, we explain here how you can use a subdirectory like example.com/nextcloud to serve Nextcloud and its applications, including SIP Trip Phone. Also, even if we don’t recommend using Apache as a web server, we explain here how Apache can be configured to serve Nextcloud on a subdomain or on a subdirectory.

26.7.2.1.3. Configure SIP Trip Phone


To configure SIP Trip Phone click on the profile picture in the upper right corner, click on ‘Settings’, then on the left sidebar, under ‘Personal’, click ‘SIP Trip Phone’. The credentials that have to be entered should look like this:

In the Display Name field you should enter the phone number that you have just configured in your Telnyx account, preceded by the country calling code: 49 for Germany, 33 for France, 44 for UK, 1 for USA, etc. So, if the number is 1212121212 and is located in Germany, the ‘Display Name’ should be 491212121212.

In the SIP User field enter the username for the SIP connection that you associated with your phone number in your Telnyx account, siptripphoneuser in this example. In the SIP User Password field enter the password for siptripphoneuser.

In the WSS URL field enter wss://sip.telnyx.com:7443

In the SIP Realm field enter sip.telnyx.com

In the STUN Server domain or IPv4 address, followed by port number field enter stun.telnyx.com:3478

Click ‘Save’ to save these settings.

26.7.2.2. Install SIP Trip Phone and connect it to Telnyx or Localphone via Asterisk

SIP Trip Phone can be installed like any other Nextcloud application: click on the profile picture from the upper right corner > Apps > search for ‘SIP Trip Phone’ using the search box on the upper bar > click ‘Download and install’. You will be able to start SIP Trip Phone only after you fill in the required fields on its Settings page, as explained below.

26.7.2.2.1. Install Asterisk and Coturn


Asterisk should be installed and configured as explained in detail in the Install Asterisk chapter.

To help in situations where callers are behind routers, install Coturn as a STUN server, as explained in the Install Coturn chapter.

26.7.2.2.2. Configure a Telnyx account


After you sign up for a Telnyx account click on the ‘My Account’ icon in the upper right corner of the screen, then click on ‘My Account’, click the ‘Account Level’ tab and take the steps to undergo verification, so that you become ‘Level 1’ and ‘Level 2’ verified. ‘Level 1’ verification usually requires verifying the email address you used to create your Telnyx account, by clicking a link included in a message sent to that email address. ‘Level 2’ verification can be requested by pressing the ‘Verify’ button in the ‘Level 2 Verification’ section (on the ‘Account Level’ tab). After you make your request for ‘Level 2’ verification, a representative from Telnyx will look at your account details and (s)he may send you an email asking about the way you plan to use your Telnyx account, after which (s)he will approve the ‘Level 2’ verification. Being ‘Level 1’ and ‘Level 2’ verified unlocks all the features of a Telnyx account: you can buy numbers, assign a connection/messaging profile to a number, set up global messaging capabilities, create a multi-user organization, make international calls, set up call forwarding, send SMS messages at a higher rate.

While logged in to your Telnyx account, click on ‘Numbers’, ‘My Numbers’ on the left panel. To buy a real phone number located in a country of your choice click on the ‘Search & Buy Numbers’ tab, then under ‘Local Numbers’, in the ‘Search Type’ select ‘Region’, in the ‘Region’ text field enter the name of the country, in the ‘Number Features’ select ‘Voice’, then, if you want your number to have other capabilities select other features such as ‘SMS’ from the drop-down list, then click on the ‘Search Numbers’ button. You will see a list with all the numbers available in the selected region. Choose the number that you like, click ‘Add to Cart’, then click on ‘Cart’ on the upper bar, then click on the ‘Place Order’ button.

After you have bought a local phone number click on ‘Numbers’, ‘My Numbers’ on the left panel; on the ‘My Numbers’ tab you will see your number in the list of acquired phone numbers.

Then click on ‘Voice’, ‘SIP Trunking’ on the left panel. On the ‘SIP Connections’ tab click on the ‘Add SIP Connection’ button, in the ‘Name’ field enter the name of the new SIP connection, for example SIP_Trip_Phone, then click on ‘Create SIP Connection’. After you create the new connection click on the small pencil icon to open the options window. On the options window, on the ‘BASIC’ tab, under ‘SIP Connection Type’ choose ‘Credentials’, then in the ‘Username’ field enter a username for this connection, siptripphoneuser for example, in the ‘Password’ field enter a strong password; write down the username and password to use them later. Next, under ‘AnchorSite’ choose a town that is closer to the physical location of your server, then, under ‘Expert Settings’, in the ‘Port’ drop-down list choose ‘rtp+1’. Next, click on the ‘INBOUND’ tab and in the ‘Destination Number Format (DNIS)’ drop-down list choose ‘E.164’. (The last 2 settings are extremely important. If you connect SIP Trip Phone to Telnyx directly, the last 2 settings will be different, namely ‘Port’: ‘rtcp-mux’ and ‘Destination Number Format (DNIS)’: ‘SIP Username’.) Leave all the other settings as they are and click on the ‘Save All Changes’ button.

To be able to make phone calls you will also need to configure an Outbound Voice Profile. On the left panel click on ‘Voice’, ‘Outbound Voice Profiles’, then click on the ‘Add New Profile’ button. In the ‘Name’ field enter a name for the profile, 1_outbound for example, then click ‘Create’. In the new window, under ‘Associated Connections and Applications’ click ‘Add connections/apps to profile’, select the name of the SIP connection created earlier, SIP_Trip_Phone in this example, by checking its checkbox, then click ‘Add Connections/Apps to profile’. Next, under ‘Traffic Type’ choose ‘Conversational’, then under ‘International Allowed Destinations’ select the countries and regions to which outbound calls will be allowed, by clicking their name. You can select all the 253 countries and regions, to allow outbound calls to all of them. Click on ‘Save’ to save the changes.

Next, create a Billing Group. Click on the ‘My Account’ icon in the upper right corner of the screen, then click on ‘Billing Overview’, then on the ‘Billing Groups’ tab. In the ‘Create Billing Group’ field enter a name, Default_Billing for example, then click on ‘Create’. Then add the billing group to your phone number: click on ‘Numbers’, ‘My Numbers’ on the left panel, then on your number’s row, in the ‘Billing Group’ field select the billing group that you have just created, Default_Billing in this example. Also, in the ‘Connection or App’ field on the same row, choose the connection created earlier, SIP_Trip_Phone in this example.

26.7.2.2.3. Configure a Localphone account


After you sign up for a Localphone account at https://www.localphone.com/register, log in to your account and click on the ‘Internet Phone’ tab, then click on ‘Manage this account’ next to your SIP ID. On the next screen, under ‘Call from your own VoIP device’ you will find your ‘SIP ID’, ‘SIP Password’ and ‘Server’ that you’ll need to configure Asterisk, so write them down.

To buy a real phone number located in a country of your choice, first click on the ‘Incoming Numbers’ tab, then under ‘Get more Incoming Numbers’ select the country where you want your new phone number to be located, then click on ‘Continue’; you will see a list with the towns or states of the selected country, and you will have to choose in which town or state you want your number to be located; click on ‘Select’ or ‘View Locations’, then click on ‘Purchase’ or on ‘Select’ then ‘Purchase’.

Please note that for some countries, like Germany, to be able to buy a local number, you have to be a resident of that country. When selecting a number located in a town of such a country, you will have to send the copy of a bill or of an ID card showing that you are a resident of that country.

After you have bought a local phone number, click on the ‘Incoming Numbers’ tab, then, under ‘Your Incoming Numbers’, click on the ‘Manage Number’ link next to the local number. Then, under ‘Forward incoming calls’, click on ‘Forward calls to a SIP URI (advanced)’ and in the text box displayed below enter:

sip:8611@123.123.123.123:5827

where 8611 is the name of the extension configured in Asterisk, where you want all the incoming calls to be forwarded by Localphone, 123.123.123.123 is the public IP of your server, and 5827 is the custom Asterisk port that you have set up when installing Asterisk. Then click on ‘Update’. With these settings in place, all the calls to your newly acquired local phone number will be forwarded by Localphone to your Asterisk server, to extension 8611.

If you acquire more than one real phone number from Localphone, you can configure the other numbers in a similar way. You can forward the calls from all the real phone numbers to the same extension, 8611, or you can forward the calls from each number to a different extension. So, you forward the calls from the first phone number to 8611, the calls from the second phone number to 8612, the calls from the third phone number to 8613, etc.

26.7.2.2.4. Configure the web server


Taking into account that cloud.example.com is the subdomain used to serve Nextcloud, to connect SIP Trip Phone to Telnyx or Localphone via Asterisk, the server blocks configuration file of Nginx, /etc/nginx/sites-enabled/0-conf, should contain the following blocks:

server {
    listen  80;
    listen [::]:80;
    server_name cloud.example.com;
    server_tokens off;
    return  301 https://cloud.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name cloud.example.com;
    root /var/www/cloud.example.com;
    index index.php index.html /index.php$request_uri;


    ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/cloud.example.com/chain.pem;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    ssl_session_timeout 4h;
    ssl_session_cache shared:SSL:40m;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    ssl_stapling on;
    ssl_stapling_verify on;

    # Prevent Nginx HTTP Server Detection
    server_tokens off;

    # Set max upload size
    client_max_body_size 1G;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header Referrer-Policy                    "no-referrer"   always;
    add_header X-Content-Type-Options             "nosniff"       always;
    add_header X-Download-Options                 "noopen"        always;
    add_header X-Frame-Options                    "SAMEORIGIN"    always;
    add_header X-Permitted-Cross-Domain-Policies  "none"          always;
    add_header X-Robots-Tag                       "none"          always;
    add_header X-XSS-Protection                   "1; mode=block" always;

    fastcgi_hide_header X-Powered-By;

    location = /robots.txt {
        allow all;
    }

    location ^~ /.well-known {
        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }

        location /.well-known/acme-challenge    { root /var/www; try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }

        # Let Nextcloud's API for `/.well-known` URIs handle all other
        # requests by passing them to the front-end controller.
        return 301 /index.php$request_uri;
    }

    # Hide certain paths from clients
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

    location ~ \.php(?:$|/) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        try_files $fastcgi_script_name =404;
        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;  # Enable pretty urls
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
        fastcgi_max_temp_file_size 0;
    }

    location ~ \.(?:css|js|svg|gif|png|jpg|jpeg|ico|ttf|wasm|tflite|map|woff|woff2)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463";

        location ~ \.wasm$ {
            default_type application/wasm;
        }
    }

    location /remote {
        return 301 /remote.php$request_uri;
    }

    location / {
        try_files $uri $uri/ /index.php$request_uri;
    }

    # This is needed by SIP Trip Phone
    location /apps/sip_trip_phone/phone {
        try_files $uri /index.html;
    }

    # This is also needed by SIP Trip Phone
    location /apps/sip_trip_phone/lib {

        # prevents 502 bad gateway error
        proxy_buffers 8 32k;
        proxy_buffer_size 64k;

        proxy_pass http://0.0.0.0:8088/ws;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # enables WS support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    access_log /var/log/sites/cloud.example.com/access.log;
    error_log  /var/log/nginx/cloud.example.com.error.log notice;
}

Even if we don’t recommend using a subdirectory to serve Nextcloud, we explain here how you can use a subdirectory like example.com/nextcloud to serve Nextcloud and its applications, including SIP Trip Phone. Also, even if we don’t recommend using Apache as a web server, we explain here how Apache can be configured to serve Nextcloud on a subdomain or on a subdirectory.

26.7.2.2.5. Configure SIP Trip Phone


Click on the profile picture > Settings > then, on the left sidebar, under ‘Personal’ click ‘SIP Trip Phone’. The credentials that have to be entered should look similar to the following:

– in the Display Name field enter your name or a nickname;

– in the SIP user field enter the extension configured on the Asterisk server that you want to use (Eg: 601);

– in the SIP User Password enter the password for that Asterisk extension (set up in the /etc/asterisk/pjsip.conf file);

– in the WSS URL field enter wss://cloud.example.com:8089/ws;

– in the SIP Realm field enter the IPv4 address of your server, eg. 123.123.123.123;

– in the STUN Server domain or IPv4 address, followed by port number field enter 123.123.123.123:8443, where 123.123.123.123 is the IP of your server, then click ‘Save’;

If Nginx, Asterisk and Coturn are properly configured as described in the above mentioned chapters, and you have completed the required fields on the application’s Settings page as explained above, to start SIP Trip Phone, all you need to do is to click on its icon on the upper bar. The browser will warn you about opening a pop-up window. Accept opening the pop-up window and then you will be asked for permission to allow the application to access your microphone. Click ‘Allow’. (When you log in to Nextcloud, you also see a message on the upper bar asking if you allow notifications from the domain of your Nextcloud installation. You should click ‘Allow’ in order to see on-screen notifications when you receive new calls.) The phone’s pop-up window will look like this:

If you click on the ‘Show Keypad’ button in the upper left corner, the keypad will show up:

26.7.2.3. Making calls with SIP Trip Phone

To make a call, use the keypad to enter the number and press ‘Call’, or use the keyboard of your computer to enter the number in the number field, then press Enter.

If you want to make a call to one of the extensions of your own company/organization, just call that extension (601, 602, 603, etc.). As explained before, the number of an internal extension can be of any length, although, for simplicity, they are in general made up of 3 digits.

If you want to call a number outside your company/organization, don’t forget to place a 9 in front of the phone number if you want to make calls using Telnyx, or an 8 if you want to make calls using Localphone (as per the settings made in Asterisk explained earlier). Also, the 9 or 8 have to be followed by the country calling code, and only afterwards by the recipient’s number. For example, if you want to call the German number 1212121212 using Telnyx, you’ll have to call:

9491212121212

where 49 is the country calling code for Germany.

26.7.2.4. Receiving calls with SIP Trip Phone

To receive calls with SIP Trip Phone just leave the phone’s window open. You can also minimize it. All incoming calls will be announced in 3 different ways:

1) SIP Trip Phone will generate the classic intermittent ringing sound. You can hear it in your headphones, earphones or computer speakers.

2) System notifications will appear in the upper right or lower right corner of the screen, with the message: ‘New incoming call !’

3) The title of the window will blink, showing the message: ‘New call !!!’.

Given these signals, even if you don’t have your headphones close to your ears to hear the ringing, you can still notice the system notifications or the blinking title. The three signals make new calls hard to miss. Even if you miss a call, you’ll see the number of the caller in the recent calls log, in the application’s window (if you haven’t closed the window).

Please note that if you leave the phone’s window open (possibly minimized), even if you log out of Nextcloud, the phone will remain connected to Asterisk and will be perfectly functional, allowing you to receive and make phone calls.

26.7.2.5. SIP Trip Phone workflow

Please note that any individual user will have to enter their own credentials on the settings page: by clicking on the profile picture from the upper right corner > ‘Settings’ > then in the left panel, under ‘Personal’, by clicking ‘SIP Trip Phone’. They can’t use the phone if they don’t have their own extension configured in Asterisk and if they don’t enter their credentials in SIP Trip Phone’s settings.

The admin can restrict the use of the application to certain user groups by clicking on the profile picture in the upper right corner > ‘Apps’, then by clicking on ‘SIP Trip Phone’ in the list of apps, then by checking the ‘Limit to groups’ checkbox, then entering the name of the group whose members will be allowed to use the application.

26.7.2.6. Disable the microphone indicator in Firefox

By default, when a web page requests access to the computer’s microphone or webcam and the user grants access, a microphone/webcam indicator icon is displayed at the top of the screen until that web page is closed. If you want to disable this microphone/webcam indicator when using SIP Trip Phone and in other similar situations, follow these steps:

– In Firefox, go to ‘Help’ > ‘Troubleshooting Information’ and find the directory listed in ‘Profile Directory’. For Debian 11, this is /root/.mozilla/firefox/oikqae27.default-esr

– In the ‘Profile Directory’ create the chrome directory (/root/.mozilla/firefox/oikqae27.default-esr/chrome)

– In the chrome directory create the file userChrome.css file with the following content:

#webrtcIndicator {
  display: none;
}

– Type about:config in the address bar of Firefox, press Enter, click ‘I accept the risk’, then search for:

toolkit.legacyUserProfileCustomizations.stylesheets

Double-click it to change its value from false to true.

Restart Firefox.

26.7.2.7. Upgrading SIP Trip Phone

SIP Trip Phone can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that SIP Trip Phone has an active ‘Update’ button, click on it and the new version will be installed.

26.7.3. Install SMS Relentless

SMS Relentless connects to a ‘telnyx.com’, ‘plivo.com’, ‘twilio.com’ or ‘flowroute.com’ account to send and receive SMS/MMS messages. It needs at least one SMS enabled phone number acquired from Telnyx, Plivo, Twilio or Flowroute. It allows sending and receiving SMS/MMS messages from a browser, using one or multiple phone numbers located in a country chosen by the user. The numbers can be acquired from either of the 4 providers or from all. Users can send individual SMS/MMS messages to any SMS/MMS enabled phone numbers in the world, they can send messages to multiple recipients by uploading ‘csv’ or ‘txt’ files containig the target phone numbers, they receive delivery receipts for sent messages, they receive Nextcloud notifications and can also receive email notifications when new messages arrive, they can list all the sent and received messages in paginated tables, filter all the messages by any table column, archive messages older than a specified number of days before deleting them, so that they become available for future viewing and analysis, list current balance and current phone numbers, set alphanumeric sequences as Sender IDs for sent messages, etc.

For SMS Relentless to work correctly, the well-known ‘libcurl’ PHP library has to be installed on the server (it’s usually installed automatically when PHP is installed), and the logtimezone parameter has to be included in the Nextcloud configuration file, like this:

'logtimezone' => 'Europe/Berlin',

Replace Europe/Berlin with your own timezone. Accepted timezones can be found here.

Before explainig how to install and configure SMS Relentless, we’ll describe how to buy a real phone number from Telnyx/Plivo/Twilio/Flowroute and configure it for SMS messaging.

26.7.3.1. Acquire a phone number from Telnyx and configure it for SMS messaging

After you sign up for a Telnyx account here and log in to your account here, the first thing to do is to click on the ‘My Account’ icon in the upper right corner of the screen, then click on ‘My Account’, click on the ‘Account Level’ tab and then take the steps to undergo verification, to become ‘Level 1’ and ‘Level 2’ verified. ‘Level 1’ verification usually requires verifying the email address you used to create your Telnyx account, by clicking a link included in a message sent to that email address. ‘Level 2’ verification can be requested by pressing the ‘Verify’ button in the ‘Level 2 Verification’ section (on the ‘Account Level’ tab). After you make your request for ‘Level 2’ verification, a representative from Telnyx will look at your account details and (s)he may send you an email asking about the way you plan to use your Telnyx account, after which (s)he will approve the ‘Level 2’ verification. Being ‘Level 1’ and ‘Level 2’ verified unlocks all the features of a Telnyx account: you can buy numbers, assign a connection/messaging profile to a number, set up global messaging capabilities, create a multi-user organization, make international calls, set up call forwarding, send SMS messages at a higher rate.

While logged in to your telnyx.com account, click on ‘Numbers’, ‘My Numbers’ on the left panel. To buy a real phone number located in a country of your choice click on the ‘Search & Buy Numbers’ tab, then under ‘Local Numbers’, in the ‘Search Type’ select ‘Region’, in the ‘Region’ text field enter the name of the country, in the ‘Number Features’ select ‘Voice’, then, if you want your number to have other capabilities select other features such as ‘SMS’ from the drop-down list, then click on the ‘Search Numbers’ button. You will see a list with all the numbers available in the selected region. Choose the number that you like, click ‘Add to Cart’, then click on ‘Cart’ on the upper bar, then click on the ‘Place Order’ button.

After you have bought a local phone number click on ‘Numbers’, ‘My Numbers’ on the left panel; on the ‘My Numbers’ tab you will see your number in the list of acquired phone numbers.

Then create a new messaging profile: click on ‘Messaging’, ‘Programmable Messaging’ on the left panel, then click the ‘Add new profile’ button, then enter a name for the new messaging profile in the ‘Profile Name’ field, then click the ‘Save’ button. To associate the new messaging profile with the phone number that you have just bought, click on ‘Numbers’, ‘My Numbers’ on the left panel, then, on the row of the phone number, on the ‘Messaging Profile’ column, click on the drop-down list and select the name of the messaging profile that you have just created. When you assign a messaging profile to a phone number, a $0.10 fee will be added to the monthly recurring charge for that phone number. Therefore, if the phone number costs $1.00 per month, after you assign a messaging profile to it and by doing so you enable it to send and receive SMS messages, the monthly recurring charge for that number will be $1.10. The same messaging profile can be associated with multiple phone numbers.

Next, create a ‘Billing Group’. Click on the ‘My Account’ icon in the upper right corner of the screen, click on ‘Billing Overview’, then click on the ‘Billing Groups’ tab. In the ‘Create Billing Group’ field enter a name for the new billing group, then click on ‘Create’. Then add the billing group to your phone number: click on ‘Numbers’, ‘My Numbers’ on the left panel, then on your number’s row, in the ‘Billing Group’ field select the name of the billing group that you have just created.

26.7.3.2. Acquire a phone number from Plivo and configure it for SMS messaging

After you sign up for a Plivo account here and log in to your account here, to buy a phone number click on the pound sign (#) on the left hand vertical bar, then, on the left sidebar, under ‘Phone Numbers’, click on ‘Buy Numbers’. From the ‘Country’ drop-down list select the country where you want your number to be located. Under ‘Type’ check ‘Any’ and under ‘Capability’ check ‘Any’. If you know what prefix you want for your number, type the prefix in the ‘Number’ field, while having ‘Number’ selected from the ‘drop-down’ list. You can also choose ‘Location’ from that drop-down list, then type the name of the city or state you want your number to be located in. Click the ‘Search’ button to search for the available phone numbers, then pick a phone number that you like. The number should have at least ‘SMS’ specified on the ‘Capability’ column. To buy the number just click the ‘Buy Number’ button.

After you have bought a real phone from Plivo, click on ‘Your Numbers’ on the left sidebar, then, under ‘Number and Area’ click on your phone number. In the new window, from the ‘Application Type’ drop-down list choose ‘XML Application’ and from the ‘Plivo Application’ drop-down list choose ‘Inbound SMS Messages’, then click the ‘Update Number’ button. If during tests you try to send a message from a 10 digit number to itself, it won’t get through, since Plivo doesn’t allow sending SMS messages from a 10 digit number to itself.

26.7.3.3. Acquire a phone number from Twilio and configure it for SMS messaging

After you sign up for a Twilio account here, and log in to your account here, to buy a phone number click on ‘Phone Numbers’ on the left panel > ‘Manage’ > ‘Buy a number’. Then select the country where you want your phone number to located from the ‘Country’ drop down list, check the checkboxes for the capabilities that you want your number to have: Voice, SMS, MMS, Fax. Next, under ‘Search criteria’ you can select ‘Locality’, then enter the name of a state or city in the next textbox, then click the ‘Search’ button. If you click ‘Advanced Search’, you can add additional filters: local/mobile/toll-free number, (providing proof of) address requirements, etc. After you click the ‘Search’ button, all the available phone numbers will be listed, according to your filters. Choose one phone number and click the ‘Buy’ button. A pop up window will inform you about the number capabilities, etc. Click the ‘Buy …’ button again and you will be redirected to the payment page where you can pay with your debit/credit card. After purchase, the phone number will be listed on the active phone numbers page: on the left panel click ‘Phone Numbers’ > ‘Manage’ > ‘Active phone numbers’. If you click on the phone number you will go to the ‘Configure’ page for that number, where you can add the webhook URL for incoming messages, as explained in the Twilio Settings section from below.

To be able to send messages from a phone number that you have purchased as explained above, you will have to enable sending messages to the country/countries where the destination numbers are located. To enable sending messages to different countries, on the left panel, click on ‘Messaging’ > ‘Settings’ > ‘Geo permissions’. On the ‘Messaging Geographic Permissions’ page you can check each country to which you want to be able to send messages, or you can select whole continents by checking the ‘Enable all’ checkbox under each continent’s name.

You can also associate your number with a ‘Messaging Service’, either alone, or together with other numbers or Alphanumeric Sender IDs. A Messaging Service is a type of ‘bundling’ messaging functionalities around a set of senders. The same feature configuration applies to all the senders (long code numbers, short codes, toll-free numbers, Alphanumeric Sender IDs, etc.) in the same Messaging Service pool. To create a Messaging Service and associate a number with it, on the left panel, click on ‘Messaging’ > ‘Services’, then click the ‘Create Messaging Service’ button, enter a name for the new Messaging Service in the ‘Messaging Service friendly name’ field, then select the general purpose for the Messaging Service under ‘Select what you want to use Messaging for’ (‘Notify users’, ‘Market services’, ‘Verify users’, ‘Engage in a discussion’, ‘Poll and survey users’, or you can select ‘Not listed here’). After you click ‘Create Messaging Service’, you will see the ‘Sender Pool’ page. There, when you will click the ‘Add Senders’ button, a pop up window will open. Under ‘Sender Type’ you will select any of ‘Phone Number’, ‘Short Code’, ‘Alpha Sender’, etc. If you select ‘Phone Number’ and click ‘Continue’, you will be able to add any of your active phone numbers to the new Messaging Service, then, on the ‘Integration’ page you will be able to configure the behavior for incoming messages, delivery status webhook and queue time limit. There are also the ‘Content Settings’, ‘A2P & Compliance’ and ‘Opt-Out Management’ sections, where you can find different useful options.

If during tests you try to send a message from a 10 digit number to itself, it won’t get through, since Twilio doesn’t allow sending SMS messages from a 10 digit number to itself.

26.7.3.4. Acquire a phone number from Flowroute and configure it for SMS messaging

After you sign up for a Flowroute account here, and log in to your account here, first you will be prompted to enter your address and to add funds to your new account. You can use a debit/credit card to add funds (the minimum amount accepted is $40). You can always update your address by clicking on ‘Preferences’ on the left panel and then on the ‘Account Information’ tab.

Before buying a phone number, you may want to click on ‘Preferences’ on the left panel, then click on the ‘Features’ tab, then turn off the ‘CNAM Lookups by Default’ switch, to avoid incurring additional fees for CNAM lookups for the newly purchased numbers.

It’s important to note that Flowroute only supports sending/receiving SMS/MMS messages within USA and Canada (and it doesn’t support Alphanumeric Sender IDs). Therefore, if you want to buy an SMS/MMS enabled phone number, you can only choose one located in USA or Canada and you can use it to send and receive messages only to and from USA and Canada. (On the other hand, Flowroute offers voice enabled phone numbers in 160 countries.)

To buy a phone number click on ‘DIDS’ on the left panel, then click on the ‘Purchase’ tab. On the ‘DID Purchase’ page you can use the filters on the left panel to search for the available phone numbers in the country/state of your choice. Once you see the list of available phone numbers, you can choose a number and click the ‘Purchase’ button next to it. A pop up message will ask if you want to send/receive SMS/MMS messages on the chosen number. Click ‘Yes’ and the number will be added to the list of purchased numbers that you can see by clicking on the ‘Manage’ tab.

The next step is to enable the latest messaging API version by clicking on ‘Preferences’ on the left panel, then clicking on the ‘API Control’ tab, then scrolling down to the ‘SMS Webhook Version’ and choosing ‘v2.1’, since this is the latest stable version of the messaging API.

To be able to send/receive messages, you will have to also create a pair of API keys and add the webhook URL for receiving messages on the same ‘API Control’ tab, as explained in the Flowroute Settings section from below.

26.7.3.5. Install and configure SMS Relentless

You can install SMS Relentless like any other Nextcloud application. Click on the profile picture from the upper right corner > Apps > search for ‘SMS Relentless’ using the search box on the upper bar > click ‘Download and install’. Next, configure SMS Relentless by clicking on the profile picture > Settings > then, on the left panel under ‘Personal’ click ‘SMS Relentless’. In the settings fields, you can fill in your credentials from Telnyx if you want to use Telnyx as SMS service provider, or you can fill in your credentials from Plivo if you want to use Plivo. Of course, if you have bought phone numbers from both providers and you want to use both, fill in the credentials for both. Fill in the settings fields as follows:

Telnyx Settings

– in the Telnyx API Secret Key field enter your Telnyx API Key: log in to Telnyx, then, on the ‘Home’ page, in the ‘API Keys’ section from the upper right corner, click on ‘Manage Keys’. If you already have an API key, just copy it by clicking the ‘Copy to clipboard’ icon. Otherwise, to create an API key, click the ‘Create API Key’ button, on the pop up message click ‘Create’, then copy the Key and enter it in the Telnyx API Secret Key field.

– in the Telnyx Account Public Key field enter the public key necessary to verify the signature of the incoming SMS messages: while logged in to Telnyx, on the ‘Home’ page, in the ‘API Keys’ section from the upper right corner, click on ‘Manage Keys’, then click on ‘Public Key’ on the upper bar, then copy the key from the ‘Key’ field and enter it in the Telnyx Account Public Key field.

– in the Messaging Profile ID enter the messaging profile ID that you will be using (you can have multiple phone numbers associated with the same messaging profile ID): while logged in to Telnyx, click on ‘Messaging’ on the left panel, click on the name of the messaging profile that you want to use, then under ‘Profile ID’ you will find the messaging profile ID. Copy it and enter it in the Messaging Profile ID field.

– in the Telnyx webhook URL for incoming SMS/MMS field enter the webhook URL for incoming messages. You have to first generate and then copy this URL into your Telnyx account, so that Telnyx knows where to deliver the SMS/MMS messages received by your Telnyx phone number(s). First generate the URL by pressing the ‘Generate new webhook URL for incoming SMS/MMS’ button, copy it, then, in your Telnyx account click on ‘Messaging’, then on ‘Programmable Messaging’ on the left panel, click on the name of the messaging profile that you associated with your phone number(s), then, under ‘Inbound Settings’, enter the webhook URL generated here in the field ‘Send a webhook to this URL’, then click ‘Save’.

– in the Telnyx webhook URL for delivery receipts field enter the webhook URL for the delivery receipts that you will receive for sent messages. This URL will be included by SMS Relentless in message sending requests, so that Telnyx knows where to send the delivery receipts. Just generate it by pressing the ‘Generate new webhook URL for delivery receipts’ button. You don’t have to enter this URL into your Telnyx account.

– in the Telnyx alphanumeric Sender ID field you can enter an alphanumeric sequence of up to 11 characters in the range of a-z, A-Z, 0-9 and space, if you intend to use an alphanumeric Sender ID. In certain countries there are regulations that accept only shorter alphanumeric Sender IDs, such as up to 6 characters. You cannot send SMS/MMS messages with alphanumeric Sender IDs to USA or Canada. There are even countries that require preregistration of alphanumeric Sender IDs. Before sending SMS/MMS messages to a country it’s recommended to read the country specific features and restrictions. Some carriers won’t accept messages with an alphanumeric Sender ID.

Plivo Settings

– in the Plivo Auth ID field enter your Plivo Auth ID: log in to Plivo, then, on the first page which is the Overview page, under Account, copy the ‘Auth ID’.

– in the Plivo Auth Token field enter the auth token: while logged in to Plivo, on the Overview page, under Account, copy the ‘Auth Token’.

– in the Plivo webhook URL for incoming SMS/MMS field enter the webhook URL for incoming messages. You have to first generate and then copy this URL into your Plivo account, so that Plivo knows where to deliver the SMS/MMS messages received by your Plivo phone number(s). First generate the URL by pressing the ‘Generate new webhook URL for incoming SMS/MMS’ button, copy it, then, in your Plivo account click on ‘Messaging’ on the left vertical bar, click on ‘Applications’, then, under ‘Application name’ click on ‘Inbound SMS Messages’, next, under ‘Message’, enter the webhook URL generated earlier in the field ‘Message URL’ and select ‘POST’ next to it, then click the ‘Update Application’ button.

– in the Plivo webhook URL for delivery receipts field enter the webhook URL for the delivery receipts that you will receive for sent messages. This URL will be included by SMS Relentless in message sending requests, so that Plivo knows where to send the delivery receipts. Just generate it by pressing the ‘Generate new webhook URL for delivery receipts’ button. You don’t have to enter this URL into your Plivo account.

– in the Plivo alphanumeric Sender ID field you can enter an alphanumeric sequence of up to 11 characters in the range of a-z, A-Z, 0-9 and space, if you intend to use an alphanumeric Sender ID. In certain countries there are regulations that accept only shorter alphanumeric Sender IDs, such as up to 6 characters. You cannot send SMS/MMS messages with alphanumeric Sender IDs to USA or Canada. There are even countries that require preregistration of alphanumeric Sender IDs. Before sending SMS/MMS messages to a country it’s recommended to read the country specific features and restrictions. Some carriers won’t accept messages with an alphanumeric Sender ID.

Twilio Settings

– in the Twilio Account SID field enter your Twilio Account SID: log in to Twilio, then, on the first page, under Account Info, copy the ‘Account SID’.

– in the Twilio Auth Token field enter your Auth Token: while logged in to Twilio, on the first page, under Account Info, copy the ‘Auth Token’.

– in the Twilio webhook URL for incoming SMS/MMS field enter the webhook URL for incoming messages. You have to first generate and then copy this URL into your Twilio account, so that Twilio knows where to deliver the SMS/MMS messages received by your Twilio phone number(s). First generate the URL by pressing the ‘Generate new webhook URL for incoming SMS/MMS’ button, copy it, then, in your Twilio account click on ‘Phone Numbers’ on the left panel > ‘Manage’ > ‘Active numbers’, click on the phone number you want to use for SMS/MMS, scroll down to the ‘Messaging’ section, then under ‘A MESSAGE COMES IN’ select ‘Webhook’, then paste in the webhook URL that you have just generated and select ‘HTTP POST’ as the request type. Enter the same data under ‘PRIMARY HANDLER FAILS’, then click the ‘Save’ button. If you have multiple SMS/MMS enabled phone numbers, do the same for each number.

– in the Twilio webhook URL for delivery receipts field enter the webhook URL for the delivery receipts that you will receive for sent messages. This URL will be included by SMS Relentless in message sending requests, so that Twilio knows where to send the delivery receipts. Just generate it by pressing the ‘Generate new webhook URL for delivery receipts’ button. You don’t have to enter this URL into your Twilio account.

– in the Twilio alphanumeric Sender ID field you can enter an alphanumeric sequence of up to 11 characters in the range of a-z, A-Z, 0-9 and space, if you intend to use an alphanumeric Sender ID. In certain countries there are regulations that accept only shorter alphanumeric Sender IDs, such as up to 6 characters. You cannot send SMS/MMS messages with alphanumeric Sender IDs to USA or Canada. There are even countries that require preregistration of alphanumeric Sender IDs. Before sending SMS/MMS messages to a country, it’s recommended to read the country specific features and restrictions. Some carriers won’t accept messages with alphanumeric Sender IDs.

Flowroute Settings

– in the Flowroute Access Key field enter your Acess Key: log in to Flowroute. On the left panel, click on ‘Preferences’, then on the ‘API Control’ tab. Scroll down to the ‘API Keys’ section. If you already have a pair of keys listed in that section, just copy the Access Key to the field from below. If you haven’t created any keys yet, to create a key pair, under ‘Add new API Key’, in the ‘Name’ field, enter a name for the new key pair. In the ‘Description’ field enter a short description, then click ‘Add new’. A new pair of keys will be created and you will be prompted to copy the Secret Key. Copy it in a safe location.

– in the Flowroute Secret Key field enter the Secret Key that you created earier.

– in the Flowroute webhook URL for incoming SMS/MMS field enter the webhook URL for incoming messages. You have to first generate and then copy this URL into your Flowroute account, so that Flowroute knows where to deliver the SMS/MMS messages received by your Flowroute phone number(s). First generate the URL by pressing the button from below, copy it, then, in your Flowroute account click on ‘Preferences’ on the left panel, then click on the ‘API Control tab’, turn on the ‘SMS’ switch and in the field that shows up enter the URL that you have just generated. Click ‘Save URL’. If you have an MMS enabled phone number, turn on the ‘MMS’ switch, enter the same URL in the URL field and save it. Also, under ‘SMS Webhook Version’ choose ‘v2.1’.

– in the Flowroute webhook URL for delivery receipts field enter the webhook URL for the delivery receipts that you will receive for sent messages. This URL will be included by SMS Relentless in message sending requests, so that Flowroute knows where to send the delivery receipts. Just generate it by pressing the ‘Generate new webhook URL for delivery receipts’ button. You don’t have to enter this URL into your Flowroute account.

Flowroute only supports sending/receiving SMS/MMS messages within USA and Canada and it doesn’t support Alphanumeric Sender IDs.


– in the Number of messages per page field enter the number of messages to be displayed on one page of the received and sent messages tables. If you don’t enter anything in this field, the default of 100 messages per page will be used.

– check the I want to see a notification in Nextcloud when a new SMS/MMS is received checkbox if you want to see Nextcloud notifications when new SMS/MMS messages arrive.

– if you want to enable email notifications enter your email address in the I want to receive a notification to the email address from below, when a new SMS/MMS is received field.

– if you want the SMS/MMS message to be included in the email notification, check the Include the SMS/MMS message in the email notification itself checkbox.

Click ‘Save’ to save all the settings to the database.

26.7.3.6. Using SMS Relentless

To use SMS Relentless just click on its icon on the upper bar, inspect the Telnyx/Plivo/Twilio/Flowroute available balance by selecting the name of the provider from the Balance drop-down list, then click on the refresh button on the Set ID line to refresh the list of available sender IDs, then choose one of the phone numbers or alphanumeric IDs from the drop-down list, then enter the phone number of the receiver preceded by the country code in the phone number field (Eg.: 491212121212, where 49 is the country calling code), then enter the text of the message in the message text area, then press the ‘Send SMS’ button.

You can send the same message to multiple receivers by writing their phone numbers in the number field one after the other separated by coma, or if you have a large number of receivers, like hundreds or thousands, you can upload a txt or csv file by checking the ‘Upload file with phone numbers’ checkbox. In this case you should also specify the time interval in milliseconds between two consecutive message sending requests. You will find information about different restrictions regarding the message sending rate in the info note located above the ‘Upload the file’ button.

If your message contains special characters that don’t exist in the GSM 7-bit default alphabet table, it will be automatically encoded using the UCS-2 character encoding (similar to Unicode).

You can see the received SMS messages by clicking the ‘Received SMS Messages’ button and the sent messages by clicking the ‘Sent SMS messages’ button. Both tables have a row of filters at the top, that you can use to filter the messages by the content of one or multiple columns. The row of filters shows up when you click on the arrow from the top left corner of the application content area. You can also permanently delete messages by selecting them and then clicking on the ‘Permanently delete’ icon located on the left end of the filter row.

If you are a member of the ‘admin’ Nextcloud group, you can also remove old messages to keep the database small, by checking the ‘Remove old messages’ checkbox located below the ‘Sent SMS Messages’ button. You can remove all the messages that are older than the number of days that you specify in the appropriate fields. This can be done for both sent and received messages. If you delete old messages in this way, they won’t be really lost, because before deleting them, the application saves the messages in csv files that you can later find in the SMS_Relentless/removed_received_messages, and SMS_Relentless/removed_sent_messages folders. The csv files have names that include the date of the message removal. If they try to use this option, users that are not in the ‘admin’ group will see a popup message informing them that only admins can remove old messages.

If you have an MMS enabled phone number, you can send up to 10 files of various formats, including jpeg, png and gif, as MMS messages. After you check the ‘Select file(s) to send as MMS’ checkbox, an info note will display all the necessary information about the file format and size restrictions applicable to the provider who’s phone number you selected in the ‘Set ID’ drop-down list.

Since the deliverability of MMS messages depends on the carrier and device of the receiver and carriers can reject MMS messages with files exceeding a certain size, it’s recommended to avoid sending large files or with uncommon formats. The best deliverability is achieved when sending jpeg/jpg, png or gif files, with a total message size of 600 KB or less.

The files included in incoming MMS messages are not downloaded automatically. They are stored as URL links to the actual files and the receivers can download them only if they trust the senders and the domains of the URLs.

26.7.3.7. SMS Relentless workflow

Please note that in order to be able to use this application, any individual user has to have the credentials entered on the SMS Relentless’ settings page, in his own Nextcloud account (in Nextcloud ‘Settings’, on the left panel, under ‘Personal’, ‘SMS Relentless’).

In the most simple use case, where there is only one Telnyx/Plivo/Twilio/Flowroute account with one phone number associated with it, the admin, who creates the Nextcloud account for each Nextcloud regular user, will enter his own credentials (API access keys/tokens/IDs) on the SMS Relentless settings page of each regular user account. The 2 webhook URLs should be generated for each individual user by pressing the respective buttons. The webhook URL for delivery receipts being different from one user to the other, will allow each user to get the delivery receipts for the messages that he sends. In this type of setup, the admin’s credentials from the settings page are invisible to regular users, because they are replaced with placeholders once they are saved to the database (in encrypted form). Each message sent by a user will appear in the ‘Sent SMS Messages’ table as being sent by that respective user, and all the received messages will appear in the ‘Received SMS messages’ table as being received by the admin user, whose credentials are on the settings page.

Another use case is when different app users have different phone numbers in the same Telnyx/Plivo/Twilio/Flowroute account. In this situation, each user will enter the same credentials on the settings page, but they will have different webhook URLs for receiving messages, since separate phone numbers allow setting up separate webhook URLs for receiving messages.

Another use case is when different SMS Relentless users have different Telnyx/Plivo/Twilio/Flowroute accounts with different phone numbers associated with them. In this case, each user will enter his own credentials on the settings page and obviously, his own webhook URL for receiving messages.

In the ‘Sent SMS Messages’ table, each message record will show the user who sent the message and from what phone number. If all the users have different phone numbers in the same Telnyx/Plivo/Twilio/Flowroute account, or different Telnyx/Plivo/Twilio/Flowroute accounts, in the Received Messages table, each message record will show the specific user who received the message. As mentioned above, when all the users use the admin’s credentials on the settings page, all the received messages will be displayed in the ‘Received SMS Messages’ table as being received by the admin.

The admin can restrict the use of the application to certain user groups by clicking on the profile picture in the upper right corner > Apps, then by clicking on ‘SMS Relentless’ in the list of apps, then by checking the ‘Limit to groups’ checkbox, then entering the name of the group whose members will be allowed to use the application.

26.7.3.8. Upgrading SMS Relentless

SMS Relentless can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that SMS Relentless has an active ‘Update’ button, click on it and the new version will be installed.

26.7.4. Install Pax Fax

Pax Fax allows sending and receiving faxes in Nextcloud by connecting to a ‘phaxio.com’ account. A real fax number acquired from Phaxio is needed. Users can send up to 20 documents in one fax call (supported file formats are: pdf, doc, docx, odt, jpeg/jpg, png, tiff/tif, txt, html), they can send faxes to 15 different fax numbers at once, they can receive faxes as pdf documents in Nextcloud, they receive notifications in Nextcloud and can receive email notifications when new faxes arrive. All the sent and received faxes are stored in specific Nextcloud folders. Users can search for faxes by caller/callee phone number or date; they can see the current Phaxio balance; they can set their fax number as caller ID for sent faxes. When they want to send a fax, they can upload files from their computer or choose them directly from Nextcloud.

For Pax Fax to work correctly, the well-known ‘libcurl’ PHP library has to be installed on the server (it’s usually installed automatically when PHP is installed), and the logtimezone parameter has to be included in the Nextcloud configuration file, like this:

'logtimezone' => 'Europe/Berlin',

Replace Europe/Berlin with your own timezone. Accepted timezones can be found here.

Like with any other Nextcloud application, to install Pax Fax click on the profile picture from the upper right corner > ‘Apps’ > search for ‘Pax Fax’ using the search box on the upper bar > click ‘Download and install’. Next, configure Pax Fax by clicking on the profile picture > ‘Settings’ > then, on the left panel, under ‘Personal’ click ‘Pax Fax’.

pax_fax_settings

– in the Phaxio API Key and Phaxio API Secret fields enter the key and secret that you can find by logging in to Phaxio and clicking ‘API Keys’ on the left panel; then, under ‘Live Keys’ you will find the ‘API Key’ and the ‘API Secret’.

– in the Phaxio Webhook Token field enter your webhook token that you can find in your Phaxio account, by clicking ‘Webhooks’ on the left panel, then scrolling down to ‘Webhook Token’.

– in the Phaxio callback URL for incoming faxes field enter the callback URL that Phaxio will use to send incoming faxes to. This URL must have the form: https://username:6VTGs-c36j4-qK2wm-RgJcl-9pjUD@cloud.example.com/apps/pax_fax/api/recfaxphaxio if Nextcloud is served on a subdomain, or https://username:6VTGs-c36j4-qK2wm-RgJcl-9pjUD@example.com/nextcloud/apps/pax_fax/api/recfaxphaxio if Nextcloud is served on a subdirectory, where username is the Nextcloud user who has a Phaxio phone number in her/his Phaxio account (callback URLs can only be configured one per Phaxio phone number. If username contains an @ , replace @ with &commat; otherwise the URL won’t function), 6VTGs-c36j4-qK2wm-RgJcl-9pjUD is the ‘application password’ created for this purpose as explained below, and cloud.example.com is your Nextcloud domain. To create the Nextcloud ‘application password’ click on the profile picture in the upper right corner, then click ‘Personal settings’, then, on the left panel, under ‘Personal’ click ‘Security’, then under ‘Devices & sessions’, in the ‘App name’ field enter Pax_Fax, then click the ‘Create new app password’ button. The password will be displayed only when created. Copy the password, click the ‘Done’ button, enter the password in the constructed callback URL between ‘:’ and ‘@’ as shown above, copy the entire callback URL to a safe location, then enter the callback URL in the field Phaxio callback URL for incoming faxes. The next step is to enter the callback URL that you have just created in your Phaxio account: log in to Phaxio, click ‘Phone Numbers’ on the left panel, click the settings wheel on the row of the phone number for which you want to set up the callback URL, enter the URL in the ‘Callback URL’ field, then click ‘Save’. Also, click on ‘Webhooks’ on the left panel, then scroll down to ‘Webhook Version’ and choose ‘Version 2.1.0’, then click the ‘Update’ button.

– check the ‘I want to see a notification in Nextcloud when a new fax is received‘ checkbox if you want to receive Nextcloud notifications when new faxes arrive.

– in the ‘I want to receive a notification to the email address from below, when a new fax is received‘ field enter your email address if you want to receive an email notification when new faxes arrive.

Click the ‘Save’ button at the bottom of the page to save all the settings to the database.

26.7.4.1. Using Pax Fax

To use Pax Fax, click on its icon on the upper bar. You can see the current Phaxio balance by clicking the ‘Phaxio balance’ refresh button. Then, on the ‘Set ID’ line, you can first refresh the list of the available IDs, then choose from the drop-down list one of your Phaxio fax numbers, or the blank space if you want to send a fax with no Sender ID. If you don’t choose a fax number as Sender ID, the receiver will see the fax as coming from one of Phaxio’s internal numbers.

Next, in the phone number field enter the reveiver’s fax number preceded by the country calling code. For example, a German fax number would look like this:

491212121212

where 49 is the country calling of Germany. You can enter up to 15 fax numbers separated by comma in this field, if you want to send the fax simultaneously to multiple recipients.

Next, upload a file from your computer to send as fax, or choose a file from Nextcloud. Allowed formats are: pdf, odt, jpg, png, txt, tif, html, doc, docx. You can upload or choose from Nextcloud multiple files to be sent in the same fax call, one after the other; you can send up to 20 files in one fax call, with a cumulative size of up to 20 MB, and up to 200 pages. If you have more pages to send, you can split them in two or more groups and send them in multiple fax calls.

Then click ‘Send Fax’. You can see the sent faxes by clicking on the ‘Sent Faxes’ button and the received faxes by clicking on the ‘Received Faxes’ button. If sending a fax fails because the fax number was wrong, or the connection dropped, or the receiving fax machine had a problem, etc., you will find the failed fax in the Pax_Fax/faxes_sent_failed folder or by clicking on the ‘Failed Sent Faxes’ button. Similarly, if for some reason an incoming fax fails, you will find a failed fax file in the Pax_Fax/faxes_received_failed folder, or by clicking on the ‘Failed Received Faxes’ button. The faild faxes files will be empty but they will have a name that will include the date of the received fax.

All the received faxes will be pdf files and all the sent and received faxes will have the date of sending/receiving included in their names, as well as the to/from fax numbers, so that they can be easily found by their destination/origin fax number or by their date, using the search function of Nextcloud. To use the Nextcloud search function to filter the sent/received faxes navigate to Pax_Fax/faxes_sent or Pax_Fax/faxes_received and enter a fax number or a date in the search box located on the upper bar.

If you follow all the instructions of this guide to properly install and use Nextcloud and Pax Fax and you also follow the steps presented on this Phaxio page, your faxes sent via Phaxio will be HIPAA-compliant (Health Insurance Portability and Accountability Act).

If you send as fax a jpg, png or tiff image with a height between 500 px and 700 px, in general, Phaxio will flip the image on its side clockwise and enlarge it, so that it becomes easier to distinguish on the receiver side.

Please note that if you want to send as fax a jpg, png or tiff image which is more than 700 px in height, it’s safer to paste it inside an A4-sized or letter-sized page of a pdf, odt or docx document and send it included in that document. Otherwise, Phaxio can downsize it automatically so much, that its content can be difficult to distinguish.

Please also note that when using Pax Fax, from time to time, you will get a ‘failed incoming fax’ notification in Nextcloud and a notification email, if email notifications are enabled. This failed incoming faxes are very rarely true faxing attempts that failed due to legitimate reasons, such as phone line congestion, etc. In general, they are scamming attempts: scammers try to make very short calls to random numbers and if the receivers call them back to see what they want, the receivers get charged large amounts of money for international calls, since the calling numbers are set up as premium-rate numbers and are typically located overseas. Therefore, our advice is to totally ignore all the ‘failed incoming faxes’ notifications. You shouldn’t send a fax to such numbers or call them back, just because you received one or multiple failed faxing attempts from them. If an incoming fax fails for legitimate reasons, a legitimate fax sender will know that the fax failed and will send it successfully when (s)he will try again. The extremely short calls that you may get on fax numbers or regular phone numbers from unknown callers located overseas are highly suspect and should be ignored.

It’s important to know that Phaxio only charges for fax pages that get through and not for failed faxing attempts.

When you will click on the ‘Received Faxes’ or ‘Sent Faxes’ button and then open a pdf file or a jpg or png image sent as fax, you will notice that the viewer’s upper bar with the ‘Close’ button doesn’t show up. Therefore, to close the open pdf or jpg/png image, you will have to click the ‘Received Faxes’ or ‘Sent Faxes’ button again. This is because in the latest Nextcloud versions, the viewer’s upper bar with the ‘Close’ button was moved from below the Nextcloud upper bar right over it. Since the Nextlcoud upper bar is hidden in Pax Fax’ right panel, the viewer bar is not shown either:

However, if you install the ‘Custom CSS’ app, you can overcome this problem and make the viewer’s upper bar appear at the top of open pdf/jpg/png files, as shown below:

This has the disadvantage that when you will open any odt, ods, odp, docx, xlsx, pptx, etc. file with Collabora Online, the bottom bar containing the search box, the language drop-down list, the zoom level indicator, etc., will be pushed downwards and will not be visible. If you still want to install the ‘Custom CSS’ app, just click on the user icon in the upper right corner > ‘Apps’, then enter ‘Custom CSS’ in the search box on the Nextcloud upper bar. When you find the ‘Custom CSS’ app click on the ‘Download and enable’ button to install it. Once the app is installed, click again on the user icon > ‘Settings’, then, on the left panel, under ‘Administration’, click on ‘Theming’ and scroll to the bottom of the page. There, in the ‘Custom CSS’ text area enter:

#viewer { margin-top: 50px !important; height: 30px !important; }
.modal-header { height: 30px !important; }

Click ‘Save’ to save the changes. From that moment on, the viewer’s upper bar will be shown below the Nextcloud upper bar and you will be able to use it to close open pdf/jpg/png documents in Pax Fax.

26.7.4.2. Pax Fax workflow

Please note that any individual user will have to have the Pax Fax credentials on the settings page of Pax Fax, under ‘Personal’, in their own Nextcloud account in order to be able to use the application. In general, the admin, who creates the Nextcloud account for each regular user, enters his own API Key and API Secret on the Pax Fax settings page of each regular user Nextcloud account. The API Key and Secret, as well as the webhook token and the callback URL are invisible to the regular users, because they are replaced with placeholders once they are saved to the database (encrypted). In this way, all the received faxes will be saved in the Pax_Fax/faxes_received directory of the admin Nextcloud account and not in the regular users’ Pax_Fax/faxes_received respective directories. If the admin wants any other users apart from himself to see the received faxes, he has to share the Pax_Fax/faxes_received folder with those users. With sent faxes, the situation is different: if a Nextcloud user sends a fax, the sent fax will be saved in the Pax_Fax/faxes_sent folder of that respective user, regardless if he is a regular user or the admin. If the admin wants to see what faxes were sent by what users, he can ask the users to share their Pax_Fax/faxes_sent directories with him, or he can inspect/download the sent faxes of any user directly via FTP, by connecting to the server and navigating to /var/www/cloud.example.com/data/username/files/Pax_Fax/faxes_sent directory, where example.com is the Nextcloud domain and username is the name of the user.

Like with other Nextcloud applications, the admin can restrict the use of Pax Fax to certain user groups by clicking on the profile picture in the upper right corner > Apps, then by clicking on ‘Pax Fax’ in the list of apps, then by checking the ‘Limit to groups’ checkbox, then entering the name of the group whose members will be alllowed to use the application.

However, if a Phaxio account has multiple fax numbers associated with it, different Nextcloud users of Pax Fax can use different fax numbers of the same Phaxio account, each number having a different webhook for receiving faxes. In this situation, if a fax is received on one fax number, it will be saved only in the Pax_Fax/faxes_received directory of the user whose fax number received the fax. Also, different users of Pax Fax can have different Phaxio accounts, each with its own associated fax number(s). In this situation again, if a fax is received, it will be saved only in the Pax_Fax/faxes_received directory of the user whose fax number received the fax.

It’s good to know that Phaxio gives its users the ability to receive all incoming faxes as email attachments. If you don’t want your faxes to be received by Pax Fax and you want to receive them as email attachments, log in to Phaxio, click on ‘Phone Numbers’ on the left panel, click on the wheel next to the fax number(s), delete the webhook URL associated with the number(s) for receiving faxes, click ‘Save’, then click on ‘Webhooks’ on the left panel and in the ‘Sent Handler’ and ‘Received Handler’ fields enter mailto:admin@example.com where admin@example.com is the email address where you want to receive your faxes, then click ‘Update’. On the same page, in the ‘Webhook Version’ field, make sure it’s Version 2.1.0 selected.

For increased privacy it’s recommended that you configure your Phaxio account so that the sent/received faxes are not stored on Phaxio’s servers. To do this click on ‘Fax’ on the left panel, then scroll down and uncheck ‘Store sent fax files on Phaxio server?’ and ‘Store received fax files on Phaxio server?’, then click ‘Update’.

On the same page, there is another checkbox: ‘Receive faxes that only partially completed’. It’s recommended to check this checkbox. You can also check the ‘Include caller name for received faxes’ checkbox, but if you do, you will be charged $0.08 per received page instead of $0.07, for faxes from USA or Canada. Leave all the other settings as they are, then click ‘Update’.

26.7.4.3. Upgrading Pax Fax

Pax Fax can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that Pax Fax has an active ‘Update’ button, click on it and the new version will be installed.

26.7.5. Install the Calendar app

To install the Calendar app click on the upper right corner user icon > click on ‘Apps’ > click on the ‘Search’ icon on the Nextcloud upper bar, search for ‘Calendar’ > when the app is found click on ‘Download and enable’.

To open the Calendar app click on its shortcut on the Nextcloud upper bar.

To create a new calendar, click on the plus sign next to ‘New calendar’ on the left panel and choose ‘New calendar’. Enter a name for the new calendar then click the arrow to create the calendar. You can create multiple calendars. To toggle the visibility of a calendar just click on its name. On the left panel you can choose the month to view, you can switch between Day/Week/Month/List view for the selected calendar(s) and you can create a new event by clicking on the ‘New event’ button. Yet, the best way to create events is by clicking on the rectangle of the day of the month in which you want to place the event.

While a calendar is displayed in ‘month view’, if you click on a day of the month, the ‘New event’ panel will open at the right end of the screen. There you can enter a suggestive name for the new event, you can choose the name of the calendar to which the event will belong, if you have multiple calendars, you can choose the moment when the event will start and the moment when it will end or whether it will last all day.

On the ‘Details’ tab you can add a location for the new event, a description, whether the event is confirmed or not, the visibility of the event in shared calendars, whether the time interval of the event will count as busy or free time, you can add a category and a specific color to the event.

On the ‘Attendees’ tab you can search for other Nextcloud users to add as attendees to the newly created event. You can also enter the email addresses of attendees that are not Nextcloud users. After you add each attendee, you can click on the three dots next to their email address to assign them a role: ‘Chairperson’/’Required participant’/’Optional participant’/’Non-participant’. If you leave the ‘Send e-mail’ checkbox checked, the attendee will receive the invitation to the event by email, the moment you save the event.

On the ‘Reminders’ tab you can add a reminder for the event. You can choose the moment when the reminder will be sent (a day before the event starts, 30 minutes before the event starts, etc.). After the reminder is added, you can click on the three dots next to it to choose whether the reminder will be a notification or an email. If you choose ‘Notification’, the attendees will see a Nextcloud notification when they will log in to Nextcloud. If you choose ‘Email’, the attendees will receive an email on the moment of the reminder. However, Nextcloud can send emails at specific times only if its cron script is run at those specific times. So, to enable email notifications, you will need to set up a cron job on the server, that will run the cron script inside Nextcloud with a specific frequency. So, on your server run:

crontab -e

At the bottom of the file enter the following lines:

# Run the Nextcloud cron script every 15 minutes
*/15 * * * * sudo -u www-data php -f /var/www/cloud.example.com/cron.php

Replace example.com with your main domain. Of course, you can run the Nextcloud cron script with a higher or lower frequency, like once every 10 or 5 minutes, or once every hour, etc. After setting up this cron job, make sure that in Nextcloud Settings, under ‘Administration’ > ‘Basic settings’ > ‘Background jobs’, the ‘Cron’ option is selected.

On the ‘Repeat’ tab, you can choose if the new event should be repeated, and with what frequency (once every day/several days, once or multiple times per week, month, year).

You may find useful the fact that you can share a calendar with persons that don’t have a Nextcloud account. To create the public share link for a calendar, click on the share sign next to the calendar name, on the left panel, then click on the plus sign. You can then copy the public access link to clipboard by clicking on the ‘Copy public link’ icon. If you send the public access link by email to somebody, they can open it in a browser and have read-only access to the calendar, without being logged in to Nextcloud.

26.7.5.1. Add Nextcloud calendars as remote calendars in Thunderbird

First click on the Calendar app icon. If you click on the three dots next to the name of each calendar, and then on ‘Copy private link’, you can get the URL of that respective calendar that you can use to add it to Thunderbird. Next open Thunderbird, go to File > New > Calendar > Check ‘On the Network’ > Next > check CalDAV, enter your Nextcloud username and the calendar’s URL copied earlier, leave ‘Offline Support’ checked > Next > enter a name for the new calendar, leave ‘Show Reminders’ checked, select the email you want to associate with this calendar > Next > Finish. To see the new calendar, go to ‘Events and Tasks’ > Calendar (or click on the ‘Switch to the calendar tab’ icon located in the upper right corner). The name of all the calendars will be listed on the left panel.

26.7.5.2. Upgrading the Calendar app

The Calendar app can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that Calendar has an active ‘Update’ button, click on it and the new version will be installed.

26.7.6. Install the Tasks app

To install the Tasks app click on the upper right corner user icon > click on ‘Apps’ > click on the ‘Search’ icon on the Nextcloud upper bar, search for ‘Tasks’ > when the app is found click on ‘Download and enable’.

To open the Tasks app click on its shortcut on the Nextcloud upper bar.

Tasks are grouped in tasks lists. To create a new tasks list, on the left panel click on ‘Add List…’, enter a name for the new list, choose a color, then click on the tick sign to save the new list. Then on the right panel, in the ‘Add a task’ text box enter a short suggestive name for the new task and press Enter to save it. In order to edit the task and set its description, due date, etc., click on its name. When you click on a task’s name, a new vertical panel will open at the right end of the screen. There you can set a start date for the task, a due date, the way it will be shown when shared, the priority, the degree of completeness, the category associated with it, a description, etc. If you click on the three dots next to the task name, you can see a menu with an option to add a subtask. If you want to add a subtask click on the ‘Add subtask’ option, enter a name for the new subtask, then click on its name to enter its details like you did for the parent task. You can even add subtasks to subtasks in this way.

If you want to share a list of tasks with other Nextcloud users, on the left panel, click on the name of the tasks list to select it, then click on the share button, then enter the name of the Nextcloud user whom you want to share the tasks list with, then click on its name.

When you click on a tasks list on the left panel and all its tasks are displayed on the right panel, you can click on the ‘Change sort order’ button next to the ‘Add a task’ text box, to order the tasks by various criteria: start date, due date, last modified, priority, alphabetically, etc.

26.7.6.1. Upgrading the Tasks app

The Tasks app can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that Tasks has an active ‘Update’ button, click on it and the new version will be installed.

26.7.7. Install the Forms app

To install the Forms app click on the upper right corner user icon > click on ‘Apps’ > click on the ‘Search’ icon on the Nextcloud upper bar, search for ‘Forms’ > when the app is found click on ‘Download and enable’.

To open the Forms app click on its shortcut on the Nextcloud upper bar. To create a new form click on the ‘Create a form’ button, enter the name of the form and a short description in the respective text boxes. Then click the ‘Add a question’ button to add a question to the newly created form. You will see a menu with multiple types of answer for the new question: Checkboxes, Multiple choice, Dropdown, Short answer, Long text, Date, Datetime. Choose the type of answer which best suits your question and click on it. Next enter the text of the question and the tags for the checkboxes/multiple choice radio buttons, dropdown menu, etc. If you click the three dots next to the question, you can check the ‘Required’ checkbox, so as to make the question mandatory. To add a new question click again on the ‘Add a question’ button and repeat the process.

In the upper right corner of the screen you will see the ‘Toggle settings’ icon. If you click on it, you will see a new vertical panel, in which you can choose how you want to share the form. If you click on the ‘Copy share link’ button, the URL of the form will be copied to the clipboard and you can send it by email or by other means to any person whom you want to get answers from. That person can have direct access to the form using that URL. The default method for sharing is ‘Share via link’ but there are other two options: ‘Show to all users of this instance’ and ‘Choose users to share with’. Under ‘Settings’ you can check ‘Anonymous responses’ to allow anonymous users to fill in the form and send it; you can check ‘Allow multiple reponses per person’ and you can also set up an expiration date by checking the ‘Set expiration date’ checkbox and entering a date after which the form will be inaccessible.

To see the responses sent by various users click on the ‘Response’ button located in the upper right corner of the form. You will see a screen similar to this:

On the ‘Summary’ tab you will see a summary of all the answers, while on the ‘Responses’ tab you will see the actual answers of all users. If you click on the three dots next to the ‘Responses’ tab, you will see the ‘Export to CSV’ option, which you can use if you want to export the answers to the form’s questions in csv format.

26.7.7.1. Upgrading the Forms app

The Forms app can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that Forms has an active ‘Update’ button, click on it and the new version will be installed.

26.7.8. Install the Polls app

To install the Polls app click on the upper right corner user icon > click on ‘Apps’ > click on the ‘Search’ icon on the Nextcloud upper bar, search for ‘Polls’ > when the app is found click on ‘Download and enable’.

To open the Polls app click on its shortcut on the Nextcloud upper bar. To create a new poll click the ‘Add new Poll’ button, enter a name for the new poll, choose its type (‘Date poll’ or ‘Text poll’) and click ‘Apply’. To add a new option to the poll click the ‘Add some!’ button. The ‘Details’ panel will open. Here, in the ‘Add a new text/date option’ text box you can enter the name of the option and click the arrow to save it. In this manner you can enter as many options as you need. All the options will show up on the middle panel, like below:

Below the options there is the ‘Receive notification email on activity’ checkbox that you can check if you want to receive an email notification each time a user takes the poll. However, to properly enable the Polls app to send email notifications on new activity, you will need to set up a cron job to regularly run the cron script included in Nextcloud, like we explained for the Calendar app. To run the cron script every 15 minutes you will need a cron job like this:

# Run the Nextcloud cron script every 15 minutes
*/15 * * * * sudo -u www-data php -f /var/www/cloud.example.com/cron.php

Where example.com is your main domain. After setting up this cron job, make sure that in Nextcloud Settings, under ‘Administration’ > ‘Basic settings’ > ‘Background jobs’, the ‘Cron’ option is selected.

On the ‘Configuration’ tab of the Details panel you can enter a description, you can check options to allow admins to edit the poll, to allow ‘maybe’ votes, to allow anonymous users to take the poll, to close the poll or set up a closing date, to give access to the poll to all users or only to invited users, to display the results at all times, only after the poll is closed or never, etc.

On the ‘Shares’ tab, under ‘Effective shares’ you can search for Nextcloud users and select them in order to share the poll with them, or you can enter the email address of external users, that don’t have a Nextcloud account. After you add a user under ‘Effective shares’, its name or email address will show up under ‘Unsent invitations’, at the bottom of the panel. You can send users emails to invite them to take the poll, by clicking on the right arrow next to their name or email address.

Under ‘Public shares’, if you click the ‘Add a public link’ button, you create a URL which you can copy to the clipboard by clicking the ‘Copy link to clipboard’ button. Then you can send that URL by email or by other means to any person, so that they can access the poll without having a Nextcloud account.

On the ‘Comments’ tab, in the ‘New comment’ text box you can enter various comments related to the poll.

Once the poll results begin to arrive, if you selected ‘Always show results’ on the ‘Configuration’ tab, when you click on the ‘Switch to desktop view’ button located in the upper right corner of the middle panel, you will see the detailed results of the poll in a table, like below:

26.7.8.1. Upgrading the Polls app

The Polls app can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that Polls has an active ‘Update’ button, click on it and the new version will be installed.

26.7.9. Install the ‘External storage support’ app

Using the ‘External storage support’ app, you can mount in Nextcloud any directory that is outside the /var/www/cloud.example.com/data directory of Nextcloud. To prevent errors during future upgrades, it’s recommended to mount a directory that is outside the /var/www/cloud.example.com directory. It should be also readable and writable by the HTTP server user, www-data. Thus, you’ll have to set the following permissions for the directory that you want to mount in Nextcloud:

chown -R www-data:root /path/to/folder
chmod 700 /path/to/folder

A directory that you will want to mount in Nextcloud is /var/bm_archives, where Backup Manager stores the archives of all the important directories and which can also be used to store the archives of applications that you will make manually before upgrading those applications, as we described earlier. Once /var/bm_archives is mounted, you can use Nextcloud to download all the archives in that directory to your computer, when you need to.

To enable the ‘External storage support’ app click on the upper right corner user icon > click on ‘Apps’ > click on the ‘Search’ icon on the Nextcloud upper bar, search for ‘External storage support’ > when the app is found click on ‘Enable’.

We’ll exemplify how to mount an external directory in Nextcloud, using the /var/bm_archives directory.

Click on the upper right corner user icon > Settings > on the left panel, under ‘Administration’, click on ‘External storages’. Next, in the ‘Folder name’ textbox enter the folder name that you want to appear on the ‘Files’ page, for example, Server_Backups; in the ‘External storage’ field choose ‘Local’, in the ‘Authentication’ field choose ‘None’, in the ‘Configuration’ field enter the full path of the folder you want to mount, which in this case is /var/bm_archives, in the ‘Available for’ box choose the users or user groups that will have access to the mounted folder. Next click on ‘Save’. That’s it.

We’ll show later how to configure Backup Manager to save all the backups to /var/bm_archives. In this way, you will be able to download all the backups to your desktop/laptop, with the click of a button, like you would do with any other Nextcloud files or folders. For the moment, set the right ownership and permissions for /var/bm_archives, so that all the archives stored in it could be accessed using Nextcloud’s web interface:

chown -R www-data:root /var/bm_archives
chmod 700 /var/bm_archives

26.7.9.1. Upgrading the ‘External storage support’ app

The ‘External storage support’ app can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that ‘External storage support’ has an active ‘Update’ button, click on it and the new version will be installed.

26.7.10. Install the ‘Antivirus for files’ app

To install the ‘Antivirus for files’ app click on the upper right corner user icon > click on ‘Apps’ > click on the ‘Search’ icon on the Nextcloud upper bar, search for ‘Antivirus for files’ > when the app is found click on ‘Download and enable’. Then go to Settings > Administration > Security > scroll down to the ‘Antivirus for Files’ section, set ‘Mode’ to ‘ClamAV Daemon (Socket)’; in the ‘Socket’ field enter /var/run/clamav/clamd.ctl . You can leave the ‘Stream Length’ set to ‘26214400’ (this value sets the number of bytes read in one pass); you can also leave the ‘File size limit for periodic background scans’ set to ‘-1’, which means no limit of file size; in the ‘When infected files are found during a background scan’ field select ‘Delete file’, to have the infected files deleted right when they reach the server, then click ‘Save’.

To test if ClamAV scans, detects and deletes an infected file, save the following string, in a txt file:

X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

This will create a standard antivirus test file. Then put that file in a folder, archive the folder as zip or other archive format, then try to upload the archive to Nextcloud. The upload will begin but then you will see the message: “Virus Win.Test.EICAR_HDB-1 is detected in the file. Upload cannot be completed.” and Nextcloud will refuse the upload, so nothing will be saved on the server. Then, the /var/log/clamav/clamav.log file will also mention the detection:

instream(local): Win.Test.EICAR_HDB-1(44d88612fea8a8f36de82e1278abb02f:68) FOUND

26.7.10.1. Configure ClamAV to periodically scan Nextcloud directories and mail directories

Once Nextcloud and all the important apps are installed, you can configure ClamAV to periodically scan the Nextcloud directories. We’ll also configure ClamAV to scan the mail directories periodically, since they are also very sensitive. This is a reasonable thing to do, because although ClamAV scans files the moment they are uploaded to Nextcloud or the moment emails arrive, at a later date, when the virus signatures get updated, ClamAV can detect viruses that it didn’t detect before, on real-time scanning.

First create a directory to store the scan reports:

mkdir /srv/scripts/detections

Create the cron job:

crontab -e

Enter the following lines:

# Scan the '/var/www/cloud.example.com/data' directory and the '/var/vmail' directory with ClamAV once every three days
20 4 */3 * * cat /dev/null > /srv/scripts/detections/clamav_nextcloud_report && clamdscan --fdpass --quiet /var/www/cloud.example.com/data -l /srv/scripts/detections/clamav_nextcloud_report
40 4 */3 * * cat /dev/null > /srv/scripts/detections/clamav_mail_report && clamdscan --fdpass --quiet /var/vmail -l /srv/scripts/detections/clamav_mail_report

Replace example.com with the main domain on your server.

The results of the periodic scan will be read by ‘System Health and Security Probe’, which we’ll present later, and will be included in the periodic email reports sent to the admin. The results will be displayed also on the dashboard of ‘RED Scarf Suite Panel’, which we’ll also describe later.

26.7.10.2. Upgrading the ‘Antivirus for files’ app

The ‘Antivirus for files’ app can be upgraded like any other Nextcloud application. If you click on the profile picture, then on Apps, and you see that ‘Antivirus for files’ has an active ‘Update’ button, click on it and the new version will be installed.

26.8. Note about the Talk and Mail apps

The Talk app seems very attractive because it promises to allow Nextcloud users to have text, audio and video conversations and even video conference calls. Its main advantage is that it allows quick one-to-one audio/video calls to other users of the same Nextcloud instance or to external users. However, it has a big structural problem: it works peer to peer, which means that each participant sends a stream to every other participant and receives a stream from every other participant. In this way, the bandwidth usage grows rapidly with each new participant and together with the computing effort to decode each video stream, it puts a big strain on the participant’s system. This is why conferences with more than 5 participants generally don’t work. Indeed, there is a component called High Performance Backend (HPB) that has been “open-sourced” and can be used as a signaling server to increase the performance and scalability of the Talk app, but this component has high hardware demands, it’s complicated to install and not clearly documented. In addition to this, the only way to use Talk in conjunction with the High Performance Backend to make/receive phone calls to/from real phone numbers, is to add a proprietary SIP bridge to the High Performance Backend, offered by Nextcloud’s partner, Struktur AG. For these reasons, we didn’t include Talk in RED SCARF Suite. Of course, if you think you will only need to have one-to-one audio/video calls or video conferences with 5 participants or less, or that you won’t need to call and receive calls from real phone numbers, you can try installing and using it.

If, on the contrary, you want to use an application that allows good quality video/audio/text conversations with other users, as well as video conferences, which includes a central server (Asterisk, installed on your server) and also allows calls to/from real phone numbers on the Public Switched Telephone Network (PSTN), then you may want to use Roundpin, an application that we built in order to offer precisely what Nextcloud Talk doesn’t offer. Roundpin can be installed independently of Nextcloud and it aims to be a FOSS self-hosted alternative to Zoom, under your full control. Roundpin is part of RED SCARF Suite and in the next chapter of this guide we describe how to install and use it.

The Mail app can also seem attractive to many Nextcloud users. However, if you install it, you will see that it lacks important features and you will understand why we didn’t include it in RED SCARF Suite and why Roundcube is the only web based IMAP client that you will need.

26.9. Use Fail2ban to protect Nextcloud against brute-force attacks

First create a Fail2ban configuration file for Nextcloud:

nano /etc/fail2ban/filter.d/nextcloud.conf

Add the following content inside:

[Definition]
failregex = ^{\"reqId\":\".*Login failed: .*\(Remote IP: <HOST>\)\".*}$
ignoreregex =

Then edit the /etc/fail2ban/jail.local file:

nano /etc/fail2ban/jail.local

Add the following block under the [phpmyadmin] block:

[nextcloud]
enabled = true
port = 80,443
filter = nextcloud
logpath = /var/log/nextcloud/nextcloud.log
maxretry = 3
bantime = 259200

Restart Fail2ban:

systemctl restart fail2ban

26.10. Installing the Nextcloud Desktop Synchronization Client

Nextcloud can be used without installing a desktop synchronization client. You just upload any files that you want to your Nextcloud server while also keeping the files on your local computer. However, if you want to synchronize a folder (or multiple folders) from your desktop/laptop with your Nextcloud server, so that any file that you save in that folder gets automatically uploaded to Nextcloud, you can install the Nextcloud Desktop Synchronization Client.

To install the Nextcloud Desktop Synchronization Client on Debian 11 run:

apt-get update
apt-get install nextcloud-desktop

Then, you can install the package that integrates the Nextcloud Desktop Synchronization Client with your file manager, as follows:

If your desktop environment is Mate, run:

apt-get install caja-nextcloud

If you are using Gnome run:

apt-get install nautilus-nextcloud

If you are using Plasma run:

apt-get install dolphin-nextcloud

If you are using Cinnamon run:

apt-get install nemo-nextcloud

Please note that even if you install the client while logged in as root, you will not be able to start it as root. To be able to start the Nextcloud Desktop Synchronization Client and connect it to your Nextcloud server, you have to log in to your desktop/laptop as a regular user (we’ll show below how you can actually use the client even logged in as root, but to connect it to your remote server, you have to log in as a regular user).

While logged in as a non-privileged user, create a folder that you want to synchronize with your Nextcloud server, preferably in /home/nameofuser. Give this folder a suggestive name, such as synchronized_with_nextcloud, so, the path of the new folder will be /home/nameofuser/synchronized_with_nextcloud. Then go to the Main Menu > ‘Accessories’ > ‘Nextcloud desktop sync client’. You will see the following screen:

Click ‘Log in’. The next screen will let you enter the URL of your Nextcloud server:

Click ‘Next’.

Click ‘Log in’.

Enter your username and password and click ‘Log in’.

Click ‘Grant access’.

In the next screen, under ‘Server’ select ‘Choose what to sync’ and click the ‘Choose what to sync’ button to choose the remote folder from your Nextcloud server that you want to sync with your local folder. Under ‘Local Folder’ click the button and choose the local folder that you want to sync with the remote Nextcloud folder, namely the folder that you have created earlier, /home/nameofuser/synchronized_with_nextcloud. Then click ‘Connect…’. The two folders will be synchronized automatically and you will see a green tick sign with the name of the remote folder, with the specification: ‘Synchronized with local folder’. Please note that the synchronization process is bi-directional, in the sense that when you add a file in the local folder it will be automatically uploaded to the remote folder and when you add a file to the remote folder, it will be automatically added in the local folder. The same thing will happen when you modify an existing file.

You can sync additional local folders with remote folders. To add a local folder to the sync client, click on the ‘Add Folder Sync Connection’ button on the client’s main screen. You will be able to select a new local folder that you want to sync, then, after you click ‘Next’, you will be able to choose a remote folder to sync with.

Next, click on the ‘General’ tab of the client and under ‘General Settings’ you can check ‘Launch on System Startup’, if you want the sync client to start at system startup.

If you want to use the Nextcloud Desktop Synchronization Client while logged in as root, you will have to start it in command line, under the regular user. To make things simpler, you can create a small script in a directory like /srv/scripts:

mkdir /srv/scripts
cd /srv/scripts
nano nextcloud-sync-client

Add the following lines inside this file:

#!/bin/bash
xhost si:localuser:nameofuser
sudo -u nameofuser /usr/bin/nextcloud

where nameofuser is the username of the regular user that you used to connect the client to your Nextcloud server. Change permissions:

chmod 700 nextcloud-sync-client

Then, when you want to start the client run:

/srv/scripts/nextcloud-sync-client

Before starting, Nextcloud Desktop Synchronization Client will ask you to enter your root password.

In the client’s main screen, if you click on the three dots next to the name of the synchronized remote folder and choose ‘Open folder’, you will open the local synchronized folder.

Please note that if you implement basic HTTP authentication for the login page of Nextcloud (https://cloud.example.com), the sync client will fail to connect to the remote server because it doesn’t have a mechanism to specify the username and password required by basic HTTP authentication. This is the only reason why we didn’t show how to implement basic HTTP authentication when we described how to configure Nginx for Nextcloud. If you are confident that you won’t need Nextcloud Desktop Synchronization Client in the future, you can implement basic HTTP authentication for the Nextcloud login page in the same way as we showed for other applications, such as Dolibarr, to add an extra layer of security to Nextcloud.

Nextcloud also offers a desktop synchronization client for Windows and macOS (https://nextcloud.com/install/#install-clients). However, since we strongly discourage the use of these operating systems, because of their contempt for digital freedom and privacy, we won’t describe how to install and use the sync clients for them.

There are also Nextcloud synchronization clients in the form of mobile apps for Android and iOS (https://nextcloud.com/install/#install-clients). Since we also discourage the use of both Android and iOS because of their digital freedom restrictions and privacy issues, we won’t present how to install and use these apps. The only setup that would be acceptable would be that in which you use a PinePhone and try to install the Nextcloud sync client from F-Droid.

26.11. Upgrading Nextcloud

As mentioned before, Nextcloud can work flawlessly for years and then break or loose functionalities, or generate errors, just because of a simple upgrade, even if the version of Nextcloud that you installed is tagged as ‘stable’. This happens because Nextcloud is so complex and the apps that can be installed are so numerous, that it’s still possible that some bugs will go undetected when new Nextcloud versions get released. This is true both for major and minor new versions. To prevent the situations in which you have to loose entire days to find solutions to problems generated by such upgrades, we recommend upgrading Nextcloud only after upgrading Debian, which means once every 2 years. The only exceptions to this general rule should be the cases in which critical security vulnerabilities will be discovered and you will need to install newer versions sooner, to apply the fixes. To find out if and when critical security vulnerabilities will be discovered in Nextcloud, you can check web pages like this periodically, or you can subscribe to our ‘Updates Newsletter’. Subscribers get an email each time a security vulnerability that needs to be fixed urgently by an upgrade is discovered in Nextcloud, or in any other application that is part of RED SCARF Suite.

Therefore, it’s recommended to ignore all the notifications received in Nextcloud about new versions being available, and proceed to upgrade Nextcloud only once every 2 years, after you upgrade Debian. Before doing the actual Nextcloud upgrade, it’s also recommended to check if the new version has been tested and confirmed to function well and as a result it has been included on the list available on this page. If the new Nextcloud version that you intend to upgrade to hasn’t been included on the mentioned list, it means it’s safer to keep the old Nextcloud version running and upgrade later.

The major Nextcloud versions are 20, 21, 22, 23, 24, etc. and the minor versions are intermediate versions for each major version, like 20.0.1, 21.0.4, 23.0.2, etc. Before you can upgrade to the next major version, Nextcloud has to be upgraded to the latest minor version. You cannot skip major Nextcloud versions. Even if your installed version is two or more versions behind the latest Nextcloud version, the standard way to upgrade is to re-run the upgrade process described below for every superior version, until the latest version available.

Before upgrading Nextcloud, make sure you backup the Nextcloud database (using phpMyAdmin) and the /var/www/cloud.example.com directory (with the tar czf command). Don’t forget to include the date in the name of the backup files. The built-in updater makes some backups, but it doesn’t backup the Nextcloud database or the /var/www/cloud.example.com/data directory.

You can upgrade Nextcloud by using either the web based updater, or the command line.

It’s easier to use the web based updater.

Before the upgrade you should temporarily disable the ‘External storage support’ app, so as to avoid errors during the upgrade process.

To upgrade Nextcloud using the web based method, follow these steps:

  1. Once there is a new update available, Nextcloud will display a notification when you log in. Click on the upper right corner profile picture > ‘Settings’ > under ‘Administration’ click on ‘Overview’ > under ‘Version’ you will see the ‘Open updater’ button. This button as well as the update notification will only be available if the ‘Update notification’ app is enabled.
  2. Click the ‘Open updater’ button.
  3. Verify the information that is shown and click the button “Start update” to start the update.
  4. In case an error happens or a check fails, the updater will stop and will show a message. You can try to solve the problem and then click the “Retry update” button. This will start the update and re-run the failed step. It will not re-run the previous steps that succeeded.
  5. In case you close the updater before it finished, you can open the updater page again and proceed from the last succeeded step. Closing the web page will still execute the running step but will not continue with the next step, because this is triggered by the ‘open updater’ page.
  6. Once all steps are executed, the updater will display the button ‘Disable maintenance mode and continue in the web based updater’. You can perform the actual upgrade using the web interface by clicking this button, or you can upgrade in command line by navigating to /var/www/cloud.example.com and running sudo -u www-data php ./occ upgrade . It’s easier to use the web interface, therefore, click the mentioned button.
  7. You will see a screen with the message:

    “Nextcloud will be updated to version n.n.n

    The following apps will be updated:

    Please make sure that the database, the config folder and the data folder have been backed up before proceeding”

    Click on the ‘Start update’ button.
    That’s it.

After the upgrade, log in to Nextcloud, re-enable the ‘External storage support’ app, then go to Settings > Overview. You may see the following warnings:

“The database is missing some indexes. Due to the fact that adding indexes on big tables could take some time they were not added automatically. By running “occ db:add-missing-indices” those missing indexes could be added manually while the instance keeps running. Once the indexes are added queries to those tables are usually much faster.”

Update the indexes manually by running:

cd /var/www/cloud.example.com
sudo -u www-data php ./occ db:add-missing-indices

“The database is missing some primary keys. Due to the fact that adding primary keys on big tables could take some time they were not added automatically. By running “occ db:add-missing-primary-keys” those missing primary keys could be added manually while the instance keeps running.”

Add the missing primary keys by running:

cd /var/www/cloud.example.com
sudo -u www-data php ./occ db:add-missing-primary-keys

“Some columns in the database are missing a conversion to big int. Due to the fact that changing column types on big tables could take some time they were not changed automatically. By running ‘occ db:convert-filecache-bigint’ those pending changes could be applied manually. This operation needs to be made while the instance is offline. For further details read thedocumentation page about this.”

Make the necessary changes manually by running:

cd /var/www/cloud.example.com
sudo -u www-data php ./occ db:convert-filecache-bigint

If you also see a warning about the fact that PHP doesn’t have read access to /dev/urandom, just log out, restart Nginx, then log in again.

If after upgrade you experience problems receiving faxes with Pax Fax, go to Settings > Personal > Security > scroll to the bottom of the page, revoke the old Pax Fax app password by clicking on the three dots next to its name, then choosing Revoke. Then enter pax_fax in the box next to the ‘Create new app password’ button, then press the button to create a new password for Pax Fax. Then take the username and the newly created password, log in to your Phaxio account, go to ‘Phone Numbers’, click on the little wheel to the right of your phone number, then enter the new callback URL, containing the username and the new password, like this:

https://username:sJyq3-eflGB-46H2qj-SpZ50-4T7lr@cloud.example.com/apps/pax_fax/api/recfax

where username is your Nextcloud username, sJyq3-eflGB-46H2qj-SpZ50-4T7lr is the newly created app password and cloud.example.com is your Nextcloud domain.

26.11.1. Copy the configuration file outside the web root

Please note that after upgrade, the /var/www/cloud.example.com/config/config.php file is overwritten by Nextcloud, therefore, to increase security, you should copy it outside the web root by running:

cp /var/www/cloud.example.com/config/config.php /srv/scripts/nextcloud.php

Then change ownership and permissions:

cd /srv/scripts
chown www-data:root nextcloud.php
chmod 400 nextcloud.php

Then replace the content of the /var/www/cloud.example.com/config/config.php file with:

<?php include('/srv/scripts/nextcloud.php'); ?>
You can send your questions and comments to: