远程调用脚本并校验MD5的安全方案
当需要通过 curl 远程调用并运行脚本时,同时需要校验脚本的完整性(MD5校验),以下是几种安全实现方式:
方法1:下载脚本后校验MD5再执行
#!/bin/bash
SCRIPT_URL="https://example.com/script.sh"
EXPECTED_MD5="d41d8cd98f00b204e9800998ecf8427e" # 替换为正确的MD5值
# 下载脚本
TEMP_SCRIPT=$(mktemp)
curl -fsSL "$SCRIPT_URL" -o "$TEMP_SCRIPT" || { echo "下载失败"; exit 1; }
# 计算MD5校验和
ACTUAL_MD5=$(md5sum "$TEMP_SCRIPT" | awk '{print $1}')
# 校验
if [ "$EXPECTED_MD5" != "$ACTUAL_MD5" ]; then
echo "MD5校验失败!预期: $EXPECTED_MD5,实际: $ACTUAL_MD5"
rm -f "$TEMP_SCRIPT"
exit 1
fi
# 执行脚本
chmod +x "$TEMP_SCRIPT"
"$TEMP_SCRIPT"
rm -f "$TEMP_SCRIPT"
方法2:直接管道传输并校验(较不安全)
EXPECTED_MD5="d41d8cd98f00b204e9800998ecf8427e"
SCRIPT_URL="https://example.com/script.sh"
# 下载、校验并执行(不推荐,存在竞态条件)
curl -fsSL "$SCRIPT_URL" | {
tee >(md5sum > /tmp/script.md5) | \
if [ "$(cat /tmp/script.md5 | awk '{print $1}')" = "$EXPECTED_MD5" ]; then
bash
else
echo "MD5校验失败"
exit 1
fi
}
方法3:使用更安全的SHA校验(推荐)
#!/bin/bash
SCRIPT_URL="https://example.com/script.sh"
EXPECTED_SHA256="aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f"
TEMP_SCRIPT=$(mktemp)
curl -fsSL "$SCRIPT_URL" -o "$TEMP_SCRIPT" || { echo "下载失败"; exit 1; }
# 计算SHA256
ACTUAL_SHA256=$(sha256sum "$TEMP_SCRIPT" | awk '{print $1}')
if [ "$EXPECTED_SHA256" != "$ACTUAL_SHA256" ]; then
echo "SHA256校验失败!预期: $EXPECTED_SHA256,实际: $ACTUAL_SHA256"
rm -f "$TEMP_SCRIPT"
exit 1
fi
chmod +x "$TEMP_SCRIPT"
"$TEMP_SCRIPT"
rm -f "$TEMP_SCRIPT"
安全建议
- 优先使用SHA256:MD5已被证明不安全,建议使用SHA256或SHA512
- 使用HTTPS:确保下载链接是HTTPS而非HTTP
- 临时文件处理:使用
mktemp创建临时文件,执行后立即删除 - 考虑使用GPG签名:比单纯的哈希校验更安全
- 避免直接管道执行:方法2存在安全隐患,不推荐生产环境使用
GPG签名验证方案(最安全)
#!/bin/bash
SCRIPT_URL="https://example.com/script.sh"
SIG_URL="https://example.com/script.sh.sig"
GPG_KEY_URL="https://example.com/public.key"
# 下载脚本和签名
TEMP_SCRIPT=$(mktemp)
TEMP_SIG=$(mktemp)
TEMP_KEY=$(mktemp)
curl -fsSL "$SCRIPT_URL" -o "$TEMP_SCRIPT"
curl -fsSL "$SIG_URL" -o "$TEMP_SIG"
curl -fsSL "$GPG_KEY_URL" -o "$TEMP_KEY"
# 导入GPG密钥
gpg --import "$TEMP_KEY"
# 验证签名
if gpg --verify "$TEMP_SIG" "$TEMP_SCRIPT"; then
chmod +x "$TEMP_SCRIPT"
"$TEMP_SCRIPT"
else
echo "GPG签名验证失败!"
fi
# 清理
rm -f "$TEMP_SCRIPT" "$TEMP_SIG" "$TEMP_KEY"
选择哪种方案取决于您的安全需求,对于关键系统,建议使用GPG签名验证方式。
文档更新时间: 2025-07-11 00:01 作者:月影鹏鹏