Manual Installation (Custom Integration)
While the grommunio Appliance delivers a comprehensive solution for the majority of installations, some special needs might require a different approach. For these cases, the grommunio base system and core (groupware) can be installed manually with guidance from this chapter.
Note
grommunio is a comprehensive communication and collaboration solution with many services and components. With this modularity, grommunio is extremely versatile and allows various installation types which all of them can't be covered in detail. This section is intentionally as generic as possible.
Important
Please note that this section is targeted at adept administrators who are experienced in advanced linux administration and configuration.
This chapter assumes a basic system is running already. Basic in this regard means:
a system service manager of some kind should be running (systemd, sysvinit, etc.)
the system should be in its typical multi-user state (in terms of systemd, multi-user.target should have at least been started; in terms of sysvinit, init level 3 or 5)
should have an interactive shell for you to use
should not be ephemeral and not lose its state when turned off
Establish networking
[Text-based screenshot of networkctl being issued from a command shell.]
localhost:~ # networkctl
IDX LINK TYPE OPERATIONAL SETUP
1 lo loopback carrier unmanaged
2 host0 ether routable configured
2 links listed.
localhost:~ # networkctl status host0
* 2: host0
Link File: n/a
Network File: /etc/systemd/network/host0.network
Type: ether
State: routable (configured)
Online state: online
HW Address: aa:b2:5f:b1:9d:46
MTU: 1500 (min: 68, max: 65535)
QDisc: noqueue
IPv6 Address Generation Mode: none
Queue Length (Tx/Rx): 32/32
Auto negotiation: no
Speed: 10Gbps
Duplex: full
Port: tp
Address: 192.0.2.196
2001:db8:10b:45d8::f27
Gateway: 192.0.2.1
2001:db8:10b:45d8::1
Activation Policy: up
Required For Online: yes
Mar 31 23:47:13 localhost systemd-networkd[22]: host0: Link UP
Mar 31 23:47:13 localhost systemd-networkd[22]: host0: Gained carrier
For this setup, we enabled systemd-networkd
and the
network configuration put in place apriori. This section is a
reminder to hook up the host to Internet, as it will be needed to get the package repositories later.
The particular method of network configuration
varies wildly between operating systems, and not every system is using
systemd-networkd
. Consult the documentation relevant for your environment to
get online.
[Text-based screenshot of iproute2 being issued from a command shell.]
localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: host0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether aa:b2:5f:b1:9d:46 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.0.2.196/24 scope global host0
valid_lft forever preferred_lft forever
inet6 2001:db8:10b:45d8::f27/64 scope global
valid_lft forever preferred_lft forever
IPv6 is mandatory on the host itself. If you have ::1
assigned, that is sufficient.
We advise that a packet filter (i.e., a firewall) should be installed and configured by default to disallow every service. More details will be presented throughout the sections going forward. However, the following ports need to be open for grommunio to function properly:
VPN, SSH and/or port 8443 (AWEB) for the admin
smtp/25 for server-to-server mail passing
https/443 for end-user interactions
imaps, pop3s for end-user interactions if desired
Declare hostname identity
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
localhost:~ # echo mail.example.net >/etc/hostname
localhost:~ # hostname mail.example.net
localhost:~ # exec bash --login
mail:~ #
If you have not set a hostname yet, do so, especially if some default setting has left you with localhost as the hostname. You cannot reasonably reach localhost from another machine without unnecessary pains.
We used example.net
for the domain part of later e-mail addresses
(e.g. someuser@example.net
), and this machine that Grommunio
will be installed has a hostname of mail.example.net
.
Arbitrary names can be chosen as long as they are meaningful for their intended
network.
Note
The hostname(5) manual page provided in Linux/systemd systems says that
the name in /etc/hostname
should be a single label (no dots). If
you choose to do this, and if the single label does not constitute a
fully-qualified name already, you must set the host_id
directive in
/etc/gromox/http.cfg
to the fully-qualified name. (AutoDiscover
responses contain references to the server. Other services like zcore,
imap, etc. do not depend on FQDNs.)
Package manager setup
Pre-build packages are available for different platforms on https://download.grommunio.com. Different operating systems may use the same archive format (RPM, DEB, etc.), or the same repository metadata formats (such as rpm-md, apt). However, do not use a repository which does not exactly match your system nor do not attempt to convert between formats. This action might lead to unnecessary problems.
zypp
openSUSE uses yum-style .repo
files for declaring repositories.
For openSUSE Leap 15.4, you can create a file /etc/zypp/repos.d/grommunio.repo
and populate it as below:
[grommunio]
enabled=1
autorefresh=1
baseurl=https://download.grommunio.com/community/openSUSE_Leap_15.4
type=rpm-md
keeppackages=0
Retrieve the GPG key and import it into the RPM database to trust it. Then, optionally, download the repository metadata (if not, it will be done the next time you install anything).
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
mail:~ # curl https://download.grommunio.com/RPM-GPG-KEY-grommunio >gr.key
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3175 100 3175 0 0 18021 0 --:--:-- --:--:-- --:--:-- 18039
mail:~ # rpm --import gr.key
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
mail:~ # zypper ref grommunio
Retrieving repository 'grommunio' metadata ... [done]
Building repository 'grommunio' cache ... [done]
Specified repositories have been refreshed.
dnf
RHEL uses .repo
files as well, though in another directory. The file to edit
would be /etc/yum.repos.d/grommunio.repo
, with contents:
[grommunio]
name=grommunio for Enterprise Linux 9
baseurl=https://download.grommunio.com/community/EL9/
enabled=1
gpgcheck=1
gpgkey=https://download.grommunio.com/RPM-GPG-KEY-grommunio
Accept the GPG key during the first package installation or update when proceeding with dnf or yum commands.
Note
Our packages depend on packages in the CodeReady Linux Builder and
the EPEL repository. To enable them, run dnf install epel-release
followed by crb enable
.
apt
For Debian-based systems, the repository information needs to be added.
Create a new file in /etc/apt/sources.list.d/
, e.g. grommunio.sources
:
Types: deb
URIs: https://download.grommunio.com/community/Debian_12
Suites: Debian_12
Components: main
Signed-By: /usr/share/keyrings/download.grommunio.com.gpg
# wget -qO - https://download.grommunio.com/RPM-GPG-KEY-grommunio | gpg --dearmor --output /usr/share/keyrings/download.grommunio.com.gpg
(This equally works for Ubuntu_22.04, for example. For the specific case of
Ubuntu installations however, the Ubuntu universe
repository is also
required, so be sure to enable it. For Debian, the base distribution is
sufficient.)
Then import the GPG key and update the repositories.
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
# curl https://download.grommunio.com/RPM-GPG-KEY-grommunio >/etc/apt/trusted.gpg.d/download.grommunio.com.asc
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3175 100 3175 0 0 50396 0 --:--:-- --:--:-- --:--:-- 50396
Note
The apt-key
command is deprecated and should no longer be used. For
more information, see the apt-key(8) manpage.
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
# apt-get update
Hit:1 http://gb.archive.ubuntu.com/ubuntu jammy InRelease
Hit:2 http://gb.archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:3 http://gb.archive.ubuntu.com/ubuntu jammy-backports InRelease
Get:4 https://download.grommunio.com/community/Ubuntu_22.04 Ubuntu_22.04 InRelease [4,692 B]
Hit:5 http://security.ubuntu.com/ubuntu jammy-security InRelease
Get:6 https://download.grommunio.com/community/Ubuntu_22.04 Ubuntu_22.04/main amd64 Packages [7,072 B]
Get:7 https://download.grommunio.com/community/Ubuntu_22.04 Ubuntu_22.04/main i386 Packages [4,637 B]
Fetched 16.4 kB in 1s (23.8 kB/s)
Reading package lists... Done
TLS certificates
For obtaining a certificate, refer to external documentation.
Self-signed certificate: https://stackoverflow.com/a/10176685
Let's Encrypt certificate: https://certbot.eff.org/instructions
The certificate's key must be passwordless as interactive prompting is not implemented.
If you plan on using multiple subdomains for your deployment, e.g.
meet.example.net
for grommunio-meet and mail.example.net
for
grommunio-web, the generation a certificate with a subjectAltName (SAN)
field, or even a wildcard certificate, may be desirable over individual
certificates. Not all network protocols have something like Server Name
Indication (SNI), and even fewer system services support multiple individual
certificates even if they serve multiple IP addresses.
Autodiscover clients, as part of their routine, attempt to resolve and use
autodiscover.example.net
in addition to example.net
. Because it tries
multiple names, a SAN entry for the autodiscover.
subdomain is not strictly
necessary. See MS-OXDISCO §3.1.5
for further details.
The following services need access to the certificate(s):
gromox
nginx
postfix (optional)
Some processes read TLS certificates and their keyfiles after switching to an unprivileged user identity. For this reason, certificate files may need to be enhanced with a filesystem ACL or duplicate copies be made with suitable ownership.
nginx
nginx is used as a frontend to handle HTTP requests. RPC/HTTP requests are proxied to Gromox, Administration API (AAPI for short) requests are proxied to an uwsgi instance, and requests to the chat API are proxied to a Mattermost instance.
An alternative HTTP server may be used if you feel comfortable in configuring all of it, however this guide will only focus on nginx from here on.
Obtain the nginx package for your operating system, and have the service started both on next boot and immediately.
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
mail:~ # zypper in nginx nginx-module-vts
Loading repository data...
Reading installed packages...
Resolving package dependencies...
The following 26 NEW packages are going to be installed:
fontconfig libX11-6 libX11-data libXau6 libXpm4 libaom3 libavif13 libdav1d5
libdb-4_8 libexslt0 libfontconfig1 libfreetype6 libgd3 libgdbm6
ilbgdbm_compat4 libjbig2 libjpeg8 libpng16-16 librav1e0 libtiff5 libwebp7
libxcb1 libxslt1 nginx nginx-module-vts perl
26 new packages to install.
Overall download size: 15.2 MiB. Already cached: 0 B. After the operation,
additional 68.4 MiB will be used.
Continue? [y/n/v/...? shows all options] (y):
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
(22/26) Installing: libXpm4-3.5.13-1.8.x86_64 ... [done]
(23/26) Installing: libfontconfig1-2.13.1-2.12.x86_64 ... [done]
(24/26) Installing: libgd3-2.3.3-2.2.x86_64 ... [done]
(25/26) Installing: nginx-1.21.5-1.1.x86_64 ... [done]
Additional rpmoutput:
/usr/bin/systemd-sysusers --replace=/usr/lib/sysusers.d/nginx.conf -
Creating group nginx with gid 477.
Creating user nginx (User for nginx) with uid 477 and gid 477.
(26/26) Installing: nginx-module-vts-0.1.116-1.1.x86_64 ... [done]
mail:~ # systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service
In this screenshot, we also requested the installation of the nginx VTS module, which AAPI uses for reporting traffic statistics. VTS is not available for all platforms, and you can omit it.
Being the main entrypoint for everything, the nginx HTTPS network service must be configured in the packet filter to be publicly accessible. In other words, open port 443.
By default, Debian-based distributions ship default web server configs which
are in conflict with grommunio. It is recommended to remove the default web
service entry, generally located at /etc/nginx/sites-enabled/default
. By
removing this link, the webserver default website is disabled.
Configuration snippets should solely be edited under /etc/
. Files in
/usr
belong to the vendor/the distribution and are subject to (silent)
changes when an update is processed by the package manager.
nginx support package
The grommunio-common
package contains the initial configuration
fragments for nginx. Install it.
zypper in grommunio-common
The nginx default configuration as shipped by Linux distributions (file
/etc/nginx/nginx.conf
) contains a line include conf.d/*
. The support
package places a file to /etc/nginx/conf.d/grommunio.conf
, such that the
nginx-related grommunio configuration gets automatically loaded on the next
nginx (re-)start.
The actual fragment files for nginx are located under
/usr/share/grommunio-common
for packaging policy reasons; they are not
meant to be modified. However, they have further include
directives
pointing back to /etc
to facilitate overriding specific aspects.
/usr/share/grommunio-common/nginx/locations.d/autodiscover.conf
for example
contains the fragment that tells nginx to recognize the /Autodiscover
space
and forward such requests to gromox-http on port 10443 (see later section).
TLS for nginx
Create /etc/grommunio-common/nginx/ssl_certificate.conf
and populate with
the certificate directives, exchanging paths as appropriate:
ssl_certificate zzz.pem;
ssl_certificate_key zzz.key;
(The exact chain of includes is /etc/nginx/nginx.conf
>
/etc/nginx/conf.d/grommunio.conf
>
/usr/share/grommunio-common/nginx.conf
>
/etc/grommunio-common/nginx/ssl_certificate.conf
.)
The port 80 and 443 listen declarations are provided by
/usr/share/grommunio-common/nginx.conf
.
nginx's configuration can be tested and shown, respectively:
nginx -t
nginx -T
MariaDB
MariaDB/MySQL is used to store the user database and other auxiliary configuration parameters. If you plan on setting up a Gromox cluster, this database needs to be globally available to all nodes that will host Gromox services.
A preexisting MariaDB server may be used. All the standard tools and procedures that the database community has developed around SQL are applicable, in terms of e.g. configuration, backup/restore, and replication.
Assuming that you are going for a new SQL server instance, source the MariaDB packages from your operating system, and have the service started both on next boot and immediately.
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
mail:~ # zypper in mariadb mariadb-client
Loading repository data...
Reading installed packages...
Resolving package dependencies...
The following 15 NEW packages are going to be installed:
libJudy1 libaio1 libedit0 libltdl7 liblzo2-2 libmariadb3 libodbc2
libpython3_8-1_0 libwrap0 mariadb mariadb-client mariadb-errormessages
python38-base python38-mysqlclient
15 new packages to install.
Overall download size: 33.3 MiB. Already cached: 0 B. After the operation,
additional 160.7 MiB will be used.
Continue? [y/n/v/...? shows all options] (y):
(13/15) Installing: python38-base-3.8.12-3.2.x86_64 ... [done]
(14/15) Installing: pytnon38-mysqlclient-2.0.3-2.2.x86_64 ... [done]
(15/15) Installing: mariadb-10.6.5-4.1.x86_64 ... [done]
mail:~ # systemctl enable --now mariadb
Created symlinks /etc/systemd/system/mysql.service → /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /usr/lib/systemd/system/mariadb.service
After the installation, create a blank database and user identity for accessing it.
[Terminal screenshot of an interactive mysql session.]
mail:~ # mariadb
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.6.5-MariDB MariaDB package
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE DATABASE `grommunio`;
Query OK, 1 row affected (0.001 sec)
MariaDB [(none)]> GRANT ALL ON `grommunio`.* TO 'grommunio'@'localhost' IDENTIFIED BY 'freddledgruntbuggly';
Query OK, 0 rows affected (0.004 sec)
MariaDB [(none)]>
CREATE DATABASE `grommunio`;
GRANT ALL ON `grommunio`.* TO 'grommunio'@'localhost' IDENTIFIED BY 'freddledgruntbuggly';
The MariaDB network service is not meant to be open to the public Internet. Within your private network, it may need to be opened if (and only if) you plan on using it in a multi-host Grommunio setup, or when your plans about database replication demand it.
In certain versions, such as MySQL 8 (on e.g. Ubuntu 20.04), the GRANT statement no longer implicitly creates users and one must use CREATE USER instead. Furthermore, authentication with MariaDB/older MySQL clients may fail due to what appears to be a hashing method change; the remedy is an extra parameter for CREATE USER or ALTER USER.
Gromox in general
Gromox is the central groupware server component of grommunio. It provides the services for Outlook RPC, IMAP/POP3, an LDA for ingestion, and a PHP module for Z-MAPI.
The pre-built package is available in the Grommunio repositories. This guide is subsequently based on such a pre-built Gromox. Experts wishing to build from source and who have general knowledge on how to do so are referred to the Gromox installation documentation on specific aspects of the build procedure.
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
mail:~ # zypper in gromox
Loading repository data...
Reading installed packages...
Resolving package dependencies...
The following 26 NEW packages are going to be installed:
gromox libHX32 libbfio1 libcdata1 libcerror1 libcfile1 libclocale1 libcnotify1
libcpath1 libcsplit1 libcthreads1 libfcache1 libfdata1 libfmapi1 libgumbo1
ilbjsoncpp25 libpff1 libuna1 php8 php8-cli php8-mysql php8-pdo php8-soap
system-user-gromox system-user-wwwrun timezone
26 new packages to install
Overall download size: 5.8 MiB. Already cached: 0 B. After the operation,
additional 19.3 MiB will be used.
Continue? [y/n/v/...? shows all options] (y):
Gromox runs a number of processes and network services. None of them are meant to be open to the public Internet, because nginx is already that important point of ingress. The Gromox exmdb service (port 5000/tcp by default) needs to be reachable from other Gromox nodes in a multi-host grommunio setup for internal forwarding to a mailbox's home server.
Daemon executables are located in /usr/libexec/gromox
, they have short
names like http
, zcore
, etc. The manpage carries the same name, so you
would use man http
to call up the corresponding manpage. The configuration
files read by default follow the same scheme, e.g. /etc/gromox/http.cfg
.
Process information utilities such as ps(1) may show the full path of the
executable or just http
, depending on how these diagnostic utilities are
used. The systemd unit name, though, is gromox-http.service
.
All log output goes to stderr. When run from systemd, this is automatically redirected to the journal.
Gromox user database
The connection parameters for MariaDB need to be conveyed to Gromox with the
file /etc/gromox/mysql_adaptor.cfg
, whose contents could look like this:
mysql_username=grommunio
mysql_password=freddledgruntbuggly
mysql_dbname=grommunio
schema_upgrade=host:mail.example.net
Make sure to set restrictive permissions on this file (cf. section Permissions).
The data stored in MariaDB is shared among all mailbox nodes in a clustered
setup. Table schema (DDL) changes are necessary at times, but at most one node
in such a cluster should perform these changes to avoid running the risk of
corruption. The hostname after host:
specifies which machine will be
considered authoritative, if any. The schema_upgrade=host:...
line should
be consistent across all mailbox nodes. It is possible to completely omit
schema_upgrade
, at which point no updates will be done automatically.
After the database parameters have been set in the configuration file, the initial tables can be created by issuing the gromox-dbop command:
[Text-based screenshot of shell prompts (not part of the command) and commands to issue.]
mail:~ # gromox-dbop -C
Creating admin_roles
Creating associations
Creating configs
Creating domains
Creating forwards
Creating groups
Creating hierarchy
Creating members
Creating mlists
Creating options
Creating orgs
Creating specifieds
Creating users
Creating aliases
Creating user_properties
Creating admin_role_permission_relation
Creating admin_user_role_relation
Creating classes
Creating fetchmail
Creating secondary_store_hints
Creating user_devices
Creating user_device_history
Creating task_queue
mail:~ #
If automatic schema upgrades are disabled, manual updates can be performed later with:
gromox-dbop -U
gromox-event/timer
gromox-event is a notification daemon for an interprocess channel between gromox-imap/gromox-midb. No configuration is needed.
gromox-timer is an at(1)/atd(8)-like daemon for delayed delivery. No configuration is needed.
systemctl enable --now gromox-event gromox-timer
gromox-http
Because nginx was set up earlier as a frontend to listen on ports 80 and 443,
gromox-http needs to be moved "out of the way" (its built-in defaults are also
80/443). In addition, the daemon needs to be told the paths to the TLS
certificates. A manual page is provided with all the configuration directives
and can be called up with man 8gx http
. For now, these directives for
/etc/gromox/http.cfg
should suffice:
listen_port=10080
listen_ssl_port=10443
http_support_ssl=yes
http_certificate_path=zzz.pem
http_private_key_path=zzz.key
Run the service.
systemctl enable --now gromox-http
Perform a connection test. The expected result of requesting the /
URI will
be a 404 status code. (It could serve a static HTML file, but the default
config has no such file, and /
is not mapped to anywhere.)
curl -kv https://localhost:10443/
Expected output:
> GET / HTTP/1.1
> Host: localhost:10443
…
< HTTP/1.1 404 Not Found
…
Gromox's default config however has a mapping for /web
(to
/usr/share/grommunio-web
). If you have the grommunio-web
package already installed, requests to this subdirectory will succeed.
You can test the following URLs (port 10443 for gromox-http directly, 443 for
nginx, respectively) with curl from the server command-line, and it should
serve a static file:
curl -kv https://localhost:10443/web/version
curl -kv https://localhost:443/web/version
# firefox https://mail.example.net/web/version
Using a browser from a separate desktop machine is also possible provided port 10443 was made accessible. (Normally, 10443 need not be exposed to any other hosts.) The result for localhost:10443 and localhost:443 should be the same. Expected output:
< HTTP/1.1 200 OK
< Date: Tue, 29 Mar 2024 23:08:33 GMT
< Content-Type: text/plain
< Content-Length: 26
< Accept-Ranges: bytes
< Last-Modified: Tue, 29 Mar 2024 07:09:12 GMT
< ETag: "19165e1100000000-1a000000-98b0426200000000"
<
User-agent: *
Disallow: /
gromox-midb & zcore
gromox-midb is the IMAP Message Index Database, and gromox-zcore the bridge process for PHP-MAPI. No further configuration needed.
systemctl enable --now gromox-midb gromox-zcore
gromox-imap & pop3
Similar to http.cfg
, configure the TLS certificate paths for the IMAP/POP3
daemons. Skip this section if you do not intend to run these protocols.
IMAP/POP3 can run in unencrypted mode, but only for developers. Hence,
imap_force_starttls is set here. In /etc/gromox/imap.cfg
, declare:
listen_ssl_port=993
imap_support_starttls=true
imap_certificate_path=zzz.pem
imap_private_key_path=zzz.key
imap_force_starttls=true
In /etc/gromox/pop3.cfg
:
listen_ssl_port=995
pop3_support_stls=true
pop3_certificate_path=zzz.pem
pop3_private_key_path=zzz.key
pop3_force_stls=true
Enable and start services you wish to utilize. Adjust your packet filter configuration for these new ports as needed.
systemctl enable --now gromox-imap gromox-pop3
Manual testing can be performed with a utility like telnet, socat, and curl can issue more complex IMAP/POP3 protocol command chains.
curl -kv imaps://localhost/
curl -kv pop3s://localhost/
Expected output for IMAP:
* Trying ::1:993...
…
< * OK mail.example.net service ready
> A001 CAPABILITY
< * CAPABILITY IMAP4rev1 XLIST SPECIAL-USE UNSELECT UIDPLUS IDLE AUTH=LOGIN STARTTLS
< A001 OK CAPABILITY completed
…
Expected output for POP3:
* Trying ::1:995...
* TCP_NODELAY set
* Connected to localhost (::1) port 995 (#0)
…
< +OK mail.example.net pop service ready
> CAPA
< +OK capability list follows
< STLS
< TOP
< USER
< PIPELINING
< UIDL
< TOP
< .
> LIST
< -ERR login first
PHP-FPM
The installation of the gromox
package already pulls in php-fpm as a
dependency.
For completeness, verify that PHP knows about the MAPI module.
echo -en '<?php phpinfo(); ?>' | php | grep mapi
Verify that the gromox pool file was placed.
ls -al /etc/php8/fpm/php-fpm.d/gromox.conf
Then enable/start php-fpm:
systemctl enable --now php-fpm
For completeness, verify that the socket in the pool file was created:
ls -al /run/gromox/php-fpm.sock
Try to elicit a response from the Autodiscover code, via gromox-http (10443)
and/or nginx (443).
(/usr/share/grommunio-common/nginx/locations.d/autodiscover.conf
defines
the handler for the /Autodiscover
URI path, to pass all requests to
gromox-http on port 10443. gromox-http forwards this to php-fpm. This way,
Autodiscover also works in test setups without a frontend like nginx.)
curl -kv https://localhost:10443/Autodiscover/Autodiscover.xml
curl -kv https://localhost:443/Autodiscover/Autodiscover.xml
# firefox https://mail.example.net/Autodiscover/Autodiscover.xml
Expected result of this operation:
> GET /Autodiscover/Autodiscover.xml HTTP/1.1
> Host: localhost:10443
…
< HTTP/1.1 200 Success
< Date: Tue, 29 Mar 2024 23:54:16 GMT
< Transfer-Encoding: chunked
< Content-type: text/html; charset=UTF-8
<
E-2000: invalid request method, must be POST!
Administration API (AAPI)
Install the grommunio-admin-api
package. This package contains a
command-line interface, and an application server implemented using uwsgi.
zypper in grommunio-admin-api
Edit /etc/grommunio-admin-api/conf.d/database.yaml
to make AAPI aware of
the MariaDB configuration:
DB:
host: 'localhost'
user: 'grommunio'
pass: 'freddledgruntbuggly'
database: 'grommunio'
Set the password for the AAPI admin. This shell command can also be used later to recover from a lost password situation.
grommunio-admin passwd
grommunio Admin Web supports the exposure of the available features to be seen in
the upper left corner. Since grommunio can be installed in a distributed way, this
setting can be configured in /etc/grommunio-admin-common/config.json
.
{
"mailWebAddress": "https://mail.example.com/web",
"chatWebAddress": "https://mail.example.com/chat",
"videoWebAddress": "https://mail.example.com/meet",
"fileWebAddress": "https://mail.example.com/files",
"archiveWebAddress": "https://mail.example.com/archive"
}
This configuration file needs to be made available to nginx, ideally in the pluggable
location of /etc/grommunio-admin-common/nginx.d/web-config.conf
.
location /config.json {
alias /etc/grommunio-admin-common/config.json;
}
The main user of the uwsgi server is the Administrator Web interface (AWEB), so do enable/start the service now.
systemctl enable --now grommunio-admin-api
Permissions
The pre-built packages create the following identities:
Group
gromox
, which is used for objects in the information store (/var/lib/gromox
)Group
gromoxcf
, which is used for configuration files (/etc/gromox
)Gromox service user:
gromox
of groupgromox
, with supplementary groupgromoxcf
AAPI service user:
grommunio
of groupgrommunio
, with supplementary groupsgromox
andgromoxcf
The intention is that Gromox and AAPI services can interact with the information store and configuration files.
The directory /var/lib/gromox
and all contents shall be owned by user
gromox
or grommunio
. The group owner shall be gromox
with
read-write permission. Others should not have any access whatsoever.
drwxrwx--- 5 gromox gromox 62 Feb 13 23:15 /var/lib/gromox
The directory /etc/gromox
and all contents are supposed to be owned by
either user root
or grommunio
, be owned by group gromoxcf
read-only, and be otherwise inaccessible. Gromox has no need to update config
files at all, just read them. AAPI needs to write there (which it can via the
grommunio
user ownership). Any other users ought not to be able to access
this directory as it contains credentials for MySQL and LDAP.
drwxr-x--- 2 grommunio gromoxcf 125 Feb 20 21:47 /etc/gromox
nginx support package for AAPI/AWEB
The installation of grommunio-admin-api
or grommunio-admin-web
also
pulls in grommunio-admin-common
, which places a number of nginx fragments
into the filesystem similar to the earlier grommunio-common
.
The package adds nginx configuration fragments to make it listen on port 8080
unencrypted. You can edit /etc/nginx/conf.d/grommunio-admin.conf
and
disable the inclusion of /usr/share/grommunio-admin-common/nginx.conf
and/or enable encrypted access by uncommenting
/usr/share/grommunio-admin-common/nginx-ssl.conf
. The latter will make
nginx listen on port 8443.
Create /etc/grommunio-admin-common/nginx-ssl.conf
as a file, or as a
symlink to /etc/grommunio-common/nginx/ssl_certificate.conf
to the existing
TLS directives.
ln -s /etc/grommunio-common/nginx/ssl_certificate.conf /etc/grommunio-admin-common/nginx-ssl.conf
Reload/restart nginx as needed. Adjust your packet filter configuration for the new ports as needed.
The fragment files installed a route for the /api/v1
URI space to be
forwarded to the uwsgi process. It is now possible to make requests to the AAPI
endpoints, and we can test for that with curl or even firefox.
curl -kv https://localhost:8443/api/v1/login
# firefox https://mail.example.net:8443/api/v1/login
The expected result is a JSON response.
…
< HTTP/1.1 405 METHOD NOT ALLOWED
…
{"message":"Method 'GET' not allowed on this endpoint"}
An authenticated request can also be made:
curl -kv https://localhost:8443/api/v1/login -d 'user=admin&pass=freddledgruntbuggly'
Expected output:
{"grommunioAuthJwt":"eyJ0…"}
Administration Web Interface (AWEB)
AWEB is a package containing a HTML/JavaScript frontend and which will make use of AAPI's endpoints via REST.
zypper in grommunio-admin-web
Since this package contains just static files, the login page is now ready.
Visit https://mail.example.net:8443/
and log in with the credentials you
have previously assigned (username: admin
, password: as you did).
The details on how to use AWEB (sometimes also referred to as AUI) are provided on the Grommunio documentation website.
Known issues
The systemd service list in the dashboard (subsection “Performance”, box
container in the left third) has action buttons to trigger systemctl
enable/disable/start/stop/restart
. Despite the placement of the file
/usr/share/polkit-1/rules.d/pkit-10-gromox.rules
, AAPI is unable to issue
systemctl commands, and a red error box with text Interactive authentication
required
will appear.
Create domain & user
Create the example.net
domain, and a user using AWEB. Afterwards, one can
test the login/use in various ways. For example, to run the Autodiscover
procedure from the command-line:
PASS=abcdef /usr/libexec/gromox/autodiscover -e [email protected]
Expected output:
<?xml version="1.0" encoding="utf-8"?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
<Response xmlns=…
You can connect with Outlook if necessary.
To be able to log into IMAP/POP3, the user must have this feature explicitly enabled. This can be changed using AWEB by going to the Domains > example.net > Users tab on the left-hand side navigation pane. Once enabled,
curl -kv imaps://localhost/ -u [email protected]:abcdef
Expected output:
…
> A001 CAPABILITY
< * CAPABILITY IMAP4rev1 XLIST SPECIAL-USE UNSELECT UIDPLUS IDLE AUTH=LOGIN STARTTLS
< A001 OK CAPABILITY completed
> A002 AUTHENTICATE LOGIN
< + VXNlciBOYW1lAA==
> Ym9ua0Byb3V0ZTM4LnRlc3Q=
< + UGFzc3dvcmQA
> YWJjZGVm
< A002 OK logged in
> A003 LIST "" *
< * LIST (\HasNoChildren) "/" {5}
* LIST (\HasNoChildren) "/" {5}
< INBOX
…
grommunio-web
Install grommunio-web
. Verify that you can load the login page and login:
curl -kv https://localhost:443/web/
# firefox https://mail.example.net/web/
Loopback mail
The gromox-delivery-queue and gromox-delivery services comprise the Local Delivery Agent. This LDA supports a bit of SMTP to facilitate it being used in a filter-free loopback scenario. That is, one can send mail from example.net to example.net (only), with no SMTP to the outside.
(A mail composed and submitted with grommunio-web will ultimately be emitted by the gromox-zcore process, which sends it to localhost:25. Alternatively, when using Outlook, the gromox-http process emits the mail to localhost:25. And on port 25, one can either run the LDA, or indeed a full MTA like Postfix.)
On some systems which exuberantly start services (hi Debian), you may need to disable an existing MTA first before being able to perform this test. (Alternatively, you can skip right to the "Postfix" section below.)
systemctl stop postfix
systemctl enable --now gromox-delivery gromox-delivery-queue
Postfix
Because gromox-delivery-queue listens on port 25 by default, it needs to be
moved out the way when putting a full MTA in its place. Edit
/etc/gromox/smtp.cfg
and declare:
listen_port = 24
Within the Postfix configuration, we will be making use of the mysql lookup plugin, so do install that alongside Postfix itself:
zypper in postfix postfix-mysql
Set up a few Postfix directives:
postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mbxdom.cf
postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mbxmaps.cf
postconf -e virtual_alias_maps=mysql:/etc/postfix/alias.cf,mysql:/etc/postfix/mbxmaps.cf
postconf -e virtual_transport="smtp:[localhost]:24"
Filenames for these additional configuration fragments, mbxdom.cf
,
mbxmaps.cf
and alias.cf
, can be freely chosen. Add the MariaDB
parameters to the alias resolution fragment that (here) goes into
/etc/postfix/alias.cf
:
user = grommunio
password = freddledgruntbuggly
hosts = localhost
dbname = grommunio
query = SELECT mainname FROM aliases WHERE aliasname='%s'
Then, add the MariaDB connection parameters to the domain resolution fragment
that (here) goes into /etc/postfix/mbxdom.cf
:
user = grommunio
password = freddledgruntbuggly
hosts = localhost
dbname = grommunio
query = SELECT 1 FROM domains WHERE domain_status=0 AND domainname='%s'
Furthermore, add the MariaDB parameters to the mailbox resolution fragment,
here in /etc/postfix/mbxmaps.cf
:
user = grommunio
password = freddledgruntbuggly
hosts = localhost
dbname = grommunio
query = SELECT username FROM users WHERE username='%s'
If you plan to use reject_authenticated_sender_login_mismatch
for SMTP
submission, e.g. in the Postfix directive smtpd_sender_restrictions
or
smtpd_recipient_restrictions
to ensure that the SASL login name is an owner
for the e-mail sender address, set another Postfix directive:
postconf -e smtpd_sender_login_maps=mysql:/etc/postfix/mbxmaps.cf,mysql:/etc/postfix/alias.cf
Finally, enable/restart the services so they can take their new places:
systemctl enable --now gromox-delivery gromox-delivery-queue postfix
systemctl restart gromox-delivery-queue postfix
Other services
This chapter only covers the core component. Optional components, such as Chat, Meet, Files, Office and/or Archive, will be published in their own chapter at a later date.