OPNsense Forum

English Forums => General Discussion => Topic started by: bubbel on November 30, 2020, 05:30:27 pm

Title: Postfix/rspamd DKIM signing
Post by: bubbel on November 30, 2020, 05:30:27 pm
Hi there,

I'm trying to get DKIM signing up and running for outgoing e-mail. I have configured my public DNS with DKIM public key. So that's ok.
But I cannot find out where I have to put the DKIM private key for DKIM signing. I checked in  in the postfix or the rspamd plugins. I read that both can be used to perform the DKIM signing on outgoing e-mails, but I cannot find a way.

Is there someone that can point me in to the right direction?

Thank you.
Title: Re: Postfix/rspamd DKIM signing
Post by: AlienMindbender on February 11, 2021, 04:36:32 pm
Hi bubbel,

switching over from a Sophos UTM home licence to OPNsense I was up to the same taks.
It appears to me that especially the rspamd / postfix integration is work in progress, for DKIM signing the options are uncommented and a bit cryptic, plus there appears to be no way from the GUI to upload / manage the DKIM keys in redis.

Rspamd would be able to use keys from a config file, but such CLI changes would most probably be overwritten.

There is a generic description on how to use redis based DKIM key storage in the rspamd documentation:
https://rspamd.com/doc/modules/dkim_signing.html#dkim-key-management (https://rspamd.com/doc/modules/dkim_signing.html#dkim-key-management)

I am going to try this approach and I will comment on my findings, should anybody be interested.
Title: Re: Postfix/rspamd DKIM signing
Post by: mimugmail on February 11, 2021, 09:41:14 pm
Hi bubbel,

switching over from a Sophos UTM home licence to OPNsense I was up to the same taks.
It appears to me that especially the rspamd / postfix integration is work in progress, for DKIM signing the options are uncommented and a bit cryptic, plus there appears to be no way from the GUI to upload / manage the DKIM keys in redis.

Rspamd would be able to use keys from a config file, but such CLI changes would most probably be overwritten.

There is a generic description on how to use redis based DKIM key storage in the rspamd documentation:
https://rspamd.com/doc/modules/dkim_signing.html#dkim-key-management (https://rspamd.com/doc/modules/dkim_signing.html#dkim-key-management)

I am going to try this approach and I will comment on my findings, should anybody be interested.

If you have a quick howto on where to put which content I can update the GUI for this.
Title: Re: Postfix/rspamd DKIM signing
Post by: AlienMindbender on February 11, 2021, 11:18:27 pm
...that would be great, I'll follow up!  :)
Title: Re: Postfix/rspamd DKIM signing
Post by: Rolfieo on March 02, 2021, 06:01:10 pm
I'm also really interested on this feature. Is there maybe an update on this feature?

My current ISP relay host detects my scanner email as spam, what i can't solve.

I was just looking for a solution, and was ready to setup the relay on OPNSense, as this would perfectly fit my solution. Even better than my ISP setup, as i have everything under my own control.

But... No DKIM, would be a no go.
Title: Re: Postfix/rspamd DKIM signing
Post by: mimugmail on March 02, 2021, 07:02:59 pm
Hi bubbel,

switching over from a Sophos UTM home licence to OPNsense I was up to the same taks.
It appears to me that especially the rspamd / postfix integration is work in progress, for DKIM signing the options are uncommented and a bit cryptic, plus there appears to be no way from the GUI to upload / manage the DKIM keys in redis.

Rspamd would be able to use keys from a config file, but such CLI changes would most probably be overwritten.

There is a generic description on how to use redis based DKIM key storage in the rspamd documentation:
https://rspamd.com/doc/modules/dkim_signing.html#dkim-key-management (https://rspamd.com/doc/modules/dkim_signing.html#dkim-key-management)

I am going to try this approach and I will comment on my findings, should anybody be interested.

If you have a quick howto on where to put which content I can update the GUI for this.

