You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
4.8 KiB

  1. #!/bin/bash
  2. #Here is a sample custom api script.
  3. #This file name is "myapi.sh"
  4. #So, here must be a method myapi_deploy()
  5. #Which will be called by acme.sh to deploy the cert
  6. #returns 0 means success, otherwise error.
  7. ######## Public functions #####################
  8. #domain keyfile certfile cafile fullchain
  9. s3_deploy() {
  10. _cdomain="$1"
  11. _ckey="$2"
  12. _ccert="$3"
  13. _cca="$4"
  14. _cfullchain="$5"
  15. if [ -z "$S3_BUCKET" ] ; then
  16. _err "You haven't specified the bucket name yet."
  17. _err "Please set it via export and try again."
  18. _err "e.g. export S3_BUCKET=acme"
  19. return 1
  20. fi
  21. if ! _exists aws; then
  22. _debug "AWS CLI not installed, defaulting to curl method"
  23. _aws_cli_installed=0
  24. else
  25. _debug "AWS CLI installed, defaulting ignoring curl method"
  26. _aws_cli_installed=1
  27. fi
  28. if [ "$_aws_cli_installed" -eq "0" ] && ([ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]); then
  29. _err "AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY not set."
  30. _err "Please set them via export, or use the aws-cli."
  31. return 1
  32. fi
  33. if [ -z "$S3_REGION" ]; then
  34. S3_REGION="us-east-1"
  35. fi
  36. # Save s3 options if it's succesful (First run case)
  37. _saveaccountconf S3_BUCKET "$S3_BUCKET"
  38. _saveaccountconf S3_REGION "$S3_REGION"
  39. _debug _cdomain "$_cdomain"
  40. _debug _ckey "$_ckey"
  41. _debug _ccert "$_ccert"
  42. _debug _cca "$_cca"
  43. _debug _cfullchain "$_cfullchain"
  44. _debug S3_BUCKET "$S3_BUCKET"
  45. _secure_debug AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID"
  46. _secure_debug AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY"
  47. _info "Deploying certificate to s3 bucket: $S3_BUCKET in $S3_REGION"
  48. if [ "$_aws_cli_installed" -eq "0" ]; then
  49. _debug "deploying with curl method"
  50. else
  51. _debug "deploying with aws cli method"
  52. fi
  53. # private
  54. _deploy_to_bucket $_ckey "$_cdomain/$_cdomain.key"
  55. # public
  56. _deploy_to_bucket $_ccert "$_cdomain/$_cdomain.cer"
  57. # ca
  58. _deploy_to_bucket $_cca "$_cdomain/ca.cer"
  59. # fullchain
  60. _deploy_to_bucket $_cfullchain "$_cdomain/fullchain.cer"
  61. return 0
  62. }
  63. #################### Private functions below ##################################
  64. _deploy_to_bucket() {
  65. if [ "$_aws_cli_installed" -eq "0" ]; then
  66. _deploy_with_curl $1 $2
  67. else
  68. _deploy_with_awscli $1 $2
  69. fi
  70. }
  71. _deploy_with_awscli() {
  72. file="$1"
  73. bucket="$S3_BUCKET"
  74. prefix="$2"
  75. region="$S3_REGION"
  76. aws s3 cp "$file" s3://"$bucket"/"$prefix" --region "$region"
  77. }
  78. _deploy_with_curl() {
  79. file="${1}"
  80. bucket="${S3_BUCKET}"
  81. prefix="${2}"
  82. region="${S3_REGION}"
  83. acl="private"
  84. timestamp="$(date -u "+%Y-%m-%d %H:%M:%S")"
  85. signed_headers="date;host;x-amz-acl;x-amz-content-sha256;x-amz-date"
  86. if [[ $(uname) == "Darwin" ]]; then
  87. iso_timestamp=$(date -ujf "%Y-%m-%d %H:%M:%S" "${timestamp}" "+%Y%m%dT%H%M%SZ")
  88. date_scope=$(date -ujf "%Y-%m-%d %H:%M:%S" "${timestamp}" "+%Y%m%d")
  89. date_header=$(date -ujf "%Y-%m-%d %H:%M:%S" "${timestamp}" "+%a, %d %h %Y %T %Z")
  90. else
  91. iso_timestamp=$(date -ud "${timestamp}" "+%Y%m%dT%H%M%SZ")
  92. date_scope=$(date -ud "${timestamp}" "+%Y%m%d")
  93. date_header=$(date -ud "${timestamp}" "+%a, %d %h %Y %T %Z")
  94. fi
  95. _info "Uploading $S3_BUCKET/$prefix"
  96. export _H1="Authorization: AWS4-HMAC-SHA256 Credential=${AWS_ACCESS_KEY_ID}/${date_scope}/${region}/s3/aws4_request,SignedHeaders=${signed_headers},Signature=$(_signature)"
  97. export _H2="Date:${date_header}"
  98. export _H3="x-amz-acl:${acl}"
  99. export _H4="x-amz-content-sha256:$(_payload_hash)"
  100. export _H5="x-amz-date:${iso_timestamp}"
  101. response=$(_post "${file}" "https://${bucket}.s3.${region}.amazonaws.com/${prefix}")
  102. _debug response
  103. }
  104. _payload_hash() {
  105. hash_output=$(shasum -ba 256 "$file")
  106. echo "${hash_output%% *}"
  107. }
  108. _canonical_request() {
  109. echo "PUT"
  110. echo "/${prefix}"
  111. echo ""
  112. echo "date:${date_header}"
  113. echo "host:${bucket}.s3.${region}.amazonaws.com"
  114. echo "x-amz-acl:${acl}"
  115. echo "x-amz-content-sha256:$(_payload_hash)"
  116. echo "x-amz-date:${iso_timestamp}"
  117. echo ""
  118. echo "${signed_headers}"
  119. printf "$(_payload_hash)"
  120. }
  121. _canonical_request_hash() {
  122. _canonical_request_output=$(_canonical_request | shasum -a 256)
  123. echo "${_canonical_request_output%% *}"
  124. }
  125. _string_to_sign() {
  126. echo "AWS4-HMAC-SHA256"
  127. echo "${iso_timestamp}"
  128. echo "${date_scope}/${region}/s3/aws4_request"
  129. printf "$(_canonical_request_hash)"
  130. }
  131. _signature_key() {
  132. secret_key=$(printf "AWS4${AWS_SECRET_ACCESS_KEY?}" | _hex_dump | tr -d " ")
  133. date_key=$(printf ${date_scope} | _hmac "sha256" "${secret_key}" | _hex_dump | tr -d " ")
  134. region_key=$(printf ${region} | _hmac "sha256" "${date_key}" | _hex_dump | tr -d " ")
  135. service_key=$(printf "s3" | _hmac "sha256" "${region_key}" | _hex_dump | tr -d " ")
  136. printf "aws4_request" | _hmac "sha256" "${service_key}" | _hex_dump | tr -d " "
  137. }
  138. _signature() {
  139. _string_to_sign | _hmac "sha256" $(_signature_key) | _hex_dump | tr -d " " | sed "s/^.* //"
  140. }