-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(deploy_ali_cdn): support Alibaba Cloud CDN deployment #5205
Conversation
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" | ||
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" | ||
if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then | ||
Ali_Key="" | ||
Ali_Secret="" | ||
_err "You don't specify aliyun api key and secret yet." | ||
return 1 | ||
fi | ||
|
||
#save the api key and secret to the account conf file. | ||
_saveaccountconf_mutable Ali_Key "$Ali_Key" | ||
_saveaccountconf_mutable Ali_Secret "$Ali_Secret" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy from
Lines 13 to 24 in 377a37e
Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" | |
Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" | |
if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then | |
Ali_Key="" | |
Ali_Secret="" | |
_err "You don't specify aliyun api key and secret yet." | |
return 1 | |
fi | |
#save the api key and secret to the account conf file. | |
_saveaccountconf_mutable Ali_Key "$Ali_Key" | |
_saveaccountconf_mutable Ali_Secret "$Ali_Secret" |
# stdin stdout | ||
_url_encode_upper() { | ||
encoded=$(_url_encode) | ||
|
||
for match in $(echo "$encoded" | _egrep_o '%..' | sort -u); do | ||
upper=$(echo "$match" | _upper_case) | ||
encoded=$(echo "$encoded" | sed "s/$match/$upper/g") | ||
done | ||
|
||
echo "$encoded" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alibaba Cloud API signature needs parameters encoded in upper-case.
_url_encode
function from acme.sh
can only encode with lower-case.
We have an ali_urlencode
function from dns_ali.sh
but it does not support multi-line strings.
Maybe we can add an argument to _url_encode
function to make it support upper-case? (it only needs a very simple change in the *)
case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 884 to 887 in 0d8a314
#other hex | |
*) | |
printf '%%%s' "$_hex_code" | |
;; |
Can we change it to:
*)
case "$1" in
'[uU]*') # for upper-case
printf '%%%s' "$_hex_code" | _upper_case
;;
*) # default to lower-case
printf '%%%s' "$_hex_code"
;;
esac
;;
_ali_urlencode() { | ||
_str="$1" | ||
_str_len=${#_str} | ||
_u_i=1 | ||
while [ "$_u_i" -le "$_str_len" ]; do | ||
_str_c="$(printf "%s" "$_str" | cut -c "$_u_i")" | ||
case $_str_c in [a-zA-Z0-9.~_-]) | ||
printf "%s" "$_str_c" | ||
;; | ||
*) | ||
printf "%%%02X" "'$_str_c" | ||
;; | ||
esac | ||
_u_i="$(_math "$_u_i" + 1)" | ||
done | ||
} | ||
|
||
_ali_nonce() { | ||
#_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31 | ||
#Not so good... | ||
date +"%s%N" | sed 's/%N//g' | ||
} | ||
|
||
_timestamp() { | ||
date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# act ign mtd | ||
_ali_rest() { | ||
act="$1" | ||
ign="$2" | ||
mtd="$3" | ||
|
||
signature=$(printf "%s" "$mtd&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) | ||
signature=$(_ali_urlencode "$signature") | ||
url="$Ali_API?$query&Signature=$signature" | ||
|
||
if [ "$mtd" = "GET" ]; then | ||
response="$(_get "$url")" | ||
else | ||
# post payload is not supported yet because of signature | ||
response="$(_post "" "$url")" | ||
fi | ||
|
||
_ret="$?" | ||
_debug2 response "$response" | ||
if [ "$_ret" != "0" ]; then | ||
_err "Error <$act>" | ||
return 1 | ||
fi | ||
|
||
if [ -z "$ign" ]; then | ||
message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" | ||
if [ "$message" ]; then | ||
_err "$message" | ||
return 1 | ||
fi | ||
fi | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reference https://github.com/acmesh-official/acme.sh/blob/3.0.7/dnsapi/dns_ali.sh
However, the original method was hard coded with the GET
method.
So, I made a new argument to specify the method.
Notice that Alibaba Cloud API supports passing the parameters by either query or body. (https://help.aliyun.com/zh/sdk/product-overview/rpc-mechanism#section-9x3-wo3-8l9)
But we must sign with all the parameters, in alphabetical order, regardless of where they come from.
So, I didn't support the post-payload yet.
Solve #1461 |
How to use this deploy script? |
For example:
or using docker:
|
Hope this PR merged ASAP. |
Great job man, thanks a lot. <3 |
@PMExtra Can DCDN be supported? Thanks. Great job. 是否可以支持DCDN? |
@ShirasawaSama 目前没有支持,但只要把这一行代码的 Line 145 in 945b7de
|
@ShirasawaSama 哦,还漏了API版本,一共改两处,一个是 Lines 142 to 157 in 945b7de
|
@PMExtra 可以试试这个接口 https://api.aliyun.com/document/cas/2020-04-07/UploadUserCertificate ,阿里云主要的云产品基本都支持使用证书中心管理证书,cdn/dcdn/oss/slb/alb/clb ,相比较各个产品各自管各自的证书,不如用证书中心统一管理 |
@anjia0532 我认为这样是增加了复杂性,各个产品自己的接口还是需要调用,只是在调用接口的时候,传递一个证书payload,还是传递一个cas id的区别而已。既然都用acme接管证书管理了,就没必要再去用cas。 |
|
||
# stdin stdout | ||
_url_encode_upper() { | ||
encoded=$(_url_encode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
能不能把 encoded 直接全部 _upper_case 一下 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
不可以,原始输入是 base64 ,要区分大小写的。
阿里云要求是特殊字符转义的 %XX
必须是大写的 HEX ,否则签名验证通不过。
但不能把 base64 给全转成大写。
其实就是为了处理 +
, /
, =
和 \n
字符对应的转义,其余字符必须保持原样。
确实cas增加了复杂性,但是好处是 1. 可以付费使用部署功能(支持部署到腾讯云,aws,华为云,以及阿里云自身云产品),2. 操作主动吊销泄露的证书更方便。3. 方便删除过期证书。 4. 支持从cas下载证书(具体产品里的证书不支持下载) 当然分开写确实更小而美一些。 |
|
Dose it support muti-domains? I found it is said that:
And, there is an API that supports muti-domains: |
I haven't tested it yet. |
It supports multiple domains by a loop. It will call the Line 57 in 945b7de
|
@PMExtra 现在如果需要使用dcdn的话还是需要手动复制一份脚本吗?是否考虑过添加环境变量的形式区分是否为dcdn或者是正常cdn?又或者说再加一个ali_dcdn.sh脚本? Now if I need to use dcdn, do I still need to copy the script manually? Have you considered adding an environment variable to determine if it's a dcdn deployment or a normal cdn? Or maybe adding another ali_dcdn.sh script? |
考虑到可能有人同时需要 CDN 和 DCDN ,所以直接通过环境变量进行区分的方式可能不太合适。 而直接复制一份 我个人希望抽出一个 除了阿里,包括 awscn / 腾讯云 / 华为云 等等,也都有不止一个服务有证书需求,也都有各自的dnsapi,而其中有大量可以复用的函数。 请问 @Neilpang 对此有什么想法? |
@PMExtra 想法不错. 如果只是有些方法可以直接复用. 可以考虑直接 把对应的文件 source 进来. 可以使用 |
问题好像和 对于特定的一个 deployhook 或者 dnsapi ,它需要哪个服务商的API这是确定的,可以直接用硬编码的相对路径引入。 例如 这样以后加入 我现在是需要您评估一下,在acme的顶层目录结构新增一个 |
不要直接写死相对路径. 用 加个libs变动有点大, 内部倒是问题不大, 但是很多第三方环境都集成了acme.sh, 他们可能已经假定了顶层的目录样子. 单加一个目录他们都需要更新安装脚本. 工作量有点大. 如果不更新, 以前工作的hook 可能就不工作了. 比如, 你把很多函数都抽走了. 而且, 所谓的需要公用的云服务商, 两只手都能数完. 对比起来感觉不划算. 咱们最重要的目标之一就是要尽最大努力保持兼容性, 除非外部因素变动. 不能让客户之前能工作的场景升级后爆了. 因为acme的价值和目标就是无人值守. 没有人愿意每天盯着. 简单你就source吧. 你说呢. |
没太理解,你的意思是有人会通过第三方脚本来安装和更新 对于使用常规手段进行安装和更新的用户( 对于不更新脚本的用户,我们的新feature也是不会对它有影响的。 唯一可能受影响的,就是使用非官方建议的方式更新脚本,只拉取特定文件的用户。 那么这种情况下,无论目录结构怎么样,只要新增了文件,它都有可能缺失。我认为这种超出官方支持范围,「自作聪明」做精简的行为,就理应承担相应的风险。 或者退一步,我们不对现有的 |
终极用户当然大多数都是用脚本安装的. 但是第三方环境, 例如宝塔之类的, 他们是写死路径的, 可能还要对路径设置相关权限. 他们不会用安装脚本. 既然要抽函数避免copy, 那就只保留一份. 保留已有的文件不动 dnsapi/dns_ali.sh. 其他的文件需要引用的, 就source 它. 让新增文件对旧文件保持严格单向依赖. 这样会减少很多麻烦. |
@PMExtra 除了dcdn是否还存在其他需要配置证书的场景?如oss、云建站、云函数等? |
是有这些场景的,我在上面已经描述过了。 |
我个人觉得是否提供一个 |
@ShirasawaSama 你每个服务下的域名是不一样的,而且个别服务可能需要额外的参数,这对于只使用其中一个或少数服务的人来说,会增加配置的难度。 |
这取决于 这几个文件的相似度. 如果仅仅是几个调用参数不一样, 那没问题. 如果几个服务差异比较大, 会导致 all-in-one 脚本太长, 过于复杂而不利于维护. 其中一个出了bug 没人愿意来修, 看一眼都头大. |
另外, 对于一个证书需要部署到多个服务的场景, 可以使用 多个 |
API Documents
zh-cn
en