How to Configure DKIM (OpenDKIM) with Postfix
Install OpenDKIM and Postfix
sudo apt install opendkim opendkim-tools postfix
Configure OpenDKIM
OpenDKIM can add DKIM signatures to outbound mail and check DKIM signatures on inbound mail. It can be configured to reject mail that has missing or invalid DKIM signatures.
Create a directory structure that will store trusted hosts, key tables, signature tables, and crypto keys:
sudo mkdir /etc/opendkim sudo mkdir /etc/opendkim/keys # or one line sudo mkdir -p /etc/opendkim/keys
Generate the key pair for your DNS domain and selector:
For key generation, the opendkim-tools package provides the opendkim-genkey program. This program generates a private key named <my_selector>.private in the specified directory, as well as a public key <my_selector>.txt ready to be included in a bind DNS zone file.sudo -u opendkim opendkim-genkey -D /etc/opendkim/keys -d my-domain.org -s my_selector
Now, edit /etc/opendkim.conf. For the socket, the easiest option is to use a TCP socket listening on a local port (bypassing socket file ownership or chroot access issues). The file looks like this:
# This is a basic configuration that can easily be adapted to suit a standard # installation. For more advanced options, see opendkim.conf(5) and/or # /usr/share/doc/opendkim/examples/opendkim.conf.sample. # Log to syslog Syslog yes # Required to use local socket with MTAs that access the socket as a non- # privileged user (e.g. Postfix) UMask 007 # Sign for example.com with key in /etc/dkimkeys/dkim.key using # selector '2007' (e.g. 2007._domainkey.example.com) Domain my-domain.be KeyFile /etc/opendkim/keys/my_selector.private Selector my_selector # Map domains in From addresses to keys used to sign messages # KeyTable /etc/opendkim/KeyTable # SigningTable refile:/etc/opendkim/SigningTable # Hosts to ignore when verifying signatures ExternalIgnoreList /etc/opendkim/TrustedHosts InternalHosts /etc/opendkim/TrustedHosts # Commonly-used options; the commented-out versions show the defaults. #Canonicalization simple #Mode sv #SubDomains no # Socket smtp://localhost # # ## Socket socketspec # ## # ## Names the socket where this filter should listen for milter connections # ## from the MTA. Required. Should be in one of these forms: # ## # ## inet:port@address to listen on a specific interface # ## inet:port to listen on all interfaces # ## local:/path/to/socket to listen on a UNIX domain socket # # Socket local:/run/opendkim/opendkim.sock Socket inet:8891@localhost ## PidFile filename ### default (none) ### ### Name of the file where the filter should write its pid before beginning ### normal operations. # PidFile /run/opendkim/opendkim.pid # Always oversign From (sign using actual From and a null From to prevent # malicious signatures header fields (From and/or others) between the signer # and the verifier. From is oversigned by default in the Debian pacakge # because it is often the identity key used by reputation systems and thus # somewhat security sensitive. OversignHeaders From ## ResolverConfiguration filename ## default (none) ## ## Specifies a configuration file to be passed to the Unbound library that ## performs DNS queries applying the DNSSEC protocol. See the Unbound ## documentation at http://unbound.net for the expected content of this file. ## The results of using this and the TrustAnchorFile setting at the same ## time are undefined. ## In Debian, /etc/unbound/unbound.conf is shipped as part of the Suggested ## unbound package # ResolverConfiguration /etc/unbound/unbound.conf ## TrustAnchorFile filename ## default (none) ## ## Specifies a file from which trust anchor data should be read when doing ## DNS queries and applying the DNSSEC protocol. See the Unbound documentation ## at http://unbound.net for the expected format of this file. TrustAnchorFile /usr/share/dns/root.key ## Userid userid ### default (none) ### ### Change to user "userid" before starting normal operation? May include ### a group ID as well, separated from the userid by a colon. # UserID opendkim
In the file
/etc/opendkim/TrustedHosts
specify which hosts will have messages signed. If needed, include localhost as it is not implicit:127.0.0.1 ::1 localhost [SERVER_IP] [YOUR_HOSTNAME] mail.[MY_DOMAIN].be [MY_DOMAIN].be [MY_OTHER_DOMAIN].be
Multiple domains
For a single-domain DKIM setup with only a single key, the configuration shown above, using the three parameters Domain, Selector, KeyFile is enough. However, opendkim configuration supports multiple domains and keys, read from a variety of sources (files, SQL databases, Lua scripts, …). KeyTable and SigningTable are the configuration parameters that enable this. For mail servers that are “smarthosts”, opendkim can be configured to sign messages from subnets of trusted systems via the InternalHosts parameter. So, uncomment
KeyTable
andSigningTable
in/etc/opendkim/opendkim.conf
:# Map domains in From addresses to keys used to sign messages KeyTable /etc/opendkim/KeyTable # To use regular expressions in the file, use refile: instead of file: SigningTable refile:/etc/opendkim/SigningTable
Now in the file
/etc/opendkim/KeyTable
, put information about the private key:my_selector_key my-domain.be:my_selector:/etc/opendkim/keys/my_selector.private my_other_selector_key my-other-domain.be:my_other_selector:/etc/opendkim/keys/my_other_selector.private
In the file
/etc/opendkim/SigningTable
, specify which key will sign a domain:*@my-doamin.be my_selector_key *@my-other-domain.be my_other_selector_key
Socket
The opendkim service has to provide a communication channel for the MTA (Postfix). A TCP socket listening on a port only accessible locally is a reasonable choice that is also easy to set up.
We have to changeSOCKET
in/etc/default/opendkim
:# SOCKET=local:$RUNDIR/opendkim.sock SOCKET="inet:8891@localhost"
Change ownership of all files to opendkim:
sudo chown -R opendkim:opendkim /etc/opendkim sudo chmod -R 600 /etc/opendkim/keys sudo chmod -R go-rw /etc/opendkim/keys
Don’t forget to restart opendkim to apply the settings.
sudo service opendkim restart
Configure Postfix
- To integrate the opendkim service with Postfix. Edit /etc/postfix/main.cf to connect the two.
Also, we have to make some changes to imporve presentation. By default, TLS is disabled in the Postfix SMTP server, so no difference to plain Postfix is visible. Explicitly setsmtpd_use_tls
andsmtp_use_tls
toyes
. Add your SERVER IP tomynetworks
and your DOMAIN tomydestination
.
More about Postfix Configuration Parameters# TLS parameters ... smtpd_use_tls = yes smtp_use_tls = yes ... # Add DOMAIN to mydestination mydestination = $myhostname, postcodejobs, localhost.localdomain, localhost, my-domain.be # Add SERVER IP to mynetworks mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 XX.XXX.XXX.XX ... # per domain outgoing IP, uncomment it if needed # sender_dependent_default_transport_maps = regexp:/etc/postfix/sdd_transport_maps.regexp # can also /etc/postfix/sender_map ... # DKIM milter_default_action = accept # Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2 milter_protocol = 6 smtpd_milters = inet:localhost:8891 non_smtpd_milters = $smtpd_milters
- Postfix assign dedicated IP for outgoing mail sending
Postfix allows to route mails through specific IPs depending on a senders domain or email address.
This is achieved throughsender_dependent_default_transport_map
.
Next we create sender transport mapping in a new file/etc/postfix/sdd_transport_maps.regexp
. This file contain a regular expression matching the domain with smtp transport to use./@mydomain\.be/ smtp_be: /@myotherdomain\.ru/ smtp_ru:
- Now,
add transports
for them inmaster.cf
:
Don’t to forget uncommentsmtp_be unix - - n - - smtp -o syslog_name=mydomain -o smtp_helo_name=mydomain.be -o smtp_bind_address=XX.XX.XXX.XX smtp_ru unix - - n - - smtp -o syslog_name=myotherdomain -o smtp_helo_name=myotherdomain.ru -o smtp_bind_address=XX.XX.XXX.XX
sender_dependent_default_transport_map
inmain.cf
. - Restart postfix to apply the settings.
sudo service postfix restart
Add SPF record is a type of DNS TXT record
To see server IP4 and IP6 we can run: ip addr
.
Let’s begin with SPF, Sender Policy Framework. It is a mechanism to tell what hosts are allowed to send emails from your Email server. This will help your Emails to avoid being flagged as SPAM.
To implement it, add this TXT record to your DNS.
Name | Record Type | Value |
---|---|---|
@ | TXT | v=spf1 a mx ip4:44.49.444.57 ip6:3b24:3f0:c0c:a88b::3 ~all |
More about SPF Record Syntax
Add DKIM record is a type of DNS TXT record
DomainKeys Identified Mail (DKIM) combines several existing antiphishing and antispam methods to improve the quality of the classification and identification of legitimate e-mail. Instead of the traditional IP-address to determine the message sender, DKIM adds a digital signature associated with the domain name of the organization. In tandem, DNS is used to publish TXT records with the public portion of the cryptographic certificate used for digital signing.
Get and display the Public Key:
sudo cat /etc/opendkim/keys/my_selector.txt
# Output, we copy the highlighted part.
my_selector._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; s=email; "
"p=[...]"
"[...]"
"[...]==" ) ; ----- DKIM key my_selector for my-domain.com
Name | Record Type | Value |
---|---|---|
my_selector._domainkey | TXT | v=DKIM1; k=rsa; s=email; p=MIIBIjANBg…NqQIDAQAB |
More about DKIM Signature explained
Add DMARC record is a type of DNS TXT record
DMARC, which stands for “Domain-based Message Authentication, Reporting & Conformance”, is an email authentication, policy, and reporting protocol. It builds on the widely deployed SPF and DKIM protocols, adding linkage to the author (“From:”) domain name, published policies for recipient handling of authentication failures, and reporting from receivers to senders, to improve and monitor protection of the domain from fraudulent email.
Name | Record Type | Value |
---|---|---|
_dmarc | TXT | v=DMARC1; p=none |
More about DMARC Record Syntax
Testing
opendkim-testkey
verifies the setup of signing and verifying (private and public) keys for use with opendkim
.
The test program will read a domain name and selector from the command line, configuration file or a key table, then query and parse the resulting DKIM key(s), reporting any errors found.
If a key path is also provided, the test program will read the private key named and attempt to confirm that the private key specified by keypath (or in the key table) and the public DKIM key retrieved match.
We run opendkim-testkey:
opendkim-testkey -d my-domain.be -s my_selector -vvv
or with dig
dig myselector._domainkey.my-domain.be TXT +dnssec
The output will be as follows:
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: key loaded from /etc/opendkim/keys/my_selector.private
opendkim-testkey: checking key 'my_selector._domainkey.my-domain.be'
opendkim-testkey: key secure
opendkim-testkey: key OK
Use Mail Tester web service:
This service provides you with an email address to send an email from your email server for analysis. It is a very powerful audit tool, which provides a lot of information in the report.
Comments
Post a Comment