Hey Walter,

that is certainly another Option. Currently i use the following in my scripts.

_grom_query_maildir(){
  grommunio-admin user query --filter username="${1}" maildir
}
2 months later

Learn Ham - Update 2024.04.28 2024.06.26

As i was bothered by the Spam-Handling on some Mails from an Mailinglist which always landed in my Junk-Folder i finally got around to create this little Function script.

Both scripts can be configured to wait at least N Days before the Mail will be processed by the script.
And aswell as in the original you can configure if it should delete the Mail after learning it.

The HAM-Runner will mark messages as READ after indexing them if they aren't deleted.

Additionally you can now provide optional parameters to rspamc to be able to use another RSPAMD Installation.

grommunio-ham-run.sh

.service, .timer & installscript in the folder

grommunio-spam-run.sh

Create HAM-LEARN-FOLDER for all users

USERS=$(grommunio-admin user query username status maildir |awk '$2=="0/active" && $3 ~ /\/var\/lib\/gromox/ {print$1}')
# this might say it failed but then the folder just exists already
for USER in $USERS; do 
grommunio-admin exmdb $USER folder create -t IPF.Note --comment "HAM-Training" TRAIN-HAM 9; 
done

PS: HowTo Moving mails automatically to Junk-Folder via Inbox-Rule https://community.grommunio.com/d/572-spam-handling/12

Autodiscover

GPO Copy/Paste

<?xml version="1.0" encoding="utf-8"?>
<RegistrySettings clsid="{A3CCFC41-DFDB-43a5-8D26-0FE8B954DA51}">
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeExplicitO365Endpoint" status="ExcludeExplicitO365Endpoint" image="11" changed="2023-01-06 06:48:06" uid="{3607AC9F-C086-4FF5-AD5E-DC8A2A8EC815}" bypassErrors="1"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeExplicitO365Endpoint" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeLastKnownGoodURL" status="ExcludeLastKnownGoodURL" image="11" changed="2023-01-06 06:47:24" uid="{A4BDDC22-D8C2-40E3-ABA8-2E4C4CE47558}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeLastKnownGoodURL" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpsRootDomain" status="ExcludeHttpsRootDomain" image="11" changed="2023-01-06 06:47:28" uid="{A9023706-376D-4FB9-8E30-4BBBB0FA6981}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpsRootDomain" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpsAutoDiscoverDomain" status="ExcludeHttpsAutoDiscoverDomain" image="11" changed="2023-01-06 06:47:31" uid="{36E47622-6C23-4D1E-8ECB-07A350DFCFD0}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpsAutoDiscoverDomain" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpRedirect" status="ExcludeHttpRedirect" image="11" changed="2023-01-06 06:47:35" uid="{105A60A9-BBAC-40AF-88FC-7AF986D6A568}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpRedirect" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeScpLookup" status="ExcludeScpLookup" image="11" changed="2023-01-06 06:47:39" uid="{699006E9-FB8F-492F-81F4-80472FFE8972}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeScpLookup" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeSrvRecord" status="ExcludeSrvRecord" image="11" changed="2023-01-06 06:47:45" uid="{5B7B8077-42E9-4671-A6B5-FBA0F0B277A7}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeSrvRecord" type="REG_DWORD" value="00000000"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="EnableOffice365ConfigService" status="EnableOffice365ConfigService" image="11" changed="2023-01-06 06:47:51" uid="{194041B7-4A42-49AD-9AB1-BFC997765D6F}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Microsoft\Office\16.0\Outlook\AutoDiscover" name="EnableOffice365ConfigService" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeExplicitO365Endpoint" status="ExcludeExplicitO365Endpoint" image="11" changed="2023-01-06 06:44:28" uid="{5F314DA6-E185-477E-985C-06B23414101E}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeExplicitO365Endpoint" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeLastKnownGoodURL" status="ExcludeLastKnownGoodURL" image="11" changed="2023-01-06 06:44:52" uid="{4E4FA923-0695-44F2-A4C1-8026615BA571}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeLastKnownGoodURL" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpsRootDomain" status="ExcludeHttpsRootDomain" image="11" changed="2023-01-06 06:45:05" uid="{A9B1A99D-16F2-4421-BD93-B8850A6B62C1}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpsRootDomain" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpsAutoDiscoverDomain" status="ExcludeHttpsAutoDiscoverDomain" image="11" changed="2023-01-06 06:45:31" uid="{85F10106-1B5D-49A6-8782-D69355A0719C}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpsAutoDiscoverDomain" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeHttpRedirect" status="ExcludeHttpRedirect" image="11" changed="2023-01-06 06:45:36" uid="{DD799D8D-A86C-4EB4-B0DB-D31A7E0B5E7D}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeHttpRedirect" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeScpLookup" status="ExcludeScpLookup" image="11" changed="2023-01-06 06:45:42" uid="{DC5FA5D9-0ADC-4A87-9525-7A6D436D9957}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeScpLookup" type="REG_DWORD" value="00000001"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="ExcludeSrvRecord" status="ExcludeSrvRecord" image="11" changed="2023-01-06 06:45:50" uid="{7232EDBC-B500-4BB7-BB54-87F674C5A5F5}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="ExcludeSrvRecord" type="REG_DWORD" value="00000000"/></Registry>
  <Registry clsid="{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" name="EnableOffice365ConfigService" status="EnableOffice365ConfigService" image="11" changed="2023-01-06 06:45:57" uid="{E08FC552-3554-4909-84FE-8D04FF60F921}"><Properties action="R" displayDecimal="1" default="0" hive="HKEY_CURRENT_USER" key="Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover" name="EnableOffice365ConfigService" type="REG_DWORD" value="00000001"/></Registry>
