| Info |
|---|
Depuis le 19 Juillet 2016, l'accès aux paquets SOGo est devenu payant : https://sogo.nu/news/2016/article/sogo-package-repositories.html Sur cette page, on décrit comment mettre en place SOGo sur une CentOS 7.2 rapidement depuis les sources github. Ce qui ne nécessite pas de s'acquitter de licences auprès d'Inverse pour ce faire. Au vu des pré-requis (version de la librairie Gnustep notamment), il est conseillé de ne pas réaliser cette installation sur une version inférieure à la version 7 de CentOS |
...
On installe ici un SOGo v3 avec authentification CAS, base de données PostgreSQL, annuaire LDAP (supann), ...
| Sommaire |
|---|
Installation des paquets nécessaires
| Bloc de code |
|---|
yum install gcc-objc gnustep-base gnustep-make gnustep-base-devel libxml2-devel openssl-devel openldap-devel postgresql-devel libmemcached-devel libcurl-devel |
Installation de SOPE
| Bloc de code |
|---|
cd /usr/local/src git clone https://github.com/inverse-inc/sope.git cd sope git checkout -b SOPE-34.0.2.1 SOPE-34.0.2.1 ./configure --with-gnustep --disable-debug --disable-strip make make install |
Installation de SOGO
| Bloc de code |
|---|
cd /usr/local/src git clone https://github.com/inverse-inc/sogo.git cd sogo git checkout -b SOGo-34.0.2.1 SOGo-34.0.2.1 ./configure --disable-debug --disable-strip make make install |
Paramétrage système
Création de l'utilisateur sogo
| Bloc de code |
|---|
adduser sogo |
Création des répertoires et affectation des droits
| Bloc de code |
|---|
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
| Bloc de code | ||
|---|---|---|
| ||
[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
| Bloc de code | ||
|---|---|---|
| ||
# 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/lib64/sogo:/usr/local/lib64:$LD_LIBRARY_PATH |
Fichier de configuration sogo
| Info | |||||
|---|---|---|---|---|---|
| Bloc de code | |||||
| |||||
Pour pouvoir lancer sogo-tool (et procéder à des backups, purge utilisateurs, etc.) la redéfinition de LD_LIBRARY_PATH est aussi nécessaire. Aussi vous pouvez ajouter dans le .bashrc de l'utilisateur sogo un
|
Fichier de configuration sogo
| Bloc de code | |||||||
|---|---|---|---|---|---|---|---|
| |||||||
<?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> <string>admi2login< <key>SOGoTrashFolderName</key> <string>Trash</string> <key>SOGoUserSources</key> <array> <dict> <key>CNFieldName</key> <string>displayName</string> </array> <key>SOGoTimeZone<<key>IDFieldName</key> <string>Europe<string>uid</Paris</string> <key>SOGoTrashFolderName< <key>UIDFieldName</key> <string>Trash< <string>uid</string> <key>SOGoUserSources< <key>baseDN</key> <array> <dict><string>ou=people,dc=univ-rouen,dc=fr</string> <key>CNFieldName<<key>bindDN</key> <string>displayName<<string>cn=sogo,dc=univ-rouen,dc=fr</string> <key>IDFieldName<<key>bindFields</key> <string>uid</string><array> <key>UIDFieldName<<string>uid</key>string> <string>uid<</string>array> <key>baseDN<<key>bindPassword</key> <string>ou=people,dc=univ-rouen,dc=fr<<string>sogoldappassword</string> <key>bindDN<<key>canAuthenticate</key> <string>cn=sogo,dc=univ-rouen,dc=fr<<string>yes</string> <key>bindFields<<key>displayName</key> <array><string>Adresses partagées</string> <string>uid<<key>hostname</string>key> </array><string>ldap.univ-rouen.fr ldap-spare.univ-rouen.fr</string> <key>bindPassword<<key>id</key> <string>sogoldappassword<<string>ldap.univ-rouen.fr</string> <key>canAuthenticate<<key>isAddressBook</key> <string>yes</string> <key>displayName<<key>type</key> <string>Adresses partagées<<string>ldap</string> </dict> </array> <key>hostname<<key>SOGoVacationEnabled</key> <string>ldap.univ-rouen.fr ldap-spare.univ-rouen.fr</string> <key>id<<string>YES</string> <key>WOMessageUseUTF8</key> <string>YES</string> <key>WOParsersUseUTF8</key> <string>YES</string> <string>ldap.univ-rouen.fr</string><key>WOPort</key> <string>20000</string> <key>isAddressBook<<key>WOWatchDogRequestTimeout</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> <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 :
| Bloc de code |
|---|
{
NGImap4ConnectionStringSeparator = "/";
NGImap4DisableIMAP4Pooling = "YES";
............
............
} |
Si vous optez pour placer ce fichier dans /home/sogo/GNUstep/Defaults/.GNUstepDefaults il sera cependant sous cette forme :
| Bloc de code |
|---|
{
NSGlobalDomain = {
};
sogod = {
NGImap4ConnectionStringSeparator = "/";
NGImap4DisableIMAP4Pooling = "YES";
............
............
};
}
|
Fichier de configuration Apache
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
<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> |
...
REMOTE_ADDR},PT]
</VirtualHost> |
Fichier CGI cas-proxy-validate.py
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
#!/usr/bin/python # -*- coding: utf-8 -*- # cas-proxy-validate.py |
...
| Bloc de code | ||||
|---|---|---|---|---|
| ||||
#!/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 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 freedistributed software;in youthe canhope redistributethat it will and/or modifybe useful, # but itWITHOUT underANY theWARRANTY; termswithout ofeven the GNUimplied Generalwarranty Publicof # LicenseMERCHANTABILITY asor publishedFITNESS by #FOR theA FreePARTICULAR SoftwarePURPOSE. Foundation; eitherSee version 2, or (at your option) # any later versionthe # GNU General Public License for more details. # # ThisYou fileshould ishave distributedreceived ina thecopy hopeof thatthe itGNU willGeneral bePublic useful,License # butalong WITHOUTwith ANYthis WARRANTYprogram; 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",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: "memcached-addrs": ["127.0.0.1:11211"] } class CASProxyValidator: self._runAsCmd() def run_runAsCGI(self): if osself.environ.has_keycgiChecks("GATEWAY_INTERFACE"): form self._runAsCGI= cgi.FieldStorage() else if form.has_key("pgtId") and form.has_key("pgtIou"): self._runAsCmd() pgtIou def _runAsCGI(self):= form.getfirst("pgtIou") if self._cgiChecks(): pgtId = form = cgi.FieldStoragegetfirst("pgtId") if form.has_key("pgtId") and form.has_key("pgtIou"): self._registerPGTIdAndIou(pgtIou, pgtId) pgtIoumessage = form.getfirst("pgtIou") "'%s' set to '%s'" \ pgtId = form.getfirst("pgtId" % ("cas-pgtiou:%s" % pgtIou, pgtId) self._registerPGTIdAndIouprintCGIError(pgtIoumessage, pgtId200) else: message = "'%s' set to '%s'" \ self._printCGIError("Missing parameter.", 200) def _cgiChecks(self): rc = False if os.environ["REQUEST_METHOD"] % ("cas-pgtiou:%s" % pgtIou, pgtId) == "GET": #if selfos._printCGIError(message, 200) elseenviron["REMOTE_ADDR"] == config["cas-addr"]: # self._printCGIError("Missing parameter.", 200)rc = True def _cgiChecks(self): rc = False #else: if os.environ["REQUEST_METHOD"] == "GET": # self._printCGIError("Who are you? (%s)" #if% os.environ["REMOTE_ADDR"] == config["cas-addr"]:) # rc = True #elseelse: # self._printCGIError("WhoOnly are you? (%s)" % os.environ["REMOTE_ADDR"]) 'GET' is accepted.") return rc rcdef _printCGIError(self, message, code = True403): else: sys.stderr.write('error %s , message : %s' % (code, message)) self._printCGIErrorprint("Only 'GET' is accepted.")Status: %d\n" return rc def _printCGIError(self, message, code = 403): "Content-Type: text/plain; charset=utf-8\n\n%s" sys.stderr.write('error %s , message : %s' % (code, message)) def _runAsCmd(self): if print("Status: %d\n"len(sys.argv) == 3: "Content-Type: text/plain; charset=utf-8\n\n%s"self._registerPGTIdAndIou(sys.argv[1], sys.argv[2]) print "set '%s' % (code, message)) to '%s'" \ def _runAsCmd(self): if% len(("cas-pgtiou:%s" % sys.argv[1], sys.argv[2]) == 3 else: self._registerPGTIdAndIou(sys.argv[1], sys.argv[2])raise Exception, "Missing or too many parameters." def _registerPGTIdAndIou(self, pgtIou, pgtId): print "set '%s'mc to '%s'" \= memcache.Client(config["memcached-addrs"]) % mc.set("cas-pgtiou:%s" % sys.argv[1]pgtIou, sys.argv[2]pgtId) if __name__ else== "__main__": process = 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
| Bloc de code |
|---|
systemctl enable sogo
systemctl restart sogo |
...
CASProxyValidator()
process.run()
|
Systemctl et Lancement
| Bloc de code |
|---|
systemctl enable sogo
systemctl restart sogo |
Mises à jour
Arrêt
| Bloc de code |
|---|
systemctl stop sogo |
Mise à jour de SOPE
| Bloc de code |
|---|
cd /usr/local/src/sope
git fetch
git checkout -b SOPE-4.0.3 SOPE-4.0.3
make clean
./configure --with-gnustep --disable-debug --disable-strip
make -j$(grep -c '^processor' /proc/cpuinfo)
make install |
Mise à jour de SOGO
| Bloc de code |
|---|
cd /usr/local/src/sogo
git fetch
git checkout -b SOGo-4.0.3 SOGo-4.0.3
make clean
./configure --disable-debug --disable-strip
make -j$(grep -c '^processor' /proc/cpuinfo)
make install |
Redémarrage
| Bloc de code |
|---|
systemctl start sogo |