...
Title: Re: Postfix/rspamd DKIM signing
Post by: Rolfieo on March 21, 2021, 05:59:04 pm
I have done some testing, and got it to work.


Code: [Select]
rspamadm dkim_keygen -b 2048 -s opndkim -k /tmp/opndkim.key | sudo tee -a  /tmp/opndkim.pub
chown -R rspamd: /tmp/opndkim.*
chmod 440 /tmp/opndkim.*

This generate the DKIM keys on my tmp location.

I changed in my configuration file, with a domain selection.

Code: [Select]
/usr/local/etc/rspamd/local.d/dkim_signing.conf

# Please don't modify this file as your changes might be overwritten with
# the next update.
#

  allow_envfrom_empty = true;
  allow_hdrfrom_mismatch = false;
  allow_hdrfrom_multiple = false;
  allow_username_mismatch = false;
  auth_only = true;
  #path = "/var/lib/rspamd/dkim/$domain.$selector.key";
  selector = "dkim";
  sign_local = true;
  symbol = "DKIM_SIGNED";
  try_fallback = false;
  use_domain = "header";
  use_esld = true;
  use_redis = false;
  # Hash for DKIM keys in Redis
  key_prefix = "DKIM_KEYS";
 
  domain {
    # Domain name is used as key
    mydomain.com {
      # Private key path
      path = "/tmp/opndkim.key";
      # Selector
      selector = "opndkim";
      }
  }

I just needed to add mydomain.com with the selector and the key location.

This worked for my, all the configuration was reset after a restart from opnsense rspamd service, and the keys are not saved at a correct location and i did not use the redis database.

Would this be enough information to configure something from the GUI for this?
If needed to can do some more testing/configuring.

Title: Re: Postfix/rspamd DKIM signing
Post by: mimugmail on March 22, 2021, 11:07:18 am
Yes this should be ..
Title: Re: Postfix/rspamd DKIM signing
Post by: Rolfieo on March 26, 2021, 11:24:42 am
Yes this should be ..
if you want me to test something, just let me know.
Title: Shell script to setup DKIM signing with postfix / rspamd
Post by: AlienMindbender on May 23, 2021, 04:03:11 pm
I put together a small script that automates the setup for a DKIM signing of outgoing e-mails. The keys are created in /root/dkim, uploaded to Redis, and the configuration will survive a restart / reboot of the firewall. These are the available commands:
Code: [Select]
usage: setup-dkim-signing.sh {add|check|del|deleteall} [example.com] [myselector]
  add {example.com} {myselector}
    Generate a new DKIM key (if necessary), upload it into Redis and configure rspamd accordingly.
  check
    Show keys stored in Redis and domains configured in rspamd
  del {example.com} {myselector}
    Delete a single key from Redis and rspamd. The key files will not be deleted.
  deleteall
    Delete all keys from Redis and rspamd. The key files will not be deleted.

So to add a new domain for signing one would simply need to call:
Code: [Select]
./setup-dkim-signing.sh add example.com myselector(Update 05.08.2021: Bug: The domain clause in the config file is not formatted properly in case of multiple domains, but this can be fixed manually following the template at the end of this post)

setup-dkim-signing.sh
Code: [Select]
#!/bin/sh

# setup-dkim-signing.sh
# OPNsense firewall shell script to implement DKIM signing of outgoing e-mails
# Forum thread: https://forum.opnsense.org/index.php?topic=20280.0
# v0.1 20210523 AlienMindbender

# prepare environment
COMMAND=$1
DOMAIN=$2
SELECTOR=$3
KEYPATH="/root/dkim"
CONFIGPATH="/usr/local/etc/rspamd/local.d/"
CONFIGFILE=$CONFIGPATH"dkim_signing.conf"
TMPFILE="/tmp/setup-dkim-signing.$$.tmp"
mkdir $KEYPATH >/dev/null 2>&1
cd $KEYPATH

