On note que Inverse propose une documentation concise de l'installation de SOGo depuis les sources.
Ici, cette documentation est une documentation interne à l'Université de Rouen que l'on a souhaité rendre publique ; elle se présente sous forme de notes, d'exemples de fichiers de configuration, de scripts ...
On installe ici un SOGo v5 avec authentification CAS, base de données PostgreSQL, annuaire LDAP (supann), ...
Installation des paquets nécessaires
apt-get install gobjc gnustep-core-devel gnustep-make libxml2-dev libssl-dev libldap2-dev libpq-dev libmemcached-dev libcurl4-openssl-dev libsodium-dev libzip-dev libytnef0-dev
Installation de SOPE
. /usr/share/GNUstep/Makefiles/GNUstep.sh
cd /usr/local/src
git clone https://github.com/inverse-inc/sope.git
cd sope
git checkout -b SOPE-5.0.1 SOPE-5.0.1
./configure --with-gnustep --disable-debug --disable-strip
make -j$(grep -c '^processor' /proc/cpuinfo)
make install
Installation de SOGO
. /usr/share/GNUstep/Makefiles/GNUstep.sh
cd /usr/local/src
git clone https://github.com/inverse-inc/sogo.git
cd sogo
git checkout -b SOGo-5.0.1 SOGo-5.0.1
./configure --disable-debug --disable-strip
make -j$(grep -c '^processor' /proc/cpuinfo)
make install
Paramétrage système
Création de l'utilisateur sogo
Création des répertoires et affectation des droits
mkdir -p /var/local/spool/sogo && chown -R sogo:sogo /var/local/spool/sogo
mkdir /etc/sogo && chown -R sogo:sogo /etc/sogo
mkdir -p /var/local/run/sogo && chown -R sogo:sogo /var/local/run/sogo
mkdir /var/log/sogo/ && chown -R sogo:sogo /var/log/sogo/
Fichier systemd
[Unit]
Description=SOGo is a groupware server
After=network.target
After=postgresql.service
[Service]
Environment="PREFORK=3"
EnvironmentFile=-/etc/sysconfig/sogo
Type=forking
ExecStart=/usr/local/sbin/sogod -WOWorkersCount ${PREFORK} -WOPidFile /var/local/run/sogo/sogo.pid -WOLogFile /var/log/sogo/sogo.log
PIDFile=/var/local/run/sogo/sogo.pid
User=sogo
[Install]
WantedBy=multi-user.target
Fichier d'environnement sysconfig
# The amount of processes that should be spawned (Default: 3)
PREFORK=8
# The name of the account under which SOGo will be running (Default: sogo)
# USER=sogo
LD_LIBRARY_PATH=/usr/local/lib/sogo:/usr/local/lib:$LD_LIBRARY_PATH
Fichier de configuration sogo
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//GNUstep//DTD plist 0.9//EN" "http://www.gnustep.org/plist-0_9.xml">
<plist version="0.9">
<dict>
<key>NGImap4ConnectionStringSeparator</key>
<string>/</string>
<key>NGImap4DisableIMAP4Pooling</key>
<string>YES</string>
<key>OCSEMailAlarmsFolderURL</key>
<string>postgresql://sogo:password@127.0.0.1:5432/sogo/sogo_alarms_folder</string>
<key>OCSFolderInfoURL</key>
<string>postgresql://sogo:password@127.0.0.1:5432/sogo/sogo_folder_info</string>
<key>OCSSessionsFolderURL</key>
<string>postgresql://sogo:password@127.0.0.1:5432/sogo/sogo_sessions_folder</string>
<key>SOGoACLsSendEMailNotifications</key>
<string>YES</string>
<key>SOGoAppointmentSendEMailNotifications</key>
<string>YES</string>
<key>SOGoAuthenticationType</key>
<string>CAS</string>
<key>SOGoCASLogoutEnabled</key>
<string>YES</string>
<key>SOGoCASServiceURL</key>
<string>https://cas.univ-rouen.fr</string>
<key>SOGoDAVAuthenticationType</key>
<string>CAS</string>
<key>SOGoDraftsFolderName</key>
<string>Drafts</string>
<key>SOGoEnableEMailAlarms</key>
<string>YES</string>
<key>SOGoFirstDayOfWeek</key>
<string>1</string>
<key>SOGoFirstWeekOfYear</key>
<string>First4DayWeek</string>
<key>SOGoFoldersSendEMailNotifications</key>
<string>NO</string>
<key>SOGoForwardEnabled</key>
<string>YES</string>
<key>SOGoHideSystemEMail</key>
<string>YES</string>
<key>SOGoIMAPServer</key>
<string>imap://imap.univ-rouen.fr</string>
<key>SOGoLanguage</key>
<string>French</string>
<key>SOGoMailAuxiliaryUserAccountsEnabled</key>
<string>YES</string>
<key>SOGoMailDomain</key>
<string>univ-rouen.fr</string>
<key>SOGoMailMessageCheck</key>
<string>every_10_minutes</string>
<key>SOGoMailMessageForwarding</key>
<string>attached</string>
<key>SOGoMailShowSubscribedFoldersOnly</key>
<string>NO</string>
<key>SOGoMailingMechanism</key>
<string>smtp</string>
<key>SOGoMemcachedHost</key>
<string>127.0.0.1</string>
<key>SOGoProfileURL</key>
<string>postgresql://sogo:password@127.0.0.1:5432/sogo/sogo_user_profile</string>
<key>SOGoSMTPServer</key>
<string>smtp.univ-rouen.fr</string>
<key>SOGoSentFolderName</key>
<string>Sent</string>
<key>SOGoSieveScriptsEnabled</key>
<string>YES</string>
<key>SOGoSieveServer</key>
<string>sieve://sieve.univ-rouen.fr:2000</string>
<key>SOGoMailSpoolPath</key>
<string>/var/local/spool/sogo</string>
<key>SOGoSuperUsernames</key>
<array>
<string>adminlogin</string>
<string>admi2login</string>
</array>
<key>SOGoTimeZone</key>
<string>Europe/Paris</string>
<key>SOGoTrashFolderName</key>
<string>Trash</string>
<key>SOGoUserSources</key>
<array>
<dict>
<key>CNFieldName</key>
<string>displayName</string>
<key>IDFieldName</key>
<string>uid</string>
<key>UIDFieldName</key>
<string>uid</string>
<key>baseDN</key>
<string>ou=people,dc=univ-rouen,dc=fr</string>
<key>bindDN</key>
<string>cn=sogo,dc=univ-rouen,dc=fr</string>
<key>bindFields</key>
<array>
<string>uid</string>
</array>
<key>bindPassword</key>
<string>sogoldappassword</string>
<key>canAuthenticate</key>
<string>yes</string>
<key>displayName</key>
<string>Adresses partagées</string>
<key>hostname</key>
<string>ldap.univ-rouen.fr ldap-spare.univ-rouen.fr</string>
<key>id</key>
<string>ldap.univ-rouen.fr</string>
<key>isAddressBook</key>
<string>yes</string>
<key>type</key>
<string>ldap</string>
</dict>
</array>
<key>SOGoVacationEnabled</key>
<string>YES</string>
<key>WOMessageUseUTF8</key>
<string>YES</string>
<key>WOParsersUseUTF8</key>
<string>YES</string>
<key>WOPort</key>
<string>20000</string>
<key>WOWatchDogRequestTimeout</key>
<string>1</string>
</dict>
</plist>
Concernant le fichier de configuration, on peut aussi utiliser le format non xml de plist.
Le fichier /etc/sogo/sogo.conf sera alors de cette forme :
{
NGImap4ConnectionStringSeparator = "/";
NGImap4DisableIMAP4Pooling = "YES";
............
............
}
Si vous optez pour placer ce fichier dans /home/sogo/GNUstep/Defaults/.GNUstepDefaults il sera cependant sous cette forme :
{
NSGlobalDomain = {
};
sogod = {
NGImap4ConnectionStringSeparator = "/";
NGImap4DisableIMAP4Pooling = "YES";
............
............
};
}
Fichier de configuration Apache
<VirtualHost *:80>
ServerName sogo-rwd.univ-rouen.fr
ServerAlias sogo-rwd soual soual.univ-rouen.fr
ServerAdmin ent-bugs@unr-runn.fr
ServerSignature Off
ErrorLog /var/log/httpd/sogo.univ-rouen.fr-error.log
LogLevel warn
CustomLog /var/log/httpd/sogo.univ-rouen.fr-access.log combined
RewriteEngine On
RewriteRule ^/(.*) https://sogo-rwd.univ-rouen.fr/$1 [L,R]
</VirtualHost>
<VirtualHost *:443>
ServerName sogo-rwd.univ-rouen.fr
ServerAlias sogo-rwd
ServerAdmin ent-bugs@unr-runn.fr
ServerSignature Off
ErrorLog /var/log/httpd/sogo.univ-rouen.fr-error.log
LogLevel warn
CustomLog /var/log/httpd/sogo.univ-rouen.fr-access.log combined
SSLEngine on
SSLCertificateKeyFile /etc/httpd/ssl/sogo-rwd.univ-rouen.fr.key
SSLCertificateFile /etc/httpd/ssl/cert-12345--.univ-rouen.fr.pem
SSLCertificateChainFile /etc/httpd/ssl/chain-12345--.univ-rouen.fr.pem
DocumentRoot /var/www/
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
ErrorDocument 503 /webmail-503/503.html
RewriteEngine On
RewriteRule ^/$ /SOGo [L,R]
ExpiresActive On
#ExpiresByType text/css "access plus 3 hours"
#ExpiresByType text/javascript "access plus 3 hours"
ExpiresByType text/css "access plus 3 hours"
ExpiresByType text/javascript "access plus 3 hours"
ExpiresByType image/gif "access plus 1 day"
ExpiresByType image/png "access plus 1 day"
ExpiresByType image/jpg "access plus 1 day"
#CacheEnable mem /SOGo.woa/WebServerResources/
Alias /SOGo.woa/WebServerResources \
/usr/local/lib64/GNUstep/SOGo/WebServerResources
Alias /SOGo/WebServerResources \
/usr/local/lib64/GNUstep/SOGo/WebServerResources
AliasMatch /SOGo/so/ControlPanel/Products/(.*)/Resources/(.*) \
/usr/local/lib64/GNUstep/SOGo/$1.SOGo/Resources/$2
<Directory /usr/local/lib64/GNUstep/SOGo>
AllowOverride None
Require all granted
</Directory>
<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*\.(jpg|png|gif|css|js)">
SetHandler default-handler
</LocationMatch>
ProxyRequests Off
SetEnv proxy-nokeepalive 1
ProxyPreserveHost On
ProxyPass /SOGo/casProxy !
ScriptAlias /SOGo/casProxy /var/www/cgi-bin/cas-proxy-validate.py
<LocationMatch "^/SOGo/casProxy.*">
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from All
AddHandler cgi-script .py
</LocationMatch>
ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0
<Proxy http://127.0.0.1:20000/SOGo>
RequestHeader set "x-webobjects-server-port" "443"
RequestHeader set "x-webobjects-server-name" "sogo-rwd.univ-rouen.fr"
RequestHeader set "x-webobjects-server-url" "https://sogo-rwd.univ-rouen.fr"
RequestHeader set "x-webobjects-server-protocol" "HTTP/1.0"
RequestHeader set "x-webobjects-remote-host" %{REMOTE_HOST}e env=REMOTE_HOST
AddDefaultCharset UTF-8
Order allow,deny
Allow from all
</Proxy>
# header of emails.
RewriteRule ^/SOGo/(.*)$ /SOGo/$1 [env=REMOTE_HOST:%{REMOTE_ADDR},PT]
</VirtualHost>
Fichier CGI cas-proxy-validate.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# cas-proxy-validate.py - this file is part of SOGo
#
# Copyright (C) 2010 Inverse inc.
#
# Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# This script provides a CGI to avoid reentrancy issues when using SOGo in CAS
# mode
# debian dep: python-memcache
import cgi
import memcache
import os
import sys
config = { "cas-addr": "10.10.10.2",
"memcached-addrs": ["127.0.0.1:11211"] }
class CASProxyValidator:
def run(self):
if os.environ.has_key("GATEWAY_INTERFACE"):
self._runAsCGI()
else:
self._runAsCmd()
def _runAsCGI(self):
if self._cgiChecks():
form = cgi.FieldStorage()
if form.has_key("pgtId") and form.has_key("pgtIou"):
pgtIou = form.getfirst("pgtIou")
pgtId = form.getfirst("pgtId")
self._registerPGTIdAndIou(pgtIou, pgtId)
message = "'%s' set to '%s'" \
% ("cas-pgtiou:%s" % pgtIou, pgtId)
self._printCGIError(message, 200)
else:
self._printCGIError("Missing parameter.", 200)
def _cgiChecks(self):
rc = False
if os.environ["REQUEST_METHOD"] == "GET":
#if os.environ["REMOTE_ADDR"] == config["cas-addr"]:
# rc = True
#else:
# self._printCGIError("Who are you? (%s)" % os.environ["REMOTE_ADDR"])
rc = True
else:
self._printCGIError("Only 'GET' is accepted.")
return rc
def _printCGIError(self, message, code = 403):
sys.stderr.write('error %s , message : %s' % (code, message))
print("Status: %d\n"
"Content-Type: text/plain; charset=utf-8\n\n%s"
% (code, message))
def _runAsCmd(self):
if len(sys.argv) == 3:
self._registerPGTIdAndIou(sys.argv[1], sys.argv[2])
print "set '%s' to '%s'" \
% ("cas-pgtiou:%s" % sys.argv[1], sys.argv[2])
else:
raise Exception, "Missing or too many parameters."
def _registerPGTIdAndIou(self, pgtIou, pgtId):
mc = memcache.Client(config["memcached-addrs"])
mc.set("cas-pgtiou:%s" % pgtIou, pgtId)
if __name__ == "__main__":
process = CASProxyValidator()
process.run()
Systemctl et Lancement
systemctl enable sogo
systemctl restart sogo
Mises à jour
Arrêt
Mise à jour de SOPE
. /usr/share/GNUstep/Makefiles/GNUstep.sh
cd /usr/local/src/sope
git fetch
git checkout -b SOPE-5.0.2 SOPE-5.0.2
make clean
./configure --with-gnustep --disable-debug --disable-strip
make -j$(grep -c '^processor' /proc/cpuinfo)
make install
Mise à jour de SOGO
. /usr/share/GNUstep/Makefiles/GNUstep.sh
cd /usr/local/src/sogo
git fetch
git checkout -b SOGo-5.0.2 SOGo-5.0.2
make clean
./configure --disable-debug --disable-strip
make -j$(grep -c '^processor' /proc/cpuinfo)
make install
Redémarrage
SOGo v2
Notez que l'on peut toujours faire tourner une SOGo v2 (l'installation sur une debian bullseye par exemple depuis les sources et via compilation suit la même procédure que pour les versions 5) en parallèle (même base de données) qu'un SOGo v5, si et seulement si vous utilisez l'ancien schéma de la base de données pour ce faire, les propriétés OCSCacheFolderURL, OCSStoreURL et OCSAclURL ne doivent pas être positionnés alors.
Dans ce mode, de très nombeuses tables sont créés par utilisateur (3 minimum) et des commandes de maintenance usuelle de postgresql (sous mariadb, ce doit être la même chose) ne sont alors pas fonctionnelles (pg_dump, pg_upgradecluster ou même simple listing des tables).
Si l'intérêt de SOGo v2 était de proposer une interface web classique à la thundirbird, il est conseillé aujourd'hui d'utiliser uniquement la dernière version SOGo (5), la seule encore effectivement supportée et maintenue.
Base de données en SOGo v5
Cf paragraphe ci-dessus, depuis SOGo v3 il est possible de bénéficier d'une base de données usuelle avec seulement 9 tables (et non des centaines de milliers) en paramétrant simplement OCSCacheFolderURL, OCSStoreURL et OCSAclURL.
C'est la configuration recommandée ici et qui est sans nul doute la plus optimale et efficace.
Support de ActiveSync
Le support de ActiveSync doit être compilé depuis les sources SOGo via des commandes supplémentaires.
Il vous faudra installer libwbxml2 pour cela, sous debian bookworm par exemple :
apt install libwbxml2-1 libwbxml2-dev
Puis on lance simplement la compilation ainsi :
cd /usr/local/src/sogo/ActiveSync
make
make install
On doit ensuite redémarrer le SOGo pour prise en compte.
Pour rappel/information, un proxypass spécifique (sur apache ou nginx) aura été configuré sur le path en /Microsoft-Server-ActiveSync