宝塔面板宝塔 API 怎么用

域名注册
域名注册 正式会员超兽战士 👑年卡会员
发布于 2026-10-07 04:19 ·2 浏览 ·0 回复

学完这篇你能自己开启宝塔面板的 API、算出签名、用 curl 和 Python 调通接口,把建站、查状态这些操作接到自己的脚本或运维系统里。

第一步:开启 API 接口并拿到密钥

这一步要做什么:在面板里把 API 开关打开,拿到密钥和接口文档地址,这是后面所有调用的前提。

登录宝塔面板(默认地址 http://你的服务器IP:8888,Linux 版 9.x 界面略有差异但路径一致),点左侧菜单最下方的「面板设置」,切到「API 接口」这一栏。把「API 接口」的开关从关闭切成开启。开启后页面会出现两个关键信息:

  • 接口密钥:一串 32 位字符串,相当于密码
  • IP 白名单:填调用方服务器的公网 IP

注意:白名单不填等于允许所有 IP 调用,非常危险。如果调用方是本机,填 127.0.0.1;如果是另一台服务器,必须填它的公网出口 IP,而不是内网 IP。

同页面往下拉有「接口文档」链接,也可以直接访问 http://你的IP:8888/api.html,里面列了所有可用接口和参数。

第二步:搞懂签名规则

这一步要做什么:明白宝塔 API 的身份校验怎么算,不然请求会一直返回 签名校验失败。

宝塔不用 Bearer Token,而是用「时间戳 + 两层 MD5」的方式:

request_token = md5(request_time + md5(api_key))

拆开看就是:

  1. 先对接口密钥做一次 MD5,得到 32 位小写字符串
  2. 把这个结果拼在时间戳 request_time 后面
  3. 整体再做一次 MD5,结果就是 request_token

request_time 是 Unix 时间戳(秒),必须和服务器时间相差不大,默认允许 3 小时。所以服务器时间不准会直接导致 401 类报错。

注意:两个 MD5 都是小写十六进制,不要用大写,也不要去掉前导零。

第三步:用 curl 调通第一个接口

这一步要做什么:用最原始的命令行方式验证签名对不对,成功就能看到服务器负载数据。

以「获取系统基础信息」为例,接口是 POST /system?action=GetSystemTotal:

API_KEY="你在面板里复制的那串密钥"
HOST="http://你的服务器IP:8888"
RT=$(date +%s)
TOKEN=$(echo -n "${RT}$(echo -n "$API_KEY" | md5sum | cut -d' ' -f1)" | md5sum | cut -d' ' -f1)

curl -s -X POST "${HOST}/system?action=GetSystemTotal" \
  -d "request_time=${RT}" \
  -d "request_token=${TOKEN}"

返回类似:

{"cpuNum":2,"memTotal":3882,"memFree":1024,"system":"CentOS 7","version":"9.2.0"}

看到这段 JSON 就说明签名和网络都通了。

注意:macOS 的 md5sum 不存在,要换成 md5 -q;写脚本时推荐直接用 Python,跨平台省事。

第四步:用 Python 封装成函数

这一步要做什么:把签名逻辑封成一个可复用的类,之后换接口只改 URL 和参数。

import hashlib, time, requests

class BtApi:
    def __init__(self, host, key):
        self.host = host.rstrip('/')
        self.key = key

    def _token(self, rt):
        k = hashlib.md5(self.key.encode()).hexdigest()
        return hashlib.md5((str(rt) + k).encode()).hexdigest()

    def call(self, path, data=None):
        rt = int(time.time())
        payload = {'request_time': rt, 'request_token': self._token(rt)}
        if data:
            payload.update(data)
        url = f"{self.host}/{path}"
        r = requests.post(url, data=payload, timeout=15, verify=False)
        return r.json()

bt = BtApi('http://你的IP:8888', '你的接口密钥')
print(bt.call('system?action=GetSystemTotal'))
print(bt.call('site?action=GetSiteList', {'p': 1, 'limit': 20}))

site?action=GetSiteList 会在 data 字段里返回所有站点列表;files?action=GetDir&path=/www/wwwroot 可以列目录;data?action=getData&table=sites 能查数据库列表。

注意:AddSite、DeleteSite、DeleteFile 这类写操作接口一调就生效,没有二次确认,测试时一定用不重要的服务器。

第五步:常见坑排查

  • 返回「IP 校验失败」:白名单里的 IP 和实际出口 IP 不一致。用 curl ifconfig.me 在调用机上确认。
  • 返回「签名错误」:九成是时间戳单位用成了毫秒,宝塔要秒。
  • 接口文档打不开:面板安全组只开了 8888,但没开 888,或者你访问的路径写成了 /api.html 之外的形式。
  • 生产环境:把 HTTP 换成面板 SSL 后的 HTTPS,端口也会变成 https://IP:8888,证书是自签的,请求时要关掉证书校验。

小结

  1. 开启路径固定在「面板设置 → API 接口」,密钥和白名单必须同时配好。
  2. 签名公式是 md5(request_time + md5(api_key)),全部小写,时间戳用秒。
  3. 所有接口用 POST,公共参数放在请求体里,业务参数直接拼接。
  4. 先用 curl 验证通,再用 Python 封装,排查成本最低。
  5. 写操作接口无确认、即调即生效,务必先在测试机验证。
版权声明:本文来自 GJ论坛《宝塔面板宝塔 API 怎么用》
原文链接:https://www.gj0.com/thread-62.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~