使用 1Panel 内置 API 配合计划任务,实现面板自动更新,支持开启 MFA 认证及安全入口。
风险警告:不论是手动还是自动更新,都存在更新失败或出现问题的风险,请确保自身有解决问题的能力。
一、注意事项
在 “面板设置” - “面板”,设置 “服务器地址”(必做,多数情况设置为公网 IP 地址)
在 “面板设置” - “面板”,将 “默认网卡” 设置为 “所有”(可选,排错的时候或许可以解决问题)
在 “面板设置” - “安全”,将 “监听地址” 设置为 “0.0.0.0”(可选,排错的时候或许可以解决问题)
若已开启 MFA 认证,但没有保存密钥,请关闭 “两步验证” 后重新生成,密钥显示位置,如下图所示
二、安装 OATH Tool 软件包(启用 MFA 时必做)
如果面板启用 MFA 认证,则需要在系统安装 oathtool
软件包,并且在脚本设置 MFA 密钥
# Debian
sudo apt -y install oathtool
# CentOS (具体使用 dnf 还是 yum 根据自己使用的发行版决定)
sudo dnf -y install oathtool
sudo yum -y install oathtool
三、创建计划任务
任务类型:
Shell脚本
任务名称:根据自己喜好,自行决定。
执行周期:根据需求和自己解决问题的能力,自行决定,喜欢折腾也不必太频繁,每周或每月一次就够了
脚本内容:复制下方的脚本(记得填写面板密码和 MFA 密钥,如果遇到问题,根据实际情况自行调整代码)
保留份数:保留日志的数量,通常留 1 个月就够了,自行决定
四、自动更新脚本
一般来讲只需要设置PASSWORD
和MFA_SECRET
就可以用了,但毕竟每个人的环境各不相同,本人仅测试了开启 MFA 和安全入口、且服务器地址和监听地址均为公网 IP 的情况,如果遇到问题,请自行调整代码~
#!/bin/bash
PASSWORD="XXXXXXXXXXXXXXXXXXXXXXXXXX" # 1Panel 面板密码
MFA_SECRET="XXXXXXXXXXXXXXXXXXXXXXXXXX" # MFA 密钥
DEBUG=false # 显示调试信息
# 输出调试信息
debug() {
if [ "$(echo "$DEBUG" | tr '[:upper:]' '[:lower:]')" = "true" ]; then
echo -e "$1"
fi
}
# 检查 OATH Tool 安装情况
if [ -n "$MFA_SECRET" ] && ! command -v oathtool &> /dev/null; then
echo "[错误] 请在系统中安装 oathtool 后重试"
exit 1
fi
if [ -z "$PASSWORD" ]; then
echo "[错误] 请在脚本的 PASSWORD 变量中正确填写 1Panel 面板的登录密码"
exit 1
fi
# 获取 1Panel 面板地址及用户名
USER_INFO=$(1pctl user-info)
debug "[调试] 执行 1pctl user-info 输出的信息:\n$USER_INFO"
if echo "$USER_INFO" | grep -q "Panel address:"; then
BASE_URL=$(echo "$USER_INFO" | grep "Panel address:" | awk '{print $3}')
USERNAME=$(echo "$USER_INFO" | grep "Panel user:" | awk '{print $3}')
else
BASE_URL=$(echo "$USER_INFO" | grep "面板地址:" | awk '{print $2}')
USERNAME=$(echo "$USER_INFO" | grep "面板用户:" | awk '{print $2}')
fi
debug "[调试] 经过处理的信息:"
echo "[信息] 面板地址: $BASE_URL"
echo "[信息] 面板用户: $USERNAME"
ENTRANCECODE=""
# 处理安全入口
if echo "$BASE_URL" | grep -q "^[^/]*//[^/]*/"; then
ENTRANCECODE=$(echo "$BASE_URL" | sed -E 's#^[^/]*//[^/]*/([^/]+).*#\1#')
BASE_URL=$(echo "$BASE_URL" | sed -E 's#^(([^/]*/+){3})[^/]+.*#\1#' | sed 's:/$::')
fi
echo "[信息] 基本地址: $BASE_URL"
echo "[信息] 安全入口: $ENTRANCECODE"
ENTRANCECODE=$(echo -n "$ENTRANCECODE" | base64)
debug "[调试] 安全入口(Base64): $ENTRANCECODE"
if [ -z "$BASE_URL" ] || [ -z "$USERNAME" ]; then
echo "[错误] 无法获取面板地址或用户名,请检查 1pctl 命令是否可用"
exit 1
fi
COOKIE_FILE=$(mktemp)
debug "[调试] 临时文件(Cookie): $COOKIE_FILE"
# 设置 MFA 密钥时生成 TOTP 验证码
if [ -n "$MFA_SECRET" ]; then
MFA_CODE=$(oathtool --totp -b "$MFA_SECRET")
echo "[信息] 使用的 MFA 验证码(TOTP):$MFA_CODE"
# 使用 MFA 登录
LOGIN_RESPONSE=$(curl -k -s --location --request POST "$BASE_URL/api/v1/auth/mfalogin" \
--header "entrancecode: $ENTRANCECODE" \
--data-raw '{
"name": "'"$USERNAME"'",
"password": "'"$PASSWORD"'",
"secret": "",
"code": "'"$MFA_CODE"'",
"authMethod": "session"
}' --cookie-jar $COOKIE_FILE)
else
# 常规登录方式
LOGIN_RESPONSE=$(curl -k -s --location --request POST "$BASE_URL/api/v1/auth/login" \
--header "entrancecode: $ENTRANCECODE" \
--data-raw '{
"authMethod": "session",
"captcha": "",
"captchaID": "",
"ignoreCaptcha": true,
"language": "zh",
"name": "'"$USERNAME"'",
"password": "'"$PASSWORD"'"
}' --cookie-jar $COOKIE_FILE)
fi
debug "[调试] 完整登录响应: $LOGIN_RESPONSE"
CODE=$(echo "$LOGIN_RESPONSE" | grep -o '"code":[0-9]*' | awk -F':' '{print $2}')
echo "[信息] 登录响应代码: $CODE"
if [ "$CODE" != "200" ]; then
echo "[错误] 登录失败,请检查 MFA 密钥和验证码或面板密码是否正确"
rm $COOKIE_FILE -f
exit 1
fi
# 检查面板更新
UPGRADE_RESPONSE=$(curl -k -s --request GET "$BASE_URL/api/v1/settings/upgrade" --cookie $COOKIE_FILE \
--header "entrancecode: $ENTRANCECODE")
debug "[调试] 完整版本检查响应: $UPGRADE_RESPONSE"
CODE=$(echo "$UPGRADE_RESPONSE" | grep -o '"code":[0-9]*' | awk -F':' '{print $2}')
TEST_VERSION=$(echo "$UPGRADE_RESPONSE" | grep -o '"testVersion":"[^"]*' | sed 's/"testVersion":"//')
NEW_VERSION=$(echo "$UPGRADE_RESPONSE" | grep -o '"newVersion":"[^"]*' | sed 's/"newVersion":"//')
LATEST_VERSION=$(echo "$UPGRADE_RESPONSE" | grep -o '"latestVersion":"[^"]*' | sed 's/"latestVersion":"//')
echo "[信息] 版本检查响应代码: $CODE"
if [ "$CODE" == "200" ]; then
if [ -n "$TEST_VERSION" ]; then
VERSION_TO_UPDATE="$TEST_VERSION"
echo "[信息] 测试版本: $TEST_VERSION"
elif [ -n "$LATEST_VERSION" ]; then
VERSION_TO_UPDATE="$LATEST_VERSION"
echo "[信息] 最新版本: $LATEST_VERSION"
elif [ -n "$NEW_VERSION" ]; then
VERSION_TO_UPDATE="$NEW_VERSION"
echo "[信息] 更新版本: $NEW_VERSION"
else
echo "[信息] 当前已是最新版本"
rm $COOKIE_FILE -f
exit 0
fi
echo "[信息] 检测到新版本($VERSION_TO_UPDATE),即将进行升级..."
UPDATE_RESPONSE=$(curl -k -s --location --request POST "$BASE_URL/api/v1/settings/upgrade" \
--header "entrancecode: $ENTRANCECODE" \
--data-raw '{
"version": "'"$VERSION_TO_UPDATE"'"
}' --cookie $COOKIE_FILE)
UPDATE_CODE=$(echo "$UPDATE_RESPONSE" | grep -o '"code":[0-9]*' | awk -F':' '{print $2}')
echo "[信息] 版本检查响应: $UPDATE_RESPONSE"
echo "[信息] 版本检查响应代码: $UPDATE_CODE"
if [ "$UPDATE_CODE" == "200" ]; then
echo "[信息] 面板更新完毕"
else
echo "[错误] 面板更新失败"
fi
else
echo "[错误] 检查更新失败"
fi
rm -f $COOKIE_FILE
此脚本参考 https://bbs.fit2cloud.com/t/topic/9241 根据本人需求进行了一些调整,在此感谢原作者的分享,各位可以根据自身需求参考本帖和原版来调整出适合自己的版本。
调整内容:
支持 1pctl 命令英文输出(由于我的环境 1pctl 输出是英文的,直接使用原贴的代码,首先遇到了无法获取面板地址和用户名的问题,所以增加了一些判断)
移除了将面板地址转换为环回地址的步骤(可能是由于我在面板设置中,指定了默认网卡或监听地址,所以127.0.0.1无法访问面板)
添加 调试信息 选项(显示详细输出,方便定位错误)
调整 输出消息 格式(有一点点强迫症,看起来稍微整齐一些)
评论