Menu

#70 Simple way of using E-MailRelay to implement DKIM?

v1.0 (example)
closed
nobody
None
5
2022-05-18
2022-05-16
No

I am trying to add DKIM to an existing windows server which is currently using IIS SMTP for outgoing mail.

It seems like this could be done by using E-MailRelay in connection with a suitable mail filter, but after reading the basics it seems like there is no preconfigured way to do this (such as supplying the name of a .pem file and selector to a default filter and letting E-MailRelay do the rest)

I think I understand the basics of implementing such a filter on my own, but before reinventing the wheel I just wanted to ask if someone has implemented a filter for DKIM signing already.

Thanks in advance for your help!

Discussion

  • Graeme Walker

    Graeme Walker - 2022-05-16

    I'm not aware of any DKIM signers specifically for E-MailRelay but as you say it should be doable with a filter and the starting point would depend on your scripting language of choice -- perhaps perl's Mail::DKIM::Signer. Let us know how you get on.

     
  • Graeme Walker

    Graeme Walker - 2022-05-17

    I've attached a perl script to show how Mail::DKIM::Signer could be turned into an emailrelay filter.

     
  • Graeme Walker

    Graeme Walker - 2022-05-18

    I've tested my signing script and it seems to work. I had to remove the call to dkim CLOSE() because that is done by load() and two CLOSE()s are not idempotent. Instructions for testing are in the header comments.

     
  • Graeme Walker

    Graeme Walker - 2022-05-18
    • status: open --> closed
     
  • Adrian Grigore

    Adrian Grigore - 2022-05-18

    Thanks a lot, Graeme! This is just what I needed.

     
  • Adrian Grigore

    Adrian Grigore - 2022-05-18

    Here's a C# / .NET 6 port of your script in case someone else needs this:

    using System.IO;
    using System.Text;
    using MimeKit;
    using MimeKit.Cryptography;
    
    namespace E_MailRelay.DKIM.Filter;
    
    /// <summary>
    /// Reads an e-mail message, adds a Hardcoded DKIM signature and and writes the updated message back to disk
    /// Note that this requires the installation MailKit to work. 
    /// </summary>
    
    
    internal class Program
    {
        private const string DKIMSelector = "ENTER_YOUR_DKIM_SELECTOR_HERE";
        private const string _DKIMDomain = "ENTER_YOUR_DOMAIN_NAME_HERE";
        private const string DKIMPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n"
                                              + @"ENTER_YOUR_PRIVATE_KEY_HERE"
                                              + "\r\n-----END RSA PRIVATE KEY-----";
    
        private static int Main(string[] args)
        {
            LoadSignAndRewriteMail(args);
            return 102;
        }
    
        private static void LoadSignAndRewriteMail(string[] args)
        {
            var emailMessage = MimeMessage.Load(args[0]);
            if (!emailMessage.Headers.Contains(HeaderId.DkimSignature)
                && !emailMessage.Headers.Contains(HeaderId.DomainKeySignature))
            {
                SignMail(emailMessage);
            }
    
            emailMessage.WriteTo(args[0]);
        }
    
    
        private static void SignMail(MimeMessage emailMessage)
        {
            var pk = DKIMPrivateKey;
            MemoryStream stream = new(Encoding.UTF8.GetBytes(pk));
            {
                stream.Position = 0;
            }
    
    
    
            var dkimSigner = new DkimSigner(stream, _DKIMDomain, DKIMSelector);
    
    
            HeaderId[] dkimSignHeaders =
            {
                HeaderId.To, HeaderId.Cc, HeaderId.Subject, HeaderId.From, HeaderId.Date, HeaderId.MessageId, HeaderId.Body,
                HeaderId.Date, HeaderId.MimeVersion, HeaderId.Sender, HeaderId.ReplyTo, HeaderId.ContentTransferEncoding,
                HeaderId.ContentId, HeaderId.ContentDescription, HeaderId.ResentDate, HeaderId.ResentFrom,
                HeaderId.ResentSender, HeaderId.ResentTo, HeaderId.ResentCc, HeaderId.ResentMessageId, HeaderId.InReplyTo,
                HeaderId.References
            };
    
            dkimSigner.Sign(FormatOptions.Default, emailMessage, dkimSignHeaders);
        }
    }
    
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.