DKIM record được tạo từ cặp khóa riêng + công khai. Khóa công khai đặt ở DNS server và trong header của email. Mailserver bên nhận sẽ so khớp với khóa riêng trên mailserver bên gởi để xác nhận email “chính chủ”.
Các hệ thống email như GSuite hay Google Mail sẽ trả lại email nếu không so khớp được DKIM.
Thông thường khóa công khai khá dài có dạng như sau:
dkim._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApxh2sNxBgYCs7EKgYbM8Yc0vNoOy8oCA0OBSsIdD44WPu9+PlwAzCrVWHCjralgSZwz6sGw6jwgJBXZrMMNXFbdLEiQdmpRNlRYq8yFZAXV2Mwis4q+6QYACIkFVZ4S7ElPeenm75aff1ALjTD41kKoajTgMJ5MK2q68e31H4Zz41pK5Qw1ZsGvotGodwFG5XDNPbeeaGNQv8EE2V"
"XEtI8U17Ry+UP7GFUFzXF0EVUO1RhozegEtUqAUAbBIrKKp3LODqSoC3ImrE2RWoIFBuLqRoPT0R04i6AEH2DucHs92yx0fW2fVNmdo283C5jgGq3QRIg2yM+4X9+DJE2SYYQIDAQAB"
);
Chúng ta phải nối chuỗi trong cặp () để lấy khóa công khai.
Script sau đây tạo record TXT dkim._domainkey nếu chưa có, hoặc cập nhật giá trị nếu đã có rồi. Cú pháp
cfdkim domain.org [path_to_dkim.pubkey]
Mặc định: domain.org.pubkey
#!/bin/bash
# Tên script: cfdkim.sh
# Tạo mới/Cập nhật DKIM record cho cloudflare.com
# © 2020 LNT <lnt@ly-le.info>
# version 20200824
#
echo 'Tạo mới/Cập nhật DKIM record cho cloudflare.com...'
( command -v jq &> /dev/null ) || apt install -y jq
AUTH_EMAIL='your_account'
AUTH_KEY='your_auth_public_key'
BASE_URL='https://api.cloudflare.com/client/v4/zones'
if [ $# -eq 1 ]; then
DKIM="$1.pubkey"
[ ! -e $DKIM ] && error=1 || error=0
elif [ $# -eq 2 ]; then
DKIM=$2
[ ! -e $DKIM ] && error=1 || error=0
elif [[ $# -ne 2 || error ]]; then
echo "usage: $(basename $0) domain.org [dkim_pubkey]"
echo 'dkim_pubkey: file chứa khoá công khai, mặc định domain.org.pubkey'
exit 1
fi
DOMAIN="$1"
IFS=$'\t' read selector dkim <<<$(sed -z 's/"[ \n\t]*"//g' $DKIM | sed -z 's/\(^.*\._domainkey\).*"\(.*\)".*/\1\t\2/' | sed -z 's/\n//g')
# ID của domain
ZONE_ID=$(jq -r '.result[].id' <<< $(curl -s -H "X-Auth-Email: ${AUTH_EMAIL}" -H "X-Auth-Key: ${AUTH_KEY}" -H "Content-Type: application/json" -X GET ${BASE_URL}?name=${DOMAIN}&status=active))
[[ "${ZONE_ID}" =~ ^[0-9a-f]{32}$ ]] || { echo "Bad Zone ID"; exit 1; }
BASE_URL="${BASE_URL}/${ZONE_ID}"/dns_records
# json string of TXT
tmp=$(curl -s -X GET "${BASE_URL}?type=TXT" -H "X-Auth-Email: ${AUTH_EMAIL}" -H "X-Auth-Key: ${AUTH_KEY}" -H "Content-Type: application/json" | jq -r '.result[] | {id,name,content}' | jq -s .)
s=".name == \"$selector.$DOMAIN\""
dkim_rec=$(echo "$tmp" | jq ".[] | select($s)" | jq -s .)
IFS=$'\t' read -r id name content type <<< $(echo "$dkim_rec" | jq -r '.[] | [.id, .name, .content] | @tsv')
if [[ "$dkim" == "$content" ]]; then
echo "$selector khong thay doi!"
else
[ "$id" == '' ] && method='POST' || method='PATCH'
ret=$(curl -s -X $method "${BASE_URL}/$id" -H "X-Auth-Email: ${AUTH_EMAIL}" -H "X-Auth-Key: ${AUTH_KEY}" -H "Content-Type: application/json" --data "{\"type\":\"TXT\",\"name\":\"$selector.$DOMAIN\",\"content\":\"$dkim\",\"ttl\":3600,\"proxied\":false}" | jq -r '.success')
echo "$method $selector: success=$ret"
fi