跳转到内容
STAGING SERVER
DEVELOPMENT SERVER

Smart blaze REST API 参考#

本主题介绍 Smart blaze 相机提供的 REST API。

REST API 可用于控制虚拟机 (VM)。它允许您从命令行或使用自定义脚本管理虚拟机的生命周期、上传镜像以及配置网络设置。

所有 API 端点均可通过相机的 IP 地址访问:

http://${cameraip}

信息

将 ${cameraip} 替换为您相机的实际 IP 地址。

身份验证#

Smart blaze REST API 使用基于会话的身份验证和质询-响应(challenge-response)机制来防止未授权访问。默认密码对每台相机而言都是唯一的,并打印在相机上的标签上。

所有 API 端点(除 /login外)都需要通过会话 Cookie 进行身份验证。身份验证包含三个步骤:

  1. 获取登录质询 通过向以下地址发送 GET 请求 /login
  2. 计算质询响应,使用质询中的随机数(nonce)
  3. 提交质询响应以完成身份验证

获取登录质询#

端点: /login

方法: GET

响应:包含隐藏表单字段中随机数的 HTML 页面

计算质询响应#

必须按如下方式计算质询响应:

response = SHA256(nonce + ":" + SHA256(password))

其中:

  • nonce 是来自登录质询的值。
  • password 是您的纯文本密码。
  • SHA256 会生成一个小写十六进制字符串。

示例(使用 shell):

