letsencrypt_service 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/bin/bash
  2. DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
  3. seconds_to_wait=3600
  4. ACME_CA_URI="${ACME_CA_URI:-https://acme-v01.api.letsencrypt.org/directory}"
  5. source /app/functions.sh
  6. create_link() {
  7. local readonly target=${1?missing target argument}
  8. local readonly source=${2?missing source argument}
  9. [[ -f "$target" ]] && return 1
  10. ln -sf "$source" "$target"
  11. }
  12. create_links() {
  13. local readonly base_domain=${1?missing base_domain argument}
  14. local readonly domain=${2?missing base_domain argument}
  15. if [[ ! -f "/etc/nginx/certs/$base_domain"/fullchain.pem || \
  16. ! -f "/etc/nginx/certs/$base_domain"/key.pem ]]; then
  17. return 1
  18. fi
  19. local return_code=1
  20. create_link "/etc/nginx/certs/$domain".crt "./$base_domain"/fullchain.pem
  21. return_code=$(( $return_code & $? ))
  22. create_link "/etc/nginx/certs/$domain".key "./$base_domain"/key.pem
  23. return_code=$(( $return_code & $? ))
  24. if [[ -f "/etc/nginx/certs/dhparam.pem" ]]; then
  25. create_link "/etc/nginx/certs/$domain".dhparam.pem ./dhparam.pem
  26. return_code=$(( $return_code & $? ))
  27. fi
  28. return $return_code
  29. }
  30. update_certs() {
  31. [[ ! -f "$DIR"/letsencrypt_service_data ]] && return
  32. # Load relevant container settings
  33. unset LETSENCRYPT_CONTAINERS
  34. source "$DIR"/letsencrypt_service_data
  35. reload_nginx='false'
  36. for cid in "${LETSENCRYPT_CONTAINERS[@]}"; do
  37. # Derive host and email variable names
  38. host_varname="LETSENCRYPT_${cid}_HOST"
  39. # Array variable indirection hack: http://stackoverflow.com/a/25880676/350221
  40. hosts_array=$host_varname[@]
  41. email_varname="LETSENCRYPT_${cid}_EMAIL"
  42. test_certificate_varname="LETSENCRYPT_${cid}_TEST"
  43. create_test_certificate=false
  44. if [[ $(lc "${!test_certificate_varname:-}") == true ]]; then
  45. create_test_certificate=true
  46. fi
  47. params_d_str=""
  48. [[ $DEBUG == true ]] && params_d_str+=" -v"
  49. hosts_array_expanded=("${!hosts_array}")
  50. # First domain will be our base domain
  51. base_domain="${hosts_array_expanded[0]}"
  52. if [[ "$create_test_certificate" == true ]]; then
  53. # Use staging acme end point
  54. acme_ca_uri="https://acme-staging.api.letsencrypt.org/directory"
  55. if [[ ! -f /etc/nginx/certs/.${base_domain}.test ]]; then
  56. # Remove old certificates
  57. rm -rf /etc/nginx/certs/${base_domain}
  58. for domain in "${!hosts_array}"; do
  59. rm -f /etc/nginx/certs/$domain.{crt,key,dhparam.pem}
  60. done
  61. touch /etc/nginx/certs/.${base_domain}.test
  62. fi
  63. else
  64. acme_ca_uri="$ACME_CA_URI"
  65. if [[ -f /etc/nginx/certs/.${base_domain}.test ]]; then
  66. # Remove old test certificates
  67. rm -rf /etc/nginx/certs/${base_domain}
  68. for domain in "${!hosts_array}"; do
  69. rm -f /etc/nginx/certs/$domain.{crt,key,dhparam.pem}
  70. done
  71. rm -f /etc/nginx/certs/.${base_domain}.test
  72. fi
  73. fi
  74. # Create directory for the first domain
  75. mkdir -p /etc/nginx/certs/$base_domain
  76. cd /etc/nginx/certs/$base_domain
  77. for domain in "${!hosts_array}"; do
  78. # Add all the domains to certificate
  79. params_d_str+=" -d $domain"
  80. # Add location configuration for the domain
  81. add_location_configuration "$domain" || reload_nginx
  82. done
  83. echo "Creating/renewal $base_domain certificates... (${hosts_array_expanded[*]})"
  84. /usr/bin/simp_le \
  85. -f account_key.json -f key.pem -f fullchain.pem -f cert.pem \
  86. --tos_sha256 6373439b9f29d67a5cd4d18cbc7f264809342dbf21cb2ba2fc7588df987a6221 \
  87. $params_d_str \
  88. --email "${!email_varname}" \
  89. --server=$acme_ca_uri \
  90. --default_root /usr/share/nginx/html/
  91. simp_le_return=$?
  92. for altnames in ${hosts_array_expanded[@]:1}; do
  93. # Remove old CN domain that now are altnames
  94. rm -rf /etc/nginx/certs/$altnames
  95. done
  96. for domain in "${!hosts_array}"; do
  97. create_links $base_domain $domain && reload_nginx='true'
  98. [[ $simp_le_return -eq 0 ]] && reload_nginx='true'
  99. done
  100. done
  101. [[ "$reload_nginx" == 'true' ]] && reload_nginx
  102. }
  103. pid=
  104. # Service Loop: When this script exits, start it again.
  105. trap '[[ $pid ]] && kill $pid; exec $0' EXIT
  106. trap 'trap - EXIT' INT TERM
  107. update_certs
  108. # Wait some amount of time
  109. echo "Sleep for ${seconds_to_wait}s"
  110. sleep $seconds_to_wait & pid=$!
  111. wait
  112. pid=