从环境变量传递证书到 curl
Passing certs to curl from an environment variable
我正在为我的应用程序开发 CORS 监视器,需要执行以下操作:
- 从我们的 Hashicorp Vault 实例下载证书
- 使用这些证书卷曲端点
- 评估响应
我目前可以这样做:
vault kv get -field crt my/cert/path/CACERT > CACERT.crt
vault kv get -field crt my/cert/path/TESTCERT > CERT.crt
vault kv get -field key my/cert/path/TESTCERT > KEY.key
curl -v\
--cacert CACERAT.crt \
--cert CERT.crt \
--key KEY.key \
--location \
--request GET 'https://my.end.point'
# <evaluate here>
rm CACERT.crt CERT.crt KEY.key
虽然这可行,但我宁愿不将证书写入文件,而是将它们保存在内存中,例如使用环境变量或一些我不知道的 bash-ism .
在我看来它看起来更像这样:
CACERT=$(vault kv get -field crt my/cert/path/CACERT)
CERT=$(vault kv get -field crt my/cert/path/TESTCERT)
KEY=$(vault kv get -field key my/cert/path/TESTCERT)
curl -v\
--cacert $CACERT \
--cert $CERT \
--key $KEY \
--location \
--request GET 'https://my.end.point'
# <evaluate here>
显然这行不通,因为 curl 需要文件路径,但出于说明目的,这可能吗?如果可能的话,这是一个糟糕的方法吗?也许还有另一种我没有考虑过的方法来解决这个问题?我知道我可以相对容易地使用 python 完成上述操作,但是如果可能的话,我更愿意坚持使用 bash + curl。
只有 POSIX shell,可以用显式创建的命名管道替换进程替换。
后台任务将不同的密钥和证书流式传输到它们的专用命名管道。
#!/usr/bin/env sh
# These are the randomly named pipes
cacert_pipe=$(mktemp -u)
cert_pipe=$(mktemp -u)
key_pipe=$(mktemp -u)
# Remove the named pipes on exit
trap 'rm -f -- "$cacert_pipe" "$cert_pipe" "$key_pipe"' EXIT
# Create the named pipes
mkfifo -- "$cacert_pipe" "$cert_pipe" "$key_pipe" || exit 1
# Start background shells to stream data to the respective named pipes
vault kv get -field crt my/cert/path/CACERT >"$cacert_pipe" &
vault kv get -field crt my/cert/path/TESTCERT >"$cert_pipe" &
vault kv get -field key my/cert/path/TESTCERT >"$key_pipe" &
curl -v\
--cacert "$cacert_pipe" \
--cert "$cert_pipe" \
--key "$key_pipe" \
--location \
--request GET 'https://example.com/my.end.point'
与Bash的进程替换方法相比的缺点是;在使用命名管道作为文件参数调用 curl
之前,需要明确地重新启动流式传输任务。
Bash 使用 <(cmd)
语法支持 process substitution。这会导致 cmd
的输出被替换为文件名。这允许您将命令输出作为参数传递给需要文件名的地方。
在你的例子中,你会做这样的事情:
CACERT=$(vault kv get -field crt my/cert/path/CACERT)
CERT=$(vault kv get -field crt my/cert/path/TESTCERT)
KEY=$(vault kv get -field key my/cert/path/TESTCERT)
curl -v \
--cacert <(echo "$CACERT") \
--cert <(echo "$CERT") \
--key <(echo "$KEY") \
--location \
--request GET 'https://my.end.point'
我正在为我的应用程序开发 CORS 监视器,需要执行以下操作:
- 从我们的 Hashicorp Vault 实例下载证书
- 使用这些证书卷曲端点
- 评估响应
我目前可以这样做:
vault kv get -field crt my/cert/path/CACERT > CACERT.crt
vault kv get -field crt my/cert/path/TESTCERT > CERT.crt
vault kv get -field key my/cert/path/TESTCERT > KEY.key
curl -v\
--cacert CACERAT.crt \
--cert CERT.crt \
--key KEY.key \
--location \
--request GET 'https://my.end.point'
# <evaluate here>
rm CACERT.crt CERT.crt KEY.key
虽然这可行,但我宁愿不将证书写入文件,而是将它们保存在内存中,例如使用环境变量或一些我不知道的 bash-ism .
在我看来它看起来更像这样:
CACERT=$(vault kv get -field crt my/cert/path/CACERT)
CERT=$(vault kv get -field crt my/cert/path/TESTCERT)
KEY=$(vault kv get -field key my/cert/path/TESTCERT)
curl -v\
--cacert $CACERT \
--cert $CERT \
--key $KEY \
--location \
--request GET 'https://my.end.point'
# <evaluate here>
显然这行不通,因为 curl 需要文件路径,但出于说明目的,这可能吗?如果可能的话,这是一个糟糕的方法吗?也许还有另一种我没有考虑过的方法来解决这个问题?我知道我可以相对容易地使用 python 完成上述操作,但是如果可能的话,我更愿意坚持使用 bash + curl。
只有 POSIX shell,可以用显式创建的命名管道替换进程替换。
后台任务将不同的密钥和证书流式传输到它们的专用命名管道。
#!/usr/bin/env sh
# These are the randomly named pipes
cacert_pipe=$(mktemp -u)
cert_pipe=$(mktemp -u)
key_pipe=$(mktemp -u)
# Remove the named pipes on exit
trap 'rm -f -- "$cacert_pipe" "$cert_pipe" "$key_pipe"' EXIT
# Create the named pipes
mkfifo -- "$cacert_pipe" "$cert_pipe" "$key_pipe" || exit 1
# Start background shells to stream data to the respective named pipes
vault kv get -field crt my/cert/path/CACERT >"$cacert_pipe" &
vault kv get -field crt my/cert/path/TESTCERT >"$cert_pipe" &
vault kv get -field key my/cert/path/TESTCERT >"$key_pipe" &
curl -v\
--cacert "$cacert_pipe" \
--cert "$cert_pipe" \
--key "$key_pipe" \
--location \
--request GET 'https://example.com/my.end.point'
与Bash的进程替换方法相比的缺点是;在使用命名管道作为文件参数调用 curl
之前,需要明确地重新启动流式传输任务。
Bash 使用 <(cmd)
语法支持 process substitution。这会导致 cmd
的输出被替换为文件名。这允许您将命令输出作为参数传递给需要文件名的地方。
在你的例子中,你会做这样的事情:
CACERT=$(vault kv get -field crt my/cert/path/CACERT)
CERT=$(vault kv get -field crt my/cert/path/TESTCERT)
KEY=$(vault kv get -field key my/cert/path/TESTCERT)
curl -v \
--cacert <(echo "$CACERT") \
--cert <(echo "$CERT") \
--key <(echo "$KEY") \
--location \
--request GET 'https://my.end.point'