v-add-letsencrypt-user 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #!/bin/bash
  2. # info: register letsencrypt user account
  3. # options: USER [TYPE]
  4. #
  5. # The function creates and register LetsEncript account key
  6. #----------------------------------------------------------#
  7. # Variable&Function #
  8. #----------------------------------------------------------#
  9. # Argument definition
  10. user=$1
  11. type=${2-1}
  12. key_size=4096
  13. # Includes
  14. source $VESTA/func/main.sh
  15. source $VESTA/conf/vesta.conf
  16. # encode base64
  17. encode_base64() {
  18. cat |base64 |tr '+/' '-_' |tr -d '\r\n='
  19. }
  20. #----------------------------------------------------------#
  21. # Verifications #
  22. #----------------------------------------------------------#
  23. check_args '1' "$#" 'USER [TYPE]'
  24. is_format_valid 'user'
  25. is_object_valid 'user' 'USER' "$user"
  26. if [ -e "$USER_DATA/ssl/le.conf" ]; then
  27. source "$USER_DATA/ssl/le.conf"
  28. if [ "$type" -eq 1 ] && [ ! -z "$EMAIL" ]; then
  29. exit
  30. fi
  31. if [ "$type" -eq 2 ] && [ ! -z "$KID" ]; then
  32. exit
  33. fi
  34. fi
  35. #----------------------------------------------------------#
  36. # Action #
  37. #----------------------------------------------------------#
  38. # Defining LE API endpoint
  39. if [ "$type" -eq 1 ]; then
  40. api='https://acme-v01.api.letsencrypt.org'
  41. else
  42. api='https://acme-v02.api.letsencrypt.org'
  43. fi
  44. # Defining user email
  45. if [ $type -eq 1 ]; then
  46. email=$(get_user_value '$CONTACT')
  47. fi
  48. # Defining user agreement
  49. if [ "$type" -eq 1 ]; then
  50. agreement=$(curl -s -I "$api/terms" |grep Location |\
  51. cut -f 2 -d \ |tr -d '\r\n')
  52. else
  53. #agreement=$(curl -s "$api/directory" |grep termsOfService |\
  54. # cut -f 4 -d '"')
  55. agreement=''
  56. fi
  57. # Generating user key
  58. key="$USER_DATA/ssl/user.key"
  59. if [ ! -e "$key" ]; then
  60. openssl genrsa -out $key $key_size >/dev/null 2>&1
  61. chmod 600 $key
  62. fi
  63. # Defining key exponent
  64. if [ -z "$EXPONENT" ]; then
  65. exponent=$(openssl pkey -inform pem -in "$key" -noout -text_pub |\
  66. grep Exponent: |cut -f 2 -d '(' |cut -f 1 -d ')' |sed -e 's/x//' |\
  67. xxd -r -p |encode_base64)
  68. else
  69. exponent="$EXPONENT"
  70. fi
  71. # Defining key modulus
  72. if [ -z "$MODULUS" ]; then
  73. modulus=$(openssl rsa -in "$key" -modulus -noout |\
  74. sed -e 's/^Modulus=//' |xxd -r -p |encode_base64)
  75. else
  76. modulus="$MODULUS"
  77. fi
  78. # Defining JWK token
  79. jwk='{"e":"'$exponent'","kty":"RSA","n":"'"$modulus"'"}'
  80. # Defining key thumbnail
  81. if [ -z "$THUMB" ]; then
  82. thumb="$(echo -n "$jwk" |openssl dgst -sha256 -binary |encode_base64)"
  83. else
  84. thumb="$THUMB"
  85. fi
  86. # Requesting ACME nonce
  87. nonce=$(curl -s -I "$api/directory" |grep Nonce |cut -f 2 -d \ |tr -d '\r\n')
  88. # Defining payload and protected data for v1 and v2
  89. if [ "$type" -eq 1 ]; then
  90. header='{"alg":"RS256","jwk":'"$jwk"'}'
  91. protected='{"nonce":"'"$nonce"'"}'
  92. payload='{"resource":"new-reg","contact":["mailto:'"$email"'"],'
  93. payload=$payload'"agreement":"'$agreement'"}'
  94. else
  95. protected='{"nonce": "'$nonce'",'
  96. protected=''$protected' "url": "'$api/acme/new-acct'",'
  97. protected=''$protected' "alg": "RS256", "jwk": '$jwk'}'
  98. payload='{"termsOfServiceAgreed": true}'
  99. fi
  100. # Encoding data
  101. protected=$(echo -n "$protected" |encode_base64)
  102. payload=$(echo -n "$payload" |encode_base64)
  103. # Signing request
  104. signature=$(printf "%s" "$protected.$payload" |\
  105. openssl dgst -sha256 -binary -sign "$key" |\
  106. encode_base64)
  107. if [ "$type" -eq 1 ]; then
  108. data='{"header":'"$header"',"protected":"'"$protected"'",'
  109. data=$data'"payload":"'"$payload"'","signature":"'"$signature"'"}'
  110. answer=$(curl -s -i -d "$data" "$api/acme/new-reg")
  111. status=$(echo "$answer" |grep HTTP/1.1 |tail -n1 |cut -f2 -d ' ')
  112. else
  113. data='{"protected":"'"$protected"'",'
  114. data=$data'"payload":"'"$payload"'",'
  115. data=$data'"signature":"'"$signature"'"}'
  116. answer=$(curl -s -i -d "$data" "$api/acme/new-acct" \
  117. -H "Content-Type: application/jose+json")
  118. status=$(echo "$answer" |grep HTTP/1.1 |tail -n1 |cut -f2 -d ' ')
  119. kid=$(echo "$answer" |grep Location: |cut -f2 -d ' '|tr -d '\r')
  120. fi
  121. # Checking http answer status
  122. if [[ "${status:0:2}" -ne "20" ]] && [[ "$status" -ne "409" ]]; then
  123. check_result $E_CONNECT "LetsEncrypt account registration $status"
  124. fi
  125. #----------------------------------------------------------#
  126. # Vesta #
  127. #----------------------------------------------------------#
  128. # Adding le.conf
  129. if [ ! -e "$USER_DATA/ssl/le.conf" ]; then
  130. echo "EXPONENT='$exponent'" > $USER_DATA/ssl/le.conf
  131. echo "MODULUS='$modulus'" >> $USER_DATA/ssl/le.conf
  132. echo "THUMB='$thumb'" >> $USER_DATA/ssl/le.conf
  133. if [ "$type" -eq 1]; then
  134. echo "EMAIL='$email'" >> $USER_DATA/ssl/le.conf
  135. else
  136. echo "KID='$kid'" >> $USER_DATA/ssl/le.conf
  137. fi
  138. chmod 660 $USER_DATA/ssl/le.conf
  139. else
  140. if [ "$type" -eq 1 ]; then
  141. sed -i '/^EMAIL=/d' $USER_DATA/ssl/le.conf
  142. echo "EMAIL='$email'" >> $USER_DATA/ssl/le.conf
  143. else
  144. sed -i '/^KID=/d' $USER_DATA/ssl/le.conf
  145. echo "KID='$kid'" >> $USER_DATA/ssl/le.conf
  146. fi
  147. fi
  148. # Logging
  149. log_event "$OK" "$ARGUMENTS"
  150. exit