</RegistrySettings>

user.reg

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Outlook\AutoDiscover]
"ExcludeExplicitO365Endpoint"=dword:00000001
"ExcludeLastKnownGoodURL"=dword:00000001
"ExcludeHttpsRootDomain"=dword:00000001
"ExcludeHttpsAutoDiscoverDomain"=dword:00000001
"ExcludeHttpRedirect"=dword:00000001
"ExcludeScpLookup"=dword:00000001
"ExcludeSrvRecord"=dword:00000000
"EnableOffice365ConfigService"=dword:00000000

[HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\16.0\Outlook\AutoDiscover]
"ExcludeExplicitO365Endpoint"=dword:00000001
"ExcludeLastKnownGoodURL"=dword:00000001
"ExcludeHttpsRootDomain"=dword:00000001
"ExcludeHttpsAutoDiscoverDomain"=dword:00000001
"ExcludeHttpRedirect"=dword:00000001
"ExcludeScpLookup"=dword:00000001
"ExcludeSrvRecord"=dword:00000000
"EnableOffice365ConfigService"=dword:00000000

I don't like anything other than DNS Records 😛

3 months later

Get Folder-Permissions a bit quicker than before...

exmdb_get_permissions_hr() {
  local OWNER FID PFLDS FOLDER EXMDB SQLQUERY RET
  if [[ "$#" -ne 1 ]]; then
    echo "Usage: ${FUNCNAME[0]} username@domain.tld"
    return 1
  fi
  _grom_users="${_grom_users:=$(grommunio-admin user query username |sed 1d)}"
  # Check for correct Username
  if [[ "$_grom_users" =~ $1 ]]; then
    OWNER="${1}"
    EXMDB="$(grommunio-admin user query maildir --filter username="$OWNER")/exmdb/exchange.sqlite3"
    # grommunio-admin taginfo 805371935
    # 0x3001001f (805371935): DISPLAYNAME, type WSTRING
    SQLQUERY="
-- THIS IS A COMMENT!
-- SELECT DISTINCT(printf('0x%x', p.folder_id)) as hexfid, f1.propval FROM permissions p
-- INNER JOIN folder_properties f1 on f1.folder_id = p.folder_id and f1.proptag = 805371935
SELECT DISTINCT(printf('0x%x', p.folder_id)) as hexfid FROM permissions p
WHERE p.username != 'default';
"
      # True if FILE exists and is readable.
      if [ -r "$EXMDB" ]; then
        PFLDS="$(echo "$SQLQUERY" |sqlite3 --readonly --noheader "$EXMDB")"
        if [ "${#PFLDS}" -eq 0 ]; then 
          echo "No special permissions in MBX: $OWNER"
          return 0
        fi
        grommunio-admin exmdb "$OWNER" folder list -r | while read -r FOLDER; do
          # Leading '\' in front of grep to make sure no aliases are used.
          FID="$(echo "$FOLDER" |\grep -Po '0x(?<=\ \(0x).*(?=\)$)')"
          echo -e "\033[1m${FOLDER}\033[0m"
          if [[ "$PFLDS" =~ $FID ]]; then
            grommunio-admin exmdb "$OWNER" folder permissions "$FID"
          fi
        done
      fi
  fi
}
complete -F _comp_grom_users exmdb_get_permissions_hr

Because iterating over a thousand folders with grommunio-admin exmdb user@domain.tld permissions $FOLDERID takes bit too long if nothing is configured anyway..

There are some folders which are not listed with grommunio-admin exmdb user@domain.tld folder list -r, so it might print the List in those cases.

a month later

crpb Automated version with Configs from RPMs and other sutff

The script to build and configure traffic-status and brotli now removes all temporary dependencies to keep a small footprint on the Server.

alien8.sh

a year later

/tmp as tmpfs on appliance

ref: https://en.opensuse.org/openSUSE:Tmp_on_tmpfs

BTRFS SYSTEM OLD

btrfs subvolume delete -i $(btrfs subvolume list /  |awk '/@\/tmp/ {print $2}') /
systemctl link /usr/share/systemd/tmp.mount
rm -Rf /tmp
reboot

XFS SYSTEM CURRENT

