Grommunio Mail Server
This material is work-in-progress ... This is a work in progress |
HOWTO: Install AlpineLinux Mail Server with Grommunio
This tutorial outlines the steps for setting up a mail server on Alpine Linux using Grommunio, a modern, open-source groupware solution that supports email and calendar services. The installation includes MariaDB, Nginx, PHP, Postfix, and other components necessary for a fully functioning mail server.
Prerequisites
Before proceeding with the installation, ensure you have a fresh Alpine Linux system setup. You'll need root privileges to execute these commands.
Procedure
- Install and configure MariaDB
- MariaDB performance tuning (optional)
- Install and configure Nginx
- Install and configure PHP
- Install and configure Postfix
- Install and configure Grommunio
- Configure Valkey (Redis replacement)
- Install and configure Rspamd
- Finalize and verify installation
1. Install and Configure MariaDB
Install MariaDB
To start, install MariaDB and necessary utilities
apk add mariadb mariadb-client mariadb-server-utils
Define the variables used later in the setup setup and configuration.
The default datapath is /var/lib/mysql and contains the entire database. If you prefer another location define it here and create a symlink. In any case, the grommunio database will be rather small as it only contains the configuration.
DB_DATA_PATH="/srv/mysql" DB_ROOT_PASS="Passw0rd1" DB_USER="admin" DB_PASS="Passw0rd2"
Setup the default system tables:
sudo mysql_install_db --user=mysql --datadir=${DB_DATA_PATH}
Set a symlink to the standard mysql data directory for compatibility reason:
ln -s /srv/mysql /var/lib/mysql
Restart service:
rc-service mariadb restart
Run the built-in security script:
Set the new root password to the one defined above and answer everything with 'y'
sudo mysql_secure_installation
Create MariaDB User for Grommunio
Create a new user for Grommunio and assign privileges:
echo "GRANT ALL ON *.* TO ${DB_USER}@'127.0.0.1' IDENTIFIED BY '${DB_PASS}' WITH GRANT OPTION;" > /tmp/sql echo "GRANT ALL ON *.* TO ${DB_USER}@'localhost' IDENTIFIED BY '${DB_PASS}' WITH GRANT OPTION;" >> /tmp/sql echo "GRANT ALL ON *.* TO ${DB_USER}@'::1' IDENTIFIED BY '${DB_PASS}' WITH GRANT OPTION;" >> /tmp/sql echo "DELETE FROM mysql.user WHERE User=;" >> /tmp/sql echo "FLUSH PRIVILEGES;" >> /tmp/sql cat /tmp/sql | mysql -u root --password="${DB_ROOT_PASS}"
Configure MariaDB for Grommunio
Edit the MariaDB configuration for better performance:
vi /etc/my.cnf.d/mariadb-server.cnf
Add the following configuration:
[mysqld] #skip-networking ## Configuration for grommunio (most values are default) innodb_log_buffer_size=16M innodb_log_file_size=32M innodb_read_io_threads=4 innodb_write_io_threads=4 join_buffer_size=512K query_cache_size=0 query_cache_type=0 query_cache_limit=2M # Activate performance schema performance_schema=ON # Bind to localhost only bind-address = 127.0.0.1 # Disable DNS lookups as we only use localhost connections skip-name-resolve=ON
Create a default charset configuration for MariaDB:
cat > /etc/my.cnf.d/mariadb-server-default-charset.cnf << EOF [client] default-character-set = utf8mb4 [mysqld] collation_server = utf8mb4_general_ci character_set_server = utf8mb4 [mysql] default-character-set = utf8mb4 EOF
Restart MariaDB and enable it to start on boot:
rc-update add mariadb default service mariadb restart
=== Verify MariaDB Setup Check if the MariaDB listener is running and bound to the correct interface (127.0.0.1):
ss -tulpn
Create Grommunio Database
Define the database parameters and create the Grommunio database:
MYSQL_HOST="localhost" MYSQL_USER="grommunio" MYSQL_PASS="Passw0rd3" MYSQL_DB="grommunio"
echo "create database $MYSQL_DB character set 'utf8mb4';" > /tmp/sql echo "grant select, insert, update, delete, create, drop, index, alter, create temporary tables, lock tables on $MYSQL_DB.* TO $MYSQL_USER@$MYSQL_HOST identified by '$MYSQL_PASS';" >> /tmp/sql echo "flush privileges;" >> /tmp/sql cat /tmp/sql | mysql -u admin --password="${DB_PASS}"
Test the database connection:
mysql -hlocalhost -u grommunio -p${MYSQL_PASS} grommunio
2. MariaDB Performance Tuning (Optional)
Install and configure MySQLTuner to help with database performance:
wget -v --no-check-certificate https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl -O /tmp/mysqltuner.pl mv /tmp/mysqltuner.pl /usr/local/bin/mysqltuner.pl chmod 755 /usr/local/bin/mysqltuner.pl apk add perl perl-doc /usr/local/bin/mysqltuner.pl --user admin --pass ${DB_PASS}
3. Install and Configure Nginx
Install Nginx
Install the necessary Nginx modules:
apk add nginx nginx-mod-http-headers-more nginx-mod-http-vts nginx-mod-http-brotli
Configure Nginx
Backup the original Nginx configuration and edit it for security headers and TLS settings:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig vi /etc/nginx/nginx.conf
Add the following configuration:
error_log syslog:server=unix:/dev/log,facility=local2,nohostname warn; more_set_headers "Strict-Transport-Security : max-age=2592000; includeSubDomains;"; more_set_headers "X-Frame-Options : SAMEORIGIN"; more_set_headers "Content-Security-Policy : default-src https: data: 'unsafe-inline' 'unsafe-eval' always"; more_set_headers "X-Xss-Protection : 1; mode=block"; more_set_headers "X-Content-Type-Options : nosniff"; more_set_headers "Referrer-Policy : strict-origin-when-cross-origin"; more_set_headers "Server : Follow the white rabbit.";
ssl_protocols TLSv1.2 TLSv1.3; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m;
log_format main_ssl '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' 'client_ciphers="$ssl_ciphers" client_curves="$ssl_curves"'; access_log off;
Restart Nginx and enable it to start on boot:
rc-update add nginx service nginx restart
4. Install and Configure PHP
Install PHP
Install the required PHP packages for Grommunio:
apk add php83 php83-fpm
Harden PHP Configuration
Disable insecure PHP settings and adjust PHP limits:
sed 's/^;\?\(allow_url_fopen\).*/\1 = Off/' -i /etc/php83/php.ini sed 's/^;\?\(expose_php\).*/\1 = Off/' -i /etc/php83/php.ini sed 's/^;\?\(display_errors\).*/\1 = Off/' -i /etc/php83/php.ini sed 's/^;\?\(log_errors\).*/\1 = On/' -i /etc/php83/php.ini
Configure Session Security
Configure PHP session security:
sed 's/^;\?\(session.use_strict_mode\).*/\1 = 1/' -i /etc/php83/php.ini sed 's/^;\?\(session.cookie_secure\).*/\1 = 1/' -i /etc/php83/php.ini sed 's/^;\?\(session.cookie_httponly\).*/\1 = 1/' -i /etc/php83/php.ini
5. Install and Configure Postfix
Install Postfix
Install Postfix and related modules:
apk add postfix postfix-mysql postfix-pcre
Configure Postfix
Backup and configure the Postfix settings. Adapt the values as necessary, such as `myhostname`, `mynetworks`, and `smtp_tls_chain_files`:
mv /etc/postfix/main.cf /etc/postfix/main.cf.orig mv /etc/postfix/master.cf /etc/postfix/master.cf.orig
Run Postfix setup:
newaliases postmap /etc/postfix/transport
Enable Postfix service:
rc-update add postfix service postfix restart
Verify Postfix Logs
Check the Postfix logs for any errors:
tail -f /var/log/maillog
9. Finalize and Verify Installation
Step 1: Test Server Components
Ensure that all services (Postfix, MariaDB, Nginx, PHP, Grommunio) are running correctly:
ss -tulpn
Step 2: Verify Mail Functionality
Test sending and receiving emails using a mail client and verifying server logs for any errors.
6. Install and Configure Grommunio
Enable IPv6
Since Grommunio requires IPv6 for its daemons:
1. Edit `/etc/hosts` to include IPv6 localhost:
vi /etc/hosts ----- ::1 localhost ipv6-localhost ipv6-loopback -----
2. Ensure IPv6 is enabled in `/etc/sysctl.conf`:
sed -i 's/^net\.ipv6\.conf\..*\.disable_ipv6\s=\s1/#&/' /etc/sysctl.conf sysctl -p ping ::1 # Test if IPv6 is working
Configure Database Parameters
Set up your MySQL database connection details:
MYSQL_HOST="localhost" MYSQL_USER="grommunio" MYSQL_PASS="Passw0rd3" MYSQL_DB="grommunio"
Specify Internal FQDN, Mail Domain, and Relayhost
Adjust the following for your specific setup:
FQDN="mail.example.local" MAILDOMAIN="example.com" RELAYHOST="123.123.123.1" ADMIN_PASS="Passw0rd4"
Install Dependencies and Grommunio Packages
Install necessary dependencies:
apk add valkey valkey-cli cyrus-sasl cyrus-sasl-login util-linux-login apk add grommunio-gromox grommunio-web grommunio-admin-api grommunio-admin-web grommunio-index grommunio-error-pages
Optionally, install deprecated ActiveSync if needed:
# apk add grommunio-dav grommunio-sync
Move Mail Storage to Another Disk
Move the largest directory `/var/lib/gromox` to another disk and create a symlink:
mv /var/lib/gromox /srv/gromox ln -s /srv/gromox /var/lib/gromox
Enable Required Services
Enable all necessary Grommunio services:
rc-update add grommunio-admin-api rc-update add gromox-delivery rc-update add gromox-delivery-queue # Add all the other grommunio services
Configure Grommunio Files
Modify the configuration files to match your environment:
sed -i "s/mail.example.local/${FQDN}/g" /etc/gromox/*.cfg sed -i "s/example.com/${MAILDOMAIN}/g" /etc/gromox/*.cfg # Continue modifying other configuration files (mysql_adaptor.cfg, autodiscover.ini, etc.)
Configure Postfix
Prepare Postfix for integration with Grommunio:
cp -p /etc/postfix/grommunio-virtual-mailbox-maps.cf /etc/postfix/grommunio-virtual-mailbox-sender-maps.cf sed -i '/^query =/d' /etc/postfix/grommunio-virtual-mailbox-sender-maps.cf echo "query = SELECT username FROM users WHERE username='%s' UNION SELECT aliasname FROM aliases WHERE mainname='%s'" >> /etc/postfix/grommunio-virtual-mailbox-sender-maps.cf
Configure TLS Certificates
Link and configure your SSL certificates:
ln -s /etc/grommunio-common/nginx/ssl_certificate.conf /etc/grommunio-admin-common/nginx-ssl.conf cat /etc/ssl/private/${FQDN}.key.pem /etc/ssl/certs/${FQDN}.cert.pem > /etc/ssl/private/${FQDN}.key_cert.pem chmod 640 /etc/ssl/private/*.key_cert.pem addgroup gromox ssl-cert
Configure PAM and SASL
Set up authentication services:
# Configure PAM for SMTP cat > /etc/pam.d/smtp <<EOF #%PAM-1.0 auth required pam_gromox.so service=smtp account required pam_permit.so EOF
# Configure SASL authentication cat > /etc/conf.d/saslauthd <<EOF SASLAUTHD_OPTS="-a pam -r" EOF
Initialize the Database and Set Admin Password
Initialize the database:
gromox-dbop -C
Set the Grommunio admin password:
grommunio-admin passwd --password "${ADMIN_PASS}"
Configure Firewall Ports
Open the necessary firewall ports:
# Required ports: 25, 80, 443, etc.
7. Configure Valkey (Redis Replacement)
Enable Syslog
vi /etc/valkey/grommunio.conf ----- syslog-enabled yes syslog-ident valkey syslog-facility local0 -----
Enable Memory Overcommit
vi /etc/sysctl.conf ----- vm.overcommit_memory = 1 ----- sysctl -p
Start Valkey and Test
rcctl restart valkey@grommunio valkey-cli ping # Expected result: 'PONG'
8. Install and Configure Rspamd
Install Rspamd
apk add rspamd rspamd-client
Configure Rspamd
Modify Rspamd configuration files:
cat > /etc/rspamd/local.d/options.inc <<EOF dns { enable_dnssec = true; timeout = 4s; retransmits = 5; } EOF
cat > /etc/rspamd/local.d/redis.conf <<EOF read_servers = "127.0.0.1"; write_servers = "127.0.0.1"; EOF
cat > /etc/rspamd/local.d/worker-proxy.inc <<EOF milter = yes; bind_socket = "/var/run/rspamd/worker-proxy.sock mode=0660 owner=rspamd"; timeout = 120s; upstream "local" { default = yes; self_scan = yes; } count = 4; EOF
Add Postfix to Rspamd Group
addgroup postfix rspamd
Configure DKIM Signing
cat > /etc/rspamd/local.d/dkim_signing.conf <<EOF enabled = true; path = "/var/lib/rspamd/dkim/\$domain-\$selector.key"; selector = "dkim"; sign_authenticated = true; sign_local = false; domain { example.com { selector = "202406"; } } EOF
Generate DKIM Key Pair
mkdir -p /var/lib/rspamd/dkim rspamadm dkim_keygen -s 202406 -t ED25519 -d example.com -k /var/lib/rspamd/dkim/example.com-202406.key > /var/lib/rspamd/dkim/example.com-202406.pub
Start Rspamd
rc-update add rspamd rcctl start rspamd
9. Finalize and Verify Installation
Restart Services
Restart all services:
rcctl restart postfix saslauthd rspamd valkey@grommunio nginx php-fpm83 gromox-delivery gromox-event \ gromox-http gromox-imap gromox-midb gromox-pop3 gromox-delivery-queue gromox-timer gromox-zcore \ grommunio-admin-api
Verify Service Status
Check the status of all services:
rcctl status
Check Logs
Inspect logs for any errors or issues:
find /var/log -type f | xargs tail -n50 | grep -iE '==>|fail|crit|error|alert|corrupt|warning'
Web UI Access
Admin UI: [1](https://mail.example.local:8443)
10. End User Configuration
Admin UI
Log into the Admin UI with the username `admin` and the previously created `ADMIN_PASS`.
License Configuration
If you have a license, you can configure it under Grommunio settings in the Admin UI.