~drscream
Rotate DKIM in mail.core.io environment
Rotate the DKIM keys every half a year or maybe more often is recommended. On our mail.core.io environment we’ve multiple nodes running which could be a pain in the ass to do it manually.
Because all our infrastructure is build on SmartOS we use zones. The benefit is we could store key information in mdata
. For the rotation we only need to update the mdata
variables and run one script to copy the information to an local file.
Create a new key
One of the easiest steps is to create a new public and private key pair with the awesome openssl
command. I’m sure you love it the same way I does ;-)
# create one variable make it easy to update
DKIM_SELECTOR='submission-20150205'
# generate private key, keep it secret
openssl genrsa -out ${DKIM_SELECTOR}.key 1024
# generate public key
openssl rsa -in ${DKIM_SELECTOR}.key -pubout > ${DKIM_SELECTOR}.crt
# convert to the public part you need for DNS
echo -n "v=DKIM1; k=rsa; p=" > ${DKIM_SELECTOR}.pub
cat ${DKIM_SELECTOR}.crt | grep -v '^--' | tr -d "\n" \
>> ${DKIM_SELECTOR}.pub
I like to have one file ${DKIM_SELECTOR}.pub
which contains the DNS part.
Update your dns records
This depends on your provider. Maybe they provide an API for your so you could create your own script to modify the DNS entry.
Your record should look like:
# Source as bash example
${DKIM_SELECTOR}._domainkey. IN TXT "$(cat ${DKIM_SELECTOR}.pub)"
# Example
submission-20150205._domainkey. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGS..."
This isn’t required but I recommend to wait half a day before deploy the new key on the production system. This will allow all DNS caches updated and share the new record.
Deploy the key to the mailserver
Deployment time :-) You need to upload and update your configuration files, reload exim service - and this needs to be done on all your mail servers. So it’s time for using ansbile
ad-hoc commands.
Be sure you have an inventory
which could be located at ~/.ansible/hosts
:
[mail-example]
smtp.example.de ansible_ssh_user=root
smtp.example.com ansible_ssh_user=root
mx.example.com ansible_ssh_user=root
mx.example.de ansible_ssh_user=root
For SmartOS you require the following line. This allow ansible
to find the python
interpreter.
[mail-example:vars]
ansible_python_interpreter = /opt/local/bin/python
Ready for to run? Here we go. Be sure you’re at the same location as your DKIM files.
# define the group you're using at the inventory file
GROUP='mail-example'
# update information in mdata variables
ansible ${GROUP} -m copy \
-a "src=${DKIM_SELECTOR}.key dest=/root/${DKIM_SELECTOR}.key"
ansible ${GROUP} -m shell \
-a "cat /root/${DKIM_SELECTOR}.key | mdata-put dkim_private_key"
ansible ${GROUP} \
-a "rm /root/${DKIM_SELECTOR}.key"
ansible ${GROUP} -m shell \
-a "echo ${DKIM_SELECTOR} | mdata-put dkim_selector"
# run reprovision script which will write mdata information to file
ansible ${GROUP} \
-a '/usr/bin/bash /opt/core/var/mdata-setup/includes/31-exim.sh'
# reload exim service
ansible ${GROUP} -m service -a "name=exim state=reloaded"
Because I use the pipe to put information into mdata the -m shell
is required. Ansible
only support piping and other special commands if you have a valid shell.
Send your comment by mail.