case $1 in
add)
# check for 3 arguments
if [ $# -lt 3 ]; then
    echo "Both domain name and selector are required to add a key:"
echo "  add {example.com} {myselector}"
    exit 1
fi
# generate 2048 bit RSA key
if [ -f "$DOMAIN.key" ];
then
echo "Key file "$KEYPATH"/"$DOMAIN".key exists, skipping key generation"
else
echo "Generating new 2048 bit RSA key..."
rspamadm dkim_keygen -b 2048 -d $DOMAIN -s $SELECTOR -k $DOMAIN.key > $DOMAIN.dns
echo "Done, key stored in "$KEYPATH
fi
echo
# display DNS record
echo "The following record needs to be added to your DNS zonefile:"
cat $DOMAIN.dns
echo
# upload key to Redis
echo "Uploading key to Redis..."
echo "local key = [[""`cat $DOMAIN.key`""]]" > $DOMAIN.redis && echo "redis.call('HMSET', 'DKIM_KEYS', '$SELECTOR.$DOMAIN', key)" >> $DOMAIN.redis
redis-cli --eval ./$DOMAIN.redis
echo
# configure Rspamd
echo "Unprotecting Rspamd config file..."
chflags noschg $CONFIGFILE
chmod u+w $CONFIGFILE
echo "Adding domain "$DOMAIN" to config file..."
echo "domain { "$DOMAIN" { selector = '"$SELECTOR"'; } }" >> $CONFIGFILE
echo "Write protecting Rspamd config file..."
chmod u-w $CONFIGFILE
chflags schg $CONFIGFILE
echo
echo "Done."
;;

check)
echo "*** Redis key storage ***"
redis-cli HGETALL DKIM_KEYS
echo
echo "*** Rspamd configured domains ***"
grep "domain {" $CONFIGFILE
echo
echo "*** Rspamd config file protection ***"
ls -lo $CONFIGFILE > $TMPFILE
if grep "schg" $TMPFILE 2> /dev/null;
then
echo "Config file is write protected."
else
echo "Config file is not write protected."
fi
rm -f $TMPFILE
;;

del)
# check for 3 arguments
if [ $# -lt 3 ]; then
    echo "Both domain name and selector are required to delete a single key:"
echo "  del {example.com} {myselector}"
    exit 1
fi
echo "Removing key from Redis..."
redis-cli HDEL DKIM_KEYS $SELECTOR.$DOMAIN
echo
echo "Unprotecting Rspamd config file..."
chflags noschg $CONFIGFILE
chmod u+w $CONFIGFILE
echo "Removing key from configuration file..."
grep -v "domain { $DOMAIN { selector = '$SELECTOR'; } }" $CONFIGFILE > $TMPFILE
cat $TMPFILE > $CONFIGFILE
rm -f $TMPFILE
echo "Write protecting Rspamd config file..."
chmod u-w $CONFIGFILE
chflags schg $CONFIGFILE
echo
echo "Done."
;;

deleteall)
read -r -p "Delete all DKIM keys from Redis and Rspamd configuration (y/N)? " REPLY
case $REPLY in
[yY])
echo "Deleting keys from Redis..."
redis-cli DEL DKIM_KEYS
echo "Unprotecting Rspamd config file..."
chflags noschg $CONFIGFILE
chmod u+w $CONFIGFILE
echo "Removing domains from Rspamd configuration..."
grep -v "domain {" $CONFIGFILE > $TMPFILE
cat $TMPFILE > $CONFIGFILE
rm -f $TMPFILE
echo
echo "Done."
;;
*)
echo "Aborting."
;;
esac
;;

*)
    echo "usage: setup-dkim-signing.sh {add|check|del|deleteall} [example.com] [myselector]"
echo "  add {example.com} {myselector}"
echo "    Generate a new DKIM key (if necessary), upload it into Redis and configure rspamd accordingly."
echo "  check"
echo "    Show keys stored in Redis and domains configured in rspamd"
echo "  del {example.com} {myselector}"
echo "    Delete a single key from Redis and rspamd. The key files will not be deleted."
echo "  deleteall"
echo "    Delete all keys from Redis and rspamd. The key files will not be deleted."
echo
    exit 1
