docker-entrypoint.sh 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #!/bin/bash
  2. ACME_BASE=/var/lib/acme
  3. mkdir -p ${ACME_BASE}/acme/private
  4. restart_containers(){
  5. for container in $*; do
  6. curl -X POST \
  7. --unix-socket /var/run/docker.sock \
  8. "http/containers/${container}/restart"
  9. done
  10. }
  11. if [[ $(openssl x509 -in ${ACME_BASE}/cert.pem -noout -issuer) != *"Let's Encrypt"* &&
  12. $(openssl x509 -in ${ACME_BASE}/cert.pem -noout -issuer) != *"mailcow"* ]]; then
  13. echo "Skipping ACME client"
  14. exit 0
  15. fi
  16. while true; do
  17. declare -a SQL_DOMAIN_ARR
  18. declare -a CONFIG_DOMAINS
  19. declare -a ADDITIONAL_VALIDATED_SAN
  20. IFS=' ' read -r -a ADDITIONAL_SAN_ARR <<< "${ADDITIONAL_SAN}"
  21. IPV4=$(curl -4s https://mailcow.email/ip.php)
  22. while read line; do
  23. SQL_DOMAIN_ARR+=("${line}")
  24. done < <(mysql -h mysql-mailcow -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SELECT domain FROM domain" -Bs)
  25. for SQL_DOMAIN in "${SQL_DOMAIN_ARR[@]}"; do
  26. A_CONFIG=$(dig A autoconfig.${SQL_DOMAIN} +short)
  27. if [[ ! -z ${A_CONFIG} ]]; then
  28. echo "Found A record for autoconfig.${SQL_DOMAIN}: ${A_CONFIG}"
  29. if [[ ${IPV4} == ${A_CONFIG} ]]; then
  30. echo "Confirmed A record autoconfig.${SQL_DOMAIN}"
  31. CONFIG_DOMAINS+=("autoconfig.${SQL_DOMAIN}")
  32. else
  33. echo "Cannot match Your IP against hostname autoconfig.${SQL_DOMAIN}"
  34. fi
  35. else
  36. echo "No A record for autoconfig.${SQL_DOMAIN} found"
  37. fi
  38. A_DISCOVER=$(dig A autodiscover.${SQL_DOMAIN} +short)
  39. if [[ ! -z ${A_DISCOVER} ]]; then
  40. echo "Found A record for autodiscover.${SQL_DOMAIN}: ${A_CONFIG}"
  41. if [[ ${IPV4} == ${A_DISCOVER} ]]; then
  42. echo "Confirmed A record autodiscover.${SQL_DOMAIN}"
  43. CONFIG_DOMAINS+=("autodiscover.${SQL_DOMAIN}")
  44. else
  45. echo "Cannot match Your IP against hostname autodiscover.${SQL_DOMAIN}"
  46. fi
  47. else
  48. echo "No A record for autodiscover.${SQL_DOMAIN} found"
  49. fi
  50. done
  51. for SAN in "${ADDITIONAL_SAN_ARR[@]}"; do
  52. A_SAN=$(dig A ${SAN} +short)
  53. if [[ ! -z ${A_SAN} ]]; then
  54. echo "Found A record for ${SAN}: ${A_SAN}"
  55. if [[ ${IPV4} == ${A_SAN} ]]; then
  56. echo "Confirmed A record ${SAN}"
  57. ADDITIONAL_VALIDATED_SAN+=("${SAN}")
  58. else
  59. echo "Cannot match Your IP against hostname ${SAN}"
  60. fi
  61. else
  62. echo "No A record for ${SAN} found"
  63. fi
  64. done
  65. acme-client \
  66. -v -e -b -N -n \
  67. -f ${ACME_BASE}/acme/private/account.key \
  68. -k ${ACME_BASE}/acme/private/privkey.pem \
  69. -c ${ACME_BASE}/acme \
  70. ${MAILCOW_HOSTNAME} ${CONFIG_DOMAINS[*]} ${ADDITIONAL_VALIDATED_SAN[*]}
  71. case "$?" in
  72. 0) # new certs
  73. # cp the new certificates and keys
  74. cp ${ACME_BASE}/acme/fullchain.pem ${ACME_BASE}/cert.pem
  75. cp ${ACME_BASE}/acme/private/privkey.pem ${ACME_BASE}/key.pem
  76. # restart docker containers
  77. restart_containers ${CONTAINERS_RESTART}
  78. ;;
  79. 1) # failure
  80. exit 1;;
  81. 2) # no change
  82. ;;
  83. *) # unspecified
  84. exit 1;;
  85. esac
  86. echo "ACME certificate validation done. Sleeping for another day."
  87. sleep 86400
  88. done