rm -Rf /tmp/*
systemctl link /usr/share/systemd/tmp.mount
reboot
crpb changed the title to scripting / snippets / notepad .

grommunio-spam-run.sh

only learn and optional delete with a minimum age of n days

#!/bin/bash
# vim:ts=2 sts=2 sw=2 et

if ! [ -e /etc/gromox/spamrun.cfg ]; then
  cat << EOF > /etc/gromox/spamrun.cfg
# Only scan messages which are older than n days.
# Default: SPAMRUN_DAYS=7
SPAMRUN_DAYS=7
# To delete the message after the scan set to 'true' 
# Default: SPAMRUN_DELETE=false
SPAMRUN_DELETE=false
EOF
fi


# source config file
if [ -r /etc/gromox/spamrun.cfg ]; then
  . /etc/gromox/spamrun.cfg
fi
if [ -z ${SPAMRUN_DAYS+x} ]; then
  SQLITE_QUERY='select message_id,mid_string from messages where parent_fid=0x17;'
else
  SQLITE_QUERY="""
  SELECT m.message_id,m.mid_string
  FROM messages m
  INNER JOIN message_properties mp1
  ON mp1.message_id = m.message_id
  AND mp1.proptag = 235274304
  AND (mp1.propval/10000000-11644473600) < unixepoch('now','-$SPAMRUN_DAYS days')
  WHERE m.parent_fid = 0x17;
  """
fi
DO_DEL="${SPAMRUN_DELETE:-"false"}"
# add "-d" to delete junk emails after they have been learned
if [ "$1" = "-d" ]
then
  DO_DEL=true
fi

MYSQL_CFG="/etc/gromox/mysql_adaptor.cfg"

if [ ! -e "${MYSQL_CFG}" ] ; then
  echo "MySQL configuration not found. (${MYSQL_CFG})"
  exit 1
fi

MYSQL_PARAMS="--skip-column-names --skip-line-numbers"
MYSQL_USERNAME=$(sed -ne 's/mysql_username\s*=\s*\(.*\)\s*/-u\1/pI' ${MYSQL_CFG})
MYSQL_PASSWORD=$(sed -ne 's/mysql_password\s*=\s*\(.*\)\s*/-p\1/pI' ${MYSQL_CFG})
MYSQL_DBNAME=$(sed -ne 's/mysql_dbname\s*=\s*\(.*\)\s*/\1/pI' ${MYSQL_CFG})
MYSQL_HOST=$(sed -ne 's/mysql_host\s*=\s*\(.*\)\s*/-h\1/pI' ${MYSQL_CFG})
MYSQL_QUERY="SELECT username,maildir from users where id <> 0 and maildir <> \"\";"
MYSQL_CMD=("mysql" "${MYSQL_PARAMS}" "${MYSQL_USERNAME:=-uroot}" "${MYSQL_PASSWORD:=}" "${MYSQL_HOST:=-hlocalhost}" "${MYSQL_DBNAME:=grommunio}")
# shellcheck disable=SC2068
if ${MYSQL_CMD[@]}<<<"exit"&>/dev/null; then
  echo "${MYSQL_QUERY}" | ${MYSQL_CMD[@]} | while read -r USERNAME MAILDIR ; do
  sqlite3 -readonly -tabs -noheader "${MAILDIR}/exmdb/exchange.sqlite3" "$SQLITE_QUERY" |
    while read -r MESSAGEID MIDSTRING; do
      echo "Learning spam for user ${USERNAME}" | systemd-cat -t grommunio-spam-run
      MSGFILE="$MAILDIR/eml/$MIDSTRING"
      if [[ ! -f "$MSGFILE" ]]; then
        gromox-exm2eml -u "${USERNAME}" "${MESSAGEID}" 2>/dev/null | rspamc learn_spam | systemd-cat -t grommunio-spam-run
      else
        rspamc learn_spam --header 'Learn-Type: bulk' "$MSGFILE" | systemd-cat -t grommunio-spam-run
      fi
      if [ ${DO_DEL} == "true" ]; then
        /usr/sbin/gromox-mbop -u "${USERNAME}" delmsg -f 0x17 "${MESSAGEID}" | systemd-cat -t grommunio-spam-run
      fi
    done
    rm -f "${SPAMLIST}"
  done
else
  echo "MySQL-Connection couldn't be established, please check your configuration." | systemd-cat -t grommunio-spam-run -p err
fi

appliance - xfs - dedicated /var/lib/gromox

DISK=/dev/sdb
parted -s $DISK mklabel gpt
parted -s $DISK mkpart primary 0GB 100%
pvcreate ${DISK}1
vgcreate gromox ${DISK}1
# use only 80% so we can make use of lvm snapshots for backups
lvcreate gromox -n maildir -l80%VG
mkfs.xfs /dev/gromox/maildir
#lsblk -f /dev/gromox/maildir --output UUID --noheadings
echo "UUID=$(lsblk -f /dev/gromox/maildir --noheadings --output UUID) /var/lib/gromox xfs defaults 0 0" |tee -a /etc/fstab
mv /var/lib/gromox{,.bak}
mkdir /var/lib/gromox
mount /var/lib/gromox
#cp -a /var/lib/gromox.bak/* /var/lib/gromox/
rsync -av /var/lib/gromox.bak/ /var/lib/gromox
find /var/lib/gromox -ls
#chown gromox:gromox /var/lib/gromox
#chmod 770 /var/lib/gromox
rm -Rf /var/lib/gromox.bak

LVM Snapshot for backups - example