;;
esac

I have to confess that I am a clumsy and awful coder, plus this is rather a hack than a solution, e.g. the setup is made persistent by setting the immutable flag on the configuration file. However, it serves my needs until this feature will make it to the GUI.

Update 05.08.2021
This is what the configuration file should look like:
/usr/local/etc/rspamd/local.d/dkim_signing.conf
Code: [Select]
enabled = true;
allow_envfrom_empty = true;
allow_hdrfrom_mismatch = true;
allow_hdrfrom_multiple = false;
allow_username_mismatch = true;
auth_only = false;
selector = "dkim";
sign_local = true;
symbol = "DKIM_SIGNED";
try_fallback = false;
use_domain = "header";
use_esld = true;
use_redis = true;
key_prefix = "DKIM_KEYS";
domain { example.com { selector = 'selectone'; },
              example2.com { selector = 'selecttwo'; }
            }
Title: Re: Postfix/rspamd DKIM signing
Post by: Rolfieo on July 05, 2021, 08:50:10 am
Yes this should be ..

Do you maybe know if this will be part of 21.7 release?
Title: Re: Postfix/rspamd DKIM signing
Post by: mimugmail on July 05, 2021, 09:04:23 am
I'm not sure if I find the time for it. Is there already a feature request in github?
Title: Re: Postfix/rspamd DKIM signing
Post by: Rolfieo on July 05, 2021, 09:30:47 pm
I'm not sure if I find the time for it. Is there already a feature request in github?

Good one, i have no idea i have to say.
I just lifted on this topic.

Where can i do / find this? I will raise one, if there is none yet.
Title: Re: Postfix/rspamd DKIM signing
Post by: AlienMindbender on August 05, 2021, 12:52:48 pm
I'm not sure if I find the time for it. Is there already a feature request in github?

There is at least an open issue in github from March 2021 that was opened by mimugmail...  ;)
https://github.com/opnsense/plugins/issues/2294
Title: Re: Postfix/rspamd DKIM signing
Post by: yannik on February 26, 2022, 11:35:45 am
Hi,

unfortunately, the mentioned issue (https://github.com/opnsense/plugins/issues/2294) was automatically closed.
Is there an update on the plugin, by chance? :)
Title: Re: Postfix/rspamd DKIM signing
Post by: mimugmail on February 26, 2022, 12:38:44 pm
If there is an easy to use example, maybe
Title: Re: Postfix/rspamd DKIM signing
Post by: opncon on November 15, 2023, 04:26:44 pm
i check the setup file and correct the format for multi-domains - but i dont get any dkim signed mails out of the opnsense.
Is there any changes since this solution was posted?
Title: Re: Postfix/rspamd DKIM signing
Post by: opncon on November 27, 2023, 12:40:55 pm
Hi, i have configured it with the setup script and get this config file with modification of the domains for correct syntax. But the mails will not be signed. i make restarts of the servers, reboot the opnsense, but nothing works. here is my config file:

Code: [Select]
root@sense:/usr/local/etc/rspamd/local.d # cat dkim_signing.conf
enabled = true;
allow_envfrom_empty = true;
allow_hdrfrom_mismatch = true;
allow_hdrfrom_multiple = false;
allow_username_mismatch = true;
auth_only = false;
selector = "dkim";
sign_local = true;
symbol = "DKIM_SIGNED";
try_fallback = false;
use_domain = "header";
use_esld = true;
use_redis = true;
key_prefix = "DKIM_KEYS";
path = "/root/dkim/$domain.key";

domain { xxxx.eu      { selector = 'selector2'; },
         xxxx.at      { selector = 'selector2'; },
         xxxx.eu     { selector = 'selector2'; },
         xxxx.at { selector = 'selector2'; },
         xxxx.com { selector = 'selector2'; }
        }

did anyone have a hint for me?