opendkim-signer 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #!/usr/bin/env bash
  2. #####################################################
  3. # This script require the following DNS SETUP!!!!
  4. # SEE:
  5. # https://git.giaever.org/joachimmg/dnssec-signer)
  6. #
  7. # USAGE:
  8. #
  9. # 1. Make `opendkim-setter` executable:
  10. # chmod +x /path/to/opendkim-setter
  11. #
  12. # 2. Run:
  13. # ./path/to/opendkim-setter <domain.tld>
  14. # 3. Or for every domain already signed by OpenDKIM
  15. # ./path/to/opendkim-setter
  16. #
  17. ######################################################
  18. SELF="$(basename ${0})"
  19. ######################################################
  20. # START OF CONFIG #
  21. ######################################################
  22. # SET YOU SYSTEM SPECIFIC DATA (which systemctl e.g) #
  23. SELF=$(basename $0)
  24. DKIMUSER="opendkim"
  25. DKIMGRP="${DKIMUSER}"
  26. DKIMCONF="/etc/opendkim"
  27. KEYTABLE="${DKIMCONF}/key.table"
  28. SIGNTABLE="${DKIMCONF}/signing.table"
  29. KEYDIR="${DKIMCONF}/keys"
  30. ZONESDIR="/etc/bind/zones"
  31. KEYGEN=/usr/bin/opendkim-genkey
  32. LOGGER=/usr/bin/logger
  33. LOGGERFLAGN="-t $(whoami) -p daemon.info"
  34. LOGGERFLAGE="-t $(whoami) -p daemon.err"
  35. RESIGNDNS=1
  36. DNSTOOL=/usr/bin/dnssec-signer
  37. ######################################################
  38. # END OF CONFIG #
  39. ######################################################
  40. function error_msg {
  41. FOR=${1}
  42. ERRMSG="${2}"
  43. echo -e "\e[31m[${SELF}:\e[1m${FOR}\e[21m]:\e[0m ${ERRMSG}"
  44. ${LOGGER} ${LOGGERFLAGE} "[${SELF}:${FOR}]: ${ERRMSG}"
  45. }
  46. function note_msg {
  47. FOR=${1}
  48. NOTEMSG="${2}"
  49. echo -e "\e[32m[${SELF}:\e[1m${FOR}\e[21m]:\e[0m ${NOTEMSG}"
  50. ${LOGGER} ${LOGGERFLAGN} "[${SELF}:${FOR}]: ${NOTEMSG}"
  51. }
  52. if [[ ${EUID} -ne 0 ]]; then
  53. error_msg "${USER}" "Must execute file as root."
  54. exit 1
  55. fi
  56. #function remove_signing_table {
  57. # grep -v "*@${1} " "${SIGNTABLE}" > "${TMPTBL}" && mv "${TMPTBL}" "${SIGNTABLE}"
  58. #}
  59. function update_signing_table {
  60. grep -q "^*@${1}" "${SIGNTABLE}"
  61. if [ $? -ne 0 ]; then
  62. note_msg "${1}" "Added to signing table"
  63. echo "*@${1} ${1}" >> "${SIGNTABLE}"
  64. fi
  65. }
  66. function update_key_table {
  67. grep -q "^${1}" "${KEYTABLE}"
  68. if [ $? -eq 0 ]; then
  69. note_msg "${1}" "Updated key in key table"
  70. sed -i 's,^'"${1}"'[^\n]\+,'"${1}"' '"${1}"':'"${2}"':'"${3}"',' "${KEYTABLE}"
  71. else
  72. note_msg "${1}" "Added key to key table"
  73. echo "${1} ${1}:${2}:${3}" >> "${KEYTABLE}"
  74. fi
  75. }
  76. function dkim {
  77. ENTRY="${1}"
  78. ENTRYDIR="${KEYDIR}/${ENTRY}"
  79. ENTRYZONE="${ZONESDIR}/${ENTRY}/db"
  80. DATE=$(date +%Y%m)
  81. PRIVATEKEY="${ENTRYDIR}/${DATE}.private"
  82. DOMAINKEY="${ENTRYDIR}/${DATE}.txt"
  83. note_msg "${ENTRY}" "DKIM Signing"
  84. if ! [ -w "${ENTRYZONE}" ]; then
  85. error_msg "${ENTRY}" "There is not zone file. Abort"
  86. return 1
  87. fi
  88. if ! [ -d "${ENTRYDIR}" ]; then
  89. note_msg "${ENTRY}" "Creating directory for entry"
  90. mkdir -p "${ENTRYDIR}"
  91. fi
  92. cd "${ENTRYDIR}"
  93. ${KEYGEN} -b 2048 -h rsa-sha256 -r -s "${DATE}" -d "${ENTRY}" -v
  94. if [ $? -ne 0 ]; then
  95. error_msg "${ENTRY}" "Error generating keys"
  96. fi
  97. KEYCONTENT=$(sed -e 's/h\=rsa-sha256/h\=sha256/' "${DOMAINKEY}" | tr '\n' '\r')
  98. ZONE=$(cat "${ENTRYZONE}" | tr '\n' '\r')
  99. grep -Eq "[0-9]{6}._dom" <<< "${ZONE}"
  100. if [ $? -eq 0 ]; then
  101. note_msg "${ENTRY}" "Altering DKIM-record in zone file"
  102. sed -e 's,[0-9]\{6\}._dom.*\-\+\sDKIM[^\r]\+\r\?\+,'"${KEYCONTENT}"',' <<< "${ZONE}" | tr '\r' '\n' > "${ENTRYZONE}"
  103. sed -i '${/^$/d;}' "${ENTRYZONE}"
  104. else
  105. note_msg "${ENTRY}" "Adding DKIM-record in zone file"
  106. echo -e "${ZONE}\r; DKIM for ${DOMAINKEY} start\r${KEYCONTENT}" | tr '\r' '\n' > "${ENTRYZONE}"
  107. fi
  108. update_signing_table "${ENTRY}"
  109. update_key_table "${ENTRY}" "${DATE}" "${PRIVATEKEY}"
  110. note_msg "${ENTRY}" "Signing successful"
  111. }
  112. # Collect arguments (zones)
  113. ENTRIES="${*}"
  114. IFS=' ', read -r -a ENTRIES <<< "${ENTRIES}"
  115. if [ ${#ENTRIES[@]} -ne 0 ]; then
  116. note_msg "${#ENTRIES[@]}" "Start signing"
  117. CWDIR=$(pwd)
  118. for ENTRY in "${ENTRIES[@]}"; do
  119. dkim "${ENTRY}"
  120. done
  121. cd "${CWDIR}"
  122. chown -R "${DKIMUSER}:${DKIMGROUP}" "${DKIMCONF}"
  123. chmod -R go-rw "${DKIMCONF}"
  124. if [ "${RESIGNDNS}" -eq 1 ]; then
  125. ${DNSTOOL} "${ENTRIES[@]}"
  126. fi
  127. else
  128. for ENTRY in $(cat "${SIGNTABLE}"); do
  129. if ! [[ "${ENTRY}" == "*"* ]]; then
  130. ENTRIES[${#ENTRIES[@]}]="${ENTRY}"
  131. fi
  132. done
  133. ${SELF} "${ENTRIES[@]}"
  134. fi