##  STOP SERVICES TO CLEANUP midb's
/usr/bin/systemctl stop gromox-midb.service gromox-imap.service gromox-pop3.service
# DO SOME CLEANUP ON THE MAILBOXES
for d in /var/lib/gromox/user/*/*; do
  /usr/sbin/gromox-mbop -d $d vacuum;
  /usr/sbin/gromox-mbop -d $d purge-datafiles;
done
## CREATE LVM SNAPSHOT
/sbin/lvcreate -l10%FREE --snapshot --name s_maildir /dev/gromox/maildir
    Logical volume "s_maildir" created.
## START SERVICES AGAIN (we have a snapshot!)
/usr/bin/systemctl start gromox-midb.service gromox-imap.service gromox-pop3.service
## SHOW THAT WE HAVE A SNAP
/sbin/lvs
  LV        VG        Attr       LSize  Pool Origin  Data%  Meta%  Move Log Cpy%Sync Convert
  LVRoot    grommunio -wi-ao---- 19.68g
  maildir   gromox    owi-aos--- 40.00g
  s_maildir gromox    swi-a-s---  1.00g      maildir 0.00
## TEMPORARY MOUNT POINT
SNAP=$(mktemp --suffix=lvmsnap --directory)
## MOUNT XFS ( we need -o nouuid as xfs doesn't like duplicates of UUIDs )
/usr/bin/mount -o nouuid /dev/gromox/s_maildir $SNAP
## SHOW THE CONTENTS
/usr/bin/find $SNAP -ls
      128      0 drwxrwx---   5 gromox   gromox         45 Apr  1 16:41 /tmp/tmp.xa5jeBj8Rylvmsnap
      131      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/domain
 33554560      0 drwxrwx---   6 gromox   gromox         56 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue
 67149888      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue/mess
100663424      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue/save
      132      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue/timer
 33554561      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/queue/cache
 67149889      0 drwxrwx---   2 gromox   gromox          6 Mar 30 20:50 /tmp/tmp.xa5jeBj8Rylvmsnap/user
## RUN BACKUP / RSYNC / WHATEVER

## AND AFTER WE ARE FINISHED
/usr/bin/umount $SNAP
/sbin/lvremove /dev/gromox/s_maildir --yes

APT Pinning Supported/Community/Devel

Whomever might need it. Now you can 🙂

v=supported will also be available in a few days.

% apt policy
Package files:
 100 /var/lib/dpkg/status
     release a=now
  50 https://download.grommunio.com/devel/Debian_12 Debian_12/main amd64 Packages
     release v=devel,o=grommunio,n=Debian_12,l=grommunio,c=main,b=amd64
     origin download.grommunio.com
 450 https://download.grommunio.com/community/Debian_12 Debian_12/main amd64 Packages
     release v=community,o=grommunio,n=Debian_12,l=grommunio,c=main,b=amd64
     origin download.grommunio.com
 500 https://download.grommunio.com/supported/Debian_12 Debian_12/main amd64 Packages
     release o=grommunio,n=Debian_12,l=grommunio,c=main,b=amd64
     origin download.grommunio.com
 500 http://ftp2.de.debian.org/debian bookworm-updates/main amd64 Packages
     release v=12-updates,o=Debian,a=stable-updates,n=bookworm-updates,l=Debian,c=main,b=amd64
     origin ftp2.de.debian.org
 500 http://security.debian.org/debian-security bookworm-security/main amd64 Packages
     release v=12,o=Debian,a=stable-security,n=bookworm-security,l=Debian-Security,c=main,b=amd64
     origin security.debian.org
 500 http://ftp2.de.debian.org/debian bookworm/main amd64 Packages
     release v=12.5,o=Debian,a=stable,n=bookworm,l=Debian,c=main,b=amd64
     origin ftp2.de.debian.org
Pinned packages:
     libapache2-mod-php -> 2:8.2+93 with priority -1
     apache2-bin -> 2.4.57-2 with priority -1
     apache2 -> 2.4.57-2 with priority -1


% cat /etc/apt/preferences.d/80-grommunio
Package: *
Pin: release o=grommunio, v=devel
Pin-Priority: 50

Package: *
Pin: release o=grommunio, v=community
Pin-Priority: 450


% cat /etc/apt/sources.list.d/grommunio.sources
# Supported
Types: deb
URIs: https://download.grommunio.com/supported/Debian_12/
Suites: Debian_12
Components: main
Enabled: yes
Signed-By: /usr/share/keyrings/download.grommunio.com.gpg
Signed-By:
 -----BEGIN PGP PUBLIC KEY BLOCK-----
 .
 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
 mGJfShvIgpqehgKMDoUzZkpIov34ef7O6RxVVA==
 =D9oD
 -----END PGP PUBLIC KEY BLOCK-----

# Community
Types: deb
URIs: https://download.grommunio.com/community/Debian_12/
Suites: Debian_12
Components: main
Enabled: yes
#Signed-By: /usr/share/keyrings/download.grommunio.com.gpg
Signed-By:
 -----BEGIN PGP PUBLIC KEY BLOCK-----
 .
 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
 mGJfShvIgpqehgKMDoUzZkpIov34ef7O6RxVVA==
 =D9oD
 -----END PGP PUBLIC KEY BLOCK-----

# Devel
Types: deb
URIs: https://download.grommunio.com/devel/Debian_12/
Suites: Debian_12
Components: main
Enabled: yes
#Signed-By: /etc/apt/keyrings/download.grommunio.com.gpg
Signed-By:
 -----BEGIN PGP PUBLIC KEY BLOCK-----
 .
 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
 mGJfShvIgpqehgKMDoUzZkpIov34ef7O6RxVVA==
 =D9oD
 -----END PGP PUBLIC KEY BLOCK-----
a month later

Activate ZRAM Swap

*vroom* *vroom*

OpenSuSe

zypper in -y zramswap.service
systemctl --now enable zramswap.service

Debian

apt-get install -y systemd-zram-generator
echo 'zram-size = int(ram)' |tee -a /etc/systemd/zram-generator.conf

This will end up with 100% zramswap of the original ramsize.
That isn't the double of ram just out of the blue tho :-).

https://www.kernel.org/doc/html/next/admin-guide/blockdev/zram.html

a month later

Passwordless IMAP for archive purposes

No more relying on users to update their passwords for external mail archiving over imap or worse storing their passwords /o\.

References:
https://community.grommunio.com/d/349-geloschte-objekte-wiederherstellen/9
https://community.grommunio.com/d/836-seperate-authmgrcfg/6

Upstream: https://github.com/crpb/grommunio/blob/main/tools/enable-pwless-imapd

Changed a few things, look at the upstream url..

Caveats: as i use an additional firewall-cmd zone the rules for like 443,8443,.. will not work and you might have to add them if you need or you might change the script to use the public zone.

2 months later

Appliance Basic Setup - Ansible

Here is my freshly revised Playbook to prepare the Appliance.

And no, i haven't had the need for complex roles so it's just a play.

Requirements on Appliance

  • root password set (for access via ssh)
  • Network configured (The MachineID fix might lead to a new ip with dhcp)

Requirements on Workstation

mkdir -p group_vars
echo pubkey_url: https://what.ever/some/pubkey.pub >> ~/group_vars/all
cat << EOF > inventory.yaml
grommunio:
  hosts:
    grommunio-test-1.your.network.local:
EOF

Tasks

  • Fixes Systemd-Machine-ID
  • Auto-accept Repo-Keys and apply latest Updates
  • Set Timezone
  • Install various Software-Packages
  • Install virtualizing agent depending on the Hardware (QEMU, VMware or Hyper-V)
  • Activate ZRAM (100%)
  • Enable automatic installation of security updates / daily
  • Enable group wheel and allow sudo for them (no user creation included)
  • Grub timeout 2 seconds instead of 10
  • Install SSH pubkey for root via http link
  • Disable Password Auth for SSH (pubkey only!)
  • Enable tmpfs for /tmp

prepare-appliance.json

[
	{
		"name": "SystemD",
		"hosts": "grommunio",
		"become": false,
		"tags": "systemd",
		"tasks": [
			{
				"name": "DiffUUIDs",
				"ansible.builtin.command": "diff -q /etc/machine-id /var/lib/dbus/machine-id",
				"ignore_errors": true,
				"register": "diffuuid"
			},
			{
				"name": "DeleteUUID",
				"ansible.builtin.file": {
					"path": "{{ item }}",
					"state": "absent"
				},
				"when": "diffuuid.rc != 0",
				"register": "tmpfsdeleted",
				"with_items": [
					"/etc/machine-id",
					"/var/lib/dbus/machine-id"
				]
			},
			{
				"name": "MachineID",
				"ansible.builtin.command": "/usr/bin/systemd-machine-id-setup",
				"register": "machinedactivate",
				"changed_when": "machinedactivate"
			},
			{
				"name": "DBUS-UUIDGEN",
				"ansible.builtin.command": "/usr/bin/dbus-uuidgen --ensure",
				"register": "dbusactivate",
				"changed_when": "dbusactivate"
			},
			{
				"name": "JournalDPersistent",
				"ansible.builtin.replace": {
					"path": "/etc/systemd/journald.conf",
					"regexp": "^#Storage=auto",
					"replace": "Storage=persistent"
				}
			}
		]
	},
	{
		"name": "Virtualization",
		"hosts": "grommunio",
		"become": false,
		"tags": "virtualization",
		"gather_facts": true,
		"tasks": [
			{
				"name": "Install QemuGuestAgent",
				"community.general.zypper": {
					"name": [
						"qemu-guest-agent"
					],
					"state": "installed",
					"disable_recommends": true,
					"clean_deps": true
				},
				"tags": "hypervisor",
				"when": "ansible_system_vendor == \"QEMU\""
			},
			{
				"name": "Enable qemu-guest-agent",
				"ansible.builtin.systemd": {
					"name": "qemu-guest-agent.service",
					"state": "started",
					"enabled": true
				},
				"tags": "hypervisor",
				"when": "ansible_system_vendor == \"QEMU\""
			},
			{
				"name": "Install HyperV agent",
				"community.general.zypper": {
					"name": [
						"hyper-v"
					],
					"state": "installed",
					"disable_recommends": true,
					"clean_deps": true
				},
				"tags": "hypervisor",
				"when": "ansible_system_vendor == \"Microsoft Corporation\""
			},
			{
				"name": "Enable HyperV agent",
				"ansible.builtin.systemd": {
					"name": "{{ item }}.service",
					"state": "started",
					"enabled": true
				},
				"with_items": [
					"hv_fcopy_daemon",
					"hv_kvp_daemon",
					"hv_vss_daemon"
				],
				"tags": "hypervisor",
				"when": "ansible_system_vendor == \"Microsoft Corporation\""
			},
			{
				"name": "Install OpenVMTools",
				"community.general.zypper": {
					"name": [
						"open-vm-tools"
					],
					"state": "installed",
					"disable_recommends": true,
					"clean_deps": true
				},
				"tags": "hypervisor",
				"when": "ansible_system_vendor == \"VMware, Inc.\""
			},
			{
				"name": "Enable OpenVMTools",
				"ansible.builtin.systemd": {
					"name": "{{ item }}.service",
					"state": "started",
					"enabled": true
				},
				"with_items": [
					"vgauthd",
					"vmtoolsd"
				],
				"tags": "hypervisor",
				"when": "ansible_system_vendor == \"VMware, Inc.\""
			}
		]
	},
	{
		"name": "TmpFS_Enable",
		"hosts": "grommunio",
		"tags": "tmpfs",
		"become": false,
		"tasks": [
			{
				"name": "FindMntTmp",
				"ansible.builtin.command": "findmnt --types=tmpfs --target=/tmp --noheadings",
				"ignore_errors": true,
				"register": "notmpfs"
			},
			{
				"name": "DeleteTmp",
				"ansible.builtin.file": {
					"path": "/tmp",
					"state": "absent"
				},
				"when": "notmpfs.rc != 0",
				"register": "tmpfsdeleted"
			},
			{
				"name": "CreateTmp",
				"ansible.builtin.file": {
					"path": "/tmp",
					"state": "directory",
					"mode": "0755"
				},
				"when": "notmpfs != 0",
				"register": "tmpfsempty"
			},
			{
				"name": "TmpfsEnable",
				"ansible.builtin.file": {
					"src": "/usr/share/systemd/tmp.mount",
					"dest": "/etc/systemd/system/tmp.mount",
					"state": "link"
				},
				"register": "tmpfsenabled",
				"when": "tmpfsempty",
				"changed_when": "tmpfsenabled.changed"
			},
			{
				"name": "Reboot",
				"ansible.builtin.reboot": {
					"msg": "Reboot initiated by Ansible for TmpFS",
					"connect_timeout": 5,
					"reboot_timeout": 300,
					"pre_reboot_delay": 0,
					"post_reboot_delay": 30,
					"test_command": "uptime"
				},
				"when": "tmpfsenabled.changed"
			}
		]
	},
	{
		"name": "Install Updates",
		"hosts": "grommunio",
		"become": false,
		"tags": "updates",
		"tasks": [
			{
				"name": "TestRepo",
				"ansible.builtin.shell": "zypper --quiet repos --name grommunio >/dev/null 2>&1",
				"register": "grommuniorepo",
				"ignore_errors": true,
				"changed_when": "grommuniorepo"
			},
			{
				"name": "Refresh-Repos-Accept-Keys",
				"ansible.builtin.command": "zypper --quiet --gpg-auto-import-keys ref",
				"when": "grommuniorepo.rc != 0",
				"register": "refret",
				"changed_when": "refret"
			},
			{
				"name": "Activate-Grommunio-Repo-And-Upgrade",
				"ansible.builtin.command": "grommunio-update upgrade community --noreboot",
				"ignore_errors": true,
				"register": "ignoreerrors",
				"changed_when": "ignoreerrors"
			}
		]
	},
	{
		"name": "Basics",
		"hosts": "grommunio",
		"become": false,
		"gather_facts": true,
		"handlers": [
			{
				"name": "Restart ssh",
				"ansible.builtin.systemd": {
					"name": "sshd",
					"daemon_reload": true
				}
			},
			{
				"name": "Grub2MkConfig",
				"ansible.builtin.command": "grub2-mkconfig -o /boot/grub2/grub.cfg"
			}
		],
		"tasks": [
			{
				"name": "Timezone",
				"community.general.timezone": {
					"name": "Europe/Berlin"
				}
			},
			{
				"name": "Required-software",
				"community.general.zypper": {
					"name": [
						"ShellCheck",
						"aaa_base-extras",
						"acl",
						"bzip2",
						"git",
						"growpart",
						"gron",
						"htop",
						"jq",
						"man",
						"man-pages",
						"coreutils-doc",
						"nfs-client",
						"php8-APCu",
						"purge-kernels-service",
						"python3-argcomplete",
						"bash-completion",
						"sshfs",
						"system-group-wheel",
						"zram-generator",
						"vim-data"
					],
					"state": "present",
					"disable_recommends": true
				},
				"tags": "software"
			},
			{
				"name": "Uninstall replaced thingies",
				"community.general.zypper": {
					"name": [
						"systemd-zram-service",
						"yast2-online-update-configuration"
					],
					"state": "absent"
				},
				"tags": [ "software", "uninstall", "deprecated" ]
			},
			{
				"name": "Cleanup yast2-online-update-configuration",
				"ansible.builtin.file": {
					"path": "{{ item }}",
					"state": "absent"
				},
				"with_items": [
					"/etc/cron.daily/automatic_online_update",
					"/etc/cron.daily/opensuse.org-online_update"
				]
			},
			{
				"name": "Install os-update + rebootmgr",
				"community.general.zypper": {
					"name": [
						"os-update",
						"rebootmgr"
					],
					"state": "present",
					"disable_recommends": true
				},
				"tags": [ "software", "os-update", "updates", "rebootmgr" ]
			},
			{
				"name": "os-update only do security-updates",
				"ansible.builtin.lineinfile": {
					"dest": "/etc/os-update.conf",
					"regexp": "^UPDATE_CMD=.*",
					"line": "UPDATE_CMD=\"security\"",
					"state": "present"
				},
				"tags": [ "os-update", "updates" ]
			},
			{
				"name": "Enable os-update.timer",
				"ansible.builtin.systemd": {
					"name": "os-update.timer",
					"enabled": true
				},
				"tags": "software"
			},
			{
				"name": "Etckeeper install",
				"community.general.zypper": {
					"name": [
						"etckeeper",
						"etckeeper-bash-completion",
						"etckeeper-zsh-completion",
						"etckeeper-zypp-plugin"
					],
					"state": "present",
					"disable_recommends": true
				},
				"tags": [ "software", "etckeeper" ]
			},
			{
				"name": "Enable etckeeper.timer",
				"ansible.builtin.systemd": {
					"name": "etckeeper.timer",
					"enabled": true
				},
				"tags": "software"
			},
			{
				"name": "Check if Etckeeper is already initialized",
				"ansible.builtin.stat": {
					"path": "/etc/.git/"
				},
				"register": "etckeeperinit"
			},
			{
				"name": "Etckeeper init",
				"ansible.builtin.command": "etckeeper init",
				"when": "not etckeeperinit.stat.exists",
				"tags": [ "software", "etckeeper" ]
			},
			{
				"name": "Etckeeper Commit",
				"ansible.builtin.command": "etckeeper commit -m 'init'",
				"when": "not etckeeperinit.stat.exists",
				"tags": [ "software", "etckeeper" ]
			},
			{
				"name": "Enable purgekernels",
				"ansible.builtin.systemd": {
					"name": "purge-kernels.service",
					"enabled": true
				},
				"tags": "software"
			},
			{
				"name": "Enable Zram0",
				"ansible.builtin.blockinfile": {
					"path": "/etc/systemd/zram-generator.conf.d/0.conf",
					"create": true,
					"owner": "root",
					"group": "root",
					"mode": "0660",
					"block": "[zram0]\nzram-size = int(ram)\n"
				},
				"tags": "zram"
			},
			{
				"name": "Sudoers g=wheel",
				"ansible.builtin.blockinfile": {
					"path": "/etc/sudoers.d/wheel",
					"create": true,
					"owner": "root",
					"group": "root",
					"mode": "0440",
					"block": "%wheel ALL=(ALL:ALL) ALL\n"
				},
				"tags": "sudo"
			},
			{
				"name": "Grub2Timeout 2sec",
				"ansible.builtin.lineinfile": {
					"dest": "/etc/default/grub",
					"regexp": "^GRUB_TIMEOUT=10",
					"line": "GRUB_TIMEOUT=2",
					"state": "present"
				},
				"tags": "grub",
				"notify": [
					"Grub2MkConfig"
				]
			},
			{
				"name": "Sudoers use userpass",
				"ansible.builtin.replace": {
					"path": "/etc/sudoers",
					"regexp": "'^Defaults targetpw'",
					"replace": "'#Defaults targetpw'"
				},
				"tags": "sudo"
			},
			{
				"name": "Set authorized_keys for root",
				"tags": "ssh",
				"ansible.posix.authorized_key": {
					"user": "root",
					"state": "present",
					"key": "{{ lookup('url', pubkey_url, split_lines=False) }}"
				}
			},
			{
				"name": "SSHD No PasswordAuthentication",
				"ansible.builtin.lineinfile": {
					"dest": "/etc/ssh/sshd_config",
					"regexp": "^#PasswordAuthe.*$",
					"line": "PasswordAuthentication no",
					"state": "present",
					"backup": true
				},
				"tags": "ssh"
			},
			{
				"name": "SSHD No ChallengeResponseAuthentication",
				"ansible.builtin.lineinfile": {
					"dest": "/etc/ssh/sshd_config",
					"regexp": "^#ChallengeResponse.*$",
					"line": "ChallengeResponseAuthentication no",
					"state": "present",
					"backup": true
				},
				"tags": "ssh"
			},
			{
				"name": "SSHD PermitRootlogin without-password",
				"ansible.builtin.lineinfile": {
					"dest": "/etc/ssh/sshd_config",
					"regexp": "^PermitRootLogin",
					"line": "PermitRootLogin without-password",
					"state": "present",
					"backup": true
				},
				"notify": [
					"Restart ssh"
				],
				"tags": "ssh"
			}
		]
	}
]

First run with ask-pass

ansible-playbook prepare-appliance.json -l grommunio-test-1.your.network.local -k

If everything worked out you will need to ommit the -k as that is only for password auth.

From here i usually configure an additional mount for /var/lib/gromox but that i do manually followed by grommunio-setup.

11 days later

Lookup Folder Permissions in seconds

and make them easily exportable aswell

exmdb-perms.sql

-- FOLDER PERMISSIONS LOOKUP TABLE
CREATE TABLE IF NOT EXISTS "temp"."perms" (
  "perm"  INTEGER UNIQUE,
  "name"  TEXT
);
INSERT OR REPLACE INTO perms("perm","name") VALUES
( 1,'redany'),
( 2,'create'),
( 4,'sendas'),
( 8,'editowned'),
( 16,'deleteowned'),
( 32,'editany'),
( 64,'deleteany'),
( 128,'createsubfolder'),
( 256,'folderowner'),
( 512,'foldercontact'),
( 1024,'foldervisible'),
( 2048,'freebusysimple'),
( 4096,'freebusydetailed'),
( 8192,'storeowner')
;
-- FOLDER LOOKUP VIEW VIA FOLDERS INCLUDING PARENT
CREATE VIEW IF NOT EXISTS temp.folderlist
AS SELECT distinct(p.folder_id),
          p.parent_id,
          f1.propval
     FROM folders p
     JOIN folder_properties f1
       ON f1.folder_id = p.folder_id
      AND f1.proptag = 805371935
    ORDER BY p.folder_id
;
-- FOLDER LOOKUP VIEW VIA PERMISSIONS
CREATE VIEW IF NOT EXISTS temp.folderlist_p
AS SELECT distinct(p.folder_id),
          f1.propval
  FROM    permissions p
 INNER    JOIN folder_properties f1
    ON    f1.folder_id = p.folder_id
   AND    f1.proptag = 805371935
 ORDER    BY p.folder_id
;
-- LOOKUP PERMISSIONS
CREATE VIEW IF NOT EXISTS temp.folderpermissions
AS SELECT p.folder_id as folder_int,
          f.parent_id,
          (SELECT printf('0x%x',p.folder_id)) AS folder_hex,
          (SELECT printf('0x%x',f.parent_id)) AS parent_hex,
          f.propval AS folder_name,
          p.username,
          x.name as permission,
          (SELECT printf('0x%x',p.permission)) AS permission_hex
    FROM  permissions p
    JOIN  folderlist f
      ON  p.folder_id = f.folder_id
    LEFT  JOIN temp.perms x
      ON  x.perm = p.permission
ORDER BY  p.folder_id ASC,
          f.parent_id ASC,
          p.username ASC
;
-- QUERY OUR VIEW
SELECT * FROM folderpermissions
;

Usage

sqlite3 -columns /var/lib/gromox/user/X/Y/exmdb/exchange.sqlite3 < exmdb-perms.sql
for exmdb in /var/lib/gromox/user/*/*/exmdb/exchange.sqlite3; do
   echo $exmdb
   sqlite3 -csv $exmdb < sql/exmdb-perms.sql
