{"id":18593275,"url":"https://github.com/acromedia/ansible-role-dkim","last_synced_at":"2026-02-03T06:01:49.469Z","repository":{"id":52744575,"uuid":"283352086","full_name":"AcroMedia/ansible-role-dkim","owner":"AcroMedia","description":"Ansible role for adding OpenDKIM to Postfix","archived":false,"fork":false,"pushed_at":"2024-10-15T17:53:42.000Z","size":49,"stargazers_count":1,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T00:41:35.779Z","etag":null,"topics":["ansible","dkim"],"latest_commit_sha":null,"homepage":"","language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AcroMedia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-28T23:43:54.000Z","updated_at":"2024-10-15T17:53:46.000Z","dependencies_parsed_at":"2024-11-07T01:11:57.637Z","dependency_job_id":"d8dadd9d-15f2-4cf6-95c8-2106769424e2","html_url":"https://github.com/AcroMedia/ansible-role-dkim","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AcroMedia%2Fansible-role-dkim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AcroMedia%2Fansible-role-dkim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AcroMedia%2Fansible-role-dkim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AcroMedia%2Fansible-role-dkim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AcroMedia","download_url":"https://codeload.github.com/AcroMedia/ansible-role-dkim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248252691,"owners_count":21072699,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","dkim"],"created_at":"2024-11-07T01:11:52.889Z","updated_at":"2026-02-03T06:01:44.431Z","avatar_url":"https://github.com/AcroMedia.png","language":"Jinja","funding_links":[],"categories":[],"sub_categories":[],"readme":"# acromedia.ansible-role-dkim\n![.github/workflows/molecule.yml](https://github.com/AcroMedia/ansible-role-dkim/workflows/.github/workflows/molecule.yml/badge.svg)\n\nAdd OpenDKIM to Postfix.\n\nThis role is intended for use on web servers, so any mail they send out (order confirmations, blog digests, etc) has a better chance of making it to end users.\n\n\n### Requirements\n\n- Ubuntu \u003e= 14 or CentOS \u003e= 6\n- Your role must gather facts\n- If you're using RedHat / CentOS, you will need to apply an opendkim SELinux policy separately, otherwise you will experience errors.\n\n### Dependencies\n\nIf postfix isn't present yet, the role will try and install it, but that's really just so the role can pass tests. Letting this role force the install of postfix isn't recommended.\n\n### Example playbooks\n\nSee also: [Role Variables](#role-variables)\n\n#### Single server: Let the role generate a private key for you\n\n```yaml\n---\n- hosts: app-nodes\n  become: true\n  roles:\n    - role: acromedia.postfix\n      vars:\n        default_mail_recipient: webmaster@example.com\n\n    - role: acromedia.dkim\n      vars:\n        dkim_domains:\n          - name: example.com\n            selector: default\n            private_key: ''  # Lets the role generate the private key.\n            signing_table_pattern: '*@example.com'\n        dkim_report_recipient: postmaster@example.com\n```\n\n#### Load-balanced servers: Upload a prepared private key to all servers\n\n```yaml\n---\n- hosts: app-nodes\n  become: true\n  roles:\n    - role: acromedia.postfix\n      vars:\n        default_mail_recipient: webmaster@example.com\n\n    - role: acromedia.dkim\n      vars:\n        dkim_domains:\n          - name: example.com\n            selector: default\n            # Use lookup() to set the value of `private_key` to be the decrypted content of a vault-encrypted template file\n            private_key: \"{{ lookup('file', 'templates/my-responsibly-vault-encrypted-private-key.j2') }}\"  \n            signing_table_pattern: '*@example.com'\n        dkim_report_recipient: postmaster@example.com\n```\n\n### Role variables\n\nRefer to [Exmaple Playbooks](#example-playbooks) for usage. See also: [defaults/main.yml](defaults/main.yml) for less frequently used variables.\n\n#### dkim_domains[]:\n\n- Defaults to an empty list.\n\n\n- Whatever you specify here will be used by remote systems to construct a request for DNS TXT record. E.g. if your dkim selector is `foo`, and your domain is `example.com`, remote systems will look for the public DKIM key at `foo._domainkey.exmaple.com`.\n\n- #### name\n\n  - The domain name part of of email addresses that will have DKIM signatures added to.\n\n  - The values for `.name` and `.selector` are used together to construct filename paths and write configuration templates.\n\n- #### selector\n\n  - The identifier on the domain name which specifies which DKIM public key was used to sign outgoing mail.\n\n  - If you only use DKIM on one system, you can use the string `default`.\n\n- #### private_key\n\n  - The content of the RSA private key, as opposed to the filename.\n\n  - If left blank, the role will use `opendkim-genkey` to create an RSA key pair for you.\n\n  - The private key will be placed at`/etc/opendkim/keys/{{ dkim_domains.name }}/{{ dkim_domains.selector }}.private` on the server.\n\n  - For single server systems, it's fine to let the role generate a key for you. If you have multiple app nodes, or use a load balancer, generate a private key ahead of time, and use that instead.\n\n  - If you let the key pair be generated, the public half can be found in the form of a DNS text record at `/etc/opendkim/keys/{{ dkim_domains.name }}/{{ dkim_domains.selector }}.txt`. **Caveat**: You may need to massage the formatting of the generated public key record if you're adding it to AWS Route 53.\n\n- #### signing_table_pattern\n\n  - A string that tells opendkim which outgoing mail should be signed on its way out. Wilcards are supported. See http://www.opendkim.org/opendkim-README\n\n\n#### dkim_report_recipient\n\nAn email address which specifies who should receive signature failure reports.\n\n\n### How to generate a RSA key pair manually for use with DKIM\nInstall `opendkim-tools`, which provides `opendkim-keygen`. Use it like so:\n```bash\nopendkim-genkey \\\n --selector=default \\\n --domain=example.com \\\n --bits=1024 \\\n --append \\\n --verbose \\\n --directory=./\n```\nThe above is equivalent to running `openssl genrsa -out ./default.private  1024 \u0026\u0026 openssl rsa -in ./default.private -pubout -out ./default.txt`, and then massaging the format of default.txt into a usable DNS record, but opendkim-genkey saves you the hassle of that last step.\n\n### How to retreive your auto-generated public DKIM key from the server\n\nIf you let the role generate your DKIM key pair for you, (e.g. if didn't upload your private key), the public half will be on the server at:\n```\n/etc/opendkim/keys/{{ dkim_domain }}/{{ dkim_selector }}.txt\n```\nIts contents will look something like:\n```\nfoo._domainkey\tIN\tTXT\t( \"v=DKIM1; k=rsa; \"\n\t  \"p=MIGfMx... truncated for readability ...XIDAQAB\" )  ; ----- DKIM public key \"foo\" selector for \"example.com\" domain\n```\n\n\n### How to extract a public key from a private key\n```\nopenssl rsa -in /path/to/private.key -pubout\n```\nwill extract your public key, but you still need to massage it into the form of a DNS TXT record. E.g. you would need to convert:\n```\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2QFd+mOaTavpOQAQi7jI\n9Uo8K1C7NtJ6wMpDS0XA+KakPkNI6rehdg7mJxrXz7MD+mkFeahJtWwhOKTxLyXd\nDQIDAQAB\n-----END PUBLIC KEY-----\n```\nto:\n```\ndefault._domainkey 14400 IN TXT (\"v=DKIM1; k=rsa; p=\"\n\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2QFd+mOaTavpOQAQi7jI\"\n\"9Uo8K1C7NtJ6wMpDS0XA+KakPkNI6rehdg7mJxrXz7MD+mkFeahJtWwhOKTxLyXd\"\n\"DQIDAQAB\")\n```\n### Caveats\n\n1. DNS TXT records have an individual string size limit of 255 characters. To overcome this, multiple quoted strings must be concatenated to achieve a record longer than 255 characters. This will occur if you create a private key of more than 1024 bits. The record may end up something like this:\n\n1. Not all DNS providers support strings longer than 255 chars. If this is the case, your key generation cannot use more than 1024 bits.\n\n1. Not all DNS providers support the format of multiple lines inside braces. For example, AWS's Route 53 interface will *mangle* your DNS record like a boss if you don't strip those braces, newlines,  comments out, and paste it in all as a single line:\n```\nfoo._domainkey.example.com. 3600 IN TXT \"v=DKIM1; k=rsa;\" \"p=MIGfMx...xxxxx\" \"yyyyy...XIDAQAB\"\n````\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facromedia%2Fansible-role-dkim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Facromedia%2Fansible-role-dkim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facromedia%2Fansible-role-dkim/lists"}