# Get the nonce from the login page
NONCE=$(curl -s http://${cameraip}/login | grep -oP 'id="challenge-nonce"[^>]*value="\K[^"]+')

# Your password
PASSWORD="blaze-oh-yeah"

# Compute password hash
PASSWORD_HASH=$(echo -n "$PASSWORD" | sha256sum | awk '{print $1}')

# Compute challenge response
RESPONSE=$(echo -n "${NONCE}:${PASSWORD_HASH}" | sha256sum | awk '{print $1}')

提交质询响应#

端点: /login

方法: POST

Content-Type: application/x-www-form-urlencoded

参数:

参数 键入 必需 描述
challenge_response 字符串 是 计算出的质询响应(SHA256 十六进制字符串)

响应:成功时重定向到主页。失败时返回带有错误的登录页面。

示例:

curl -c cookies.txt -b cookies.txt -X POST http://${cameraip}/login \
  -d "challenge_response=${RESPONSE}"

身份验证成功后,在所有后续 API 请求中包含会话 Cookie:

# Using curl with cookie file
curl -b cookies.txt -X POST http://${cameraip}/vm/restart

完整认证示例#

以下是一个完整的 shell 脚本示例:

#!/bin/bash

CAMERA_IP="192.168.1.123"
PASSWORD="blaze-oh-yeah"

# Get login challenge
echo "Getting login challenge..."
NONCE=$(curl -s -c cookies.txt http://${CAMERA_IP}/login | \
    grep -oP 'id="challenge-nonce"[^>]*value="\K[^"]+')

if [ -z "$NONCE" ]; then
    echo "Failed to get login challenge"
    exit 1
fi

# Compute challenge response
PASSWORD_HASH=$(echo -n "$PASSWORD" | sha256sum | awk '{print $1}')
RESPONSE=$(echo -n "${NONCE}:${PASSWORD_HASH}" | sha256sum | awk '{print $1}')

# Login
echo "Logging in..."
curl -s -b cookies.txt -c cookies.txt -X POST http://${CAMERA_IP}/login \
    -d "challenge_response=${RESPONSE}" > /dev/null

# Now you can make authenticated API calls
echo "Making authenticated API call..."
curl -b cookies.txt -X POST http://${CAMERA_IP}/vm/restart

echo "Done"

安全功能#

  • 质询-响应身份验证: 防止在网络上传输密码。
  • 速率限制: 对登录失败的尝试进行速率限制,以防范暴力破解攻击。
  • 会话安全:
    • HTTP-only Cookie(无法通过 JavaScript 访问)
    • SameSite=Strict Cookie 策略
    • 60 秒质询超时
  • 密码存储: 密码仅以 SHA256 哈希值形式存储。

用户可以通过 Web 界面设置自定义密码。

会话注销#

若要注销并清除会话:

端点: /logout

方法: POST

curl -b cookies.txt -X POST http://${cameraip}/logout

API 端点#

信息

下面列出的所有端点都需要身份验证。您必须首先使用 /login 端点进行身份验证,并在请求中包含会话 Cookie。有关详细信息,请参阅 身份验证 小节。

为简便起见,以下示例展示了未包含身份验证步骤的 API 调用。在实际操作中,请在身份验证后在您的 -b cookies.txt curl 命令中包含

用于虚拟机控制的 API 调用#

重启虚拟机#

重启虚拟机。

端点: /vm/restart

方法: POST

响应: 重定向至主页

示例:

curl -X POST http://${cameraip}/vm/restart

启动虚拟机#

启动虚拟机。

端点: /vm/start

方法: POST

响应: 重定向至主页

示例:

curl -X POST http://${cameraip}/vm/start

停止虚拟机#

停止虚拟机。

端点: /vm/stop

方法: POST

响应: 重定向至主页

示例:

curl -X POST http://${cameraip}/vm/stop

用于虚拟机配置的 API 调用#

配置 IP 设置#

配置虚拟机的网络设置(DHCP 或静态 IP)。

端点: /vm/ip

方法: POST

Content-Type: application/x-www-form-urlencoded

参数:

参数 键入 必需 描述
mode 字符串 是 网络模式: "DHCP" 或 "Manual"
address 字符串 条件 带有 CIDR 表示法的 IP 地址(例如: "192.168.1.127/24")。当 mode 的值为 "Manual".
gateway 字符串 无 网关 IP 地址(例如: "192.168.1.1")。留空则表示省略。
dns0 字符串 无 主 DNS 服务器地址(例如: "8.8.8.8")。留空则表示省略。
dns1 字符串 无 备用 DNS 服务器地址。留空则表示省略。

响应: 重定向至主页

信息

该端点会临时停止虚拟机以应用网络配置更改。

示例:配置静态 IP#
curl -X POST http://${cameraip}/vm/ip \
  -d "mode=Manual" \
  -d "address=192.168.1.127/24" \
  -d "gateway=192.168.1.1" \
  -d "dns0=8.8.8.8" \
  -d "dns1=8.8.4.4"
示例:启用 DHCP#
curl -X POST http://${cameraip}/vm/ip \
  -d "mode=DHCP" \
  -d "address=192.168.1.127/24" \
  -d "gateway=" \
  -d "dns0=" \
  -d "dns1="

更新虚拟机设置#

配置虚拟机行为设置。

端点: /vm/settings

方法: POST

Content-Type: application/x-www-form-urlencoded

参数:

参数 键入 必需 描述
wait_console 字符串 无 启用控制台等待模式: "on" 或 "true"。省略或使用任何其他值则表示禁用。

响应: 重定向至主页

示例:

curl -X POST http://${cameraip}/vm/settings \
  -d "wait_console=on"

镜像管理#

列出可用镜像#

列出所有已安装的虚拟机镜像及其活动状态和大小。

端点: /vm/images

方法: GET

响应:镜像对象的 JSON 数组

响应字段:

字段 键入 描述
name 字符串 镜像名称
is_active Boolean 指示该镜像当前是否处于活动状态。
size 字符串 镜像的磁盘大小(人类可读格式,例如: "1.2G")

示例:

curl http://${cameraip}/vm/images

响应:

[
  {"name": "debian-arm64-min", "is_active": true, "size": "1.2G"},
  {"name": "custom-app", "is_active": false, "size": "2.4G"}
]

检查虚拟机镜像上传#

在传输归档文件之前,检查是否可以上传虚拟机镜像。这会使用与上传端点相同的检查机制来验证文件名、.tar.gz 扩展名、镜像名称、覆盖限制以及可用存储空间。

端点: /vm/check_image_uploadable

方法: POST

Content-Type: application/json

请求字段:

字段 键入 必需 描述
filename 字符串 是 归档文件的名称,包含 .tar.gz 扩展名
size Integer 是 归档文件大小(以字节为单位)
overwrite Boolean 无 允许替换现有的非活动镜像。默认值: false

成功响应:

{
  "success": true,
  "image_name": "debian-arm64-8GB"
}

如果存在同名的非活动镜像且 overwrite 的值为 false:

{
  "success": false,
  "error": "Image 'debian-arm64-8GB' already exists.",
  "needs_confirmation": true
}

其他验证失败将返回:

{
  "success": false,
  "error": "Error message"
}

示例:

curl -X POST http://${cameraip}/vm/check_image_uploadable \
  -H "Content-Type: application/json" \
  -d '{"filename":"debian-arm64-8GB.tar.gz","size":2147483648,"overwrite":false}'

信息

成功的检查并不会预留镜像名称或存储空间。上传端点会重复这些检查。只有在上传归档后,才能验证归档内容和文件类型。

上传虚拟机镜像#

上传新的 VM 镜像归档。该归档应包含 rootfs 和内核文件。

端点: /vm/image

方法: POST

Content-Type: multipart/form-data

参数:

参数 键入 必需 描述
file 文件 是 VM 镜像归档(.tar.gz 格式)
overwrite 查询 无 设置为 "true" 用于覆盖同名的现有镜像。默认值: "false"
set_active 查询 无 设置为 "true" 用于立即激活上传的镜像(VM 将重新启动)。设置为 "false" 用于上传但不激活。默认值: "true"

支持的归档内容:

上传的归档必须包含以下内容:

  • rootfs 文件: rootfs.qcow2, rootfs.img或 rootfs.raw
  • 内核文件: kernel

有关详细信息,请参阅 VM 镜像结构。

响应:JSON

成功响应:

{
  "success": true
}

错误响应:

{
  "success": false,
  "error": "Error message"
}
{
  "success": false,
  "error": "Image 'image-name' already exists.",
  "needs_confirmation": true
}
{
  "success": false,
  "error": "Cannot overwrite the active image: image-name"
}

信息

当 set_active=true (默认),此端点会在上传和激活过程中暂时停止 VM。当 set_active=false时,仅上传并存储镜像,而不影响正在运行的 VM。

示例:上传并激活新镜像(默认)#
curl -F "file=@debian-arm64-8GB.tar.gz" http://${cameraip}/vm/image

响应:

{"success":true}
示例:上传但不激活#
curl -F "file=@debian-arm64-8GB.tar.gz" "http://${cameraip}/vm/image?set_active=false"

响应:

{"success":true}
示例:上传失败(镜像已存在)#
curl -F "file=@debian-arm64-8GB.tar.gz" http://${cameraip}/vm/image

响应:

{"error":"Image 'debian-arm64-8GB' already exists.","needs_confirmation":true,"success":false}
示例:覆盖现有镜像并激活#
curl -F "file=@debian-arm64-8GB.tar.gz" "http://${cameraip}/vm/image?overwrite=true"
示例:覆盖现有镜像且不激活#
curl -F "file=@debian-arm64-8GB.tar.gz" "http://${cameraip}/vm/image?overwrite=true&set_active=false"

选择活动镜像#

将活动的 VM 镜像更改为其他已安装的镜像。

端点: /vm/select_image

方法: POST

Content-Type: application/x-www-form-urlencoded

参数:

参数 键入 必需 描述
image_name 字符串 是 要激活的镜像名称

响应: 重定向至主页

信息

此端点会暂时停止 VM 以切换活动的镜像。

示例:

curl -X POST http://${cameraip}/vm/select_image \
  -d "image_name=debian-arm64-8GB"

删除虚拟机镜像#

删除已安装的 VM 镜像。

端点: /vm/delete_image

方法: POST

Content-Type: application/x-www-form-urlencoded

参数:

参数 键入 必需 描述
image_name 字符串 是 要删除的图像名称

响应: 重定向至主页

信息

无法删除当前处于活动状态的图像。请先选择另一个图像。

示例:

curl -X POST http://${cameraip}/vm/delete_image \
  -d "image_name=old-image"

重命名虚拟机镜像#

重命名已安装的 VM 图像。

端点: /vm/rename_image

方法: POST

Content-Type: application/x-www-form-urlencoded

参数:

参数 键入 必需 描述
old_image_name 字符串 是 图像的当前名称
new_image_name 字符串 是 图像的新名称

响应: 重定向至主页

信息

如果您正在重命名活动图像,此端点将临时停止 VM。

示例:

curl -X POST http://${cameraip}/vm/rename_image \
  -d "old_image_name=debian-arm64-8GB" \
  -d "new_image_name=my-custom-vm"

系统维护#

恢复出厂设置#

将 VM 重置为出厂默认设置。这会删除所有自定义 VM 图像、恢复原始 rootfs 和内核并重置 VM 配置。

端点: /vm/factory_reset

方法: POST

响应:JSON

成功响应:

{
  "success": true
}

错误响应:

{
  "success": false,
  "error": "Error message"
}

信息

此端点将临时停止 VM 并删除所有用户数据。请谨慎使用!

示例:

curl -X POST http://${cameraip}/vm/factory_reset

响应:

{"success":true}

错误处理#

返回 JSON 的 API 端点包含一个 success 字段:

  • true:操作成功完成。
  • false:操作失败。请检查 error 字段以获取详细信息。

某些错误响应可能包含其他字段:

  • needs_confirmation:如果操作需要明确确认(例如覆盖现有图像),则设置为 true 。

常见用例#

上传并激活自定义虚拟机镜像#

#!/bin/bash

CAMERA_IP="192.168.1.123"
PASSWORD="blaze-oh-yeah"  # Replace with your camera's password
IMAGE_FILE="my-custom-vm.tar.gz"

# Authenticate
NONCE=$(curl -s -c cookies.txt http://${CAMERA_IP}/login | \
    grep -oP 'id="challenge-nonce"[^>]*value="\K[^"]+')
PASSWORD_HASH=$(echo -n "$PASSWORD" | sha256sum | awk '{print $1}')
RESPONSE=$(echo -n "${NONCE}:${PASSWORD_HASH}" | sha256sum | awk '{print $1}')
curl -s -b cookies.txt -c cookies.txt -X POST http://${CAMERA_IP}/login \
    -d "challenge_response=${RESPONSE}" > /dev/null

# Upload and activate the image archive (default behavior)
RESULT=$(curl -b cookies.txt -F "file=@${IMAGE_FILE}" http://${CAMERA_IP}/vm/image)
echo "$RESULT"

# The VM will automatically restart with the new image

上传虚拟机镜像而不激活它#

#!/bin/bash

CAMERA_IP="192.168.1.123"
PASSWORD="blaze-oh-yeah"  # Replace with your camera's password
IMAGE_FILE="backup-vm.tar.gz"

# Authenticate (authentication code omitted for brevity, see above)

# Upload the image without activating it (VM keeps running)
RESULT=$(curl -b cookies.txt -F "file=@${IMAGE_FILE}" \
    "http://${CAMERA_IP}/vm/image?set_active=false")
echo "$RESULT"

# The image is now stored but not active. You can activate it later using /vm/select_image

在已安装的镜像之间切换#

# Authenticate (see above for full authentication example)
# Then select a different image
curl -b cookies.txt -X POST http://${cameraip}/vm/select_image \
    -d "image_name=debian-arm64-base"

为直接连接配置静态 IP#

# Authenticate first, then configure network
curl -b cookies.txt -X POST http://${cameraip}/vm/ip \
  -d "mode=Manual" \
  -d "address=192.168.1.200/24" \
  -d "gateway=192.168.1.1" \
  -d "dns0=8.8.8.8" \
  -d "dns1="

自动化虚拟机镜像部署#

#!/bin/bash

CAMERA_IP="192.168.1.123"
PASSWORD="blaze-oh-yeah"  # Replace with your camera's password
IMAGE_FILE="production-vm.tar.gz"

# Function to authenticate
authenticate() {
    echo "Authenticating..."
    NONCE=$(curl -s -c cookies.txt http://${CAMERA_IP}/login | \
        grep -oP 'id="challenge-nonce"[^>]*value="\K[^"]+')

    if [ -z "$NONCE" ]; then
        echo "Failed to get login challenge"
        return 1
    fi

    PASSWORD_HASH=$(echo -n "$PASSWORD" | sha256sum | awk '{print $1}')
    RESPONSE=$(echo -n "${NONCE}:${PASSWORD_HASH}" | sha256sum | awk '{print $1}')

    curl -s -b cookies.txt -c cookies.txt -X POST http://${CAMERA_IP}/login \
        -d "challenge_response=${RESPONSE}" > /dev/null

    return 0
}

# Authenticate
if ! authenticate; then
    echo "Authentication failed"
    exit 1
fi

# Upload VM image without activating it
echo "Uploading VM image to camera..."
RESPONSE=$(curl -s -b cookies.txt -F "file=@${IMAGE_FILE}" \
    "http://${CAMERA_IP}/vm/image?set_active=false")

if echo "$RESPONSE" | grep -q '"success":true'; then
    echo "Upload successful!"
else
    echo "Upload failed:"
    echo "$RESPONSE"
    exit 1
fi

# Activate the uploaded image
echo "Activating new VM image..."
IMAGE_NAME="${IMAGE_FILE%.tar.gz}"
curl -s -b cookies.txt -X POST http://${CAMERA_IP}/vm/select_image \
    -d "image_name=${IMAGE_NAME}"

echo "VM is restarting with new image."

信息

此脚本可以从具有相机网络访问权限的任何系统运行,包括从 VM 内部运行。当从 VM 运行该脚本时,它会上传一个新图像,并且 VM 将在激活后使用新图像重新启动。这允许 VM 自我更新。

虚拟机控制 Web 界面#

如需进行交互式管理,请访问 Smart blaze VM Control Web 界面:

xdg-open http://${cameraip}

Web 界面为以下任务提供图形用户界面:

  • 查看 VM 状态
  • 控制 VM 生命周期(启动/停止/重新启动)
  • 配置网络设置
  • 上传和管理 VM 图像
  • 监视磁盘使用情况
  • 修改密码

信息

Web 界面使用与 REST API 相同的身份验证机制。

更多信息#

  • 有关初始设置和配置的信息,请参阅 入门指南。