done
7 days later

Export Folder Permissions to JSON

#!/bin/sh
QUERY='select username, maildir from users where maildir like "/var/lib/gromox/user/%"'
if [ $# = 1 ]; then
  USR="$1"
  QUERY="$QUERY AND username = \"${USR}\""
fi
mysql grommunio --skip-column-names \
 --execute="$QUERY" |
  while read -r username maildir; do
    printf '{ "username": "%s", "maildir": "%s", "permissions": %s }' \
      "$username" "$maildir" \
      "$(sqlite3 -json $maildir/exmdb/exchange.sqlite3 < /root/scripts/sql/exmdb-perms.sql)";
    done

Parse the output

gromi:~ # /root/scripts/sql/exmdb-perms.sh  info@domain.tld  |jq '.permissions[]|select(.username|match("default"))'
{
  "folder_int": 9,
  "parent_id": 1,
  "folder_hex": "0x9",
  "parent_hex": "0x1",
  "folder_name": "Oberste Ebene des Informationsspeichers",
  "username": "default",
  "permission": null,
  "permission_hex": "0x401"
}
{
  "folder_int": 15,
  "parent_id": 9,
  "folder_hex": "0xf",
  "parent_hex": "0x9",
  "folder_name": "Kalender",
  "username": "default",
  "permission": "freebusysimple",
  "permission_hex": "0x800"
}
{
  "folder_int": 24,
  "parent_id": 1,
  "folder_hex": "0x18",
  "parent_hex": "0x1",
  "folder_name": "Freebusy Data",
  "username": "default",
  "permission": null,
  "permission_hex": "0x0"
}
2 months later

Setup resources/rooms/... auto-accept

ref: thread

Use security-groups for easier management of access rights!

SECURITYGROUP=s_something@moo.tld
# This is just an example. You might not wanna iterate over all your shared stores!
SHAREDSTORES=$(grommunio-admin user query --filter status="4/shared" username)
for SHAREDSTORE in $SHAREDSTORES;
    do
# SET autoaccept + no overlapping + no recurring
        grommunio-admin exmdb $SHAREDSTORE store set scheduleinfoautoacceptappointments=1 scheduleinfodisallowrecurringappts=1 scheduleinfodisallowoverlappingappts=1
# CLEANUP PERMISSIONS - to be sure we have only what we want
        grommunio-admin exmdb $SHAREDSTORE folder revoke -r 0xf $SECURITYGROUP all;
# SET PERMISSIONS  - 0x041b (readany,create,editowned,deleteowned,foldervisible)
        grommunio-admin exmdb $SHAREDSTORE folder grant 0xf $SECURITYGROUP 0x041b 
done
16 days later

(sqlite) selector

  • easily extendable query thingy for exchange.sqlite3's
  • realized by creating temporary views in the database only during the call
  • access to the database with -readonly
  • output format an be changed to whatever sqlite3 provides.
  • no additional shell-foo like awk, sed, grep needed
  • the heavy lifting is done in SQL
  • can be integrated in ~/.ssh/authorized_keys:command="/path/to/symlink" ssh-

be advised, it's still a bit buggy as the sql-calls are just mangled together right now..

  • empty/new mailboxes will make problems with an all-user output..

crpb Ich würde das so machen:
alias grom_du='grommunio-admin user query username maildir | grep "/user/" | while read -r user mdir; do printf "%s %s %s\n" "$(du -hs ${mdir})" "$user"; done | sort -h'
Da werden die Gruppen weggelassen, Trennung durch Leerzeichen
Edit: meine Änderung hineinkopiert.

© 2020-2024 grommunio GmbH. All rights reserved. | https://grommunio.com | Data Protection | Legal notice