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.

184 lines
5.0 KiB

  1. #!/bin/bash
  2. #Here is the script to deploy the cert to your s3 bucket.
  3. #export S3_BUCKET=acme
  4. #export S3_REGION=eu-central-1
  5. #export AWS_ACCESS_KEY_ID=exampleid
  6. #export AWS_SECRET_ACCESS_KEY=examplekey
  7. # Checks to see if awscli present
  8. # If not, use curl + aws v4 signature to upload object
  9. # Make sure your keys have access to upload objects.
  10. # Also make sure your default region is correct, otherwise, override with $S3_REGION
  11. ######## Public functions #####################
  12. #domain keyfile certfile cafile fullchain
  13. s3_deploy() {
  14. _cdomain="$1"
  15. _ckey="$2"
  16. _ccert="$3"
  17. _cca="$4"
  18. _cfullchain="$5"
  19. if [ -z "$S3_BUCKET" ] ; then
  20. _err "You haven't specified the bucket name yet."
  21. _err "Please set it via export and try again."
  22. _err "e.g. export S3_BUCKET=acme"
  23. return 1
  24. fi
  25. if ! command -v aws; then
  26. _debug "AWS CLI not installed, defaulting to curl method"
  27. _aws_cli_installed=0
  28. else
  29. _debug "AWS CLI installed, defaulting ignoring curl method"
  30. _aws_cli_installed=1
  31. fi
  32. if [ "$_aws_cli_installed" -eq "0" ] && ([ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]); then
  33. _err "AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY not set."
  34. _err "Please set them via export, or use the aws-cli."
  35. return 1
  36. fi
  37. if [ -z "$S3_REGION" ]; then
  38. S3_REGION="us-east-1"
  39. fi
  40. # Save s3 options if it's succesful (First run case)
  41. _saveaccountconf S3_BUCKET "$S3_BUCKET"
  42. _saveaccountconf S3_REGION "$S3_REGION"
  43. _debug _cdomain "$_cdomain"
  44. _debug _ckey "$_ckey"
  45. _debug _ccert "$_ccert"
  46. _debug _cca "$_cca"
  47. _debug _cfullchain "$_cfullchain"
  48. _debug S3_BUCKET "$S3_BUCKET"
  49. _debug AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID"
  50. _debug AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY"
  51. _info "Deploying certificate to s3 bucket: $S3_BUCKET in $S3_REGION"
  52. if [ "$_aws_cli_installed" -eq "0" ]; then
  53. _debug "deploying with curl method"
  54. else
  55. _debug "deploying with aws cli method"
  56. fi
  57. # private
  58. _deploy_to_bucket $_ckey "$_cdomain/$_cdomain.key"
  59. # public
  60. _deploy_to_bucket $_ccert "$_cdomain/$_cdomain.cer"
  61. # ca
  62. _deploy_to_bucket $_cca "$_cdomain/ca.cer"
  63. # fullchain
  64. _deploy_to_bucket $_cfullchain "$_cdomain/fullchain.cer"
  65. return 0
  66. }
  67. #################### Private functions below ##################################
  68. _deploy_to_bucket() {
  69. if [ "$_aws_cli_installed" -eq "0" ]; then
  70. _deploy_with_curl $1 $2
  71. else
  72. _deploy_with_awscli $1 $2
  73. fi
  74. }
  75. _deploy_with_awscli() {
  76. file="$1"
  77. bucket="$S3_BUCKET"
  78. prefix="$2"
  79. region="$S3_REGION"
  80. aws s3 cp "$file" s3://"$bucket"/"$prefix" --region "$region"
  81. }
  82. _deploy_with_curl() {
  83. file="${1}"
  84. bucket="${S3_BUCKET}"
  85. prefix="${2}"
  86. region="${S3_REGION}"
  87. acl="private"
  88. timestamp="$(date -u "+%Y-%m-%d %H:%M:%S")"
  89. signed_headers="date;host;x-amz-acl;x-amz-content-sha256;x-amz-date"
  90. if [[ $(uname) == "Darwin" ]]; then
  91. iso_timestamp=$(date -ujf "%Y-%m-%d %H:%M:%S" "${timestamp}" "+%Y%m%dT%H%M%SZ")
  92. date_scope=$(date -ujf "%Y-%m-%d %H:%M:%S" "${timestamp}" "+%Y%m%d")
  93. date_header=$(date -ujf "%Y-%m-%d %H:%M:%S" "${timestamp}" "+%a, %d %h %Y %T %Z")
  94. else
  95. iso_timestamp=$(date -ud "${timestamp}" "+%Y%m%dT%H%M%SZ")
  96. date_scope=$(date -ud "${timestamp}" "+%Y%m%d")
  97. date_header=$(date -ud "${timestamp}" "+%a, %d %h %Y %T %Z")
  98. fi
  99. _info "Uploading $S3_BUCKET/$prefix"
  100. curl \
  101. -T "${file}" \
  102. -H "Authorization: AWS4-HMAC-SHA256 Credential=${AWS_ACCESS_KEY_ID}/${date_scope}/${region}/s3/aws4_request,SignedHeaders=${signed_headers},Signature=$(_signature)" \
  103. -H "Date:${date_header}" \
  104. -H "x-amz-acl:${acl}" \
  105. -H "x-amz-content-sha256:$(_payload_hash)" \
  106. -H "x-amz-date:${iso_timestamp}" \
  107. "https://${bucket}.s3.${region}.amazonaws.com/${prefix}"
  108. }
  109. _payload_hash() {
  110. local output=$(shasum -ba 256 "$file")
  111. echo "${output%% *}"
  112. }
  113. _canonical_request() {
  114. echo "PUT"
  115. echo "/${prefix}"
  116. echo ""
  117. echo "date:${date_header}"
  118. echo "host:${bucket}.s3.${region}.amazonaws.com"
  119. echo "x-amz-acl:${acl}"
  120. echo "x-amz-content-sha256:$(_payload_hash)"
  121. echo "x-amz-date:${iso_timestamp}"
  122. echo ""
  123. echo "${signed_headers}"
  124. printf "$(_payload_hash)"
  125. }
  126. _canonical_request_hash() {
  127. local output=$(_canonical_request | shasum -a 256)
  128. echo "${output%% *}"
  129. }
  130. _string_to_sign() {
  131. echo "AWS4-HMAC-SHA256"
  132. echo "${iso_timestamp}"
  133. echo "${date_scope}/${region}/s3/aws4_request"
  134. printf "$(_canonical_request_hash)"
  135. }
  136. _signature_key() {
  137. local secret=$(printf "AWS4${AWS_SECRET_ACCESS_KEY?}" | _hex_key)
  138. local date_key=$(printf ${date_scope} | _hmac_sha256 "${secret}" | _hex_key)
  139. local region_key=$(printf ${region} | _hmac_sha256 "${date_key}" | _hex_key)
  140. local service_key=$(printf "s3" | _hmac_sha256 "${region_key}" | _hex_key)
  141. printf "aws4_request" | _hmac_sha256 "${service_key}" | _hex_key
  142. }
  143. _hex_key() {
  144. hexdump -ve '1/1 "%.2x"'; echo
  145. }
  146. _hmac_sha256() {
  147. local hexkey=$1
  148. openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:${hexkey}
  149. }
  150. _signature() {
  151. _string_to_sign | _hmac_sha256 $(_signature_key) | _hex_key | sed "s/^.* //"
  152. }