Introduction
La formule standard de NextCloud est utile pour bien des usages. Cependant, lorsque la volumétrie des utilisateurs évolue et que l’on arrive à des usages plus intenses de NextCloud, on se rend vite compte des limites de ce service. Dans ce cas, on se retrouve confronté à une problématique de taille, à savoir gérer la quantité d’utilisateurs tout en limitant les coûts. C’est là qu’intervient l’offre GlobalScale de NextCloud.
À l’heure où ces lignes sont rédigées il existe peu de documentation sur le sujet. Nous allons tenter de combler ensemble ce manque avec cet article.
GlobalScale permet de répartir la charge du trafic et donc de gérer une utilisation plus intense de NextCloud. Cela aide énormément lorsque l’on veut utiliser NextCloud dans un cadre professionnel à grande échelle ou lorsque l’on en a une utilisation avancée comme par exemple la mise en place de nombreux plugins ou le stockage de fichiers volumineux.
Points importants
Attention: Cette installation a été réalisée sous NextCloud version 20, nous ne pouvons confirmer la validité de cette procédure pour les versions ultérieures.
Dans cet article, nous nous attarderons seulement sur la mise en place de la partie GlobalScale, nous considérerons que vos serveurs Linux sont déjà en place et que les produits de base sont déjà installés.
Les points suivants ne seront pas traités ici :
- l’adressage IP
- le dimmensionnement des serveurs
- l’installation de l’OS
- la mise en place d’un Reverse Proxy
- La gestion des certificats
- la mise en place des bases de données
- la supervision ou la métrologie
- la haute disponibilité
Caractéristiques de l’architecture GlobalScale
Pour la mise en place de cette architecture, nous aurons besoin basiquement pour la partie NextCloud :
- d’un serveur primaire NextCloud, qui servira de relai pour rediriger l’utilisateur vers le serveur où sont situées ses données/son espace personnel.
- d’un ou plusieurs serveurs secondaires sur lesquels nous allons répartir les données de nos utilisateurs, c’est en cela que réside la particularité de cette architecture et qui va permettre d’éviter les goulots d’étranglement.
- un Lookup server qui sera le serveur interrogé pour rediriger les utilisateurs vers le serveur secondaire sur lequel ils disposent d’un espace personnel.
Évidemment pour pouvoir identifier nos clients il est nécessaire d’inclure dans cette architecture un portail d’authentification Single Sign-On (SSO) ou un serveur LDAP.
Voici la nomenclature qui sera utilisée :
Nom | Rôle | Application |
---|---|---|
nextcloud1.app.domain.com | Nextcloud Primaire | Nextcloud verison 20 |
nextcloud2.app.domain.com | Nextcloud Secondaire | Nextcloud version 20 |
nextcloud3.app.domain.com | Nextcloud Secondaire | Nextcloud version 20 |
ls.app.domain.com | Lookup Server | Nextcloud version 20 |
keycloak.app.domain.com | WebSSO | Keycloak |
collabora.domain.com | Édition Collaborative | Collabora Online |
Commençons l’installation !
Installation
Prérequis
Dans notre contexte, voici comment va se présenter notre architecture :
- les différents nœuds NextCloud,
- OpenLDAP afin de centraliser les comptes et les informations utilisateurs,
- Keycloak comme WebSSO s’appuyant sur l’annuaire LDAP pour l’authentification des utilisateurs,
- Collabora Online, un outil collaboratif open-source basé sur LibreOffice Online.
Remarque: Dans le cadre d’une mise en production, nous pourrions intégrer à cette architecture un serveur REDIS pour les caches de sessions mais cela ne sera pas abordé dans cet article.
L’annuaire OpenLDAP
Dans notre architecture, nous allons nous servir d’OpenLDAP pour centraliser les utilisateurs et faciliter la gestion de leurs données.
Chaque utilisateur disposera de sa fiche qui sera présentée comme ceci:
cn
: nom d’affichage (prénom / nom)sn
: nom de famillegivenName
: prénommail
: adresse mailnclocator
: URL Nextcloud vers ses donnéesuid
: uiduserPassword
: mot de passe utilisateur
Exemple :
cn: John DOE
sn: DOE
givenName: John
mail: john.doe@example.com
nclocator : https://nextcloud-2.example.com/
uid : jdoe
userPassword : $HASH$
Keycloak va s’appuyer sur ces fiches afin de gérer les authentifications des clients et gérer efficacement les accès aux espaces personnels de chacun.
Le WebSSO Keycloak
Afin que notre outil de SSO (Single Sign-On) puisse accéder à l’annuaire LDAP pour l’authentification des utilisateurs, il est nécessaire de définir un nouveau fournisseur LDAP comme suit :
Après avoir défini le nouveau fournisseur, il est nécessaire de faire correspondre les attributs de l’annuaire avec ceux des utilisateurs qui vont être stockés dans Keycloak et qui pourront être transmis aux applications clientes :
Voici la configuration à adopter pour chaque attribut :
Une fois le mappage terminé, nous allons configurer la partie SAML et définir le noeud principal en tant que client :
Enfin il faut lui donner les éléments que l’on vient de définir pour lui permettre de s’en servir durant la connexion.
Que l’on va définir commme ceci :
Une fois toutes ces configurations faites, nous pouvons passer à la configuration du noeud primaire NextCloud.
Nextcloud Primaire
En premier lieu, nous devons modifier les Content Security Policy afin de permettre aux instances d’utiliser les iframes d’une instance à une autre. Vous devrez trouver le fichier .php au chemin suivant :
~/lib/public/AppFramework/Http/ContentSecurityPolicy.php
Voici à quoi ressemble notre fichier de conf après modification :
~# cat ./lib/public/AppFramework/Http/ContentSecurityPolicy.php
...
protected $allowedFrameDomains = [
'nextcloud1.app.domain.com',
'nextcloud2.app.domain.com',
'nextcloud3.app.domain.com',
'collabora.domain.com',
];
protected $allowedFrameAncestors = [
'nextcloud1.app.domain.com',
'nextcloud2.app.domain.com',
'nextcloud3.app.domain.com',
'collabora.domain.com',
];`
Ensuite il faut commenter les options du X-Frame
dans le .htaccess pour autoriser les autres origines :
~# cat .htaccess
# Header always set X-Frame-Options "SAMEORIGIN"`
Du côté de NextCloud, la partie SAML doit être configurée comme ceci :
Voici un extrait du config.php
modifié pour GlobalScale :
~# cat config/config.php
<?php
$CONFIG = array (
<...>
'overwriteprotocol' => 'https',
'overwritehost' => 'nextcloud1.app.domain.com',
<...>
'overwritewebroot' => '/',
'trusted_domains' =>
array (
0 => 'nextcloud1.app.domain.com',
1 => 'nextcloud2.app.domain.com',
2 => 'nextcloud3.app.domain.com',
),
'datadirectory' => '/var/www/nextcloud/data',
'lookup_server' => 'https://ls.app.domain.com',
<...>
'overwrite.cli.url' => 'https://nextcloud1.app.domain.com/nextcloud',
<...>
'app_install_overwrite' =>
array (
0 => 'globalsiteselector',
),
'gss.jwt.key' => 'XXXXX',
'gss.mode' => 'master',
'gss.master.admin' =>
array (
0 => 'admin',
),
'gs.enabled' => true,
'gss.user.discovery.module' => '\\OCA\\GlobalSiteSelector\\UserDiscoveryModules\\UserDiscoverySAML',
'gss.discovery.saml.slave.mapping' => 'nclocator',
<...>
);
NextCloud Secondaire
Comme pour le noeud primaire, vous devez modifier les CSP afin d’autoriser l’utilisation des iframes d’une instance à une autre comme ceci :
protected $allowedFrameDomains = [
'nextcloud1.app.domain.com',
'nextcloud2.app.domain.com',
'nextcloud3.app.domain.com',
'collabora.domain.com',
];
protected $allowedChildSrcDomains = [
'nextcloud1.app.domain.com',
'nextcloud2.app.domain.com',
'nextcloud3.app.domain.com',
'collabora.domain.com',
];
protected $allowedFrameAncestors = [
'nextcloud1.app.domain.com',
'nextcloud2.app.domain.com',
'nextcloud3.app.domain.com',
'collabora.domain.com',
];
Il est impératif de commenter la ligne suivante dans le .htaccess comme pour le noeud primaire :
~# cat .htaccess
#Header always set X-Frame-Options "SAMEORIGIN"
Contrairement au nœud primaire, les nœuds secondaires doivent être connectés à un annuaire LDAP pour les informations utilisateurs avec un filtre correspondant aux utilisateurs uniquement de cette instance :
On va ensuite créer un filtre correspondant au nclocator du GlobalScale :
Pour le reste, ça reste une configuration classique :
Dans l’onglet Avancé, nous désactiverons la pagination des recherches dans l’annuaire :
Pour simplifier la lecture entre SAML et LDAP, nous avons fait correspondre l’uid de l’utilisateur :
Voici un extrait du fichier config.php
correspondant aux modifications pour le GlobalScale pour une instance secondaire :
~# cat config/config.php
<?php
$CONFIG = array (
<...>
'trusted_domains' =>
array (
0 => 'nextcloud3.app.domain.com',
1 => 'nextcloud2.app.domain.com',
2 => 'nextcloud1.app.domain.com',
),
<...>
'overwrite.cli.url' => 'https://nextcloud2.app.domain.com',
'installed' => true,
'app_install_overwrite' =>
array (
0 => 'globalsiteselector',
),
<...>
'overwritewebroot' => '/',
'overwriteprotocol' => 'https',
'gss.mode' => 'slave',
'gss.discovery.saml.slave.mapping' => 'nclocator',
'lookup_server' => 'https://ls.app.domain.com',
'gss.jwt.key' => 'XXXXXXXX',
'gss.master.url' => 'https://nextcloud1.app.domain.com/',
<...>
);
Lookup Server
Voici à quoi ressemble le fichier de configuration par défaut :
# cat config/config.php
<?php
// Lookup-Server Config
$CONFIG = [
<...>
// max user search page. limit the maximum number of pages to avoid scraping.
'MAX_SEARCH_PAGE' => 100,
// max requests per IP and 10min.
'MAX_REQUESTS' => 100000,
// credential to read the replication log. IMPORTANT!! SET TO SOMETHING SECURE!!
'REPLICATION_AUTH' => 'XXXXXX',
// credential to read the slave replication log. Replication slaves are read only and don't get the authkey.
IMPORTANT!! SET TO SOMETHING SECURE!!
'SLAVEREPLICATION_AUTH' => 'YYYYYYYYYYY',
// the list of remote replication servers that should be queried in the cronjob
'REPLICATION_HOSTS' => [],
// ip black list. usefull to block spammers.
'IP_BLACKLIST' => [],
// spam black list. usefull to block spammers.
'SPAM_BLACKLIST' => [
],
// Email sender address
'EMAIL_SENDER' => 'www@ttttt.com',
// Public Server Url
'PUBLIC_URL' => 'https://ls.app.domain.com',
// does the lookup server run in a global scale setup
'GLOBAL_SCALE' => true,
// auth token
'AUTH_KEY' => 'ZZZZZZZZZ'
'TWITTER' => [
'CONSUMER_KEY' => '',
'CONSUMER_SECRET' => '',
'ACCESS_TOKEN' => '',
'ACCESS_TOKEN_SECRET' => '',
],
];
Remarque: La partie Twitter est nécessaire mais peut rester vide.
Durant l’exécution du cron.php
de NextCloud, les utilisateurs sont créés via une requête LDAP et sont injectés dans la base de données du Lookup Server comme suit :
MariaDB [lookup]> select * from users where federationId like 'user%' ;
+------+-----------------------------------------+---------------------+
| id | federationId | timestamp |
+------+-----------------------------------------+---------------------+
| 2555 | user1@nextcloud2.app.domain.com | 2021-03-03 17:14:14 |
| 24 | user10@nextcloud2.app.domain.com | 2021-03-03 14:36:07 |
| 2643 | user100@nextcloud2.app.domain.com | 2021-03-03 17:14:56 |
| 544 | user1000@nextcloud2.app.domain.com | 2021-03-03 15:42:14 |
| 1048 | user100001@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1049 | user100002@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1050 | user100003@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1051 | user100004@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1052 | user100005@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1053 | user100006@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1054 | user100007@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1055 | user100008@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1056 | user100009@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1057 | user100010@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1058 | user100011@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
| 1059 | user100012@nextcloud3.app.domain.com | 2021-03-03 15:53:00 |
…
| 3028 | user490@nextcloud2.app.domain.com | 2021-03-03 17:17:52 |
| 3029 | user491@nextcloud2.app.domain.com | 2021-03-03 17:17:53 |
| 3030 | user492@nextcloud2.app.domain.com | 2021-03-03 17:17:53 |
| 3031 | user493@nextcloud2.app.domain.com | 2021-03-03 17:17:54 |
| 3032 | user494@nextcloud2.app.domain.com | 2021-03-03 17:17:54 |
| 3033 | user495@nextcloud2.app.domain.com | 2021-03-03 17:17:54 |
| 3034 | user496@nextcloud2.app.domain.com | 2021-03-03 17:17:55 |
| 3035 | user497@nextcloud2.app.domain.com | 2021-03-03 17:17:55 |
| 3036 | user498@nextcloud2.app.domain.com | 2021-03-03 17:17:56 |
| 3037 | user499@nextcloud2.app.domain.com | 2021-03-03 17:17:56 |
| 3038 | user500@nextcloud2.app.domain.com | 2021-03-03 17:17:57 |
+------+---------------------------------------------+---------------------+
On peut alors constater les requêtes de mise à jour via l’API du Lookup Server depuis toutes les instances :
ls.app.domain.com [03/Mar/2021:17:17:55 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:55 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:55 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:55 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:56 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:56 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:56 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:56 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:57 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
ls.app.domain.com [03/Mar/2021:17:17:57 +0100] "POST /gs/users HTTP/1.1" 200 "-" "Nextcloud Server
Crawler"
Collabora
La spécificité de notre configuration de Collabora ici est qu’elle doit permettre le partage d’iframe d’un NextCLoud à un autre. Pour ce faire, nous allons alors fixer les adresses pouvant utiliser cette option dans notre fichier loolwsd.xml
:
~# cat /etc/loolwsd/loolwsd.xml
<...>
<frame_ancestors desc="Specify who is allowed to embed the LO Online iframe (loolwsd and WOPI host are
always allowed). Separate multiple hosts by space.">https://nextcloud*\.app\.domain\.com</frame_ancestors>
<...>
<host desc="Regex pattern of hostname to allow or deny." allow="true">nextcloud1\.app\.domain\.com</host>
<host desc="Regex pattern of hostname to allow or deny." allow="true">nextcloud2\.app\.domain\.com</host>
<host desc="Regex pattern of hostname to allow or deny." allow="true">nextcloud3\.app\.domain\.com</host>
<...>
<host desc="Hostname to allow" allow="true">nextcloud1\.app\.domain\.com</host>
<host desc="Hostname to allow" allow="true">nextcloud2\.app\.domain\.com</host>
<host desc="Hostname to allow" allow="true">nextcloud3\.app\.domain\.com</host>
<...>
~# systemctl restart loolwsd
Après redémarrage du service, les serveurs NextCloud peuvent désormais ouvrir des accès à leur instance aux autres.
Attention : Pour l’exemple, nous déployons un seul Collabora unique pour tous nos serveurs NextCloud, cependant il est tout à fait possible de les séparer pour que chaque serveur possède un Collabora qui lui est propre.
Cas d’usage
Maintenant que vous avez terminé l’installation de GlobalScale, voici quelques cas d’usage pour Nextcloud.
Tester son installation
Afin de tester notre architecture, nous allons procéder de la façon suivante :
- Nous allons d’abord nous rendre sur l’URL du noeud primaire
https://nextcloud1.app.domain.com
puis nous nous authentifions :
- Si tout se passe bien, nous sommes alors redirigé vers le noeud secondaire :
Partager un fichier
Sur NextCloud, nous avons 2 solutions pour partager un fichier : soit via le mail de notre collaborateur, soit via son nom.
Conclusion
Félicitations ! Si vos tests ont réussi alors vous avez désormais une architecture NextCloud GlobalScale.
Il est important de noter que la disposition mise en place dans ce tutoriel n’est qu’un exemple et reste ajustable selon vos besoins.
Voici ci-après une liste de liens utiles concernant la documentation des différents éléments mise en place dans ce tutoriel.
Liens utiles
Produit | URL |
---|---|
NextCloud | https://nextcloud.com/ |
NextCloud config.php |
https://docs.nextcloud.com/server/stable/admin_manual/ |
Lookup Server | https://github.com/nextcloud/lookup-server |
RichDocuments | https://github.com/nextcloud/richdocuments |
User SAML | https://github.com/nextcloud/user_saml |
Global Site Selector | https://github.com/nextcloud/globalsiteselector |
KeyCloak | https://www.keycloak.org/ |
Openldap | https://www.openldap.org/ |