Mattermost v4 mit MariaDB und Apache unter CentOS 7.x installieren und betreiben
Mattermost ist ein Werkzeug zum gemeinsamen Zusammenarbeiten in Teams, egal ob dies kleine schlagkräftige Gruppen sind, oder einzelne Bereiche bzw. Fachabteilungen in Firmen und Organisationen. Dabei ist es unerheblich, wo sich die einzelnen Teammitglieder befinden. egal ob vor Ort im Büro, im Homeoffice oder unterwegs. Neben der klassischen Funktion des Austausch von Informationen, Dokumenten, Programm- und Logdaten gibt es auch Möglichkeiten zum Anbinden und Einspeisen von Informationen aus verschiedenen Datenquellen, wie z.B. Datenbanken oder anderweitigen Systemen.
Hauptaufgabe von Mattermost ist die Bereitstellung der Kommunikationsplattform, um so zeitlich, räumlich und Anwendungsgeräte unabhängig die Anwender zu unterstützen. Hierzu stehen neben der rein WEB-/Browser-basierten Anwendung auch native Clients für die gängigen Betriebssysteme, wie auch Apps für iOS und Android zur Nutzung an mobilen Endgeräten zur Verfügung.
Neben der Echtzeitkommunikation in Form von Chats können Informationen an andere auch eingetragen werden, wenn diese gerade eben nicht angemeldet sind. Diese können die hinterlegten Nachrichten und Daten abgreifen, sobald sich diese wieder angemeldet haben. Kommunikationsverläufe werden fortlaufend mit archiviert und können somit nachträglich bequem durchsucht werden.
Zur Kommunikation können in Mattermost folgende Wege bereitgestellt und genutzt werden:
- Kanäle : Zur öffentlichen Kommunikation aller Anwender einer Arbeitsgruppe Teams bieten sich Kanäle an.
- Direktnachricht : Vertrauliche Kommunikation zwischen einzelnen Teammitgliedern werden typischer Weise über Direktnachrichten ausgetauscht.
- Private Gruppen : Für die Kommunikation in geschlossenen Benutzergruppen stehen Private Gruppen zur Verfügung. Ein Teamverantwortlicher wird die betreffenden Teammitglieder gesondert für eine solche private Gruppe berechtigen. Teammitglieder ohne Berechtigung bleiben solche geschlossene Benutzergruppen verwehrt.
Über alle diese Wege können auch Dateien geteilt werden. Dabei gelten die gleichen Zugriffsrechte, wie für den übergeordneten Kanal.
Anforderungen
System
Detaillierte Information zu den Voraussetzungen die für den Betrieb eines entsprechenden Mattermost-Servers finden sich in der Originaldokumentation.
In unserem Konfigurationsbeispiel gehen wir von einem Unternehmensbeispiel aus, bei dem ungefähr 250 - 500 Team-Mitglieder versorgt werden sollen. Wie setzen hierzu einen entsprechenden Server bzw. KVM Host ein, der über 2 vCPUs/cores, 4 GB RAM und etwa 100 GB Speicher-/Festplattenplatz verfügt. Der Speicherplatz für die Inhalte hängt natürlich stark von der Nutzungsfrequenz sowie Art und Größe der Inhalte ab, die gespeichert und vorgehalten werden sollen.
Datenbank
Als Datenbank setzen wir unseren MariaDB-Server ein. Eine ausführliche Installations- und Konfigurationsbeschreibung findet sich hier in Djangos WIKI.
Webserver
Mattermost selbst bringt einen eigenen Webserver mit, der über den Port 8065 erreichbar ist. Da wir aber unseren Dienst Mattermost sicherlich nicht über diesen highport unseren Nutzern zur Verfügung stellen wollen, benötigen wir noch einen Web-Proxy, der uns über Port 443 eine TLS-gesicherte Verbindung/Anwendung bereit stellt und eine Verbindung zum port 8065 des Mattermost-Daemon herstellt. Eine ausführliche Installations- und Konfigurationsbeschreibung zum Apache Webserver in der Version 2.4 ist auf folgender WIKI-Seite und zur Konfiguration eines SSL/TLS gesicherter Webserver mit mod_ssl für Apache httpd 2.4 findet sich hier.
Dokumentation
Eine ausführliche Dokumentation findet sich in der Mattermost Administrator’s Guide für Production Install on RHEL 7.1+.
vorbereitende Konfiguration
SQL-Datenbank MariaDB
Als erstes legen wir uns eine Datenbank mattermost_db an. Anschließend legen wir uns eine zugehörigen Datenbanknutzer an und weisen ihm die erforderlichen Rechte zu.
# mysql -h localhost -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 154831
Server version: 5.5.50-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database mattermost_db;
Query OK, 1 row affected (0.03 sec)
MariaDB [(none)]>CREATE USER 'mm_user'@'vml000097.dmz.nausch.org' IDENTIFIED BY 'SSK-reF48-b6gKj4376sfRF';
Query OK, 0 rows affected (0.72 sec)
MariaDB [(none)]> CREATE USER 'mm_user'@'10.0.0.97' IDENTIFIED BY 'SSK-reF48-b6gKj4376sfRF';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON mattermost_db.* TO 'mm_user'@'vml000097.dmz.nausch.org' IDENTIFIED BY 'SSK-reF48-b6gKj4376sfRF';
Query OK, 0 rows affected (0.02 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON mattermost_db.* TO 'mm_user'@'10.0.0.97' IDENTIFIED BY 'SSK-reF48-b6gKj4376sfRF';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (3.16 sec)
MariaDB [(none)]> exit
Bye
Datenbank Verbindung testen:
# mysql -h mariadb.dmz.nausch.org -D1 mattermost_db -u mm_user -p
Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 155063 Server version: 5.5.50-MariaDB MariaDB Server Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [mattermost_db]> exit Bye
Download des Programmarchivs
Bevor wir uns das aktuelle Programmpaket von mattermost herunterladen, wechseln wir in unser lokales Paketverzeichnis.
# cd /usr/local/src/packages/
Anschliessend holen wir uns das aktuelle tar.bz2-Archiv z.B. Version 4.2.0 auf unseren Server.
# wget https://releases.mattermost.com/4.2.0/mattermost-4.2.0-linux-amd64.tar.gz
Entpacken des Programmarchivs
Nun entpacken wir das heruntergeladene tar.gz-Archiv an Ort und Stelle.
# tar -xvzf /usr/local/src/packages/mattermost-4.2.0-linux-amd64.tar.gz -C /opt/
storage directory anlegen
Damit der Mattermost-Daemon die Nutzerdaten abspeichern kann, wird ein zugehöriges Datenverzeichnis benötigt. Wir legen diese nun, wie in der originalen Anleitung empfohlen, unter dem Pfad /opt/ an.
# mkdir -p /opt/mattermost/data
Benutzer und Gruppe für den Daemon anlegen
Für den vorcompilierten Daemon aus dem tar.gz-Archiv benötigen wir noch eine User und zugehörige Gruppe. Als erstes legen wir den Benutzer an:
# useradd -r mattermost -U
Diesem Nutzer mattermost weisen wir nun die Rechte am Verzeichnis /opt/mattermost zu.
# chown -R mattermost:mattermost /opt/mattermost/
# chmod -R g+w /opt/mattermost/
Damit wir mit unserem Admin-Account die betreffenden Konfigurationsdateien auch bearbeiten können, berechtigen wir diesen in dem wir ihn der Gruppe mattermost zuweisen.
# usermod -aG mattermost django
Konfiguration des Mattermost-Daemon
Die Konfiguration des Mattermost Daemon erfolgt mit Hilfe der Konfigurationsdatei /opt/mattermost/config/config.json. Der wichtigste Punkt ist dort vorerst die Definition der Datenbankanbindung, die wir im Abschnitt SQL-Datenbank MariaDB angelegt hatten.
# vim /opt/mattermost/config/config.json
- /srv/www/html/mattermost/config/config.json
{ "ServiceSettings": { "SiteURL": "", "LicenseFileLocation": "", "ListenAddress": ":8065", "ConnectionSecurity": "", "TLSCertFile": "", "TLSKeyFile": "", "UseLetsEncrypt": false, "LetsEncryptCertificateCacheFile": "./config/letsencrypt.cache", "Forward80To443": false, "ReadTimeout": 300, "WriteTimeout": 300, "MaximumLoginAttempts": 10, "GoroutineHealthThreshold": -1, "GoogleDeveloperKey": "", "EnableOAuthServiceProvider": false, "EnableIncomingWebhooks": true, "EnableOutgoingWebhooks": true, "EnableCommands": true, "EnableOnlyAdminIntegrations": true, "EnablePostUsernameOverride": false, "EnablePostIconOverride": false, "EnableAPIv3": true, "EnableLinkPreviews": false, "EnableTesting": false, "EnableDeveloper": false, "EnableSecurityFixAlert": true, "EnableInsecureOutgoingConnections": false, "AllowedUntrustedInternalConnections": "", "EnableMultifactorAuthentication": false, "EnforceMultifactorAuthentication": false, "EnableUserAccessTokens": false, "AllowCorsFrom": "", "SessionLengthWebInDays": 30, "SessionLengthMobileInDays": 30, "SessionLengthSSOInDays": 30, "SessionCacheInMinutes": 10, "WebsocketSecurePort": 443, "WebsocketPort": 80, "WebserverMode": "gzip", "EnableCustomEmoji": false, "EnableEmojiPicker": true, "RestrictCustomEmojiCreation": "all", "RestrictPostDelete": "all", "AllowEditPost": "always", "PostEditTimeLimit": 300, "TimeBetweenUserTypingUpdatesMilliseconds": 5000, "EnablePostSearch": true, "EnableUserTypingMessages": true, "EnableChannelViewedMessages": true, "EnableUserStatuses": true, "ClusterLogTimeoutMilliseconds": 2000 }, "TeamSettings": { "SiteName": "Mattermost", "MaxUsersPerTeam": 50, "EnableTeamCreation": true, "EnableUserCreation": true, "EnableOpenServer": false, "RestrictCreationToDomains": "", "EnableCustomBrand": false, "CustomBrandText": "", "CustomDescriptionText": "", "RestrictDirectMessage": "any", "RestrictTeamInvite": "all", "RestrictPublicChannelManagement": "all", "RestrictPrivateChannelManagement": "all", "RestrictPublicChannelCreation": "all", "RestrictPrivateChannelCreation": "all", "RestrictPublicChannelDeletion": "all", "RestrictPrivateChannelDeletion": "all", "RestrictPrivateChannelManageMembers": "all", "EnableXToLeaveChannelsFromLHS": false, "UserStatusAwayTimeout": 300, "MaxChannelsPerTeam": 2000, "MaxNotificationsPerChannel": 1000, "TeammateNameDisplay": "username", "ExperimentalTownSquareIsReadOnly": false }, "ClientRequirements": { "AndroidLatestVersion": "", "AndroidMinVersion": "", "DesktopLatestVersion": "", "DesktopMinVersion": "", "IosLatestVersion": "", "IosMinVersion": "" }, "SqlSettings": { "DriverName": "mysql", "DataSource": "mm_user:SSK-reF48-b6gKj4376sfRF@tcp(mariadb.dmz.nausch.org:3306)/mattermost_test?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s", "DataSourceReplicas": [], "DataSourceSearchReplicas": [], "MaxIdleConns": 20, "MaxOpenConns": 300, "Trace": false, "AtRestEncryptKey": "", "QueryTimeout": 30 }, "LogSettings": { "EnableConsole": true, "ConsoleLevel": "INFO", "EnableFile": true, "FileLevel": "INFO", "FileFormat": "", "FileLocation": "", "EnableWebhookDebugging": true, "EnableDiagnostics": true }, "PasswordSettings": { "MinimumLength": 5, "Lowercase": false, "Number": false, "Uppercase": false, "Symbol": false }, "FileSettings": { "EnableFileAttachments": true, "EnableMobileUpload": true, "EnableMobileDownload": true, "MaxFileSize": 52428800, "DriverName": "local", "Directory": "./data/", "EnablePublicLink": false, "PublicLinkSalt": "", "InitialFont": "luximbi.ttf", "AmazonS3AccessKeyId": "", "AmazonS3SecretAccessKey": "", "AmazonS3Bucket": "", "AmazonS3Region": "us-east-1", "AmazonS3Endpoint": "s3.amazonaws.com", "AmazonS3SSL": true, "AmazonS3SignV2": false, "AmazonS3SSE": false, "AmazonS3Trace": false }, "EmailSettings": { "EnableSignUpWithEmail": true, "EnableSignInWithEmail": true, "EnableSignInWithUsername": true, "SendEmailNotifications": false, "RequireEmailVerification": false, "FeedbackName": "", "FeedbackEmail": "", "FeedbackOrganization": "", "EnableSMTPAuth": false, "SMTPUsername": "", "SMTPPassword": "", "SMTPServer": "", "SMTPPort": "", "ConnectionSecurity": "", "InviteSalt": "", "SendPushNotifications": false, "PushNotificationServer": "", "PushNotificationContents": "generic", "EnableEmailBatching": false, "EmailBatchingBufferSize": 256, "EmailBatchingInterval": 30, "SkipServerCertificateVerification": false, "EmailNotificationContentsType": "full" }, "RateLimitSettings": { "Enable": false, "PerSec": 10, "MaxBurst": 100, "MemoryStoreSize": 10000, "VaryByRemoteAddr": true, "VaryByHeader": "" }, "PrivacySettings": { "ShowEmailAddress": true, "ShowFullName": true }, "SupportSettings": { "TermsOfServiceLink": "https://about.mattermost.com/default-terms/", "PrivacyPolicyLink": "https://about.mattermost.com/default-privacy-policy/", "AboutLink": "https://about.mattermost.com/default-about/", "HelpLink": "https://about.mattermost.com/default-help/", "ReportAProblemLink": "https://about.mattermost.com/default-report-a-problem/", "SupportEmail": "feedback@mattermost.com" }, "AnnouncementSettings": { "EnableBanner": false, "BannerText": "", "BannerColor": "#f2a93b", "BannerTextColor": "#333333", "AllowBannerDismissal": true }, "ThemeSettings": { "EnableThemeSelection": true, "DefaultTheme": "default", "AllowCustomThemes": true, "AllowedThemes": [] }, "GitLabSettings": { "Enable": false, "Secret": "", "Id": "", "Scope": "", "AuthEndpoint": "", "TokenEndpoint": "", "UserApiEndpoint": "" }, "GoogleSettings": { "Enable": false, "Secret": "", "Id": "", "Scope": "profile email", "AuthEndpoint": "https://accounts.google.com/o/oauth2/v2/auth", "TokenEndpoint": "https://www.googleapis.com/oauth2/v4/token", "UserApiEndpoint": "https://www.googleapis.com/plus/v1/people/me" }, "Office365Settings": { "Enable": false, "Secret": "", "Id": "", "Scope": "User.Read", "AuthEndpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", "TokenEndpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/token", "UserApiEndpoint": "https://graph.microsoft.com/v1.0/me" }, "LdapSettings": { "Enable": false, "LdapServer": "", "LdapPort": 389, "ConnectionSecurity": "", "BaseDN": "", "BindUsername": "", "BindPassword": "", "UserFilter": "", "FirstNameAttribute": "", "LastNameAttribute": "", "EmailAttribute": "", "UsernameAttribute": "", "NicknameAttribute": "", "IdAttribute": "", "PositionAttribute": "", "SyncIntervalMinutes": 60, "SkipCertificateVerification": false, "QueryTimeout": 60, "MaxPageSize": 0, "LoginFieldName": "" }, "ComplianceSettings": { "Enable": false, "Directory": "./data/", "EnableDaily": false }, "LocalizationSettings": { "DefaultServerLocale": "en", "DefaultClientLocale": "en", "AvailableLocales": "" }, "SamlSettings": { "Enable": false, "Verify": true, "Encrypt": true, "IdpUrl": "", "IdpDescriptorUrl": "", "AssertionConsumerServiceURL": "", "IdpCertificateFile": "", "PublicCertificateFile": "", "PrivateKeyFile": "", "FirstNameAttribute": "", "LastNameAttribute": "", "EmailAttribute": "", "UsernameAttribute": "", "NicknameAttribute": "", "LocaleAttribute": "", "PositionAttribute": "", "LoginButtonText": "With SAML" }, "NativeAppSettings": { "AppDownloadLink": "https://about.mattermost.com/downloads/", "AndroidAppDownloadLink": "https://about.mattermost.com/mattermost-android-app/", "IosAppDownloadLink": "https://about.mattermost.com/mattermost-ios-app/" }, "ClusterSettings": { "Enable": false, "ClusterName": "", "OverrideHostname": "", "UseIpAddress": true, "UseExperimentalGossip": false, "ReadOnlyConfig": true, "GossipPort": 8074, "StreamingPort": 8075 }, "MetricsSettings": { "Enable": false, "BlockProfileRate": 0, "ListenAddress": ":8067" }, "AnalyticsSettings": { "MaxUsersForStatistics": 2500 }, "WebrtcSettings": { "Enable": false, "GatewayWebsocketUrl": "", "GatewayAdminUrl": "", "GatewayAdminSecret": "", "StunURI": "", "TurnURI": "", "TurnUsername": "", "TurnSharedKey": "" }, "ElasticsearchSettings": { "ConnectionUrl": "http://dockerhost:9200", "Username": "elastic", "Password": "changeme", "EnableIndexing": false, "EnableSearching": false, "Sniff": true, "PostIndexReplicas": 1, "PostIndexShards": 1, "AggregatePostsAfterDays": 365, "PostsAggregatorJobStartTime": "03:00" }, "DataRetentionSettings": { "Enable": false }, "JobSettings": { "RunJobs": true, "RunScheduler": true }, "PluginSettings": { "Enable": false, "Plugins": {} } }
erster Test/Programmstart des Daemon
Nun können wir den Mattermost-Daemon das erste mal starten und so testen, ob die Konfiguration der Datenbankanbindung auch entsprechend geklappt hat. Den manuellen Start des Daemon erfolgt über den Aufruf des vorcompilierten Programms /opt/mattermost/bin/platform.
# cd /opt/mattermost/bin
# sudo -u mattermost ./platform
In der Konsole erfolgt direkt die Status-Ausgabe und Informationen bei ggf. auftretenden Fehlern.
[2017/10/05 20:21:37 CEST] [INFO] Loaded system translations for 'en' from '/opt/mattermost/i18n/en.json' [2017/10/05 20:21:37 CEST] [INFO] Current version is 4.2.0 (4.2.0/Wed Sep 13 22:25:30 UTC 2017/a5ce36d0882ae1b4b409a7b68233bf89591a5f95/38697f6cf2a9183e410e88acd13191390711d38f) [2017/10/05 20:21:37 CEST] [INFO] Enterprise Enabled: true [2017/10/05 20:21:37 CEST] [INFO] Current working directory is /opt/mattermost/bin [2017/10/05 20:21:37 CEST] [INFO] Loaded config file from /opt/mattermost/config/config.json [2017/10/05 20:21:37 CEST] [INFO] Able to write files to local storage. [2017/10/05 20:21:37 CEST] [INFO] Server is initializing... [2017/10/05 20:21:37 CEST] [INFO] Pinging SQL master database [2017/10/05 20:21:37 CEST] [INFO] The database schema has been set to version 4.2.0 [2017/10/05 20:21:37 CEST] [CRIT] Failed to create index Error 1214: The used table type doesn't support FULLTEXT indexes
Im vorliegenden Fall ist der Programmstart mit der Fehlermeldung Failed to create index Error 1214: The used table type doesn't support FULLTEXT indexes abgebrochen! Zur Behebung der Fehlerursache ist es notwendig die MariaDB Datenbank-Engine für die Datenbank mattermost_db von Innodb auf MyISAM umzustellen.
# mysql -h localhost -u root -p
Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 214784 Server version: 5.5.50-MariaDB MariaDB Server Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use mattermost_db; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Audits ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.ChannelMembers ENGINE = MyISAM; Query OK, 0 rows affected (0.15 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Channels ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.ClusterDiscovery ENGINE = MyISAM; Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Commands ENGINE = MyISAM; Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.CommandWebhooks ENGINE = MyISAM; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Compliances ENGINE = MyISAM; Query OK, 0 rows affected (0.04 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Emoji ENGINE = MyISAM; Query OK, 0 rows affected (0.04 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.FileInfo ENGINE = MyISAM; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.IncomingWebhooks ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Jobs ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Licenses ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.OAuthAccessData ENGINE= MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.OAuthApps ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.OAuthAuthData ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.OutgoingWebhooks ENGINE = MyISAM; Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Posts ENGINE = MyISAM; Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Preferences ENGINE = MyISAM; Query OK, 0 rows affected (0.63 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Reactions ENGINE = MyISAM; Query OK, 0 rows affected (0.63 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Sessions ENGINE = MyISAM; Query OK, 0 rows affected (0.07 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Status ENGINE = MyISAM; Query OK, 0 rows affected (0.35 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Systems ENGINE = MyISAM; Query OK, 3 rows affected (0.06 sec) Records: 3 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.TeamMembers ENGINE = MyISAM; Query OK, 0 rows affected (0.18 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Teams ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Tokens ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.UserAccessTokens ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> ALTER TABLE mattermost_db.Users ENGINE = MyISAM; Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [mattermost_db]> exit Bye
Nun können wir erneut Testen, ob nun der Daemon startet.
# sudo -u mattermost ./platform
[2017/10/05 20:40:46 CEST] [INFO] Loaded system translations for 'en' from '/opt/mattermost/i18n/en.json'
[2017/10/05 20:40:46 CEST] [INFO] Current version is 4.2.0 (4.2.0/Wed Sep 13 22:25:30 UTC 2017/a5ce36d0882ae1b4b409a7b68233bf89591a5f95/38697f6cf2a9183e410e88acd13191390711d38f)
[2017/10/05 20:40:46 CEST] [INFO] Enterprise Enabled: true
[2017/10/05 20:40:46 CEST] [INFO] Current working directory is /opt/mattermost/bin
[2017/10/05 20:40:46 CEST] [INFO] Loaded config file from /opt/mattermost/config/config.json
[2017/10/05 20:40:46 CEST] [INFO] Able to write files to local storage.
[2017/10/05 20:40:46 CEST] [INFO] Server is initializing...
[2017/10/05 20:40:46 CEST] [INFO] Pinging SQL master database
[2017/10/05 20:40:46 CEST] [INFO] Initializing job API routes
[2017/10/05 20:40:46 CEST] [INFO] API version 3 is scheduled for deprecation. Please see https://api.mattermost.com for details.
[2017/10/05 20:40:46 CEST] [INFO] Initializing plugin: jira
[2017/10/05 20:40:46 CEST] [INFO] Initializing plugin: ldapextras
[2017/10/05 20:40:46 CEST] [INFO] Starting 8 websocket hubs
[2017/10/05 20:40:46 CEST] [INFO] License key from https://mattermost.com required to unlock enterprise features.
[2017/10/05 20:40:46 CEST] [INFO] Starting Server...
[2017/10/05 20:40:46 CEST] [INFO] Server is listening on :8065
[2017/10/05 20:40:46 CEST] [INFO] Starting workers
[2017/10/05 20:40:46 CEST] [INFO] Starting schedulers
Der Daemon ist nun ohne Fehlermeldung gestartet und wir überprüfen nun, ob der Port 8085 vom Daemon geöffnet wurde.
# netstat -tulpen
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name tcp 0 0 10.0.0.97:80 0.0.0.0:* LISTEN 0 3314534 5595/httpd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 17398 1383/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 20993 1877/master tcp 0 0 0.0.0.0:5665 0.0.0.0:* LISTEN 993 4242609 4618/icinga2 tcp6 0 0 :::22 :::* LISTEN 0 17400 1383/sshd tcp6 0 0 ::1:25 :::* LISTEN 0 20994 1877/master tcp6 0 0 :::443 :::* LISTEN 0 3314671 5595/httpd tcp6 0 0 :::8065 :::* LISTEN 993 20420741 9521/./platform udp 0 0 0.0.0.0:35715 0.0.0.0:* 70 15118 693/avahi-daemon: r udp 0 0 0.0.0.0:5353 0.0.0.0:* 70 15117 693/avahi-daemon: r
Erstellen eines Systemd Init Daemon
Zum (automatischen) Start des Mattermost-Daemon auf unserem CentOS 7 Server benötigen wir noch eine Konfigurationsdatei für den Systemd Init Daemon.
# vim /etc/systemd/system/mattermost.service
- /etc/systemd/system/mattermost.service
[Unit] Description=Mattermost After=syslog.target network.target mysqld.service [Service] Type=simple WorkingDirectory=/opt/mattermost/bin User=mattermost ExecStart=/opt/mattermost/bin/platform PIDFile=/var/spool/mattermost/pid/master.pid LimitNOFILE=49152 [Install] WantedBy=multi-user.target
Im nächsten Schritt statten wir diese Datei mit den Dateiausführensrechten x aus.
# chmod 664 /etc/systemd/system/mattermost.service
Da wir eine neue Datei im Verzeichnis /etc/systemd/system/ angelegt haben, müssen wir den Systemd-Daemon davon in Kenntnis setzen. Ein Reload des Daemon reicht hierzu aus.
# systemctl daemon-reload
Abschliessend können wir nun Mattermost-Deamon mit Hilfe unseres soeben angelegten Scripts starten.
# systemctl start mattermost.service
# cat /opt/mattermost/logs/mattermost.log
[2017/10/05 20:47:59 CEST] [INFO] Loaded system translations for 'en' from '/opt/mattermost/i18n/en.json'
[2017/10/05 20:47:59 CEST] [INFO] Current version is 4.2.0 (4.2.0/Wed Sep 13 22:25:30 UTC 2017/a5ce36d0882ae1b4b409a7b68233bf89591a5f95/38697f6cf2a9183e410e88acd13191390711d38f)
[2017/10/05 20:47:59 CEST] [INFO] Enterprise Enabled: true
[2017/10/05 20:47:59 CEST] [INFO] Current working directory is /opt/mattermost/bin
[2017/10/05 20:47:59 CEST] [INFO] Loaded config file from /opt/mattermost/config/config.json
[2017/10/05 20:47:59 CEST] [INFO] Able to write files to local storage.
[2017/10/05 20:47:59 CEST] [INFO] Server is initializing...
[2017/10/05 20:47:59 CEST] [INFO] Pinging SQL master database
[2017/10/05 20:47:59 CEST] [INFO] Initializing job API routes
[2017/10/05 20:47:59 CEST] [INFO] API version 3 is scheduled for deprecation. Please see https://api.mattermost.com for details.
[2017/10/05 20:47:59 CEST] [INFO] Initializing plugin: ldapextras
[2017/10/05 20:47:59 CEST] [INFO] Initializing plugin: jira
[2017/10/05 20:47:59 CEST] [INFO] Starting 8 websocket hubs
[2017/10/05 20:47:59 CEST] [INFO] License key from https://mattermost.com required to unlock enterprise features.
[2017/10/05 20:47:59 CEST] [INFO] Starting Server...
[2017/10/05 20:47:59 CEST] [INFO] Server is listening on :8065
[2017/10/05 20:47:59 CEST] [INFO] Starting workers
[2017/10/05 20:47:59 CEST] [INFO] Starting schedulers
Den erfolgreichen Start sehen wir, da z.B. der Server den port 8065 geöffnet hat. Natürlich können wir auch den Status mit folgendem Aufruf überprüfen.
# systemctl status mattermost.service
● mattermost.service - Mattermost Loaded: loaded (/etc/systemd/system/mattermost.service; disabled; vendor preset: disabled) Active:active (running) since Thu 2017-10-05 20:47:58 CEST; 5s ago Main PID: 10485 (platform) CGroup: /system.slice/mattermost.service └─10485 /opt/mattermost/bin/platform Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] Initializing job API routes Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] API version 3 is scheduled for deprecation. Please see https://api.matte... details. Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] Initializing plugin: ldapextras Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] Initializing plugin: jira Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] Starting 8 websocket hubs Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] License key from https://mattermost.com required to unlock enterprise features. Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] Starting Server... Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] Server is listening on :8065 Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] Starting workers Oct 05 20:47:59 vml000107.dmz.nausch.org platform[10485]: [2017/10/05 20:47:59 CEST] [INFO] Starting schedulers
automatischen Start des Daemon beim Serverstart
Damit der Mattermost-Daemon automatisch beim Hochfahren des Servers gestartet wird, werden wir nun noch den Autostart des Damon aktivieren.
# systemctl enable mattermost.service
Created symlink from /etc/systemd/system/multi-user.target.wants/mattermost.service to /etc/systemd/system/mattermost.service.
Apache vHost als ReverseProxy
Als Webserver/(Reverse)Proxy nutzen wir unseren Apache-Webserver 2.4, dessen Installation und Konfiguration ist in diesem Kapitel beschrieben. Zur Absicherung des Web-Traffic kommt selbstredend TLS zum Einsatz. Die Installation und Konfiguration hierzu findet sich im Kapitel SSL gesicherter Webserver mit mod_ssl für Apache httpd 2.4 unter CentOS 7.x.
Für unseren virtuellen Host legen wir uns nun noch eine passende Konfigurationsdatei an:
# vim /etc/httpd/conf.d/mattermost.conf
- /etc/httpd/conf.d/mattermost.conf
# # Django : 2017-10-05 # vHost mattermost.nausch.org # <VirtualHost 10.0.0.107:80> ServerAdmin webmaster@nausch.org ServerName mattermost.nausch.org RewriteEngine on RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} # Welche Logdateien sollen beschrieben werden CustomLog logs/mattermost_access.log combined ErrorLog logs/mattermost_error.log </VirtualHost> <VirtualHost 10.0.0.107:443> ServerAdmin webmaster@nausch.org ServerName mattermost.nausch.org ServerPath / # Welcher Inhalt soll angezeigt bzw. auf welchen Server sollen die HTTP-Requests weitergeleitet werden? <Proxy *> Require all granted </Proxy> RewriteEngine On RewriteCond %{REQUEST_URI} ^/api/v[0-9]+/(users/)?websocket [NC,OR] RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR] RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC] RewriteRule .* ws://127.0.0.1:8065%{REQUEST_URI} [P,QSA,L] RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f RewriteRule .* http://127.0.0.1:8065%{REQUEST_URI} [P,QSA,L] <Location /api/v3/users/websocket> Require all granted ProxyPass ws://127.0.0.1:8065/api/v3/users/websocket ProxyPassReverse ws://127.0.0.1:8065/api/v3/users/websocket ProxyPassReverseCookieDomain 127.0.0.1 mattermost.nausch.org </Location> <Location /> Require all granted ProxyPass http://127.0.0.1:8065/ ProxyPassReverse http://127.0.0.1:8065/ ProxyPassReverseCookieDomain 127.0.0.1 mattermost.nausch.org </Location> # Welche Logdateien sollen beschrieben werden CustomLog logs/mattermost_access.log combined ErrorLog logs/mattermost_error.log # Absicherung der Übertragung mit Hilfe von TLS # Konfiguration bei Verwendung von mod_gnutls <IfModule !mod_ssl.c> <IfModule mod_gnutls.c> # Django : 2015-10-29 - TLS-Verschlüsselung mit Hilfe von mod_gnutls GnuTLSEnable on # Definition der anzubietenden Protokolle und Ciphers GnuTLSPriorities PFS:-VERS-TLS-ALL:+VERS-TLS1.2:-ARCFOUR-128:+COMP-NULL:+CURVE-SECP384R1:+CURVE-SECP521R1 # Schlüsseldatei, mit der der CSR erstellt wurde GnuTLSKeyFile /etc/pki/tls/private/power.nausch.org.serverkey.pem # Zertifikatsdatei inkl. ggf. notwendiger Zwischen- und Root-Zertifikaten # 1) Server-Zertifikat, 2) Intermediate-Root-Zertifikat und 3) Root-Zertifikat der CA GnuTLSCertificateFile /etc/pki/tls/certs/power.nausch.org.certificatechain_150104.pem # Definition der Schlüssellänge für DHE und ECDHE # DHE Schlüssel mit einer Schlüssellänge von 4096 Bit verwenden; dieser wird 1x pro Tag via cronjob # (/etc/cron.daily/edh_keygen) neu generiert und der Neustart des nginx-Daemon veranlasst! GnuTLSDHFile /etc/pki/tls/private/dh_4096.pem # Session-Tickets für Clients nicht anbieten (dieser könnte versuchen über Tickets die Session zu cachen). GnuTLSSessionTickets off </IfModule> </IfModule> # Konfiguration bei Verwendung von mod_ssl <IfModule mod_ssl.c> <IfModule !mod_gnutls.c> # Django : 2015-10-04 - TLS-Verschlüsselung mit Hilfe von mod_ssl SSLEngine on # Definition der anzubietenden Protokolle SSLProtocol All -SSLv2 -SSLv3 # Definition der Cipher SSLCipherSuite "AES256+EECDH +AEAD" # Schlüsseldatei, mit der der CSR erstellt wurde SSLCertificateKeyFile /etc/pki/tls/private/mattermost.nausch.org.serverkey.pem # Zertifikatsdatei, die von der CA signiert wurde SSLCertificateFile /etc/pki/tls/certs/mattermost.nausch.org.certificate_160926.pem # Zertifikatsdatei des bzw. der Intermediate-Zertifikate(s) SSLCertificateChainFile /etc/pki/tls/certs/CAcert_class3.pem # Änderung der Cipherorder der Clienets verneinen SSLHonorCipherOrder on # TLS 1.0 Kompremmierung deaktivieren (CRIME attacks) SSLCompression off </IfModule> </IfModule> # special stuff ### # HTTP Strict Transport Security (HSTS), bei dem der Server dem Client im HTTP-Header mitteilt, # dass dieser nur noch verschlüsselt mit dem Server kommunizieren soll. Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" # This header enables the Cross-site scripting (XSS) filter built into most recent web browsers. # It's usually enabled by default anyway, so the role of this header is to re-enable the filter for # this particular website if it was disabled by the user. # https://www.owasp.org/index.php/List_of_useful_HTTP_headers Header set X-XSS-Protection "1; mode=block" # when serving user-supplied content, include a X-Content-Type-Options: nosniff header along with the Content-Type: header, # to disable content-type sniffing on some browsers. # https://www.owasp.org/index.php/List_of_useful_HTTP_headers # currently suppoorted in IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx # http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx # 'soon' on Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=471020 Header set X-Content-Type-Options nosniff # config to don't allow the browser to render the page inside an frame or iframe # and avoid clickjacking http://en.wikipedia.org/wiki/Clickjacking # if you need to allow [i]frames, you can use SAMEORIGIN or even set an uri with ALLOW-FROM uri # https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options header set X-Frame-Options SAMEORIGIN </VirtualHost>
Konfiguration über die WEB-GUI
Die weitere Konfiguration erfolgt dann direkt über die Web-GUI, die wir über unsere URL https://mattermost.nausch.org erreichen.
Im ersten Schritt legen wir uns unseren (Admin)Useraccount an. Der erste User der angelegt wird, erhält automatische die Rolle system_admin, der die Zugriffsrechte auf die System Konsole erhält.
Als nächstes konfigurieren unsere Mattermost-Anwendung, dazu klicken wir auf den Menüpunkt Go to System Console.
Über das Menü auf der linken Seite erreichen wir die System Konsole.
Die einzelnen Konfigurationsoptionen im Menü links in dem dunkelgrauen Balken werden wir uns nun kurz betrachten und auf ggf. nötige Änderungen eingehen.
GENERAL
Configuration
Hier hinterlegen wir beim Punkt Site URL hinterlegen wir die URL unseres Mattermost Servers: https://mattermost.nausch.org
Localization
Hier wählen wir die Sprache(n) aus, die für unsere Installation nrelevant sind und angeboten werden sollen.
Users and Teams
Privacy
Bei den Privacy-Einstellungen wählen wir die für unsere Umgebung zutreffenden Datenschutzeinstellungen.
Logging
Beim Logging deaktivieren wir die Option Output logs to console, dazu ändern wir den Radiobutton auf false und klicken anschließend auf die Schaltfläche [ save ].
AUTHENTICATION
Im nächsten Abschnitt geht es rund um die Authentifikations.
Hier haben wir die Möglichkeit zu definieren, ob User sich einen Account selbst anlegen können. Ferner können wir festlegen, ob sich ein Nutzer mit seiner eMail-Adresse oder seinem Usernamen anmelden können soll.
GitLab
Die Einstellungen zum GitLab können wir einfach so übernehmen, da diese für eine Standardinstallation nicht relevant sind.
SECURITY
Sämtliche sicherheitsrelevanten Einstellungen sind im Abschnitt SECURITY zusammengefasst.
Sign Up
Die Standardoption beim Punkt Require Email Verification stellen wir von false auf true um und klicken anschließend auf die Schaltfläche [ save ].
Password
Public Links
Sessions
Connections
Notifications
Hier aktivieren wir nun folgende Optionen bzw. tragen nachfolgende Daten ein:
- Enable Email Notifications : true
- Enable Email Batching : false (Standard)
- Notification Display Name : Mattermost Notifications (Standard)
- Notification From Address : mattermost@nausch.org
- Notification Footer Mailing Address : Mattermost - secure chat 4 geeks, bereitgestellt von nausch.org
- SMTP Server Username : mattermost@nausch.org
- SMTP Server Password : KJvacByz69!fuKy
- SMTP Server : mx01.nausch.org
- SMTP Server Port : 587
- Connection Security : STARTTLS
- Enable Security Alerts : true (Default)
Vor dem Abspeichern klicken wir noch auf die Schaltfläche [ Test connection ] und überprüfen ob unser Server auch eMails verschicken kann. Ist alles O.K., speichern wir unsere Konfigurationsänderungen indem wir auf die Schaltfläche [ Save ] klicken.
Mobile Push
Integrations
Custom Integrations
External Services
FILES
Storage
Der wichtigste Konfigurationspunkt auf dieser Seite ist die Option Local Storage Directory. Hier tragen wir den Pfad ein, den wir bei der Definition des storage directory festgelegt hatten, also /opt/mattermlost/data.
Images
Customization
Custom Emoji
Legal Support
Auf der Seite Legal Support passen wir die Option Support Email: an. Hier tragen wir die Adresse der Supporthotline ein, an die eventuell gestellte Supportanfragen geschickt werden sollen.
Mattermost App Links
Die default-Werte auf dieser Seite können wir bei unserer Standardinstallation so übernehmen, es sei denn entsprechende Downloadstellen sind im Intranet vorhanden, die hierzu genutzt werden sollen.
Advanced
Rate Limiting
Die beiden Konfigurationspunkt die es auf dieser Seite anzupassen gilt sind die beiden Optionen Vary rate limit by remote address und Vary rate limit by HTTP header. Die Option Vary rate limit by remote address stellen wir um auf false und bei Vary rate limit by HTTP header hinterlegen wir X-Real-IP. Abschließend speichern wir unsere Konfigurationsänderungen, indem wir auf die Schaltfläche [ Save ] klicken.
Database
Auf der Seite brauchen wir nichts mehr ändern, da wir die Definitionen hier bereits bei der Konfiguration des Mattermost-Daemon vorgenommen hatten.
Developer
Bei der Seite Developer übernehmen wir einfach die Standardvorgaben.
Abschließend starten wir nun den Mattermost-Daemon einmal durch.
# systemctl restart mattermost.service
Anlegen des ersten Teams
Zu guter Letzt legen wir uns nun unser erstes Team an. Dazu tragen wir bei der Option Team Name den gewünschten Namen ein.
Anschliessend klicken wir auf die Schaltfläche [ Next > ] um auf die nächste Seite zu gelangen.
Nun müssen wir nur noch die Team URL definieren. Der Einfachheit halber verwenden wir dort den zuvor ausgewählten Team Namen.
Mit einen Klick auf die Schaltfläche [ Finish ] beenden wir unsere Konfigurationsaufgaben.
Anmelden als User
Nachdem unsere Mattermost Installation nun abgeschlossen ist, können wir uns als User anmelden, ggf. weitere Teams anlegen, Benutzer hinzufügen oder einladen …