Implementing DKIM Signing in IIS 7.5 on Windows Server 2008: A Step-by-Step Guide


61 views

DomainKeys Identified Mail (DKIM) is an email authentication method that uses cryptographic signatures to verify message integrity. For Windows Server 2008 running IIS 7.5, implementing DKIM requires additional components since it's not natively supported.

  • Windows Server 2008 R2 (64-bit recommended)
  • IIS 7.5 with SMTP service installed
  • Administrative privileges
  • PowerShell 2.0 or later

First, download and install the DKIM signing component:

# PowerShell command to install DKIM module
Install-Module -Name DkimSigner -Force -AllowClobber
Import-Module DkimSigner

Create a DNS TXT record for your domain first. Then configure the signing:

# Generate DKIM keys
New-DkimSignerKey -Selector "default" -Domain "yourdomain.com" -KeyLength 2048

# Configure SMTP to use DKIM
Set-DkimSignerConfig -Enabled $true -Selector "default" -Domain "yourdomain.com" 
-PathToPrivateKey "C:\DKIM\default.private"

Verify your setup with these commands:

# Test DKIM signing
Test-DkimSignerConfig

# Check DNS record
Resolve-DnsName -Name "default._domainkey.yourdomain.com" -Type TXT
  • Ensure the SMTP service has read access to the private key file
  • Verify the DNS TXT record is properly propagated
  • Check Windows Firewall isn't blocking SMTP traffic

For custom signing policies, use this PowerShell snippet:

$policy = @{
    Domains = "yourdomain.com", "sub.yourdomain.com"
    Selector = "customselector"
    KeyPath = "C:\DKIM\custom.private"
    HeaderCanonicalization = "relaxed"
    BodyCanonicalization = "simple"
    SignExpired = $false
}
Set-DkimSignerPolicy @policy

Before diving into implementation, let's clarify what we're building. DKIM (DomainKeys Identified Mail) requires:

  • A cryptographic key pair (public/private)
  • DNS TXT record for public key
  • SMTP service modification to sign outgoing messages

First, we'll generate keys using PowerShell (run as Administrator):

# Generate 2048-bit RSA key pair
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider -ArgumentList 2048
$privateKey = [Convert]::ToBase64String($rsa.ExportCspBlob($true))
$publicKey = [Convert]::ToBase64String($rsa.ExportCspBlob($false))

# Save private key to file (protect this!)
$privateKey | Out-File "C:\DKIM\default.private" -Encoding ASCII

Create a TXT record at default._domainkey.yourdomain.com with this format:

v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY_HERE

Remove line breaks from the public key before pasting into DNS.

Since IIS 7.5 lacks native DKIM support, we'll use Port25's DKIM Signer:

  1. Download from http://www.port25.com/products/authentication-products/
  2. Install with default options
  3. Configure via MMC snap-in

Create C:\DKIM\dkim.json:

{
  "Domain": "yourdomain.com",
  "Selector": "default",
  "PrivateKeyPath": "C:\\DKIM\\default.private",
  "HeaderCanonicalization": "simple",
  "BodyCanonicalization": "simple",
  "SigningAlgorithm": "rsa-sha256",
  "SocketBindAddress": "127.0.0.1",
  "SocketPort": 8891
}

Modify SMTP virtual server settings:

# PowerShell command to update SMTP settings
Set-ItemProperty -Path "IIS:\SmtpSvc\1" -Name RouteAction -Value 2
Set-ItemProperty -Path "IIS:\SmtpSvc\1" -Name SmartHost -Value "127.0.0.1:8891"

Test your setup using Telnet:

telnet localhost 25
EHLO yourdomain.com
MAIL FROM: <test@yourdomain.com>
RCPT TO: <check-auth@verifier.port25.com>
DATA
Subject: DKIM Test
This is a test message.
.
QUIT

Check the verification report sent back by Port25.

  • Key Mismatch: Verify DNS record matches public key exactly
  • Time Synchronization: Ensure server clock is accurate (DKIM uses timestamps)
  • Firewall Blocking: Port 8891 must be open for localhost

Create a scheduled task to rotate keys monthly:

# PowerShell script for key rotation
$newKey = New-Object System.Security.Cryptography.RSACryptoServiceProvider -ArgumentList 2048
$newPublicKey = [Convert]::ToBase64String($newKey.ExportCspBlob($false))
Publish-DnsRecord -Selector "default" -PublicKey $newPublicKey
Move-Item "C:\DKIM\default.private" "C:\DKIM\old.private"
$newKey.ExportCspBlob($true) | Out-File "C:\DKIM\default.private"
Restart-Service SMTPSVC