-
📋 配置包内容
-
+
+
选择 .tscfg 配置包文件以导入动作模板
+
-
-
-
-
-
-
-
`;
@@ -21461,7 +21788,7 @@ async function previewActionImport() {
const file = fileInput.files[0];
resultBox.classList.remove('hidden', 'success', 'error');
- resultBox.textContent = '🔄 正在验证配置包...';
+ resultBox.textContent = '正在验证配置包...';
importBtn.disabled = true;
step2.style.display = 'none';
@@ -21481,26 +21808,26 @@ async function previewActionImport() {
let html = `
| 配置 ID: | ${escapeHtml(data.id)} |
- | 类型: | ⚡ 动作模板 |
- | 签名者: | ${escapeHtml(data.signer)} ${data.official ? '✅ 官方' : ''} |
+ | 类型: | 动作模板 |
+ | 签名者: | ${escapeHtml(data.signer)} ${data.official ? '(官方)' : ''} |
| 备注: | ${escapeHtml(data.note || '重启后自动加载')} |
`;
if (data.exists) {
- html += `
⚠️ 该配置已存在,导入将覆盖现有文件
`;
+ html += `
该配置已存在,导入将覆盖现有文件
`;
}
previewDiv.innerHTML = html;
step2.style.display = 'block';
resultBox.className = 'result-box success';
- resultBox.textContent = '✅ 签名验证通过';
+ resultBox.textContent = '签名验证通过';
importBtn.disabled = false;
} else {
resultBox.className = 'result-box error';
- resultBox.textContent = '❌ ' + (result.message || '无法验证配置包');
+ resultBox.textContent = (result.message || '无法验证配置包');
}
} catch (e) {
resultBox.className = 'result-box error';
- resultBox.textContent = '❌ ' + e.message;
+ resultBox.textContent = e.message;
}
}
@@ -21515,7 +21842,7 @@ async function confirmActionImport() {
}
resultBox.classList.remove('hidden', 'success', 'error');
- resultBox.textContent = '🔄 正在保存配置...';
+ resultBox.textContent = '正在保存配置...';
importBtn.disabled = true;
try {
@@ -21531,22 +21858,22 @@ async function confirmActionImport() {
const data = result.data;
if (data?.exists && !data?.imported) {
resultBox.className = 'result-box warning';
- resultBox.textContent = `⚠️ 配置 ${data.id} 已存在,请勾选「覆盖」选项`;
+ resultBox.textContent = `配置 ${data.id} 已存在,请勾选「覆盖」选项`;
importBtn.disabled = false;
} else {
resultBox.className = 'result-box success';
- resultBox.innerHTML = `✅ 已保存配置:
${escapeHtml(data?.id)}重启系统后生效`;
+ resultBox.innerHTML = `已保存配置:
${escapeHtml(data?.id)}重启系统后生效`;
showToast(`已导入配置,重启后生效`, 'success');
setTimeout(() => hideImportActionModal(), 2000);
}
} else {
resultBox.className = 'result-box error';
- resultBox.textContent = '❌ ' + (result.message || '导入失败');
+ resultBox.textContent = (result.message || '导入失败');
importBtn.disabled = false;
}
} catch (e) {
resultBox.className = 'result-box error';
- resultBox.textContent = '❌ ' + e.message;
+ resultBox.textContent = e.message;
importBtn.disabled = false;
}
}
@@ -21573,4 +21900,3 @@ window.showImportActionModal = showImportActionModal;
window.hideImportActionModal = hideImportActionModal;
window.previewActionImport = previewActionImport;
window.confirmActionImport = confirmActionImport;
-
diff --git a/components/ts_webui/web/js/lang/en-US.js b/components/ts_webui/web/js/lang/en-US.js
index 9091d74..802229b 100644
--- a/components/ts_webui/web/js/lang/en-US.js
+++ b/components/ts_webui/web/js/lang/en-US.js
@@ -1540,24 +1540,24 @@ i18n.registerLanguage('en-US', {
genHttpsKeyPairDesc: 'Generate ECDSA P-256 key pair for mTLS authentication',
existingKeyWarning: '⚠️ Key pair already exists, continuing will overwrite!',
generate: '🔑 Generate',
- csrTitle: '📋 Certificate Signing Request (CSR)',
+ csrTitle: 'Certificate Signing Request (CSR)',
deviceId: 'Device ID (CN)',
deviceIdHint: 'Leave empty for default config',
organization: 'Organization (O)',
department: 'Department (OU)',
csrContentLabel: 'CSR Content (copy to CA server for signing)',
- installCertTitle: '📥 Install Device Certificate',
+ installCertTitle: 'Install Device Certificate',
installCertDesc: 'Paste CA-signed PEM format certificate',
certPem: 'Certificate PEM',
- install: '📥 Install',
- installCaTitle: '🏛️ Install CA Certificate Chain',
+ install: 'Install',
+ installCaTitle: 'Install CA Certificate Chain',
installCaDesc: 'Paste root and intermediate certificates (PEM format, can concatenate)',
caCertPem: 'CA Certificate Chain PEM',
deleteCredentialsTitle: '🗑️ Delete HTTPS Credentials',
deleteCredentialsDesc: 'This will delete key pair and certificate, regeneration required after',
deleteCredentialsWarning: '⚠️ Warning: Device cannot perform mTLS auth after deletion until reconfigured',
confirmDelete: '⚠️ Confirm Delete',
- viewCertTitle: '📜 View Certificate Details',
+ viewCertTitle: 'View Certificate Details',
close: 'Close',
// Config pack verification
configId: 'Config ID',
@@ -2074,7 +2074,7 @@ i18n.registerLanguage('en-US', {
presetUptime: 'Uptime',
presetLog: 'Log Stream',
// Management interface
- management: '📊 Data Monitoring Management',
+ management: 'Data Component Management',
panelSettings: '⚙️ Panel Settings',
autoRefreshInterval: 'Auto Refresh Interval',
disabled: 'Disabled',
@@ -2169,6 +2169,8 @@ i18n.registerLanguage('en-US', {
moreEffects: 'More',
stopEffect: 'Stop',
noEffects: 'No effects available',
+ effects: 'Effects',
+ selectAnimation: 'Please select an animation first',
// Modal - Effect
effectTitle: 'Programmatic Animation',
effectNotSelected: 'None',
@@ -2261,7 +2263,9 @@ i18n.registerLanguage('en-US', {
saveConfig: 'Save Config',
// Color Correction
colorCorrectionTitle: 'Color Correction',
+ ccGlobalTitle: 'Global Color Correction',
ccEnable: 'Enable Global Color Correction',
+ deviceEnable: 'Enable LED Device',
ccWhitePoint: 'White Balance (RGB Scaling)',
ccWhitePointHelp: 'Adjust RGB channels independently to correct color temperature. 1.0=neutral, <1.0=decrease, >1.0=increase',
ccGamma: 'Gamma Correction',
diff --git a/components/ts_webui/web/js/lang/zh-CN.js b/components/ts_webui/web/js/lang/zh-CN.js
index 90a8acb..27e3e5c 100644
--- a/components/ts_webui/web/js/lang/zh-CN.js
+++ b/components/ts_webui/web/js/lang/zh-CN.js
@@ -1541,24 +1541,24 @@ i18n.registerLanguage('zh-CN', {
genHttpsKeyPairDesc: '为设备生成 ECDSA P-256 密钥对,用于 mTLS 身份验证',
existingKeyWarning: '⚠️ 已存在密钥对,继续将覆盖现有密钥!',
generate: '🔑 生成',
- csrTitle: '📋 证书签名请求 (CSR)',
+ csrTitle: '证书签名请求 (CSR)',
deviceId: '设备 ID (CN)',
deviceIdHint: '留空则使用默认配置',
organization: '组织 (O)',
department: '部门 (OU)',
csrContentLabel: 'CSR 内容(复制到 CA 服务器签发)',
- installCertTitle: '📥 安装设备证书',
+ installCertTitle: '安装设备证书',
installCertDesc: '粘贴 CA 签发的 PEM 格式证书',
certPem: '证书 PEM',
- install: '📥 安装',
- installCaTitle: '🏛️ 安装 CA 证书链',
+ install: '安装',
+ installCaTitle: '安装 CA 证书链',
installCaDesc: '粘贴根证书和中间证书(PEM 格式,可拼接多个)',
caCertPem: 'CA 证书链 PEM',
deleteCredentialsTitle: '🗑️ 删除 HTTPS 凭证',
deleteCredentialsDesc: '此操作将删除密钥对和证书,删除后需要重新生成',
deleteCredentialsWarning: '⚠️ 警告:删除后设备将无法进行 mTLS 认证,直到重新配置',
confirmDelete: '⚠️ 确认删除',
- viewCertTitle: '📜 查看证书详情',
+ viewCertTitle: '查看证书详情',
close: '关闭',
// 配置包验证
configId: '配置 ID',
@@ -2075,7 +2075,7 @@ i18n.registerLanguage('zh-CN', {
presetUptime: '运行时间',
presetLog: '日志流',
// 管理界面
- management: '📊 数据监控管理',
+ management: '数据组件管理',
panelSettings: '⚙️ 面板设置',
autoRefreshInterval: '自动刷新间隔',
disabled: '禁用',
@@ -2170,6 +2170,8 @@ i18n.registerLanguage('zh-CN', {
moreEffects: '更多动画',
stopEffect: '停止',
noEffects: '暂无可用动画',
+ effects: '程序动画',
+ selectAnimation: '请先选择一个动画',
// Modal - Effect
effectTitle: '程序动画',
effectNotSelected: '未选择',
@@ -2262,7 +2264,9 @@ i18n.registerLanguage('zh-CN', {
saveConfig: '保存配置',
// 色彩校正
colorCorrectionTitle: '色彩校正',
+ ccGlobalTitle: '全局色彩校正',
ccEnable: '启用全局色彩校正',
+ deviceEnable: '启用 LED 设备',
ccWhitePoint: '白平衡 (RGB 缩放)',
ccWhitePointHelp: '独立调整 RGB 通道修正色温。默认 1.0,<1.0 减少该通道,>1.0 增强该通道',
ccGamma: 'Gamma 校正',
diff --git a/help/security-guide.en.mdx b/help/security-guide.en.mdx
index c3ecea2..1b02cf6 100644
--- a/help/security-guide.en.mdx
+++ b/help/security-guide.en.mdx
@@ -10,6 +10,7 @@ keywords:
- known host fingerprints
- HTTPS certificates
- mTLS
+ - config pack
- admin user
- operation guide
---
@@ -35,16 +36,18 @@ The **Security** page is TianshanOS’s security hub. It centralizes the followi
As an **admin user**, you can access **every feature** on the security page, including:
-- ✅ Generate, delete, and export SSH keys
-- ✅ Deploy public keys to remote servers
-- ✅ Revoke deployed public keys
-- ✅ Manage known host fingerprints
-- ✅ Generate and manage HTTPS certificates
+- Generate, delete, and export SSH keys
+- Deploy public keys to remote servers
+- Revoke deployed public keys
+- Manage known host fingerprints
+- Generate and manage HTTPS certificates
+- Manage config packs (import, export, view)
**Note**: The following pages require **root permissions** and are not accessible to admin users:
-- ❌ Terminal page
-- ❌ Automation page
-- ❌ Command page
+
+- Terminal page
+- Automation page
+- Command page
### How to Access the Security Page
@@ -55,14 +58,15 @@ As an **admin user**, you can access **every feature** on the security page, inc
### Page Layout Overview
-The security page is divided into four blocks from top to bottom:
+The security page is divided into five blocks from top to bottom:
| Block | Description |
|------|-------------|
-| **🔑 Key Management** | Generate, view, export, deploy, revoke, and delete SSH keys |
-| **🖥️ Deployed Hosts** | Manage the list of remote servers with deployed public keys; test connections, revoke keys, remove records |
-| **🔐 Known Host Fingerprints** | View and delete SSH server fingerprints to block man-in-the-middle attacks |
-| **🔒 HTTPS Certificates** | Generate device certificates/CSR, install CA-signed certificates, configure mTLS |
+| **Key Management** | Generate, view, export, deploy, revoke, and delete SSH keys |
+| **Deployed Hosts** | Manage the list of remote servers with deployed public keys; import host config; test connections, revoke keys, remove records |
+| **Known Host Fingerprints** | View and delete SSH server fingerprints to block man-in-the-middle attacks |
+| **HTTPS Certificates** | Generate device certificates/CSR, install CA-signed certificates, configure mTLS |
+| **Config Pack** | Export device certificate, import/export encrypted config packs, view config pack list for secure config distribution between devices |
---
@@ -74,29 +78,29 @@ This task covers generating SSH keys from scratch, deploying the public key to a
#### Steps
-1. **Enter the key management area**: Locate the “🔑 Key Management” block near the top of the security page.
+1. **Enter the key management area**: Locate the “Key Management” block near the top of the security page.
2. **Click the generate button**: Press **“➕ Generate New Key”**.
-3. **Fill out the creation form** in the “🔑 Generate New Key” modal:
+3. **Fill out the creation form** in the “Generate New Key” modal:
#### Form Field Details
| Field | Required | Description | Example |
|------|----------|-------------|---------|
-| **Key ID** | ✅ Yes | A unique identifier for the key, used for future reference. Allowed characters: letters, digits, underscores. Must be unique. | `default`, `agx_key`, `lpmu_prod` |
-| **Key Type** | ✅ Yes | Select the algorithm and key length. | See “Key Type Selection” below |
-| **Notes** | ❌ No | Describe the key’s purpose for easier recognition later. | `For AGX Orin connection`, `Test environment key` |
-| **Alias** | ❌ No | A friendly name displayed instead of the Key ID, useful when “hide key” is enabled. | `AGX Production`, `Main Server Key` |
-| **Allow Private Key Export** | ❌ No | When checked, the private key can be exported for backup/migration. **Security risk**: leaked private keys allow unauthorized access. | Check only when backup is needed |
-| **Hide Key ID** | ❌ No | When enabled, low-privilege users only see the alias or masked string instead of the real Key ID—useful in multi-user environments. | Enable for shared devices |
+| **Key ID** | Yes | A unique identifier for the key, used for future reference. Allowed characters: letters, digits, underscores. Must be unique. | `default`, `agx_key`, `lpmu_prod` |
+| **Key Type** | Yes | Select the algorithm and key length. | See “Key Type Selection” below |
+| **Notes** | No | Describe the key’s purpose for easier recognition later. | `For AGX Orin connection`, `Test environment key` |
+| **Alias** | No | A friendly name displayed instead of the Key ID, useful when “hide key” is enabled. | `AGX Production`, `Main Server Key` |
+| **Allow Private Key Export** | No | When checked, the private key can be exported for backup/migration. **Security risk**: leaked private keys allow unauthorized access. | Check only when backup is needed |
+| **Hide Key ID** | No | When enabled, low-privilege users only see the alias or masked string instead of the real Key ID—useful in multi-user environments. | Enable for shared devices |
#### Key Type Selection
| Type | Key Length | Generation Time | Compatibility | Recommended Use |
|------|------------|-----------------|---------------|------------------|
-| **RSA 2048-bit** | 2048 bits | 5-10 seconds | ⭐⭐⭐⭐⭐ | **Recommended** for daily use due to wide compatibility |
-| **RSA 4096-bit** | 4096 bits | 30-60 seconds | ⭐⭐⭐⭐⭐ | High-security scenarios; generation is slower |
-| **ECDSA P-256** | 256 bits | 3-5 seconds | ⭐⭐⭐ | ⚠️ **SSH public key auth not supported yet** |
-| **ECDSA P-384** | 384 bits | 3-5 seconds | ⭐⭐⭐ | ⚠️ **SSH public key auth not supported yet** |
+| **RSA 2048-bit** | 2048 bits | 5-10 seconds | High | **Recommended** for daily use due to wide compatibility |
+| **RSA 4096-bit** | 4096 bits | 30-60 seconds | High | High-security scenarios; generation is slower |
+| **ECDSA P-256** | 256 bits | 3-5 seconds | Medium | **Note**: SSH public key auth not supported yet |
+| **ECDSA P-384** | 384 bits | 3-5 seconds | Medium | **Note**: SSH public key auth not supported yet |
**Important**: ECDSA keys cannot currently be used for SSH public key authentication. Please choose **RSA 2048-bit** or **RSA 4096-bit**.
@@ -127,36 +131,36 @@ After generating a key, deploy its **public portion** to a remote Linux server s
#### Prerequisites
-- ✅ At least one key exists in the Key Management table.
-- ✅ You know the remote server’s IP address or hostname.
-- ✅ You know the remote username and password (required for first deployment).
-- ✅ Network connectivity exists between the device and the target server.
+- At least one key exists in the Key Management table.
+- You know the remote server’s IP address or hostname.
+- You know the remote username and password (required for first deployment).
+- Network connectivity exists between the device and the target server.
#### Steps
1. **Choose a key**: Pick the key row you want to deploy within the Key Management table.
-2. **Click Deploy**: Press the **“🚀 Deploy”** button (blue) on the right side of the row.
-3. **Fill the deployment form** in the “🚀 Deploy Public Key to Remote Server” modal:
+2. **Click Deploy**: Press the **“Deploy”** button (blue) on the right side of the row.
+3. **Fill the deployment form** in the “Deploy Public Key to Remote Server” modal:
#### Deployment Form Fields
| Field | Required | Description | Example |
|------|----------|-------------|---------|
-| **Target Host** | ✅ Yes | IP or hostname of the remote server. | `192.168.55.100`, `agx.local`, `10.10.99.98` |
-| **Username** | ✅ Yes | Remote login user. | `root`, `nvidia`, `ubuntu` |
-| **Port** | ❌ No | SSH port; default is 22. Change if using non-standard ports. | `22`, `2222`, `22022` |
-| **Authentication Password** | ✅ Yes | Password for the first deployment. Future logins will skip the password. | Your server’s login password |
+| **Target Host** | Yes | IP or hostname of the remote server. | `192.168.55.100`, `agx.local`, `10.10.99.98` |
+| **Username** | Yes | Remote login user. | `root`, `nvidia`, `ubuntu` |
+| **Port** | No | SSH port; default is 22. Change if using non-standard ports. | `22`, `2222`, `22022` |
+| **Authentication Password** | Yes | Password for the first deployment. Future logins will skip the password. | Your server’s login password |
-4. **Start the deployment** by clicking **“🚀 Start Deploy”**.
+4. **Start the deployment** by clicking **“Start Deploy”**.
5. **Watch the progress**: The modal shows logs including:
- Connecting to the server
- Verifying the host fingerprint (first-time connections prompt trust; see Task Three)
- Uploading the public key to `~/.ssh/authorized_keys`
- Validating deployment success
6. **Confirm success**:
- - “✅ Public key deployment succeeded”
- - “✅ Connection verification succeeded”
- - The host is automatically added to the “🖥️ Deployed Hosts” list.
+ - “Public key deployment succeeded”
+ - “Connection verification succeeded”
+ - The host is automatically added to the “Deployed Hosts” list.
#### Deployment Mechanism
@@ -184,6 +188,36 @@ The deployment performs these steps:
The Deployed Hosts block tracks remote servers where the device’s public keys are installed, making it easy to test and manage access.
+### 3.0 Import Host Config (Optional)
+
+If you deployed public keys via the terminal CLI (e.g. `ssh --copyid`) or manually, those hosts do not appear automatically in the Deployed Hosts list. You can **import host config** by uploading a .tscfg config package (e.g. exported from another device or backup). After import, the list reflects the same entries so you can test, revoke, or remove them from the WebUI.
+
+**Steps**:
+
+1. **Open the Deployed Hosts block**: On the security page, find the “Deployed Hosts” block; the **“Import Host”** button is on the right.
+2. **Click Import Host**: Click **“Import Host”** to open the “Import SSH Host Config” modal.
+3. **Select file**: Choose a local `.tscfg` config package (usually produced by “Export host config” on another device or by the config pack system).
+4. **Preview and confirm**: The system validates the package signature and shows config ID, signer, and notes; if that config already exists, you are prompted whether to overwrite.
+5. **Optional**: Check “Overwrite existing config” to replace an existing config with the same ID.
+6. **Confirm import**: Click **“Confirm Import”**; after success, refresh the page to see the new entries in the Deployed Hosts list.
+
+**Note**: The package must be a valid, signed SSH host config. Import only updates the local Deployed Hosts list; it does not change `authorized_keys` on remote servers.
+
+### 3.0.1 Export Host Config (Single Host)
+
+In the Deployed Hosts table, each host row has an **“Export”** button that exports that host’s config as an encrypted `.tscfg` file for backup or for importing on another device.
+
+**Steps**:
+
+1. **Select a host**: Find the host in the Deployed Hosts table.
+2. **Click Export**: Click the **“Export”** button (blue) on that row to open the “Export SSH Host Config” modal.
+3. **Target device certificate (optional)**:
+ - **Leave empty**: The config is encrypted with this device’s certificate (self-encrypt). The resulting .tscfg can only be decrypted on this device or one that has this device’s certificate—suitable for backup.
+ - **Paste target device certificate PEM**: To send this host config to another device, paste the certificate that the other device exported from the Config Pack block. The exported .tscfg can then be decrypted and imported only on that device.
+4. **Confirm export**: Click **“Export”**; the system generates the .tscfg and prompts for download or save path.
+
+**Typical use**: Back up a single host config, sync the same host across multiple TianshanOS devices, or use with “Import Host” when migrating between devices.
+
### 3.1 View the Deployed Hosts List
#### Column Definitions
@@ -194,14 +228,15 @@ The Deployed Hosts block tracks remote servers where the device’s public keys
| **Address** | Server IP or hostname | `192.168.55.100`, `10.10.99.98` |
| **Port** | SSH port | `22`, `2222` |
| **Username** | Remote login user | `nvidia`, `root`, `ubuntu` |
-| **Deployed Key** | Key ID used (displayed as a badge) | 🔑 `agx_key`, 🔑 `default` |
+| **Deployed Key** | Key ID used (displayed as a badge) | `agx_key`, `default` |
+| **Actions** | Buttons per row | Test, Export, Revoke, Remove (see subsections below) |
#### When the List Updates
-- ✅ Automatically adds hosts after successful WebUI deployment.
-- ✅ Removes hosts after WebUI revocation.
-- ✅ Deletes records when you click “Remove.”
-- ❌ Hosts added via CLI or manual `authorized_keys` edits do not appear.
+- Automatically adds hosts after successful WebUI deployment.
+- Removes hosts after WebUI revocation.
+- Deletes records when you click “Remove.”
+- Hosts added via CLI or manual `authorized_keys` edits do not appear; use “Import Host” to add them from a .tscfg config package.
#### Empty List Behavior
@@ -211,7 +246,10 @@ If the list shows “No deployed hosts”:
- Follow the Task 1, Section 2.2 steps to deploy a key.
- After a successful deployment, the host will automatically appear.
----
+#### Relation to the Commands Page
+
+The **Commands** page (root only) uses the same host list as “Deployed Hosts” here for its “Select host” dropdown. When exporting a command config from the Commands page, you can choose to **include the dependent host config** in the export, so that importing the command on another device also provides the host config without having to import hosts separately from the Security page.
+
---
### 2.3 Use the Key for Passwordless Login
@@ -220,14 +258,14 @@ After deployment, you can connect to the remote server without entering a passwo
#### Test the Connection via WebUI
1. **Go to the Deployed Hosts section** and find the host you just added.
-2. **Click “🔍 Test”** on that host row.
+2. **Click “Test”** on that host row.
3. **Wait for the test**: the system will
- Use the deployed key to connect
- Execute a simple command (e.g., `whoami`) to validate
- Review the output
4. **Check results**:
- - ✅ Success: displays “Connection successful” and the remote username
- - ❌ Failure: shows an error message (network issues, key mismatch, server configuration, etc.)
+ - Success: displays “Connection successful” and the remote username
+ - Failure: shows an error message (network issues, key mismatch, server configuration, etc.)
#### Use the Key from the Terminal
@@ -275,36 +313,36 @@ Revoke a key when you no longer need server access or suspect the key has been c
#### When to Revoke
- 🚫 Access is no longer required
-- 🔒 Suspected key compromise
-- 🔄 Server user changes necessitate key cleanup
-- 🧹 Routine security audits call for removing stale access
+- Suspected key compromise
+- Server user changes necessitate key cleanup
+- Routine security audits call for removing stale access
#### Method One: Revoke from Key Management
**Ideal for when you know which key and server need revocation**
1. **Pick the key** from the Key Management table.
-2. **Click “⚠️ Revoke”** (orange button).
+2. **Click “Revoke”** (orange button).
3. **Fill out the revocation form**:
| Field | Required | Description |
|-------|----------|-------------|
-| **Target Host** | ✅ Yes | Server address to remove the key from |
-| **Username** | ✅ Yes | Login user on that server |
-| **Port** | ❌ No | SSH port (default 22) |
-| **Authentication Password** | ✅ Yes | Required because the key might no longer work |
+| **Target Host** | Yes | Server address to remove the key from |
+| **Username** | Yes | Login user on that server |
+| **Port** | No | SSH port (default 22) |
+| **Authentication Password** | Yes | Required because the key might no longer work |
-4. **Confirm revocation** by clicking **“⚠️ Revoke Public Key”**.
+4. **Confirm revocation** by clicking **“Revoke Public Key”**.
5. **Review results**:
- - ✅ Shows the number of key lines removed from `authorized_keys`
- - ✅ Deletes the host record from the Deployed Hosts list
+ - Shows the number of key lines removed from `authorized_keys`
+ - Deletes the host record from the Deployed Hosts list
#### Method Two: Revoke from Deployed Hosts
**Best for quick revocation of a specific host**
-1. Go to the “🖥️ Deployed Hosts” table.
-2. Click **“🔓 Revoke”** (red button) on the target host row.
+1. Go to the “Deployed Hosts” table.
+2. Click **“Revoke”** (red button) on the target host row.
3. Enter the server password when prompted.
4. Confirm by clicking **“Revoke and Remove”**.
5. Wait as the system:
@@ -317,7 +355,7 @@ Revoke a key when you no longer need server access or suspect the key has been c
Use this when the server is offline, the key already deleted on the server, or you simply want a cleaner UI.
1. Find the host in the Deployed Hosts table.
-2. Click **“🗑️ Remove”** (gray button).
+2. Click **“Remove”** (gray button).
3. Confirm removal.
4. The host record is deleted locally; the remote `authorized_keys` is untouched.
@@ -325,8 +363,8 @@ Use this when the server is offline, the key already deleted on the server, or y
| Action | Remote Public Key | Local Record | Password Required | Usage |
|--------|-------------------|--------------|------------------|-------|
-| **Revoke** | ✅ Deleted | ✅ Deleted | ✅ Required | Fully remove access |
-| **Remove** | ❌ Retained | ✅ Deleted | ❌ Not required | Clean local record only |
+| **Revoke** | Deleted | Deleted | Required | Fully remove access |
+| **Remove** | Retained | Deleted | Not required | Clean local record only |
---
@@ -341,27 +379,27 @@ Use this when the server is offline, the key already deleted on the server, or y
**Steps**:
1. Locate the key in the Key Management table.
-2. Click **“📤 Public Key”**.
+2. Click **“Public Key”**.
3. In the modal:
- View the OpenSSH-formatted public key (`ssh-rsa AAAAB3NzaC1yc2E...`)
- - Click **“📋 Copy to Clipboard”**
+ - Click **“Copy to Clipboard”**
- Or **“💾 Download File”** to save as `.pub`
4. **Use the key** by pasting into `~/.ssh/authorized_keys` on another server or sharing it securely.
#### Export the Private Key
**Security Warning**: Private keys are extremely sensitive. Only export when necessary:
-- 🔒 Backups stored on encrypted offline media
-- 🔄 Migration to another device
+- Backups stored on encrypted offline media
+- Migration to another device
- 🛠️ Use in other SSH clients (desktop machines)
**Prerequisites**:
- The key must have been generated with **“Allow Private Key Export”** enabled.
-- Without that flag, the **“🔐 Private Key”** button is disabled.
+- Without that flag, the **“Private Key”** button is disabled.
**Steps**:
1. Select an exportable key.
-2. Click **“🔐 Private Key”**.
+2. Click **“Private Key”**.
3. Read the warning about exposure risks.
4. Confirm to continue.
5. In the export modal:
@@ -371,10 +409,10 @@ Use this when the server is offline, the key already deleted on the server, or y
#### Private Key Handling Recommendations
1. **Secure Transfer**:
- - ❌ Do not send private keys via email
- - ❌ Avoid pasting them into chat apps
- - ❌ Don’t upload them to unencrypted cloud storage
- - ✅ Use encrypted USB drives or encrypted archives
+ - Do not send private keys via email
+ - Avoid pasting them into chat apps
+ - Don’t upload them to unencrypted cloud storage
+ - Use encrypted USB drives or encrypted archives
2. **Secure Storage**:
- Store on encrypted disks or safes
- Restrict permissions to 600
@@ -404,9 +442,9 @@ The Known Host Fingerprints block stores SSH server keys to guard against connec
#### Why Fingerprints Matter
-- 🛡️ **Prevent MITM attacks**: Verify you’re talking to the legitimate server.
-- 🔒 **Server authentication**: Ensure the key hasn’t been tampered with.
-- 📋 **Connection record**: Keep track of which servers you’ve connected to.
+- **Prevent MITM attacks**: Verify you’re talking to the legitimate server.
+- **Server authentication**: Ensure the key hasn’t been tampered with.
+- **Connection record**: Keep track of which servers you’ve connected to.
#### Fingerprint Format
@@ -424,7 +462,7 @@ Quickly verify the connectivity of a deployed host.
#### Steps
1. Select the host from the Deployed Hosts table.
-2. Click **“🔍 Test”**.
+2. Click **“Test”**.
3. Wait as the system:
- Uses the deployed key to connect
- Runs a simple command (e.g., `whoami`)
@@ -435,7 +473,7 @@ Quickly verify the connectivity of a deployed host.
**Successful Example**:
```
-✅ SSH connection test succeeded
+SSH connection test succeeded
Host: 192.168.55.100:22
User: nvidia
Command: whoami
@@ -444,7 +482,7 @@ Output: nvidia
**Failure Example**:
```
-❌ SSH connection test failed
+SSH connection test failed
Error: Connection timeout
Suggestion: Check network connectivity and firewall settings
```
@@ -472,8 +510,8 @@ Please refer to Task One, Section 2.4: “Revoking from Deployed Hosts” for gu
| Action | Local Record | Remote Public Key | Use Case |
|--------|--------------|-------------------|----------|
-| **Revoke** | ✅ Deleted | ✅ Deleted | Fully remove access |
-| **Remove** | ✅ Deleted | ❌ Retained | The server is decommissioned or key already removed |
+| **Revoke** | Deleted | ✅ Deleted | Fully remove access |
+| **Remove** | Deleted | Retained | The server is decommissioned or key already removed |
#### When to Remove
@@ -485,7 +523,7 @@ Please refer to Task One, Section 2.4: “Revoking from Deployed Hosts” for gu
#### Steps
1. Select the host.
-2. Click **“🗑️ Remove”** (gray button).
+2. Click **“Remove”** (gray button).
3. Confirm in the dialog.
4. The host disappears from the list.
@@ -506,17 +544,17 @@ Before deleting a key, ensure:
#### Steps
1. Choose the key from the Key Management table.
-2. Click **“🗑️ Delete”** (red button).
+2. Click **“Delete”** (red button).
3. Confirm in the warning dialog noting the action is permanent.
4. Click **“Confirm”** to proceed.
5. Verify the key disappears from the list.
#### Consequences
-- ✅ Key removed permanently from NVS, freeing storage.
-- ⚠️ Deployed host records remain and must be cleaned separately.
-- ❌ The key can no longer authenticate with servers unless re-created and redeployed.
-- ❌ Recovery is impossible without a prior private key backup.
+- Key removed permanently from NVS, freeing storage.
+- Deployed host records remain and must be cleaned separately.
+- The key can no longer authenticate with servers unless re-created and redeployed.
+- Recovery is impossible without a prior private key backup.
#### Post-deletion Cleanup
@@ -543,9 +581,9 @@ The “HTTPS Certificates” block configures the device’s mTLS credentials so
- **mTLS**: both the server and the client authenticate each other (two-way).
**Benefits**:
-- 🔒 Prevents unauthorized clients from accessing the device.
-- 🛡️ Protects against man-in-the-middle attacks.
-- 🎯 Enables certificate-based access control (no password needed).
+- Prevents unauthorized clients from accessing the device.
+- Protects against man-in-the-middle attacks.
+- Enables certificate-based access control (no password needed).
#### Certificate Hierarchy
@@ -573,10 +611,10 @@ The “HTTPS Certificates” block configures the device’s mTLS credentials so
#### Private Key Never Leaves the Device
**Security design**:
-- ✅ Key pairs are generated locally and never exported.
-- ✅ Only CSR (Certificate Signing Request) can be exported.
-- ✅ CA signs the CSR without ever seeing the private key.
-- ✅ Private keys stay in NVS even across firmware updates.
+- Key pairs are generated locally and never exported.
+- Only CSR (Certificate Signing Request) can be exported.
+- CA signs the CSR without ever seeing the private key.
+- Private keys stay in NVS even across firmware updates.
**SSH key comparison**:
- SSH private keys may be exported if “Allow Private Key Export” is enabled.
@@ -608,23 +646,23 @@ If the Known Host Fingerprints section always shows “No known hosts”:
#### When to Use
-- 🗑️ The server is permanently offline or destroyed.
-- 🔄 The server was rebuilt and the old fingerprint must be cleared.
-- 🔀 The IP was reassigned to another host.
-- 🧹 Routine cleanup of unused entries.
+- The server is permanently offline or destroyed.
+- The server was rebuilt and the old fingerprint must be cleared.
+- The IP was reassigned to another host.
+- Routine cleanup of unused entries.
#### Steps
-1. Select the host in the “🔐 Known Host Fingerprints” table.
-2. Click **“🗑️ Delete”**.
+1. Select the host in the “Known Host Fingerprints” table.
+2. Click **“Delete”**.
3. Confirm in the dialog.
4. The host is removed from the list.
#### Aftermath
-- ✅ The fingerprint is permanently removed from NVS.
-- ⚠️ You will be prompted to trust the server again on the next connection.
-- ❌ If the server was rebuilt, deleting the fingerprint is required to remove recurring mismatch warnings.
+- The fingerprint is permanently removed from NVS.
+- You will be prompted to trust the server again on the next connection.
+- If the server was rebuilt, deleting the fingerprint is required to remove recurring mismatch warnings.
#### Bulk Deletion
@@ -647,17 +685,17 @@ If a saved host’s fingerprint changes, TianshanOS shows a security warning bef
| Cause | Risk Level | Description |
|-------|------------|-------------|
-| **Man-in-the-middle attack (MITM)** | 🔴 High | An attacker is spoofing the server. |
-| **Server reinstallation** | 🟡 Legitimate | The server was rebuilt, generating a new host key. |
-| **Key rotation** | 🟡 Legitimate | Admin regenerated the SSH host key. |
-| **IP reallocation** | 🟡 Legitimate | The IP now maps to a different server. |
+| **Man-in-the-middle attack (MITM)** | High | An attacker is spoofing the server. |
+| **Server reinstallation** | Legitimate | The server was rebuilt, generating a new host key. |
+| **Key rotation** | Legitimate | Admin regenerated the SSH host key. |
+| **IP reallocation** | Legitimate | The IP now maps to a different server. |
#### Warning Modal
The red warning dialog shows:
```
-⚠️ Security Warning: Host fingerprint mismatch!
+Security Warning: Host fingerprint mismatch!
The host key has changed! This could mean:
• Man-in-the-Middle Attack
@@ -694,7 +732,7 @@ Options to verify:
**Step 3: Act based on your findings**
**Scenario A: Legitimate change**
-1. Click **“🔄 Update Host Key”** in the warning.
+1. Click **“Update Host Key”** in the warning.
2. The old fingerprint is removed.
3. Retry connecting.
4. Trust the new fingerprint following the first-time connection procedure (Section 4.3).
@@ -709,8 +747,8 @@ Options to verify:
#### Consequences of Mistakes
-- ❌ Blindly trusting the new fingerprint may expose your password and data to attackers.
-- ❌ Ignoring the warning habitually weakens the security posture.
+- Blindly trusting the new fingerprint may expose your password and data to attackers.
+- Ignoring the warning habitually weakens the security posture.
**Security principle**: When in doubt, stop the connection and investigate rather than blindly trusting a new fingerprint.
@@ -781,9 +819,9 @@ Before trusting in critical environments:
If the fingerprint is truncated:
-1. Click **“👁️ View”** on the target row.
-2. The modal shows the complete fingerprint and host metadata.
-3. Optionally compare it with the server’s official fingerprint.
+1. Click **“View”** on the target row.
+2. The modal shows the **full SHA256 fingerprint** plus host, port, and key type so you can compare it character-by-character with the output of `ssh-keygen -lf` on the server.
+3. Optionally compare with the server’s official fingerprint before trusting.
**Retrieve the server fingerprint** by running on the host:
@@ -822,9 +860,9 @@ The Known Host Fingerprints block stores SSH server keys to guard against connec
#### Why Fingerprints Matter
-- 🛡️ **Prevent MITM attacks**: Verify you’re talking to the legitimate server.
-- 🔒 **Server authentication**: Ensure the key hasn’t been tampered with.
-- 📋 **Connection record**: Keep track of which servers you’ve connected to.
+- **Prevent MITM attacks**: Verify you’re talking to the legitimate server.
+- **Server authentication**: Ensure the key hasn’t been tampered with.
+- **Connection record**: Keep track of which servers you’ve connected to.
#### Fingerprint Format
@@ -842,7 +880,7 @@ Quickly verify the connectivity of a deployed host.
#### Steps
1. Select the host from the Deployed Hosts table.
-2. Click **“🔍 Test”**.
+2. Click **“Test”**.
3. Wait as the system:
- Uses the deployed key to connect
- Runs a simple command (e.g., `whoami`)
@@ -853,7 +891,7 @@ Quickly verify the connectivity of a deployed host.
**Successful Example**:
```
-✅ SSH connection test succeeded
+SSH connection test succeeded
Host: 192.168.55.100:22
User: nvidia
Command: whoami
@@ -862,7 +900,7 @@ Output: nvidia
**Failure Example**:
```
-❌ SSH connection test failed
+SSH connection test failed
Error: Connection timeout
Suggestion: Check network connectivity and firewall settings
```
@@ -890,8 +928,8 @@ Please refer to Task One, Section 2.4: “Revoking from Deployed Hosts” for gu
| Action | Local Record | Remote Public Key | Use Case |
|--------|--------------|-------------------|----------|
-| **Revoke** | ✅ Deleted | ✅ Deleted | Fully remove access |
-| **Remove** | ✅ Deleted | ❌ Retained | The server is decommissioned or key already removed |
+| **Revoke** | Deleted | ✅ Deleted | Fully remove access |
+| **Remove** | Deleted | Retained | The server is decommissioned or key already removed |
#### When to Remove
@@ -903,7 +941,7 @@ Please refer to Task One, Section 2.4: “Revoking from Deployed Hosts” for gu
#### Steps
1. Select the host.
-2. Click **“🗑️ Remove”** (gray button).
+2. Click **“Remove”** (gray button).
3. Confirm in the dialog.
4. The host disappears from the list.
@@ -924,17 +962,17 @@ Before deleting a key, ensure:
#### Steps
1. Choose the key from the Key Management table.
-2. Click **“🗑️ Delete”** (red button).
+2. Click **“Delete”** (red button).
3. Confirm in the warning dialog noting the action is permanent.
4. Click **“Confirm”** to proceed.
5. Verify the key disappears from the list.
#### Consequences
-- ✅ Key removed permanently from NVS, freeing storage.
-- ⚠️ Deployed host records remain and must be cleaned separately.
-- ❌ The key can no longer authenticate with servers unless re-created and redeployed.
-- ❌ Recovery is impossible without a prior private key backup.
+- Key removed permanently from NVS, freeing storage.
+- Deployed host records remain and must be cleaned separately.
+- The key can no longer authenticate with servers unless re-created and redeployed.
+- Recovery is impossible without a prior private key backup.
#### Post-deletion Cleanup
@@ -961,9 +999,9 @@ The “HTTPS Certificates” block configures the device’s mTLS credentials so
- **mTLS**: both the server and the client authenticate each other (two-way).
**Benefits**:
-- 🔒 Prevents unauthorized clients from accessing the device.
-- 🛡️ Protects against man-in-the-middle attacks.
-- 🎯 Enables certificate-based access control (no password needed).
+- Prevents unauthorized clients from accessing the device.
+- Protects against man-in-the-middle attacks.
+- Enables certificate-based access control (no password needed).
#### Certificate Hierarchy
@@ -991,10 +1029,10 @@ The “HTTPS Certificates” block configures the device’s mTLS credentials so
#### Private Key Never Leaves the Device
**Security design**:
-- ✅ Key pairs are generated locally and never exported.
-- ✅ Only CSR (Certificate Signing Request) can be exported.
-- ✅ CA signs the CSR without ever seeing the private key.
-- ✅ Private keys stay in NVS even across firmware updates.
+- Key pairs are generated locally and never exported.
+- Only CSR (Certificate Signing Request) can be exported.
+- CA signs the CSR without ever seeing the private key.
+- Private keys stay in NVS even across firmware updates.
**SSH key comparison**:
- SSH private keys may be exported if “Allow Private Key Export” is enabled.
@@ -1026,23 +1064,23 @@ If the Known Host Fingerprints section always shows “No known hosts”:
#### When to Use
-- 🗑️ The server is permanently offline or destroyed.
-- 🔄 The server was rebuilt and the old fingerprint must be cleared.
-- 🔀 The IP was reassigned to another host.
-- 🧹 Routine cleanup of unused entries.
+- The server is permanently offline or destroyed.
+- The server was rebuilt and the old fingerprint must be cleared.
+- The IP was reassigned to another host.
+- Routine cleanup of unused entries.
#### Steps
-1. Select the host in the “🔐 Known Host Fingerprints” table.
-2. Click **“🗑️ Delete”**.
+1. Select the host in the “Known Host Fingerprints” table.
+2. Click **“Delete”**.
3. Confirm in the dialog.
4. The host is removed from the list.
#### Aftermath
-- ✅ The fingerprint is permanently removed from NVS.
-- ⚠️ You will be prompted to trust the server again on the next connection.
-- ❌ If the server was rebuilt, deleting the fingerprint is required to remove recurring mismatch warnings.
+- The fingerprint is permanently removed from NVS.
+- You will be prompted to trust the server again on the next connection.
+- If the server was rebuilt, deleting the fingerprint is required to remove recurring mismatch warnings.
#### Bulk Deletion
@@ -1065,17 +1103,17 @@ If a saved host’s fingerprint changes, TianshanOS shows a security warning bef
| Cause | Risk Level | Description |
|-------|------------|-------------|
-| **Man-in-the-middle attack (MITM)** | 🔴 High | An attacker is spoofing the server. |
-| **Server reinstallation** | 🟡 Legitimate | The server was rebuilt, generating a new host key. |
-| **Key rotation** | 🟡 Legitimate | Admin regenerated the SSH host key. |
-| **IP reallocation** | 🟡 Legitimate | The IP now maps to a different server. |
+| **Man-in-the-middle attack (MITM)** | High | An attacker is spoofing the server. |
+| **Server reinstallation** | Legitimate | The server was rebuilt, generating a new host key. |
+| **Key rotation** | Legitimate | Admin regenerated the SSH host key. |
+| **IP reallocation** | Legitimate | The IP now maps to a different server. |
#### Warning Modal
The red warning dialog shows:
```
-⚠️ Security Warning: Host fingerprint mismatch!
+Security Warning: Host fingerprint mismatch!
The host key has changed! This could mean:
• Man-in-the-Middle Attack
@@ -1112,7 +1150,7 @@ Options to verify:
**Step 3: Act based on your findings**
**Scenario A: Legitimate change**
-1. Click **“🔄 Update Host Key”** in the warning.
+1. Click **“Update Host Key”** in the warning.
2. The old fingerprint is removed.
3. Retry connecting.
4. Trust the new fingerprint following the first-time connection procedure (Section 4.3).
@@ -1127,8 +1165,8 @@ Options to verify:
#### Consequences of Mistakes
-- ❌ Blindly trusting the new fingerprint may expose your password and data to attackers.
-- ❌ Ignoring the warning habitually weakens the security posture.
+- Blindly trusting the new fingerprint may expose your password and data to attackers.
+- Ignoring the warning habitually weakens the security posture.
**Security principle**: When in doubt, stop the connection and investigate rather than blindly trusting a new fingerprint.
@@ -1199,9 +1237,9 @@ Before trusting in critical environments:
If the fingerprint is truncated:
-1. Click **“👁️ View”** on the target row.
-2. The modal shows the complete fingerprint and host metadata.
-3. Optionally compare it with the server’s official fingerprint.
+1. Click **“View”** on the target row.
+2. The modal shows the **full SHA256 fingerprint** plus host, port, and key type so you can compare it character-by-character with the output of `ssh-keygen -lf` on the server.
+3. Optionally compare with the server’s official fingerprint before trusting.
**Retrieve the server fingerprint** by running on the host:
@@ -1222,6 +1260,52 @@ Example output:
```
---
+## Task Five: Config Pack
+
+The **Config Pack** block is used to distribute configuration securely between devices: config files are encrypted and signed into a `.tscfg` package; only the target device that holds the corresponding certificate can decrypt and use it. Suitable for bulk deployment and remote config delivery.
+
+### 5.5.1 Config Pack Overview
+
+| Feature | Description | Access |
+|---------|-------------|--------|
+| **Export device certificate** | Export this device’s HTTPS certificate (PEM) and fingerprint so others can send encrypted config packs to this device | admin |
+| **Import config pack** | Upload or paste a .tscfg file; after signature verification it is decrypted and stored on the device (encrypted storage) | admin |
+| **Export config pack** | Choose local files and target device certificate to produce an encrypted .tscfg for the target device | Developer devices only |
+| **View config pack list** | List existing config pack files by directory with signer, official flag, and status | admin |
+
+**Status card**: The block header shows device type, certificate CN, fingerprint, format version, etc. If mTLS is not configured, some features may be unavailable.
+
+### 5.5.2 Export Device Certificate
+
+**Purpose**: Share this device’s certificate with developers or systems that need to send you encrypted config packs, so they can paste your certificate when exporting a config pack.
+
+**Steps**: Click **“Export device certificate”**, then in the modal view the certificate fingerprint (SHA256), CN, and PEM; click **“Copy to clipboard”** or copy the PEM and share it through a secure channel.
+
+### 5.5.3 Import Config Pack
+
+**Purpose**: Receive a .tscfg pack from another party or system; verify signature and decrypt, then save on the device.
+
+**Steps**: Click **“Import config pack”**, select a .tscfg file or paste JSON; you can click **“Verify only”** first to check signature and content, then **“Import”** to write to the device. **Note:** “Verify only” checks the pack’s signature and format but **does not** write any config to the device—use it to confirm the source and content before importing. After import, the pack is stored encrypted; use APIs such as `config.pack.content` to decrypt when needed.
+
+### 5.5.4 Export Config Pack (Developer Devices Only)
+
+**Purpose**: Select config files on this device, encrypt and sign with the target device’s certificate, and generate a .tscfg for the target to import.
+
+**Steps**: If the device is not Developer type, the button will indicate “Only Developer devices can export config packs.” Click **“Export config pack”**, browse and select files to include, fill name and description, paste the **target device’s** exported certificate PEM, then click **“Generate config pack”** and copy or download the .tscfg to send to the target.
+
+### 5.5.5 View Config Pack List
+
+**Purpose**: List config pack files under a given path (e.g. `/sdcard/config`) with filename, size, signer, official flag, and status.
+
+**Steps**: Click **“View config pack list”**, enter or keep the default path, then click **“Refresh”**.
+
+**Column notes**:
+- **Signer**: Certificate CN that signed the pack, used to verify origin.
+- **Official**: When the signature is from a system-trusted official certificate, the row is marked “official,” so you can tell vendor-delivered config from self-signed config.
+- **Status**: Whether the pack has been applied, is valid, etc.
+
+---
+
## Secure Storage vs. File-Based Keys
This section explains why TianshanOS uses secure storage (NVS) over filesystem-based keys by default.
@@ -1230,15 +1314,15 @@ This section explains why TianshanOS uses secure storage (NVS) over filesystem-b
| Feature | Secure Storage (NVS) | File Keys (SD Card) |
|---------|----------------------|--------------------|
-| **Private Key Protection** | ✅ Encrypted NVS partition; extraction is difficult | ⚠️ Plaintext PEM files that can be copied or leaked |
-| **Usability** | ✅ Only remember the Key ID; no file paths | ❌ Requires remembering file paths, which can be confusing |
-| **Key Backup** | ⚠️ Requires enabling “Allow Export” | ✅ Copy the file directly |
-| **Cross-Device Use** | ❌ Bound to a single device | ✅ Copy to multiple devices |
-| **Protection Against Accidental Deletion** | ✅ Must explicitly delete | ⚠️ Filesystem issues can result in loss |
-| **Storage Capacity** | ⚠️ NVS has a limited capacity (8-32 keys) | ✅ SD cards have large capacity |
-| **Access Speed** | ✅ Fast NVS access | ⚠️ Slower SD card I/O |
-| **Security Rating** | ⭐⭐⭐⭐⭐ (5 stars) | ⭐⭐ (2 stars) |
-| **Recommended Use** | 🎯 Production, long-term, security-sensitive | Temporary use, key migration, multi-device sharing |
+| **Private Key Protection** | Encrypted NVS partition; extraction is difficult | Plaintext PEM files that can be copied or leaked |
+| **Usability** | Only remember the Key ID; no file paths | Requires remembering file paths, which can be confusing |
+| **Key Backup** | Requires enabling “Allow Export” | Copy the file directly |
+| **Cross-Device Use** | Bound to a single device | Copy to multiple devices |
+| **Protection Against Accidental Deletion** | Must explicitly delete | Filesystem issues can result in loss |
+| **Storage Capacity** | NVS has a limited capacity (8-32 keys) | SD cards have large capacity |
+| **Access Speed** | Fast NVS access | Slower SD card I/O |
+| **Security Rating** | High (5 stars) | Lower (2 stars) |
+| **Recommended Use** | Production, long-term, security-sensitive | Temporary use, key migration, multi-device sharing |
### Advantages of Secure Storage
@@ -1259,10 +1343,10 @@ This section explains why TianshanOS uses secure storage (NVS) over filesystem-b
Although secure storage is preferred, file keys may be appropriate when:
-- 🔄 **Migration**: Import an existing key from another device.
+- **Migration**: Import an existing key from another device.
- 🧪 **Temporary testing**: Use a key for a short-lived test.
-- 🔀 **Multi-device sharing**: The same key must run on several devices.
-- 📤 **External tooling**: Desktop SSH clients (PuTTY, Terminal) require file keys.
+- **Multi-device sharing**: The same key must run on several devices.
+- **External tooling**: Desktop SSH clients (PuTTY, Terminal) require file keys.
**CLI Example for File Keys**:
```bash
@@ -1276,21 +1360,21 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
#### When to Renew
- ⏰ The certificate is expiring soon (start renewal 30 days before expiry).
-- ⚠️ The status card shows “Expiring soon” or remaining days < 30.
-- 📅 Company PKI policy dictates issued certificates renew annually or by schedule.
+- The status card shows “Expiring soon” or remaining days < 30.
+- Company PKI policy dictates issued certificates renew annually or by schedule.
#### Renewal Steps
**Option 1: Keep the same key pair (recommended)**
1. **Generate a fresh CSR**:
- - Click **“📋 Generate CSR”** (you can reuse the same CN).
+ - Click **“Generate CSR”** (you can reuse the same CN).
- Copy the new CSR.
2. **Submit it to the CA**:
- Send the CSR to your CA for renewal.
- Receive a new certificate.
3. **Install the new certificate**:
- - Click **“📥 Install Certificate.”**
+ - Click **“Install Certificate.”**
- Paste the renewed certificate.
4. **Check the status**:
- The expiration date should update to the new certificate’s validity.
@@ -1298,16 +1382,16 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
**Option 2: Full refresh (if the private key may be compromised)**
-1. Delete all credentials via **“🗑️ Delete Credentials.”**
+1. Delete all credentials via **“Delete Credentials.”**
2. Start again from Step 5.3.1 (generate a new key pair).
3. Go through the full 5.3 flow (CSR, CA signing, install certificate, install CA chain).
#### Renewal Notes
-- ✅ The old certificate remains valid until its expiry.
-- ✅ The new certificate takes effect immediately once installed.
-- ✅ CA chains rarely need updates unless the CA infrastructure changes.
-- ⚠️ If the CA chain itself is expiring, renew it alongside the device certificate.
+- The old certificate remains valid until its expiry.
+- The new certificate takes effect immediately once installed.
+- CA chains rarely need updates unless the CA infrastructure changes.
+- If the CA chain itself is expiring, renew it alongside the device certificate.
#### Automated Renewal (Future Feature)
@@ -1323,10 +1407,10 @@ Currently, renewal is manual. Future versions may:
#### What Gets Deleted
-Clicking **“🗑️ Delete Credentials”** removes:
-- 🔑 The device private key (ECDSA P-256)
+Clicking **“Delete Credentials”** removes:
+- The device private key (ECDSA P-256)
- 📄 The device certificate
-- 🏛️ The CA certificate chain
+- The CA certificate chain
#### When to Use
@@ -1339,10 +1423,10 @@ Clicking **“🗑️ Delete Credentials”** removes:
#### Steps
-1. Click **“🗑️ Delete Credentials”** (red button).
+1. Click **“Delete Credentials”** (red button).
2. Read the warning dialog:
```
- ⚠️ Warning: This deletes all PKI credentials
+ Warning: This deletes all PKI credentials
This action will remove:
• Device private key
@@ -1358,7 +1442,7 @@ Clicking **“🗑️ Delete Credentials”** removes:
```
3. Confirm if you understand the impact.
4. After completion:
- - The status card reverts to “🔒 Key pair not generated.”
+ - The status card reverts to “Key pair not generated.”
- All buttons return to their initial states.
- The HTTPS key row disappears from the Key Management table.
@@ -1383,11 +1467,11 @@ Clicking **“🗑️ Delete Credentials”** removes:
- Copy the certificate for client configuration or backups.
**Steps**:
-1. Ensure the device certificate is installed (the “👁️ View Certificate” button is enabled).
-2. Click **“👁️ View Certificate.”**
-3. Wait as “🔄 Loading...” appears for 1-2 seconds.
+1. Ensure the device certificate is installed (the “View Certificate” button is enabled).
+2. Click **“View Certificate.”**
+3. Wait as “Loading...” appears for 1-2 seconds.
4. The modal displays the entire PEM content (scrollable).
-5. Optional: click **“📋 Copy to Clipboard”** for reuse.
+5. Optional: click **“Copy to Clipboard”** for reuse.
6. Close the modal when finished.
#### Certificate Inspection
@@ -1422,8 +1506,8 @@ Certificate:
**Purpose**: Install the CA chain (root + intermediate) so clients can validate the device certificate.
**Prerequisites**:
-- ✅ Device certificate installed (Section 5.3.4).
-- ✅ CA chain file in PEM format.
+- Device certificate installed (Section 5.3.4).
+- CA chain file in PEM format.
**Why you need it**:
- Clients need a complete trust path: `Device Cert ← Intermediate CA ← Root CA`.
@@ -1440,13 +1524,13 @@ Certificate:
(Intermediate CA content)
-----END CERTIFICATE-----
```
-3. Click **“🏛️ Install CA.”**
+3. Click **“Install CA.”**
4. Paste the chain into the modal’s text box (all `BEGIN/END` sections).
-5. Click **“🏛️ Install.”**
+5. Click **“Install.”**
6. Wait for validation and storage in NVS.
7. Confirmation steps:
- - “✅ CA chain installed successfully.”
- - Status card shows “✅ Activated” (if the certificate is valid).
+ - “CA chain installed successfully.”
+ - Status card shows “Activated” (if the certificate is valid).
- mTLS configuration is now complete.
#### CA Chain Examples
@@ -1475,8 +1559,8 @@ Certificate:
#### Post-installation Validation
1. Check the status card:
- - Should read “✅ Activated”
- - Validity shows “✅ Valid”
+ - Should read “Activated”
+ - Validity shows “Valid”
- Days remaining should be accurate
2. Test an mTLS client (configured to trust the same CA):
- Connect to the device using an mTLS-aware client.
@@ -1488,9 +1572,9 @@ Certificate:
**Goal**: Install the CA-signed device certificate so mTLS works.
**Prerequisites**:
-- ✅ Key pair must exist.
-- ✅ You have the signed certificate in PEM format.
-- ✅ The certificate was signed from the CSR you generated.
+- Key pair must exist.
+- You have the signed certificate in PEM format.
+- The certificate was signed from the CSR you generated.
**Steps**:
1. Open the certificate file (`device.crt`) on your computer.
@@ -1502,16 +1586,16 @@ Certificate:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxQ=
-----END CERTIFICATE-----
```
-3. Click **“📥 Install Certificate.”**
+3. Click **“Install Certificate.”**
4. Paste the certificate into the “Certificate PEM” field, ensuring the `BEGIN/END` lines are present.
-5. Click **“📥 Install.”**
+5. Click **“Install.”**
6. Wait while the system validates:
- - ✅ Correct PEM format
- - ✅ Certificate matches the private key
- - ✅ Certificate is currently valid (within its validity window)
- - ✅ Subject fields look as expected
+ - Correct PEM format
+ - Certificate matches the private key
+ - Certificate is currently valid (within its validity window)
+ - Subject fields look as expected
7. Confirm when the modal shows:
- - “✅ Certificate installed successfully”
+ - “Certificate installed successfully”
- Displayed certificate details (CN, issuer, validity)
- Status card updates to “Activated” or “Certificate installed, CA chain missing”
@@ -1584,15 +1668,15 @@ If the device has a public domain, use Let’s Encrypt:
#### Timing
-- 🚀 Automated CAs: minutes to seconds
+- Automated CAs: minutes to seconds
- ⏳ Manual CAs: hours to days, depending on the approval chain
#### Files You Should Receive
| File | Required | Description | Format |
|------|----------|-------------|--------|
-| **Device Certificate** | ✅ Yes | CA-signed certificate for the device | `device.crt`, PEM format |
-| **CA Chain** | ✅ Yes | Root CA plus intermediate CA certificates | `ca-chain.pem`, PEM format |
+| **Device Certificate** | Yes | CA-signed certificate for the device | `device.crt`, PEM format |
+| **CA Chain** | Yes | Root CA plus intermediate CA certificates | `ca-chain.pem`, PEM format |
Once you have both files, proceed to Section 5.3.4: Install the device certificate.
@@ -1602,25 +1686,25 @@ Once you have both files, proceed to Section 5.3.4: Install the device certifica
**Purpose**: Produce a CSR to submit to a CA for certificate signing.
**Prerequisites**:
-- ✅ Step 5.3.1 (key pair generated)
-- ✅ The **“📋 Generate CSR”** button is enabled
+- Step 5.3.1 (key pair generated)
+- The **“Generate CSR”** button is enabled
**Steps**:
-1. Click **“📋 Generate CSR.”**
+1. Click **“Generate CSR.”**
2. Fill out the CSR details in the modal:
| Field | Required | Description | Example |
|-------|----------|-------------|---------|
-| **Device ID (CN)** | ❌ No | Common Name identifying the device. Leave blank to use defaults. | `TIANSHAN-RM01-0001`, `DEVICE-AGX-001` |
-| **Organization (O)** | ❌ No | Company or organization name | `HiddenPeak Labs`, `My Company` |
-| **Organizational Unit (OU)** | ❌ No | Department or unit | `Device`, `Production`, `IoT` |
+| **Device ID (CN)** | No | Common Name identifying the device. Leave blank to use defaults. | `TIANSHAN-RM01-0001`, `DEVICE-AGX-001` |
+| **Organization (O)** | No | Company or organization name | `HiddenPeak Labs`, `My Company` |
+| **Organizational Unit (OU)** | No | Department or unit | `Device`, `Production`, `IoT` |
**Notes**:
- CN should follow a structured naming pattern (`prefix-model-serial`).
- O and OU are optional fields for metadata.
- Leaving everything blank lets the system apply defaults (e.g., MAC address-based CN).
-3. Click **“📋 Generate CSR.”**
+3. Click **“Generate CSR.”**
4. Wait ~2-3 seconds as the device:
- Uses the private key and input data to craft a CSR.
- Produces an X.509-compliant CSR (RFC 2986).
@@ -1635,15 +1719,15 @@ Once you have both files, proceed to Section 5.3.4: Install the device certifica
│ -----END CERTIFICATE REQUEST----- │
└───────────────────────────────────────────┘
```
-6. Click **“📋 Copy to Clipboard.”**
+6. Click **“Copy to Clipboard.”**
7. Optionally save the CSR as a file (`device.csr`) for CA submission.
#### CSR Contents
-- ✅ The device’s public key (from the generated key pair).
-- ✅ Subject information (CN, O, OU).
-- ✅ Device signature proving possession of the private key.
-- ❌ **No private key data** is included.
+- The device’s public key (from the generated key pair).
+- Subject information (CN, O, OU).
+- Device signature proving possession of the private key.
+- **No private key data** is included.
#### Next Step
@@ -1652,7 +1736,7 @@ Submit the CSR to your CA for signing as described in Section 5.3.3.
---
### 5.3 Full Certificate Request Flow
-Configuring mTLS from scratch involves five steps.
+Configuring mTLS from scratch involves five steps. Button and modal names below (e.g. “Generate Key Pair,” “Certificate Signing Request (CSR),” “Install Device Certificate,” “Install CA Certificate Chain,” “View Device Certificate”) match the Security page WebUI so you can follow along in the interface.
#### Process Overview
@@ -1677,7 +1761,7 @@ Step 5: Install CA certificate chain (on-device)
**Steps**:
1. **Check status**:
- Look at the certificate status card. If it already shows “Key pair generated,” skip unless you need to regenerate.
-2. **Click “🔑 Generate Key Pair.”**
+2. **Click “Generate Key Pair.”**
3. **Review the prompt**:
```
Generate an ECDSA P-256 key pair for mTLS authentication.
@@ -1685,16 +1769,16 @@ Step 5: Install CA certificate chain (on-device)
4. **Handle the overwrite warning**:
- If keys already exist, a yellow warning appears:
```
- ⚠️ A key pair already exists. Continue will overwrite the current keys!
+ Note: A key pair already exists. Continue will overwrite the current keys!
```
- Overwriting will invalidate any CSR/certificate issued by the old key.
- Only proceed if you understand the impact.
-5. **Start generation** by clicking **“🔑 Generate.”**
+5. **Start generation** by clicking **“Generate.”**
6. **Wait for completion**:
- ECDSA P-256 generation takes ~3-5 seconds.
- The modal displays progress or status.
7. **Confirm success**:
- - It shows “✅ Key pair generated successfully.”
+ - It shows “Key pair generated successfully.”
- Close the modal.
- The status card now shows “Key pair generated, certificate not installed.”
- The buttons for generating CSR, installing certificates, and installing the CA become active.
@@ -1715,18 +1799,18 @@ Step 5: Install CA certificate chain (on-device)
#### Status Card Details
-At the top of the “🔒 HTTPS Certificates” block, a status card shows the certificate state in real time.
+At the top of the “HTTPS Certificates” block, a status card shows the certificate state in real time.
#### Status Icons and Meaning
| Icon | Status Text | Meaning |
|------|-------------|---------|
-| 🔄 | Loading... | Retrieving certificate status |
-| 🔒 | Key pair not generated | No key pair exists yet |
-| 📝 | Key pair generated, certificate not installed | Keys exist but CA certificate is missing |
-| ✅ | Activated | Certificate installed and valid |
-| ⚠️ | Expiring soon | Certificate expires within 30 days—renew promptly |
-| ❌ | Expired | Certificate is invalid; mTLS cannot run |
+| Loading... | Retrieving certificate status |
+| Key pair not generated | No key pair exists yet |
+| Key pair generated, certificate not installed | Keys exist but CA certificate is missing |
+| Activated | Certificate installed and valid |
+| Expiring soon | Certificate expires within 30 days—renew promptly |
+| Expired | Certificate is invalid; mTLS cannot run |
#### Certificate Details (Installed)
@@ -1739,21 +1823,26 @@ When the certificate shows “Activated” or “Expiring soon,” the card expa
| **Valid From** | Certificate start time | `2026-01-27 00:00:00` |
| **Expires On** | Certificate end time | `2027-01-27 00:00:00` |
| **Serial Number** | Hexadecimal identifier | `01:23:45:67:89:AB` |
-| **Validity** | Is the certificate currently valid? | ✅ Valid / ❌ Expired |
+| **Validity** | Is the certificate currently valid? | Valid / Expired |
| **Days Remaining** | Days until expiration | `365 days`, `28 days` (warning appears if < 30) |
+**Status card display rules**:
+- **Days remaining** is shown only when a certificate is installed and within its validity period; it is not shown when no certificate is installed or when the certificate has expired.
+- **“Expiring soon”** state/badge appears when the certificate is still valid but has fewer than 30 days until expiry; renew as soon as possible.
+- The expanded details (Subject CN, Issuer, Valid From/Expires On, Serial Number, Validity, Days Remaining) are only visible when the status is “Activated” or “Expiring soon.”
+
#### Button States
Six action buttons are located beneath the HTTPS certificate block. Their enabled/disabled state depends on the current status:
| Button | No Key Pair | Key Pair Generated | Certificate Installed | Notes |
|--------|-------------|--------------------|------------------------|-------|
-| 🔑 Generate Key Pair | ✅ Enabled | ✅ Enabled | ✅ Enabled | Always available (will overwrite existing keys). |
-| 📋 Generate CSR | ❌ Disabled | ✅ Enabled | ✅ Enabled | Requires an existing key pair. |
-| 📥 Install Certificate | ❌ Disabled | ✅ Enabled | ✅ Enabled | Requires key pair. |
-| 🏛️ Install CA | ❌ Disabled | ✅ Enabled | ✅ Enabled | Requires key pair. |
-| 👁️ View Certificate | ❌ Disabled | ❌ Disabled | ✅ Enabled | Needs an installed certificate. |
-| 🗑️ Delete Credentials | ❌ Disabled | ✅ Enabled | ✅ Enabled | Available when keys or certificates exist. |
+| Generate Key Pair | Enabled | Enabled | Enabled | Always available (will overwrite existing keys). |
+| Generate CSR | Disabled | Enabled | Enabled | Requires an existing key pair. |
+| Install Certificate | Disabled | Enabled | Enabled | Requires key pair. |
+| Install CA | Disabled | Enabled | Enabled | Requires key pair. |
+| View Certificate | Disabled | Disabled | Enabled | Needs an installed certificate. |
+| Delete Credentials | Disabled | Enabled | Enabled | Available when keys or certificates exist. |
---
## FAQs & Troubleshooting
@@ -1793,16 +1882,16 @@ Six action buttons are located beneath the HTTPS certificate block. Their enable
- `
_`: `project_a_01`, `iot_device_001`
**Avoid**:
-- ❌ `key1`, `test`, `temp`
-- ❌ Non-ASCII or special characters
-- ❌ Excessively long names
+- `key1`, `test`, `temp`
+- Non-ASCII or special characters
+- Excessively long names
#### 2. Selecting key types
**Suggested approach**:
-- 🎯 Daily work: RSA 2048-bit (speed plus compatibility)
-- 🎯 High-security: RSA 4096-bit (stronger but slower)
-- ⚠️ ECDSA: Use only for HTTPS certificates, not SSH
+- Daily work: RSA 2048-bit (speed plus compatibility)
+- High-security: RSA 4096-bit (stronger but slower)
+- ECDSA: Use only for HTTPS certificates, not SSH
**Capacity planning**:
- RSA 2048: ~12 keys
@@ -1812,7 +1901,7 @@ Six action buttons are located beneath the HTTPS certificate block. Their enable
#### 3. Controlling private key export
Best practices:
-- 🔒 Production keys: leave “Allow Private Key Export” unchecked.
+- Production keys: leave “Allow Private Key Export” unchecked.
- 🔓 Backup keys: enable export and store in offline media.
- 🧪 Test keys: keep non-exportable and regenerate if needed.
@@ -1841,20 +1930,20 @@ Recommended cadence:
#### Q16: Can admin users use all security page functions?
-**Answer**: ✅ Yes.
+**Answer**: Yes.
**admin privileges**:
-- ✅ Access to every security page feature.
-- ✅ Access to System, Network, and Files pages.
-- ❌ Cannot access Terminal, Automation, or Command pages (root only).
+- Access to every security page feature.
+- Access to System, Network, and Files pages.
+- Cannot access Terminal, Automation, or Command pages (root only).
**Security page capabilities**:
-- ✅ Generate, delete, and export SSH keys.
-- ✅ Deploy and revoke public keys on remote servers.
-- ✅ Manage deployed host records.
-- ✅ View/delete known host fingerprints.
-- ✅ Generate, install, and delete HTTPS certificates.
-- ✅ Generate CSRs and install CA chains.
+- Generate, delete, and export SSH keys.
+- Deploy and revoke public keys on remote servers.
+- Manage deployed host records.
+- View/delete known host fingerprints.
+- Generate, install, and delete HTTPS certificates.
+- Generate CSRs and install CA chains.
**Need root functionality?**
- Contact your administrator to log in as root.
@@ -1864,7 +1953,7 @@ Recommended cadence:
#### Q17: “Insufficient permissions” when exporting private keys?
-**Symptom**: The **“🔐 Private Key”** button is greyed out or shows “Export not allowed.”
+**Symptom**: The **“Private Key”** button is greyed out or shows “Export not allowed.”
**Reason**: The key was created without “Allow Private Key Export.”
@@ -1889,31 +1978,31 @@ Recommended cadence:
- Use the WebUI deploy feature instead of exporting the private key.
**Design principle**:
-- 🔒 Private keys are the most sensitive assets—minimize export.
-- 🔒 Only export when necessary (backup/migration).
-- 🔒 Defaults prevent accidental leaks.
+- Private keys are the most sensitive assets—minimize export.
+- Only export when necessary (backup/migration).
+- Defaults prevent accidental leaks.
---
#### Q14: Certificate state shows “Expiring soon”?
-**Symptom**: The status card shows ⚠️ “Expiring soon” with remaining days < 30.
+**Symptom**: The status card shows “Expiring soon” with remaining days < 30.
**Recommendations**:
-- 🟢 **30-15 days**: Prepare to renew, but not urgent yet.
-- 🟡 **15-7 days**: Renew as soon as possible to avoid service impact.
-- 🔴 **<7 days**: Handle immediately.
+- **30-15 days**: Prepare to renew, but not urgent yet.
+- **15-7 days**: Renew as soon as possible to avoid service impact.
+- **<7 days**: Handle immediately.
**Renewal steps (keep the same key)**:
-1. Click **“📋 Generate CSR”** (you can reuse the same CN).
+1. Click **“Generate CSR”** (you can reuse the same CN).
2. Submit the CSR to your CA and request renewal.
-3. Install the new certificate via **“📥 Install Certificate.”** Paste the renewed certificate; the old one is overwritten.
+3. Install the new certificate via **“Install Certificate.”** Paste the renewed certificate; the old one is overwritten.
4. Check the status card reflects the new expiration and days remaining.
**Notes**:
-- ✅ Old certificate remains usable until it expires.
-- ✅ The new certificate becomes active immediately.
-- ✅ The CA chain usually does not timeout at the same time; update only if necessary.
-- ⚠️ If the CA chain itself is expired, renew it along with the device certificate.
+- Old certificate remains usable until it expires.
+- The new certificate becomes active immediately.
+- The CA chain usually does not timeout at the same time; update only if necessary.
+- If the CA chain itself is expired, renew it along with the device certificate.
---
@@ -1953,32 +2042,32 @@ Recommended cadence:
**Fix**:
**Option 1: Regenerate the CSR**
-1. Click **“📋 Generate CSR”** again on the device.
+1. Click **“Generate CSR”** again on the device.
2. Copy the new CSR.
3. Submit it to the CA.
4. Install the newly signed certificate.
**Option 2: Delete credentials and restart**
-1. Click **“🗑️ Delete Credentials.”**
+1. Click **“Delete Credentials.”**
2. Begin from Section 5.3.1 (generate key pair).
3. Follow the full flow to ensure CSR, signing, and installation all use the same key.
**Prevention**:
-- ✅ Do not regenerate the key pair after creating a CSR.
-- ✅ Confirm the CSR filename (e.g., `device-001.csr`) and certificate file correspond.
-- ✅ Label files clearly to avoid confusion.
+- Do not regenerate the key pair after creating a CSR.
+- Confirm the CSR filename (e.g., `device-001.csr`) and certificate file correspond.
+- Label files clearly to avoid confusion.
---
### 7.4 HTTPS Certificate Issues
#### Q12: “Generate CSR” button is greyed out?
-**Symptom**: The **“📋 Generate CSR”** button is disabled (greyed).
+**Symptom**: The **“Generate CSR”** button is disabled (greyed).
**Reason**: A key pair has not been generated. CSR signing requires a private key.
**Fix**:
-1. Click **“🔑 Generate Key Pair.”**
+1. Click **“Generate Key Pair.”**
2. Wait for the key pair to finish.
3. The CSR button (and Install Certificate/Install CA buttons) will enable automatically.
@@ -1989,24 +2078,24 @@ Recommended cadence:
---
#### Q10: How to handle Host Fingerprint mismatch warnings?
-**Symptom**: A red warning pops up: “⚠️ Security Warning: Host fingerprint mismatch.”
+**Symptom**: A red warning pops up: “Security Warning: Host fingerprint mismatch.”
**Correct handling** (see Section 4.4):
1. **🛑 Stop immediately**: Do not click “Update Host Key” without confirmation.
2. **📞 Contact the administrator**: Ask if the server was rebuilt or the host key changed.
-3. **✅ If legitimate**: Click “Update Host Key,” then reconnect and trust the new fingerprint.
-4. **❌ If uncertain**: Click “Cancel” and investigate the network/security environment.
+3. **If legitimate**: Click “Update Host Key,” then reconnect and trust the new fingerprint.
+4. **If uncertain**: Click “Cancel” and investigate the network/security environment.
**Mistakes to avoid**:
-- ❌ Clicking “Update Host Key” automatically (could signal an MITM attack).
-- ❌ Ignoring the warning and forcing the connection.
-- ❌ Assuming it’s a bug—this is a critical security feature.
+- Clicking “Update Host Key” automatically (could signal an MITM attack).
+- Ignoring the warning and forcing the connection.
+- Assuming it’s a bug—this is a critical security feature.
**Security reminder**:
-- 🔴 A fingerprint mismatch is a serious warning.
-- 🔴 Always verify before trusting.
-- 🔴 Frequent warnings may indicate an insecure network.
+- A fingerprint mismatch is a serious warning.
+- Always verify before trusting.
+- Frequent warnings may indicate an insecure network.
---
@@ -2082,18 +2171,36 @@ hosts --list --json
**Cause**: Only hosts deployed via the WebUI appear in the list.
**Not recorded scenarios**:
-- ❌ Deployments via CLI (`ssh --copyid`).
-- ❌ Manually appending the public key to `authorized_keys`.
-- ❌ Keys deployed on other devices or via different tools.
+- Deployments via CLI (`ssh --copyid`).
+- Manually appending the public key to `authorized_keys`.
+- Keys deployed on other devices or via different tools.
**Resolution**:
- If you want WebUI management, redeploy the key through the UI.
- Alternatively, use CLI commands like `hosts --deployed` to view/manage hosts.
+- Or use “Import Host” to add hosts from a .tscfg config package so the list matches your actual setup.
**Design note**:
- Records are stored locally in `ts_ssh_hosts_config`.
- Only WebUI or specific API deployments are tracked to provide a unified management interface.
+---
+#### Q8b: “Signature verification failed” when importing host or config pack?
+
+**Symptom**: After choosing or pasting a .tscfg in “Import Host” or “Import config pack,” you see a signature verification or decryption error.
+
+**Possible causes**:
+- The .tscfg file is corrupted or incomplete (missing headers/footers or truncated).
+- The pack was not signed with a certificate trusted by this (or the target) device.
+- Device system time is wrong, so certificate validity checks fail.
+- Pasted JSON is malformed (extra spaces, missing quotes, etc.).
+
+**What to do**:
+1. **Check file integrity**: Re-obtain the .tscfg and ensure it includes full `-----BEGIN ...-----` / `-----END ...-----` blocks, or re-export.
+2. **Confirm signer**: Ensure the pack was signed by this device’s certificate or a trusted official/target certificate; for “self-encrypt” host export, import on the same device or one that has the same certificate.
+3. **Fix device time**: In System/Network, verify date and time (and NTP sync if needed).
+4. **Use “Verify only”**: In the config pack import modal, click “Verify only” first and use the reported error (e.g. signer, certificate CN) to narrow down the issue.
+
---
#### Q7: Deployment succeeded but password is still requested?
@@ -2232,7 +2339,7 @@ hosts --list --json
**Method 1: Export the private key (requires prior permission)**:
1. Enable **“Allow Private Key Export”** when generating the key.
-2. After creation, click **“🔐 Private Key.”**
+2. After creation, click **“Private Key.”**
3. Download the `.pem` file.
4. Store it on encrypted offline media (USB drive, password manager).
@@ -2428,7 +2535,7 @@ The following docs provide additional technical depth and troubleshooting guidan
#### 2. Test immediately after deployment
**Workflow**:
-1. After deployment, click **“🔍 Test.”**
+1. After deployment, click **“Test.”**
2. Ensure the connection succeeds.
3. If it fails, fix issues immediately.
@@ -2517,10 +2624,10 @@ This section explains why TianshanOS uses secure storage (NVS) over filesystem-b
Although secure storage is preferred, file keys may be appropriate when:
-- 🔄 **Migration**: Import an existing key from another device.
+- **Migration**: Import an existing key from another device.
- 🧪 **Temporary testing**: Use a key for a short-lived test.
-- 🔀 **Multi-device sharing**: The same key must run on several devices.
-- 📤 **External tooling**: Desktop SSH clients (PuTTY, Terminal) require file keys.
+- **Multi-device sharing**: The same key must run on several devices.
+- **External tooling**: Desktop SSH clients (PuTTY, Terminal) require file keys.
**CLI Example for File Keys**:
```bash
@@ -2534,21 +2641,21 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
#### When to Renew
- ⏰ The certificate is expiring soon (start renewal 30 days before expiry).
-- ⚠️ The status card shows “Expiring soon” or remaining days < 30.
-- 📅 Company PKI policy dictates issued certificates renew annually or by schedule.
+- The status card shows “Expiring soon” or remaining days < 30.
+- Company PKI policy dictates issued certificates renew annually or by schedule.
#### Renewal Steps
**Option 1: Keep the same key pair (recommended)**
1. **Generate a fresh CSR**:
- - Click **“📋 Generate CSR”** (you can reuse the same CN).
+ - Click **“Generate CSR”** (you can reuse the same CN).
- Copy the new CSR.
2. **Submit it to the CA**:
- Send the CSR to your CA for renewal.
- Receive a new certificate.
3. **Install the new certificate**:
- - Click **“📥 Install Certificate.”**
+ - Click **“Install Certificate.”**
- Paste the renewed certificate.
4. **Check the status**:
- The expiration date should update to the new certificate’s validity.
@@ -2556,16 +2663,16 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
**Option 2: Full refresh (if the private key may be compromised)**
-1. Delete all credentials via **“🗑️ Delete Credentials.”**
+1. Delete all credentials via **“Delete Credentials.”**
2. Start again from Step 5.3.1 (generate a new key pair).
3. Go through the full 5.3 flow (CSR, CA signing, install certificate, install CA chain).
#### Renewal Notes
-- ✅ The old certificate remains valid until its expiry.
-- ✅ The new certificate takes effect immediately once installed.
-- ✅ CA chains rarely need updates unless the CA infrastructure changes.
-- ⚠️ If the CA chain itself is expiring, renew it alongside the device certificate.
+- The old certificate remains valid until its expiry.
+- The new certificate takes effect immediately once installed.
+- CA chains rarely need updates unless the CA infrastructure changes.
+- If the CA chain itself is expiring, renew it alongside the device certificate.
#### Automated Renewal (Future Feature)
@@ -2581,10 +2688,10 @@ Currently, renewal is manual. Future versions may:
#### What Gets Deleted
-Clicking **“🗑️ Delete Credentials”** removes:
-- 🔑 The device private key (ECDSA P-256)
+Clicking **“Delete Credentials”** removes:
+- The device private key (ECDSA P-256)
- 📄 The device certificate
-- 🏛️ The CA certificate chain
+- The CA certificate chain
#### When to Use
@@ -2597,10 +2704,10 @@ Clicking **“🗑️ Delete Credentials”** removes:
#### Steps
-1. Click **“🗑️ Delete Credentials”** (red button).
+1. Click **“Delete Credentials”** (red button).
2. Read the warning dialog:
```
- ⚠️ Warning: This deletes all PKI credentials
+ Warning: This deletes all PKI credentials
This action will remove:
• Device private key
@@ -2616,7 +2723,7 @@ Clicking **“🗑️ Delete Credentials”** removes:
```
3. Confirm if you understand the impact.
4. After completion:
- - The status card reverts to “🔒 Key pair not generated.”
+ - The status card reverts to “Key pair not generated.”
- All buttons return to their initial states.
- The HTTPS key row disappears from the Key Management table.
@@ -2641,11 +2748,11 @@ Clicking **“🗑️ Delete Credentials”** removes:
- Copy the certificate for client configuration or backups.
**Steps**:
-1. Ensure the device certificate is installed (the “👁️ View Certificate” button is enabled).
-2. Click **“👁️ View Certificate.”**
-3. Wait as “🔄 Loading...” appears for 1-2 seconds.
+1. Ensure the device certificate is installed (the “View Certificate” button is enabled).
+2. Click **“View Certificate.”**
+3. Wait as “Loading...” appears for 1-2 seconds.
4. The modal displays the entire PEM content (scrollable).
-5. Optional: click **“📋 Copy to Clipboard”** for reuse.
+5. Optional: click **“Copy to Clipboard”** for reuse.
6. Close the modal when finished.
#### Certificate Inspection
@@ -2680,8 +2787,8 @@ Certificate:
**Purpose**: Install the CA chain (root + intermediate) so clients can validate the device certificate.
**Prerequisites**:
-- ✅ Device certificate installed (Section 5.3.4).
-- ✅ CA chain file in PEM format.
+- Device certificate installed (Section 5.3.4).
+- CA chain file in PEM format.
**Why you need it**:
- Clients need a complete trust path: `Device Cert ← Intermediate CA ← Root CA`.
@@ -2698,13 +2805,13 @@ Certificate:
(Intermediate CA content)
-----END CERTIFICATE-----
```
-3. Click **“🏛️ Install CA.”**
+3. Click **“Install CA.”**
4. Paste the chain into the modal’s text box (all `BEGIN/END` sections).
-5. Click **“🏛️ Install.”**
+5. Click **“Install.”**
6. Wait for validation and storage in NVS.
7. Confirmation steps:
- - “✅ CA chain installed successfully.”
- - Status card shows “✅ Activated” (if the certificate is valid).
+ - “CA chain installed successfully.”
+ - Status card shows “Activated” (if the certificate is valid).
- mTLS configuration is now complete.
#### CA Chain Examples
@@ -2733,8 +2840,8 @@ Certificate:
#### Post-installation Validation
1. Check the status card:
- - Should read “✅ Activated”
- - Validity shows “✅ Valid”
+ - Should read “Activated”
+ - Validity shows “Valid”
- Days remaining should be accurate
2. Test an mTLS client (configured to trust the same CA):
- Connect to the device using an mTLS-aware client.
@@ -2746,9 +2853,9 @@ Certificate:
**Goal**: Install the CA-signed device certificate so mTLS works.
**Prerequisites**:
-- ✅ Key pair must exist.
-- ✅ You have the signed certificate in PEM format.
-- ✅ The certificate was signed from the CSR you generated.
+- Key pair must exist.
+- You have the signed certificate in PEM format.
+- The certificate was signed from the CSR you generated.
**Steps**:
1. Open the certificate file (`device.crt`) on your computer.
@@ -2760,16 +2867,16 @@ Certificate:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxQ=
-----END CERTIFICATE-----
```
-3. Click **“📥 Install Certificate.”**
+3. Click **“Install Certificate.”**
4. Paste the certificate into the “Certificate PEM” field, ensuring the `BEGIN/END` lines are present.
-5. Click **“📥 Install.”**
+5. Click **“Install.”**
6. Wait while the system validates:
- - ✅ Correct PEM format
- - ✅ Certificate matches the private key
- - ✅ Certificate is currently valid (within its validity window)
- - ✅ Subject fields look as expected
+ - Correct PEM format
+ - Certificate matches the private key
+ - Certificate is currently valid (within its validity window)
+ - Subject fields look as expected
7. Confirm when the modal shows:
- - “✅ Certificate installed successfully”
+ - “Certificate installed successfully”
- Displayed certificate details (CN, issuer, validity)
- Status card updates to “Activated” or “Certificate installed, CA chain missing”
@@ -2842,15 +2949,15 @@ If the device has a public domain, use Let’s Encrypt:
#### Timing
-- 🚀 Automated CAs: minutes to seconds
+- Automated CAs: minutes to seconds
- ⏳ Manual CAs: hours to days, depending on the approval chain
#### Files You Should Receive
| File | Required | Description | Format |
|------|----------|-------------|--------|
-| **Device Certificate** | ✅ Yes | CA-signed certificate for the device | `device.crt`, PEM format |
-| **CA Chain** | ✅ Yes | Root CA plus intermediate CA certificates | `ca-chain.pem`, PEM format |
+| **Device Certificate** | Yes | CA-signed certificate for the device | `device.crt`, PEM format |
+| **CA Chain** | Yes | Root CA plus intermediate CA certificates | `ca-chain.pem`, PEM format |
Once you have both files, proceed to Section 5.3.4: Install the device certificate.
@@ -2860,25 +2967,25 @@ Once you have both files, proceed to Section 5.3.4: Install the device certifica
**Purpose**: Produce a CSR to submit to a CA for certificate signing.
**Prerequisites**:
-- ✅ Step 5.3.1 (key pair generated)
-- ✅ The **“📋 Generate CSR”** button is enabled
+- Step 5.3.1 (key pair generated)
+- The **“Generate CSR”** button is enabled
**Steps**:
-1. Click **“📋 Generate CSR.”**
+1. Click **“Generate CSR.”**
2. Fill out the CSR details in the modal:
| Field | Required | Description | Example |
|-------|----------|-------------|---------|
-| **Device ID (CN)** | ❌ No | Common Name identifying the device. Leave blank to use defaults. | `TIANSHAN-RM01-0001`, `DEVICE-AGX-001` |
-| **Organization (O)** | ❌ No | Company or organization name | `HiddenPeak Labs`, `My Company` |
-| **Organizational Unit (OU)** | ❌ No | Department or unit | `Device`, `Production`, `IoT` |
+| **Device ID (CN)** | No | Common Name identifying the device. Leave blank to use defaults. | `TIANSHAN-RM01-0001`, `DEVICE-AGX-001` |
+| **Organization (O)** | No | Company or organization name | `HiddenPeak Labs`, `My Company` |
+| **Organizational Unit (OU)** | No | Department or unit | `Device`, `Production`, `IoT` |
**Notes**:
- CN should follow a structured naming pattern (`prefix-model-serial`).
- O and OU are optional fields for metadata.
- Leaving everything blank lets the system apply defaults (e.g., MAC address-based CN).
-3. Click **“📋 Generate CSR.”**
+3. Click **“Generate CSR.”**
4. Wait ~2-3 seconds as the device:
- Uses the private key and input data to craft a CSR.
- Produces an X.509-compliant CSR (RFC 2986).
@@ -2893,15 +3000,15 @@ Once you have both files, proceed to Section 5.3.4: Install the device certifica
│ -----END CERTIFICATE REQUEST----- │
└───────────────────────────────────────────┘
```
-6. Click **“📋 Copy to Clipboard.”**
+6. Click **“Copy to Clipboard.”**
7. Optionally save the CSR as a file (`device.csr`) for CA submission.
#### CSR Contents
-- ✅ The device’s public key (from the generated key pair).
-- ✅ Subject information (CN, O, OU).
-- ✅ Device signature proving possession of the private key.
-- ❌ **No private key data** is included.
+- The device’s public key (from the generated key pair).
+- Subject information (CN, O, OU).
+- Device signature proving possession of the private key.
+- **No private key data** is included.
#### Next Step
@@ -2910,7 +3017,7 @@ Submit the CSR to your CA for signing as described in Section 5.3.3.
---
### 5.3 Full Certificate Request Flow
-Configuring mTLS from scratch involves five steps.
+Configuring mTLS from scratch involves five steps. Button and modal names below (e.g. “Generate Key Pair,” “Certificate Signing Request (CSR),” “Install Device Certificate,” “Install CA Certificate Chain,” “View Device Certificate”) match the Security page WebUI so you can follow along in the interface.
#### Process Overview
@@ -2935,7 +3042,7 @@ Step 5: Install CA certificate chain (on-device)
**Steps**:
1. **Check status**:
- Look at the certificate status card. If it already shows “Key pair generated,” skip unless you need to regenerate.
-2. **Click “🔑 Generate Key Pair.”**
+2. **Click “Generate Key Pair.”**
3. **Review the prompt**:
```
Generate an ECDSA P-256 key pair for mTLS authentication.
@@ -2943,16 +3050,16 @@ Step 5: Install CA certificate chain (on-device)
4. **Handle the overwrite warning**:
- If keys already exist, a yellow warning appears:
```
- ⚠️ A key pair already exists. Continue will overwrite the current keys!
+ Note: A key pair already exists. Continue will overwrite the current keys!
```
- Overwriting will invalidate any CSR/certificate issued by the old key.
- Only proceed if you understand the impact.
-5. **Start generation** by clicking **“🔑 Generate.”**
+5. **Start generation** by clicking **“Generate.”**
6. **Wait for completion**:
- ECDSA P-256 generation takes ~3-5 seconds.
- The modal displays progress or status.
7. **Confirm success**:
- - It shows “✅ Key pair generated successfully.”
+ - It shows “Key pair generated successfully.”
- Close the modal.
- The status card now shows “Key pair generated, certificate not installed.”
- The buttons for generating CSR, installing certificates, and installing the CA become active.
@@ -2973,18 +3080,18 @@ Step 5: Install CA certificate chain (on-device)
#### Status Card Details
-At the top of the “🔒 HTTPS Certificates” block, a status card shows the certificate state in real time.
+At the top of the “HTTPS Certificates” block, a status card shows the certificate state in real time.
#### Status Icons and Meaning
| Icon | Status Text | Meaning |
|------|-------------|---------|
-| 🔄 | Loading... | Retrieving certificate status |
-| 🔒 | Key pair not generated | No key pair exists yet |
-| 📝 | Key pair generated, certificate not installed | Keys exist but CA certificate is missing |
-| ✅ | Activated | Certificate installed and valid |
-| ⚠️ | Expiring soon | Certificate expires within 30 days—renew promptly |
-| ❌ | Expired | Certificate is invalid; mTLS cannot run |
+| Loading... | Retrieving certificate status |
+| Key pair not generated | No key pair exists yet |
+| Key pair generated, certificate not installed | Keys exist but CA certificate is missing |
+| Activated | Certificate installed and valid |
+| Expiring soon | Certificate expires within 30 days—renew promptly |
+| Expired | Certificate is invalid; mTLS cannot run |
#### Certificate Details (Installed)
@@ -2997,21 +3104,26 @@ When the certificate shows “Activated” or “Expiring soon,” the card expa
| **Valid From** | Certificate start time | `2026-01-27 00:00:00` |
| **Expires On** | Certificate end time | `2027-01-27 00:00:00` |
| **Serial Number** | Hexadecimal identifier | `01:23:45:67:89:AB` |
-| **Validity** | Is the certificate currently valid? | ✅ Valid / ❌ Expired |
+| **Validity** | Is the certificate currently valid? | Valid / Expired |
| **Days Remaining** | Days until expiration | `365 days`, `28 days` (warning appears if < 30) |
+**Status card display rules**:
+- **Days remaining** is shown only when a certificate is installed and within its validity period; it is not shown when no certificate is installed or when the certificate has expired.
+- **“Expiring soon”** state/badge appears when the certificate is still valid but has fewer than 30 days until expiry; renew as soon as possible.
+- The expanded details (Subject CN, Issuer, Valid From/Expires On, Serial Number, Validity, Days Remaining) are only visible when the status is “Activated” or “Expiring soon.”
+
#### Button States
Six action buttons are located beneath the HTTPS certificate block. Their enabled/disabled state depends on the current status:
| Button | No Key Pair | Key Pair Generated | Certificate Installed | Notes |
|--------|-------------|--------------------|------------------------|-------|
-| 🔑 Generate Key Pair | ✅ Enabled | ✅ Enabled | ✅ Enabled | Always available (will overwrite existing keys). |
-| 📋 Generate CSR | ❌ Disabled | ✅ Enabled | ✅ Enabled | Requires an existing key pair. |
-| 📥 Install Certificate | ❌ Disabled | ✅ Enabled | ✅ Enabled | Requires key pair. |
-| 🏛️ Install CA | ❌ Disabled | ✅ Enabled | ✅ Enabled | Requires key pair. |
-| 👁️ View Certificate | ❌ Disabled | ❌ Disabled | ✅ Enabled | Needs an installed certificate. |
-| 🗑️ Delete Credentials | ❌ Disabled | ✅ Enabled | ✅ Enabled | Available when keys or certificates exist. |
+| Generate Key Pair | Enabled | Enabled | Enabled | Always available (will overwrite existing keys). |
+| Generate CSR | Disabled | Enabled | Enabled | Requires an existing key pair. |
+| Install Certificate | Disabled | Enabled | Enabled | Requires key pair. |
+| Install CA | Disabled | Enabled | Enabled | Requires key pair. |
+| View Certificate | Disabled | Disabled | Enabled | Needs an installed certificate. |
+| Delete Credentials | Disabled | Enabled | Enabled | Available when keys or certificates exist. |
---
## FAQs & Troubleshooting
@@ -3051,16 +3163,16 @@ Six action buttons are located beneath the HTTPS certificate block. Their enable
- `_`: `project_a_01`, `iot_device_001`
**Avoid**:
-- ❌ `key1`, `test`, `temp`
-- ❌ Non-ASCII or special characters
-- ❌ Excessively long names
+- `key1`, `test`, `temp`
+- Non-ASCII or special characters
+- Excessively long names
#### 2. Selecting key types
**Suggested approach**:
-- 🎯 Daily work: RSA 2048-bit (speed plus compatibility)
-- 🎯 High-security: RSA 4096-bit (stronger but slower)
-- ⚠️ ECDSA: Use only for HTTPS certificates, not SSH
+- Daily work: RSA 2048-bit (speed plus compatibility)
+- High-security: RSA 4096-bit (stronger but slower)
+- ECDSA: Use only for HTTPS certificates, not SSH
**Capacity planning**:
- RSA 2048: ~12 keys
@@ -3070,7 +3182,7 @@ Six action buttons are located beneath the HTTPS certificate block. Their enable
#### 3. Controlling private key export
Best practices:
-- 🔒 Production keys: leave “Allow Private Key Export” unchecked.
+- Production keys: leave “Allow Private Key Export” unchecked.
- 🔓 Backup keys: enable export and store in offline media.
- 🧪 Test keys: keep non-exportable and regenerate if needed.
@@ -3099,20 +3211,20 @@ Recommended cadence:
#### Q16: Can admin users use all security page functions?
-**Answer**: ✅ Yes.
+**Answer**: Yes.
**admin privileges**:
-- ✅ Access to every security page feature.
-- ✅ Access to System, Network, and Files pages.
-- ❌ Cannot access Terminal, Automation, or Command pages (root only).
+- Access to every security page feature.
+- Access to System, Network, and Files pages.
+- Cannot access Terminal, Automation, or Command pages (root only).
**Security page capabilities**:
-- ✅ Generate, delete, and export SSH keys.
-- ✅ Deploy and revoke public keys on remote servers.
-- ✅ Manage deployed host records.
-- ✅ View/delete known host fingerprints.
-- ✅ Generate, install, and delete HTTPS certificates.
-- ✅ Generate CSRs and install CA chains.
+- Generate, delete, and export SSH keys.
+- Deploy and revoke public keys on remote servers.
+- Manage deployed host records.
+- View/delete known host fingerprints.
+- Generate, install, and delete HTTPS certificates.
+- Generate CSRs and install CA chains.
**Need root functionality?**
- Contact your administrator to log in as root.
@@ -3122,7 +3234,7 @@ Recommended cadence:
#### Q17: “Insufficient permissions” when exporting private keys?
-**Symptom**: The **“🔐 Private Key”** button is greyed out or shows “Export not allowed.”
+**Symptom**: The **“Private Key”** button is greyed out or shows “Export not allowed.”
**Reason**: The key was created without “Allow Private Key Export.”
@@ -3147,31 +3259,31 @@ Recommended cadence:
- Use the WebUI deploy feature instead of exporting the private key.
**Design principle**:
-- 🔒 Private keys are the most sensitive assets—minimize export.
-- 🔒 Only export when necessary (backup/migration).
-- 🔒 Defaults prevent accidental leaks.
+- Private keys are the most sensitive assets—minimize export.
+- Only export when necessary (backup/migration).
+- Defaults prevent accidental leaks.
---
#### Q14: Certificate state shows “Expiring soon”?
-**Symptom**: The status card shows ⚠️ “Expiring soon” with remaining days < 30.
+**Symptom**: The status card shows “Expiring soon” with remaining days < 30.
**Recommendations**:
-- 🟢 **30-15 days**: Prepare to renew, but not urgent yet.
-- 🟡 **15-7 days**: Renew as soon as possible to avoid service impact.
-- 🔴 **<7 days**: Handle immediately.
+- **30-15 days**: Prepare to renew, but not urgent yet.
+- **15-7 days**: Renew as soon as possible to avoid service impact.
+- **<7 days**: Handle immediately.
**Renewal steps (keep the same key)**:
-1. Click **“📋 Generate CSR”** (you can reuse the same CN).
+1. Click **“Generate CSR”** (you can reuse the same CN).
2. Submit the CSR to your CA and request renewal.
-3. Install the new certificate via **“📥 Install Certificate.”** Paste the renewed certificate; the old one is overwritten.
+3. Install the new certificate via **“Install Certificate.”** Paste the renewed certificate; the old one is overwritten.
4. Check the status card reflects the new expiration and days remaining.
**Notes**:
-- ✅ Old certificate remains usable until it expires.
-- ✅ The new certificate becomes active immediately.
-- ✅ The CA chain usually does not timeout at the same time; update only if necessary.
-- ⚠️ If the CA chain itself is expired, renew it along with the device certificate.
+- Old certificate remains usable until it expires.
+- The new certificate becomes active immediately.
+- The CA chain usually does not timeout at the same time; update only if necessary.
+- If the CA chain itself is expired, renew it along with the device certificate.
---
@@ -3211,32 +3323,32 @@ Recommended cadence:
**Fix**:
**Option 1: Regenerate the CSR**
-1. Click **“📋 Generate CSR”** again on the device.
+1. Click **“Generate CSR”** again on the device.
2. Copy the new CSR.
3. Submit it to the CA.
4. Install the newly signed certificate.
**Option 2: Delete credentials and restart**
-1. Click **“🗑️ Delete Credentials.”**
+1. Click **“Delete Credentials.”**
2. Begin from Section 5.3.1 (generate key pair).
3. Follow the full flow to ensure CSR, signing, and installation all use the same key.
**Prevention**:
-- ✅ Do not regenerate the key pair after creating a CSR.
-- ✅ Confirm the CSR filename (e.g., `device-001.csr`) and certificate file correspond.
-- ✅ Label files clearly to avoid confusion.
+- Do not regenerate the key pair after creating a CSR.
+- Confirm the CSR filename (e.g., `device-001.csr`) and certificate file correspond.
+- Label files clearly to avoid confusion.
---
### 7.4 HTTPS Certificate Issues
#### Q12: “Generate CSR” button is greyed out?
-**Symptom**: The **“📋 Generate CSR”** button is disabled (greyed).
+**Symptom**: The **“Generate CSR”** button is disabled (greyed).
**Reason**: A key pair has not been generated. CSR signing requires a private key.
**Fix**:
-1. Click **“🔑 Generate Key Pair.”**
+1. Click **“Generate Key Pair.”**
2. Wait for the key pair to finish.
3. The CSR button (and Install Certificate/Install CA buttons) will enable automatically.
@@ -3247,24 +3359,24 @@ Recommended cadence:
---
#### Q10: How to handle Host Fingerprint mismatch warnings?
-**Symptom**: A red warning pops up: “⚠️ Security Warning: Host fingerprint mismatch.”
+**Symptom**: A red warning pops up: “Security Warning: Host fingerprint mismatch.”
**Correct handling** (see Section 4.4):
1. **🛑 Stop immediately**: Do not click “Update Host Key” without confirmation.
2. **📞 Contact the administrator**: Ask if the server was rebuilt or the host key changed.
-3. **✅ If legitimate**: Click “Update Host Key,” then reconnect and trust the new fingerprint.
-4. **❌ If uncertain**: Click “Cancel” and investigate the network/security environment.
+3. **If legitimate**: Click “Update Host Key,” then reconnect and trust the new fingerprint.
+4. **If uncertain**: Click “Cancel” and investigate the network/security environment.
**Mistakes to avoid**:
-- ❌ Clicking “Update Host Key” automatically (could signal an MITM attack).
-- ❌ Ignoring the warning and forcing the connection.
-- ❌ Assuming it’s a bug—this is a critical security feature.
+- Clicking “Update Host Key” automatically (could signal an MITM attack).
+- Ignoring the warning and forcing the connection.
+- Assuming it’s a bug—this is a critical security feature.
**Security reminder**:
-- 🔴 A fingerprint mismatch is a serious warning.
-- 🔴 Always verify before trusting.
-- 🔴 Frequent warnings may indicate an insecure network.
+- A fingerprint mismatch is a serious warning.
+- Always verify before trusting.
+- Frequent warnings may indicate an insecure network.
---
@@ -3340,18 +3452,36 @@ hosts --list --json
**Cause**: Only hosts deployed via the WebUI appear in the list.
**Not recorded scenarios**:
-- ❌ Deployments via CLI (`ssh --copyid`).
-- ❌ Manually appending the public key to `authorized_keys`.
-- ❌ Keys deployed on other devices or via different tools.
+- Deployments via CLI (`ssh --copyid`).
+- Manually appending the public key to `authorized_keys`.
+- Keys deployed on other devices or via different tools.
**Resolution**:
- If you want WebUI management, redeploy the key through the UI.
- Alternatively, use CLI commands like `hosts --deployed` to view/manage hosts.
+- Or use “Import Host” to add hosts from a .tscfg config package so the list matches your actual setup.
**Design note**:
- Records are stored locally in `ts_ssh_hosts_config`.
- Only WebUI or specific API deployments are tracked to provide a unified management interface.
+---
+#### Q8b: “Signature verification failed” when importing host or config pack?
+
+**Symptom**: After choosing or pasting a .tscfg in “Import Host” or “Import config pack,” you see a signature verification or decryption error.
+
+**Possible causes**:
+- The .tscfg file is corrupted or incomplete (missing headers/footers or truncated).
+- The pack was not signed with a certificate trusted by this (or the target) device.
+- Device system time is wrong, so certificate validity checks fail.
+- Pasted JSON is malformed (extra spaces, missing quotes, etc.).
+
+**What to do**:
+1. **Check file integrity**: Re-obtain the .tscfg and ensure it includes full `-----BEGIN ...-----` / `-----END ...-----` blocks, or re-export.
+2. **Confirm signer**: Ensure the pack was signed by this device’s certificate or a trusted official/target certificate; for “self-encrypt” host export, import on the same device or one that has the same certificate.
+3. **Fix device time**: In System/Network, verify date and time (and NTP sync if needed).
+4. **Use “Verify only”**: In the config pack import modal, click “Verify only” first and use the reported error (e.g. signer, certificate CN) to narrow down the issue.
+
---
#### Q7: Deployment succeeded but password is still requested?
@@ -3490,7 +3620,7 @@ hosts --list --json
**Method 1: Export the private key (requires prior permission)**:
1. Enable **“Allow Private Key Export”** when generating the key.
-2. After creation, click **“🔐 Private Key.”**
+2. After creation, click **“Private Key.”**
3. Download the `.pem` file.
4. Store it on encrypted offline media (USB drive, password manager).
@@ -3686,7 +3816,7 @@ The following docs provide additional technical depth and troubleshooting guidan
#### 2. Test immediately after deployment
**Workflow**:
-1. After deployment, click **“🔍 Test.”**
+1. After deployment, click **“Test.”**
2. Ensure the connection succeeds.
3. If it fails, fix issues immediately.
diff --git a/help/security-guide.mdx b/help/security-guide.mdx
index bc46d7e..cdeb744 100644
--- a/help/security-guide.mdx
+++ b/help/security-guide.mdx
@@ -9,6 +9,7 @@ keywords:
- 已知主机指纹
- HTTPS 证书
- mTLS
+ - 配置包
- admin 用户
- 操作指南
---
@@ -34,16 +35,18 @@ keywords:
作为 **admin 用户**,您可以使用安全页面的**所有功能**,包括:
-- ✅ 生成、删除、导出 SSH 密钥
-- ✅ 部署公钥到远程服务器
-- ✅ 撤销已部署的公钥
-- ✅ 管理已知主机指纹
-- ✅ 生成和管理 HTTPS 证书
+- 生成、删除、导出 SSH 密钥
+- 部署公钥到远程服务器
+- 撤销已部署的公钥
+- 管理已知主机指纹
+- 生成和管理 HTTPS 证书
+- 管理配置包(导入、导出、查看)
**注意**:以下页面需要 **root 权限**,admin 用户无法访问:
-- ❌ 终端页面
-- ❌ 自动化页面
-- ❌ 指令页面
+
+- 终端页面
+- 自动化页面
+- 指令页面
### 如何进入安全页面
@@ -54,14 +57,15 @@ keywords:
### 页面结构概览
-安全页面从上到下分为四个区块:
+安全页面从上到下分为五个区块:
| 区块 | 功能概述 |
|------|----------|
-| **🔑 密钥管理** | 生成、查看、导出、部署、撤销、删除 SSH 密钥 |
-| **🖥️ 已部署主机** | 管理已部署公钥的远程服务器列表,测试连接、撤销公钥、移除记录 |
-| **🔐 已知主机指纹** | 查看和删除 SSH 服务器指纹,防止中间人攻击 |
-| **🔒 HTTPS 证书** | 生成设备证书、CSR、安装 CA 签发的证书,配置 mTLS |
+| **密钥管理** | 生成、查看、导出、部署、撤销、删除 SSH 密钥 |
+| **已部署主机** | 管理已部署公钥的远程服务器列表;支持导入主机配置;测试连接、撤销公钥、移除记录 |
+| **已知主机指纹** | 查看和删除 SSH 服务器指纹,防止中间人攻击 |
+| **HTTPS 证书** | 生成设备证书、CSR、安装 CA 签发的证书,配置 mTLS |
+| **配置包 (Config Pack)** | 导出设备证书、导入/导出加密配置包、查看配置包列表,用于设备间安全配置分发 |
---
@@ -73,29 +77,29 @@ keywords:
#### 操作步骤
-1. **进入密钥管理区域**:在安全页面顶部找到「🔑 密钥管理」区块
-2. **点击生成按钮**:点击 **「➕ 生成新密钥」** 按钮
-3. **填写生成表单**:在弹出的「🔑 生成新密钥」弹窗中填写以下信息:
+1. **进入密钥管理区域**:在安全页面顶部找到「密钥管理」区块
+2. **点击生成按钮**:点击 **「生成新密钥」** 按钮
+3. **填写生成表单**:在弹出的「生成新密钥」弹窗中填写以下信息:
#### 表单字段详解
| 字段 | 必填 | 说明 | 填写示例 |
|------|------|------|----------|
-| **密钥 ID** | ✅ 是 | 密钥的唯一标识符,用于后续引用。命名规则:字母、数字、下划线,不可重复 | `default`、`agx_key`、`lpmu_prod` |
-| **密钥类型** | ✅ 是 | 选择加密算法和密钥长度 | 见下方「密钥类型选择」 |
-| **备注** | ❌ 否 | 密钥的用途说明,便于日后识别 | `用于连接 AGX Orin`、`测试环境密钥` |
-| **别名** | ❌ 否 | 替代密钥 ID 显示的友好名称,启用「隐藏密钥」时建议填写 | `AGX 生产环境`、`主服务器密钥` |
-| **允许导出私钥** | ❌ 否 | 勾选后可导出私钥进行备份或迁移。**安全风险**:私钥泄露可导致未授权访问 | 仅在需要备份时勾选 |
-| **隐藏密钥 ID** | ❌ 否 | 勾选后低权限用户无法看到真实密钥 ID,仅显示别名或掩码,适用于多用户环境 | 多人共用设备时勾选 |
+| **密钥 ID** | 是 | 密钥的唯一标识符,用于后续引用。命名规则:字母、数字、下划线,不可重复 | `default`、`agx_key`、`lpmu_prod` |
+| **密钥类型** | 是 | 选择加密算法和密钥长度 | 见下方「密钥类型选择」 |
+| **备注** | 否 | 密钥的用途说明,便于日后识别 | `用于连接 AGX Orin`、`测试环境密钥` |
+| **别名** | 否 | 替代密钥 ID 显示的友好名称,启用「隐藏密钥」时建议填写 | `AGX 生产环境`、`主服务器密钥` |
+| **允许导出私钥** | 否 | 勾选后可导出私钥进行备份或迁移。**安全风险**:私钥泄露可导致未授权访问 | 仅在需要备份时勾选 |
+| **隐藏密钥 ID** | 否 | 勾选后低权限用户无法看到真实密钥 ID,仅显示别名或掩码,适用于多用户环境 | 多人共用设备时勾选 |
#### 密钥类型选择
| 类型 | 密钥长度 | 生成时间 | 兼容性 | 推荐场景 |
|------|----------|----------|--------|----------|
-| **RSA 2048-bit** | 2048 位 | 5-10 秒 | ⭐⭐⭐⭐⭐ | **推荐**:日常使用,兼容性最好 |
-| **RSA 4096-bit** | 4096 位 | 30-60 秒 | ⭐⭐⭐⭐⭐ | 高安全场景,生成较慢 |
-| **ECDSA P-256** | 256 位 | 3-5 秒 | ⭐⭐⭐ | ⚠️ **当前不支持 SSH 公钥认证** |
-| **ECDSA P-384** | 384 位 | 3-5 秒 | ⭐⭐⭐ | ⚠️ **当前不支持 SSH 公钥认证** |
+| **RSA 2048-bit** | 2048 位 | 5-10 秒 | 兼容性最好 | **推荐**:日常使用 |
+| **RSA 4096-bit** | 4096 位 | 30-60 秒 | 兼容性最好 | 高安全场景,生成较慢 |
+| **ECDSA P-256** | 256 位 | 3-5 秒 | 一般 | **注意**:当前不支持 SSH 公钥认证 |
+| **ECDSA P-384** | 384 位 | 3-5 秒 | 一般 | **注意**:当前不支持 SSH 公钥认证 |
**重要提示**:当前版本 ECDSA 密钥暂不支持 SSH 公钥认证,请选择 **RSA 2048-bit** 或 **RSA 4096-bit**。
@@ -126,36 +130,36 @@ keywords:
#### 前提条件
-- ✅ 已在「密钥管理」中生成至少一个密钥
-- ✅ 知道远程服务器的 IP 地址或主机名
-- ✅ 知道远程服务器的用户名和密码(用于首次部署)
-- ✅ 设备与远程服务器网络连通
+- 已在「密钥管理」中生成至少一个密钥
+- 知道远程服务器的 IP 地址或主机名
+- 知道远程服务器的用户名和密码(用于首次部署)
+- 设备与远程服务器网络连通
#### 操作步骤
1. **选择密钥**:在「密钥管理」表格中找到要部署的密钥行
-2. **点击部署按钮**:点击该密钥行最右侧的 **「🚀 部署」** 按钮(蓝色)
-3. **填写部署表单**:在弹出的「🚀 部署公钥到远程服务器」弹窗中填写:
+2. **点击部署按钮**:点击该密钥行最右侧的 **「部署」** 按钮(蓝色)
+3. **填写部署表单**:在弹出的「部署公钥到远程服务器」弹窗中填写:
#### 部署表单字段
| 字段 | 必填 | 说明 | 填写示例 |
|------|------|------|----------|
-| **目标主机** | ✅ 是 | 远程服务器的 IP 地址或主机名 | `192.168.55.100`、`agx.local`、`10.10.99.98` |
-| **用户名** | ✅ 是 | 远程服务器的登录用户名 | `root`、`nvidia`、`ubuntu` |
-| **端口** | ❌ 否 | SSH 服务端口,默认 22。如果服务器使用非标准端口需修改 | `22`(默认)、`2222`、`22022` |
-| **认证密码** | ✅ 是 | 首次部署时用于身份验证的密码。部署成功后,后续连接无需密码 | 您的服务器登录密码 |
+| **目标主机** | 是 | 远程服务器的 IP 地址或主机名 | `192.168.55.100`、`agx.local`、`10.10.99.98` |
+| **用户名** | 是 | 远程服务器的登录用户名 | `root`、`nvidia`、`ubuntu` |
+| **端口** | 否 | SSH 服务端口,默认 22。如果服务器使用非标准端口需修改 | `22`(默认)、`2222`、`22022` |
+| **认证密码** | 是 | 首次部署时用于身份验证的密码。部署成功后,后续连接无需密码 | 您的服务器登录密码 |
-4. **开始部署**:点击 **「🚀 开始部署」** 按钮
+4. **开始部署**:点击 **「开始部署」** 按钮
5. **查看进度**:弹窗中会显示部署过程输出,包括:
- 连接服务器
- 验证主机密钥(首次连接会提示信任指纹,详见「任务三」)
- 上传公钥到 `~/.ssh/authorized_keys`
- 验证部署结果
6. **确认成功**:
- - 显示「✅ 公钥部署成功」
- - 显示「✅ 连接验证成功」
- - 该主机自动添加到「🖥️ 已部署主机」列表
+ - 显示「公钥部署成功」
+ - 显示「连接验证成功」
+ - 该主机自动添加到「已部署主机」列表
#### 部署原理
@@ -185,12 +189,12 @@ keywords:
#### 在 WebUI 中测试连接
-1. **进入已部署主机区域**:滚动到「🖥️ 已部署主机」表格
+1. **进入已部署主机区域**:滚动到「已部署主机」表格
2. **找到目标主机**:在列表中找到刚才部署的主机
-3. **点击测试按钮**:点击该主机行的 **「🔍 测试」** 按钮
+3. **点击测试按钮**:点击该主机行的 **「测试」** 按钮
4. **查看结果**:
- - ✅ **成功**:显示「连接成功」和远程用户名
- - ❌ **失败**:显示错误信息(网络问题、密钥不匹配、服务器配置等)
+ - **成功**:显示「连接成功」和远程用户名
+ - **失败**:显示错误信息(网络问题、密钥不匹配、服务器配置等)
#### 在终端中使用密钥连接
@@ -241,37 +245,37 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
#### 何时需要撤销
-- 🚫 不再需要访问该服务器
-- 🔒 密钥可能泄露,需要更换
-- 🔄 服务器用户变更,需要清理旧密钥
-- 🧹 定期安全审查,清理过期访问权限
+- 不再需要访问该服务器
+- 密钥可能泄露,需要更换
+- 服务器用户变更,需要清理旧密钥
+- 定期安全审查,清理过期访问权限
#### 撤销方式一:从密钥管理撤销
**适用场景**:知道具体要撤销哪个密钥、哪个服务器
1. **选择密钥**:在「密钥管理」表格中找到要撤销的密钥
-2. **点击撤销按钮**:点击 **「⚠️ 撤销」** 按钮(橙色)
+2. **点击撤销按钮**:点击 **「撤销」** 按钮(橙色)
3. **填写撤销表单**:
| 字段 | 必填 | 说明 |
|------|------|------|
-| **目标主机** | ✅ 是 | 要撤销公钥的服务器地址 |
-| **用户名** | ✅ 是 | 服务器登录用户名 |
-| **端口** | ❌ 否 | SSH 端口,默认 22 |
-| **认证密码** | ✅ 是 | 服务器密码(因为密钥可能已失效,需要密码认证) |
+| **目标主机** | 是 | 要撤销公钥的服务器地址 |
+| **用户名** | 是 | 服务器登录用户名 |
+| **端口** | 否 | SSH 端口,默认 22 |
+| **认证密码** | 是 | 服务器密码(因为密钥可能已失效,需要密码认证) |
-4. **确认撤销**:点击 **「⚠️ 撤销公钥」** 按钮
+4. **确认撤销**:点击 **「撤销公钥」** 按钮
5. **查看结果**:
- - ✅ 显示从 `authorized_keys` 中删除了几行公钥
- - ✅ 本地「已部署主机」记录自动删除
+ - 显示从 `authorized_keys` 中删除了几行公钥
+ - 本地「已部署主机」记录自动删除
#### 撤销方式二:从已部署主机撤销
**适用场景**:在「已部署主机」列表中快速撤销
-1. **进入已部署主机区域**:滚动到「🖥️ 已部署主机」表格
-2. **点击撤销按钮**:在目标主机行点击 **「🔓 撤销」** 按钮(红色)
+1. **进入已部署主机区域**:滚动到「已部署主机」表格
+2. **点击撤销按钮**:在目标主机行点击 **「撤销」** 按钮(红色)
3. **输入密码**:在弹出的撤销确认弹窗中输入服务器密码
4. **确认撤销**:点击 **「撤销并移除」** 按钮
5. **等待完成**:系统会:
@@ -288,7 +292,7 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
**操作步骤**:
1. 在「已部署主机」表格中找到目标主机
-2. 点击 **「🗑️ 移除」** 按钮(灰色)
+2. 点击 **「移除」** 按钮(灰色)
3. 确认移除
4. 本地记录删除,远程服务器的 `authorized_keys` **不会**被修改
@@ -296,8 +300,8 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
| 操作 | 远程公钥 | 本地记录 | 需要密码 | 适用场景 |
|------|----------|----------|----------|----------|
-| **撤销** | ✅ 删除 | ✅ 删除 | ✅ 需要 | 彻底取消访问权限 |
-| **移除** | ❌ 保留 | ✅ 删除 | ❌ 不需要 | 清理本地记录,保留远程访问 |
+| **撤销** | 删除 | 删除 | 需要 | 彻底取消访问权限 |
+| **移除** | 保留 | 删除 | 不需要 | 清理本地记录,保留远程访问 |
---
@@ -312,11 +316,11 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
**操作步骤**:
1. 在「密钥管理」表格中找到目标密钥
-2. 点击 **「📤 公钥」** 按钮
+2. 点击 **「公钥」** 按钮
3. 在弹出的「公钥导出」弹窗中:
- 查看 OpenSSH 格式的公钥内容(如 `ssh-rsa AAAAB3NzaC1yc2E...`)
- - 点击 **「📋 复制到剪贴板」** 复制内容
- - 或点击 **「💾 下载文件」** 保存为 `.pub` 文件
+ - 点击 **「复制到剪贴板」** 复制内容
+ - 或点击 **「下载文件」** 保存为 `.pub` 文件
4. **使用公钥**:
- 粘贴到远程服务器的 `~/.ssh/authorized_keys` 文件
@@ -325,34 +329,34 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
#### 导出私钥
**重要安全警告**:私钥是高度敏感的安全凭证,泄露后任何人都可以使用它访问已部署的服务器。仅在以下场景导出私钥:
-- 🔒 密钥备份(存储在安全的离线介质)
-- 🔄 密钥迁移到其他设备
-- 🛠️ 在其他 SSH 客户端(如桌面电脑)使用该密钥
+- 密钥备份(存储在安全的离线介质)
+- 密钥迁移到其他设备
+- 在其他 SSH 客户端(如桌面电脑)使用该密钥
**前提条件**:
- 密钥生成时勾选了 **「允许导出私钥」**
-- 如果未勾选,该密钥的「🔐 私钥」按钮会显示为灰色不可用
+- 如果未勾选,该密钥的「私钥」按钮会显示为灰色不可用
**操作步骤**:
1. 在「密钥管理」表格中找到可导出的密钥
-2. 点击 **「🔐 私钥」** 按钮
+2. 点击 **「私钥」** 按钮
3. **阅读安全警告**:系统会弹出警告对话框,提示私钥安全风险
4. **确认继续**:点击「确定」
5. 在「私钥导出」弹窗中:
- 查看 PEM 格式的私钥内容(`-----BEGIN RSA PRIVATE KEY-----` ...)
- - 点击 **「📋 复制到剪贴板」** 复制内容
- - 或点击 **「💾 下载文件」** 保存为 `.pem` 文件
+ - 点击 **「复制到剪贴板」** 复制内容
+ - 或点击 **「下载文件」** 保存为 `.pem` 文件
#### 私钥安全处理建议
导出私钥后,务必遵循以下安全实践:
1. **安全传输**:
- - ❌ 不要通过电子邮件发送私钥
- - ❌ 不要在聊天软件中粘贴私钥
- - ❌ 不要上传到云存储(除非加密)
- - ✅ 使用加密的 U 盘、移动硬盘
- - ✅ 本地加密后再传输
+ - 不要通过电子邮件发送私钥
+ - 不要在聊天软件中粘贴私钥
+ - 不要上传到云存储(除非加密)
+ - 使用加密的 U 盘、移动硬盘
+ - 本地加密后再传输
2. **安全存储**:
- 存储在加密的磁盘或保险柜
@@ -384,17 +388,17 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
#### 操作步骤
1. **选择密钥**:在「密钥管理」表格中找到要删除的密钥
-2. **点击删除按钮**:点击 **「🗑️ 删除」** 按钮(红色)
+2. **点击删除按钮**:点击 **「删除」** 按钮(红色)
3. **确认删除**:系统会弹出确认对话框,提示删除后无法恢复
4. **最终确认**:点击「确定」执行删除
5. **验证结果**:密钥从列表中消失
#### 删除后果
-- ✅ 密钥从 NVS 永久删除,释放存储空间
-- ⚠️ 已部署主机记录**仍然保留**(需手动撤销或移除)
-- ❌ 无法使用该密钥连接已部署的服务器(除非重新生成并部署)
-- ❌ 无法恢复(除非之前导出了私钥备份)
+- 密钥从 NVS 永久删除,释放存储空间
+- 已部署主机记录**仍然保留**(需手动撤销或移除)
+- 无法使用该密钥连接已部署的服务器(除非重新生成并部署)
+- 无法恢复(除非之前导出了私钥备份)
#### 删除密钥后的清理工作
@@ -414,6 +418,36 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
「已部署主机」区块记录了哪些远程服务器已部署了设备的公钥,方便您统一管理和快速测试连接。
+### 3.0 导入主机配置(可选)
+
+若您通过终端 CLI(如 `ssh --copyid`)或手动方式将公钥部署到了远程服务器,这些主机不会自动出现在「已部署主机」列表中。您可以通过**导入主机配置**,将来自其他设备或备份的 SSH 主机配置(.tscfg 配置包)导入到本设备,使列表与实际情况一致,便于在 WebUI 中统一测试、撤销或移除。
+
+**操作步骤**:
+
+1. **进入已部署主机区域**:在安全页面找到「已部署主机」区块,右侧有 **「导入主机」** 按钮
+2. **点击导入主机**:点击 **「导入主机」** 按钮,打开「导入 SSH 主机配置」弹窗
+3. **选择文件**:选择本地的 `.tscfg` 配置包文件(通常由其他设备的「导出主机配置」或配置包系统生成)
+4. **预览与确认**:系统会验证配置包签名并显示配置 ID、签名者、备注;若该配置已存在会提示是否覆盖
+5. **可选**:勾选「覆盖已存在的配置」以覆盖同 ID 的现有配置
+6. **确认导入**:点击 **「确认导入」**,导入成功后刷新页面即可在「已部署主机」列表中看到对应记录
+
+**说明**:导入的配置包需为有效的、经签名的 SSH 主机配置格式;仅用于同步「已部署主机」列表,不会修改远程服务器上的 `authorized_keys`。
+
+### 3.0.1 导出主机配置(单条)
+
+在「已部署主机」表格中,每一行主机都有 **「导出」** 按钮,可将该主机的配置导出为加密的 `.tscfg` 文件,用于备份或导入到另一台设备。
+
+**操作步骤**:
+
+1. **选择主机**:在「已部署主机」表格中找到要导出的主机
+2. **点击导出**:点击该行的 **「导出」** 按钮(蓝色),打开「导出 SSH 主机配置」弹窗
+3. **目标设备证书(可选)**:
+ - **留空**:使用本机证书加密(自加密),导出的 .tscfg 只能在本机或拥有本机证书的设备上解密,适合备份
+ - **粘贴目标设备证书 PEM**:若要将该主机配置发给另一台设备,可粘贴对方在「配置包」区块导出的设备证书,导出的 .tscfg 仅该设备能解密并导入
+4. **确认导出**:点击 **「导出」**,系统生成 .tscfg 并提示下载或保存路径
+
+**典型用途**:备份单台主机配置、在多台 TianshanOS 设备间同步同一主机配置、与「导入主机」配合完成设备迁移。
+
### 3.1 查看已部署主机列表
#### 列表字段说明
@@ -424,14 +458,15 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
| **地址** | 远程服务器的 IP 地址或主机名 | `192.168.55.100`、`10.10.99.98` |
| **端口** | SSH 服务端口 | `22`、`2222` |
| **用户名** | 远程登录用户 | `nvidia`、`root`、`ubuntu` |
-| **部署密钥** | 使用的密钥 ID(显示为徽章) | 🔑 `agx_key`、🔑 `default` |
+| **部署密钥** | 使用的密钥 ID(显示为徽章) | `agx_key`、`default` |
+| **操作** | 每行可用按钮 | 测试、导出、撤销、移除(见下文各小节) |
#### 列表何时更新
-- ✅ 通过 WebUI「部署」功能成功部署后自动添加
-- ✅ 通过 WebUI「撤销」功能撤销后自动删除
-- ✅ 手动点击「移除」后删除
-- ❌ **注意**:通过终端 CLI 或手动添加到 `authorized_keys` 的主机**不会**自动出现在此列表
+- 通过 WebUI「部署」功能成功部署后自动添加
+- 通过 WebUI「撤销」功能撤销后自动删除
+- 手动点击「移除」后删除
+- **注意**:通过终端 CLI 或手动添加到 `authorized_keys` 的主机**不会**自动出现在此列表;可使用「导入主机」导入 .tscfg 配置包以同步列表
#### 空列表处理
@@ -440,6 +475,10 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
- 请按「任务一 2.2」的步骤部署公钥
- 部署成功后主机会自动出现在此列表
+#### 与指令页面的关系
+
+**指令**页面(需 root 权限)中「选择主机」下拉列表的数据来源即为本安全页的「已部署主机」。在指令页导出指令配置时,可选择**同时导出依赖的主机配置**,便于在另一台设备上导入指令时一并导入所需主机,无需单独再在安全页导入主机。
+
---
### 3.2 测试 SSH 连接
@@ -449,7 +488,7 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
#### 操作步骤
1. **选择主机**:在「已部署主机」表格中找到要测试的主机
-2. **点击测试按钮**:点击 **「🔍 测试」** 按钮
+2. **点击测试按钮**:点击 **「测试」** 按钮
3. **等待测试**:系统会执行以下操作:
- 使用部署的密钥连接服务器
- 执行简单命令(如 `whoami`)验证连接
@@ -460,7 +499,7 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
**成功示例**:
```
-✅ SSH 连接测试成功
+SSH 连接测试成功
主机:192.168.55.100:22
用户:nvidia
命令:whoami
@@ -469,7 +508,7 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
**失败示例**:
```
-❌ SSH 连接测试失败
+SSH 连接测试失败
错误:连接超时(Connection timeout)
建议:检查网络连通性和防火墙设置
```
@@ -497,8 +536,8 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
| 操作 | 本地记录 | 远程公钥 | 适用场景 |
|------|----------|----------|----------|
-| **撤销** | ✅ 删除 | ✅ 删除 | 需要彻底取消访问权限 |
-| **移除** | ✅ 删除 | ❌ 保留 | 服务器已停用、公钥已手动删除、仅清理本地 |
+| **撤销** | 删除 | 删除 | 需要彻底取消访问权限 |
+| **移除** | 删除 | 保留 | 服务器已停用、公钥已手动删除、仅清理本地 |
#### 适用场景
@@ -510,7 +549,7 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
#### 操作步骤
1. **选择主机**:在「已部署主机」表格中找到目标主机
-2. **点击移除按钮**:点击 **「🗑️ 移除」** 按钮(灰色)
+2. **点击移除按钮**:点击 **「移除」** 按钮(灰色)
3. **确认移除**:系统弹出确认对话框
4. **最终确认**:点击「确定」
5. **验证结果**:主机从列表中消失
@@ -537,9 +576,9 @@ ssh --test --host 192.168.1.100 --user nvidia --keyid agx_key
#### 指纹的作用
-- 🛡️ **防止中间人攻击**:确保连接到的是真实服务器,而非攻击者伪造的服务器
-- 🔒 **服务器身份验证**:验证服务器的密钥没有被篡改
-- 📋 **连接记录**:追踪曾经连接过哪些服务器
+- **防止中间人攻击**:确保连接到的是真实服务器,而非攻击者伪造的服务器
+- **服务器身份验证**:验证服务器的密钥没有被篡改
+- **连接记录**:追踪曾经连接过哪些服务器
#### 指纹格式
@@ -567,9 +606,9 @@ SHA256:xYzAbC123456789aBcDeF/gHiJkLmNoPqRsTuVwXyZ01=
列表中指纹可能被截断显示,查看完整指纹:
-1. **点击查看按钮**:在目标主机行点击 **「👁️ 查看」** 按钮
-2. **查看详情**:弹窗显示完整指纹和主机信息
-3. **对比验证**(可选):在高安全场景下,可以与服务器端的官方指纹对比
+1. **点击查看按钮**:在目标主机行点击 **「查看」** 按钮
+2. **查看详情**:系统在弹窗中显示该主机的**完整 SHA256 指纹**及主机、端口、密钥类型,便于与服务器端 `ssh-keygen -lf` 的输出逐字对比
+3. **对比验证**(可选):在高安全场景下,将弹窗中的指纹与服务器官方指纹对比,确认一致后再信任
**获取服务器端指纹**(在服务器上运行):
```bash
@@ -655,17 +694,17 @@ Trust this host and continue? (yes/no):
| 原因 | 风险等级 | 说明 |
|------|----------|------|
-| **中间人攻击(MITM)** | 🔴 高危 | 攻击者在网络中拦截并伪造服务器 |
-| **服务器重装系统** | 🟡 合法 | 重装 Linux 后 SSH 主机密钥重新生成 |
-| **服务器更换密钥** | 🟡 合法 | 管理员手动重新生成了 SSH 主机密钥 |
-| **IP 地址重新分配** | 🟡 合法 | 该 IP 现在分配给了不同的服务器 |
+| **中间人攻击(MITM)** | 高危 | 攻击者在网络中拦截并伪造服务器 |
+| **服务器重装系统** | 合法 | 重装 Linux 后 SSH 主机密钥重新生成 |
+| **服务器更换密钥** | 合法 | 管理员手动重新生成了 SSH 主机密钥 |
+| **IP 地址重新分配** | 合法 | 该 IP 现在分配给了不同的服务器 |
#### 警告弹窗内容
系统会弹出红色警告弹窗:
```
-⚠️ 安全警告:主机指纹不匹配!
+安全警告:主机指纹不匹配
主机密钥已更改!这可能表明:
• 中间人攻击(Man-in-the-Middle Attack)
@@ -706,7 +745,7 @@ Trust this host and continue? (yes/no):
**步骤 3:根据核实结果处理**
**情况 A:确认是合法变更**(服务器重装、密钥更换)
-1. 在警告弹窗中点击 **「🔄 更新主机密钥」** 按钮
+1. 在警告弹窗中点击 **「更新主机密钥」** 按钮
2. 旧指纹被删除
3. 重新执行连接操作
4. 系统会再次提示信任新指纹(按 4.3 首次连接流程操作)
@@ -721,8 +760,8 @@ Trust this host and continue? (yes/no):
#### 错误操作的后果
-- ❌ **盲目信任新指纹**:如果确实是中间人攻击,您的密码和数据会被攻击者窃取
-- ❌ **忽略警告**:多次忽略后可能形成习惯,降低安全防护意识
+- **盲目信任新指纹**:如果确实是中间人攻击,您的密码和数据会被攻击者窃取
+- **忽略警告**:多次忽略后可能形成习惯,降低安全防护意识
**安全原则**:宁可中断连接排查,也不要冒险信任未验证的指纹。
@@ -732,24 +771,24 @@ Trust this host and continue? (yes/no):
#### 适用场景
-- 🗑️ 服务器已永久停用或销毁
-- 🔄 服务器已重装,需要清理旧指纹并重新信任
-- 🔀 IP 地址已分配给其他服务器,旧记录无效
-- 🧹 定期清理不再使用的服务器记录
+- 服务器已永久停用或销毁
+- 服务器已重装,需要清理旧指纹并重新信任
+- IP 地址已分配给其他服务器,旧记录无效
+- 定期清理不再使用的服务器记录
#### 操作步骤
-1. **选择主机**:在「🔐 已知主机指纹」表格中找到要删除的主机
-2. **点击删除按钮**:点击 **「🗑️ 删除」** 按钮
+1. **选择主机**:在「已知主机指纹」表格中找到要删除的主机
+2. **点击删除按钮**:点击 **「删除」** 按钮
3. **确认删除**:系统弹出确认对话框
4. **最终确认**:点击「确定」
5. **验证结果**:主机从列表中消失
#### 删除后果
-- ✅ 指纹记录从 NVS 永久删除
-- ⚠️ 下次连接该服务器时,会再次提示信任指纹(按首次连接流程)
-- ❌ 如果服务器重装,**必须先删除旧指纹**,否则会持续提示指纹不匹配
+- 指纹记录从 NVS 永久删除
+- 下次连接该服务器时,会再次提示信任指纹(按首次连接流程)
+- 如果服务器重装,**必须先删除旧指纹**,否则会持续提示指纹不匹配
#### 批量删除
@@ -798,9 +837,9 @@ hosts --clear --yes
- **mTLS**:服务器和客户端互相验证证书(双向)
**优势**:
-- 🔒 双向身份认证,防止未授权客户端访问
-- 🛡️ 防止中间人攻击
-- 🎯 基于证书的访问控制(无需密码)
+- 双向身份认证,防止未授权客户端访问
+- 防止中间人攻击
+- 基于证书的访问控制(无需密码)
#### 证书体系结构
@@ -828,10 +867,10 @@ hosts --clear --yes
#### 私钥不离开设备原则
**安全设计**:
-- ✅ 设备私钥在本地生成,永不导出
-- ✅ 仅导出 CSR(证书签名请求,不含私钥)
-- ✅ CA 使用 CSR 签发证书,CA 无法获得设备私钥
-- ✅ 私钥始终存储在设备的 NVS 中,即使固件升级也保留
+- 设备私钥在本地生成,永不导出
+- 仅导出 CSR(证书签名请求,不含私钥)
+- CA 使用 CSR 签发证书,CA 无法获得设备私钥
+- 私钥始终存储在设备的 NVS 中,即使固件升级也保留
**对比 SSH 密钥**:
- SSH 密钥可选择「允许导出私钥」
@@ -843,18 +882,18 @@ hosts --clear --yes
#### 状态卡片信息
-在「🔒 HTTPS 证书」区块顶部,有一个状态卡片实时显示证书状态。
+在「HTTPS 证书」区块顶部,有一个状态卡片实时显示证书状态。
-#### 状态图标与含义
+#### 状态与含义
-| 图标 | 状态文本 | 说明 |
-|------|----------|------|
-| 🔄 | 加载中... | 正在获取证书状态 |
-| 🔒 | 未生成密钥 | 尚未生成密钥对,需要先生成 |
-| 📝 | 已生成密钥,未安装证书 | 密钥对已生成,但未安装 CA 签发的证书 |
-| ✅ | 已激活 | 证书已安装且有效 |
-| ⚠️ | 即将过期 | 证书在 30 天内过期,建议续期 |
-| ❌ | 已过期 | 证书已过期,mTLS 功能不可用 |
+| 状态文本 | 说明 |
+|----------|------|
+| 加载中... | 正在获取证书状态 |
+| 未生成密钥 | 尚未生成密钥对,需要先生成 |
+| 已生成密钥,未安装证书 | 密钥对已生成,但未安装 CA 签发的证书 |
+| 已激活 | 证书已安装且有效 |
+| 即将过期 | 证书在 30 天内过期,建议续期 |
+| 已过期 | 证书已过期,mTLS 功能不可用 |
#### 证书详情(已安装时)
@@ -867,27 +906,32 @@ hosts --clear --yes
| **生效时间** | 证书的起始有效时间 | `2026-01-27 00:00:00` |
| **过期时间** | 证书的结束有效时间 | `2027-01-27 00:00:00` |
| **序列号** | 证书的唯一序列号(16 进制) | `01:23:45:67:89:AB` |
-| **有效状态** | 当前是否在有效期内 | ✅ 有效 / ❌ 已过期 |
+| **有效状态** | 当前是否在有效期内 | 有效 / 已过期 |
| **剩余天数** | 距离过期还有多少天 | `365 天`、`28 天`(<30 天显示警告) |
+**状态卡片显示规则**:
+- **剩余天数**:仅在证书已安装且处于有效期内时显示;未安装证书或已过期时不显示此项。
+- **「即将过期」角标/状态**:当证书有效但距离过期不足 30 天时,状态文本会变为「即将过期」,并可能显示角标提醒,建议尽快续期。
+- 卡片展开的详细信息(主体 CN、签发者、生效/过期时间、序列号、有效状态、剩余天数)仅在状态为「已激活」或「即将过期」时显示。
+
#### 按钮状态说明
HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁用:
| 按钮 | 未生成密钥 | 已生成密钥 | 已安装证书 | 说明 |
|------|-----------|-----------|-----------|------|
-| 🔑 生成密钥对 | ✅ 可用 | ✅ 可用 | ✅ 可用 | 任何时候都可以生成(会覆盖旧密钥) |
-| 📋 生成 CSR | ❌ 禁用 | ✅ 可用 | ✅ 可用 | 需要先有密钥对 |
-| 📥 安装证书 | ❌ 禁用 | ✅ 可用 | ✅ 可用 | 需要先有密钥对 |
-| 🏛️ 安装 CA | ❌ 禁用 | ✅ 可用 | ✅ 可用 | 需要先有密钥对 |
-| 👁️ 查看证书 | ❌ 禁用 | ❌ 禁用 | ✅ 可用 | 需要已安装证书 |
-| 🗑️ 删除凭证 | ❌ 禁用 | ✅ 可用 | ✅ 可用 | 有密钥或证书时可删除 |
+| 生成密钥对 | 可用 | 可用 | 可用 | 任何时候都可以生成(会覆盖旧密钥) |
+| 生成 CSR | 禁用 | 可用 | 可用 | 需要先有密钥对 |
+| 安装证书 | 禁用 | 可用 | 可用 | 需要先有密钥对 |
+| 安装 CA | 禁用 | 可用 | 可用 | 需要先有密钥对 |
+| 查看证书 | 禁用 | 禁用 | 可用 | 需要已安装证书 |
+| 删除凭证 | 禁用 | 可用 | 可用 | 有密钥或证书时可删除 |
---
### 5.3 完整证书申请流程
-从零开始配置设备的 mTLS 证书,完整流程包括 5 个步骤。
+从零开始配置设备的 mTLS 证书,完整流程包括 5 个步骤。下文中提到的按钮与弹窗名称(如「生成密钥对」「证书签名请求 (CSR)」「安装设备证书」「安装 CA 证书链」「查看设备证书」)均与安全页 WebUI 一致,便于在界面上对应操作。
#### 流程总览
@@ -915,9 +959,9 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
- 查看证书状态卡片,确认当前状态
- 如果显示「已生成密钥」,跳过此步骤(除非需要重新生成)
-2. **点击生成按钮**:点击 **「🔑 生成密钥对」** 按钮
+2. **点击生成按钮**:点击 **「生成密钥对」** 按钮
-3. **阅读说明**:弹出的「🔑 生成 HTTPS 密钥对」弹窗显示:
+3. **阅读说明**:弹出的「生成 HTTPS 密钥对」弹窗显示:
```
为设备生成 ECDSA P-256 密钥对,用于 mTLS 身份验证
```
@@ -925,19 +969,19 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
4. **注意覆盖警告**:
- 如果已存在密钥对,会显示黄色警告:
```
- ⚠️ 已存在密钥对,继续将覆盖现有密钥!
+ 注意:已存在密钥对,继续将覆盖现有密钥!
```
- **慎重考虑**:覆盖密钥后,旧密钥生成的 CSR 和证书将失效
- 确认要覆盖才继续
-5. **开始生成**:点击 **「🔑 生成」** 按钮
+5. **开始生成**:点击 **「生成」** 按钮
6. **等待完成**:
- 生成 ECDSA P-256 密钥约需 3-5 秒
- 弹窗显示进度或结果信息
7. **确认成功**:
- - 显示「✅ 密钥对生成成功」
+ - 显示「密钥对生成成功」
- 关闭弹窗
- 状态卡片更新为「已生成密钥,未安装证书」
- 「生成 CSR」「安装证书」「安装 CA」按钮变为可用
@@ -960,27 +1004,27 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
**目的**:生成 CSR(Certificate Signing Request),提交给 CA(证书颁发机构)签发证书。
**前提条件**:
-- ✅ 已完成「5.3.1 生成密钥对」
-- ✅ 「📋 生成 CSR」按钮已启用(蓝色可点击)
+- 已完成「5.3.1 生成密钥对」
+- 「生成 CSR」按钮已启用(蓝色可点击)
**操作步骤**:
-1. **点击生成 CSR 按钮**:点击 **「📋 生成 CSR」** 按钮
+1. **点击生成 CSR 按钮**:点击 **「生成 CSR」** 按钮
-2. **填写 CSR 信息**:在「📋 证书签名请求 (CSR)」弹窗中填写:
+2. **填写 CSR 信息**:在「证书签名请求 (CSR)」弹窗中填写:
| 字段 | 必填 | 说明 | 填写示例 |
|------|------|------|----------|
-| **设备 ID (CN)** | ❌ 否 | 设备的唯一标识(Common Name),留空使用默认配置 | `TIANSHAN-RM01-0001`、`DEVICE-AGX-001` |
-| **组织 (O)** | ❌ 否 | 公司或组织名称(Organization) | `HiddenPeak Labs`、`My Company` |
-| **部门 (OU)** | ❌ 否 | 组织单位或部门(Organizational Unit) | `Device`、`Production`、`IoT` |
+| **设备 ID (CN)** | 否 | 设备的唯一标识(Common Name),留空使用默认配置 | `TIANSHAN-RM01-0001`、`DEVICE-AGX-001` |
+| **组织 (O)** | 否 | 公司或组织名称(Organization) | `HiddenPeak Labs`、`My Company` |
+| **部门 (OU)** | 否 | 组织单位或部门(Organizational Unit) | `Device`、`Production`、`IoT` |
**字段说明**:
- **CN(Common Name)**:最重要,建议使用规范命名,如 `前缀-型号-序列号`
- **O 和 OU**:可选,用于证书的组织信息
- **留空处理**:如果所有字段留空,系统使用默认配置(如设备 MAC 地址作为 CN)
-3. **生成 CSR**:点击 **「📋 生成 CSR」** 按钮
+3. **生成 CSR**:点击 **「生成 CSR」** 按钮
4. **等待生成**:约 2-3 秒,系统会:
- 使用私钥和填写的信息生成 CSR
@@ -998,7 +1042,7 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
└───────────────────────────────────────────┘
```
-6. **复制 CSR**:点击 **「📋 复制到剪贴板」** 按钮复制 CSR 内容
+6. **复制 CSR**:点击 **「复制到剪贴板」** 按钮复制 CSR 内容
7. **保存 CSR**(可选):
- 将 CSR 粘贴到文本编辑器
@@ -1007,10 +1051,10 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
#### CSR 包含的信息
-- ✅ 设备的公钥(从密钥对中提取)
-- ✅ 主体信息(CN、O、OU)
-- ✅ 设备签名(证明请求者拥有私钥)
-- ❌ **不包含**私钥(私钥永不离开设备)
+- 设备的公钥(从密钥对中提取)
+- 主体信息(CN、O、OU)
+- 设备签名(证明请求者拥有私钥)
+- **不包含**私钥(私钥永不离开设备)
#### 下一步
@@ -1068,7 +1112,7 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
#### 等待时间
-- 🚀 **自动化 CA**:秒级到分钟级
+- **自动化 CA**:秒级到分钟级
- ⏳ **手动 CA**:小时到天级(取决于审批流程)
#### 获取的文件
@@ -1077,8 +1121,8 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
| 文件 | 必需 | 说明 | 格式 |
|------|------|------|------|
-| **设备证书** | ✅ 是 | CA 签发的设备证书 | `device.crt`、PEM 格式 |
-| **CA 证书链** | ✅ 是 | 根 CA + 中间 CA 证书 | `ca-chain.pem`、PEM 格式 |
+| **设备证书** | 是 | CA 签发的设备证书 | `device.crt`、PEM 格式 |
+| **CA 证书链** | 是 | 根 CA + 中间 CA 证书 | `ca-chain.pem`、PEM 格式 |
准备好这两个文件后,继续「5.3.4 安装设备证书」。
@@ -1089,9 +1133,9 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
**目的**:将 CA 签发的设备证书安装到设备,使 mTLS 功能生效。
**前提条件**:
-- ✅ 已生成密钥对
-- ✅ 已从 CA 获取签发的设备证书(PEM 格式)
-- ✅ 证书是使用本设备密钥生成的 CSR 签发的
+- 已生成密钥对
+- 已从 CA 获取签发的设备证书(PEM 格式)
+- 证书是使用本设备密钥生成的 CSR 签发的
**操作步骤**:
@@ -1106,22 +1150,22 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
-----END CERTIFICATE-----
```
-3. **点击安装按钮**:在安全页面点击 **「📥 安装证书」** 按钮
+3. **点击安装按钮**:在安全页面点击 **「安装证书」** 按钮
-4. **粘贴证书**:在「📥 安装设备证书」弹窗中:
+4. **粘贴证书**:在「安装设备证书」弹窗中:
- 将证书内容粘贴到「证书 PEM」文本框
- 确保内容完整(包括开头和结尾的 `-----BEGIN/END-----`)
-5. **提交安装**:点击 **「📥 安装」** 按钮
+5. **提交安装**:点击 **「安装」** 按钮
6. **等待验证**:系统会自动验证:
- - ✅ 证书格式是否正确(PEM 格式)
- - ✅ 证书与设备私钥是否匹配(关键)
- - ✅ 证书是否在有效期内
- - ✅ 证书主体信息是否符合预期
+ - 证书格式是否正确(PEM 格式)
+ - 证书与设备私钥是否匹配(关键)
+ - 证书是否在有效期内
+ - 证书主体信息是否符合预期
7. **确认成功**:
- - 显示「✅ 证书安装成功」
+ - 显示「证书安装成功」
- 显示证书详情(CN、签发者、有效期等)
- 状态卡片更新为「已激活」或「已生成密钥,未安装 CA 链」
@@ -1151,8 +1195,8 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
**目的**:安装 CA 证书链(根 CA + 中间 CA),使客户端可以验证设备证书的签发者。
**前提条件**:
-- ✅ 已安装设备证书(完成 5.3.4)
-- ✅ 已从 CA 获取证书链文件(PEM 格式)
+- 已安装设备证书(完成 5.3.4)
+- 已从 CA 获取证书链文件(PEM 格式)
**为什么需要 CA 链**:
- 客户端(浏览器、API 客户端)需要验证设备证书是否由可信 CA 签发
@@ -1180,19 +1224,19 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
- 顺序不重要(系统会自动识别根 CA 和中间 CA)
- 如果只有一个 CA(简化环境),只需一个证书块
-3. **点击安装 CA 按钮**:点击 **「🏛️ 安装 CA」** 按钮
+3. **点击安装 CA 按钮**:点击 **「安装 CA」** 按钮
-4. **粘贴证书链**:在「🏛️ 安装 CA 证书链」弹窗中:
+4. **粘贴证书链**:在「安装 CA 证书链」弹窗中:
- 将 CA 链内容粘贴到文本框
- 检查内容完整(包括所有 BEGIN/END 标记)
-5. **提交安装**:点击 **「🏛️ 安装」** 按钮
+5. **提交安装**:点击 **「安装」** 按钮
6. **等待完成**:系统验证证书链格式并存储到 NVS
7. **确认成功**:
- - 显示「✅ CA 链安装成功」
- - 状态卡片更新为「✅ 已激活」(如果证书有效)
+ - 显示「CA 链安装成功」
+ - 状态卡片更新为「已激活」(如果证书有效)
- mTLS 配置完成
#### CA 链示例
@@ -1217,8 +1261,8 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
#### 安装后验证
1. **检查状态卡片**:
- - 状态应为「✅ 已激活」
- - 有效状态显示「✅ 有效」
+ - 状态应为「已激活」
+ - 有效状态显示「有效」
- 剩余天数应显示正常值
2. **测试 mTLS 连接**(需要客户端配置):
@@ -1236,18 +1280,18 @@ HTTPS 证书区块下方有 6 个操作按钮,根据当前状态启用或禁
**操作步骤**:
-1. **前提条件**:已安装设备证书(「👁️ 查看证书」按钮为可用状态)
+1. **前提条件**:已安装设备证书(「查看证书」按钮为可用状态)
-2. **点击查看按钮**:点击 **「👁️ 查看证书」** 按钮
+2. **点击查看按钮**:点击 **「查看证书」** 按钮
-3. **等待加载**:弹窗显示「🔄 加载中...」,约 1-2 秒
+3. **等待加载**:弹窗显示「加载中...」,约 1-2 秒
4. **查看证书内容**:
- 显示完整的设备证书 PEM 内容
- 可滚动查看所有内容
5. **复制证书**(可选):
- - 点击 **「📋 复制到剪贴板」** 复制证书
+ - 点击 **「复制到剪贴板」** 复制证书
- 用途:配置客户端、存档备份
6. **关闭弹窗**:点击「关闭」按钮
@@ -1287,10 +1331,10 @@ Certificate:
#### 删除内容
-点击「🗑️ 删除凭证」会删除以下所有内容:
-- 🔑 设备私钥(ECDSA P-256)
-- 📄 设备证书
-- 🏛️ CA 证书链
+点击「删除凭证」会删除以下所有内容:
+- 设备私钥(ECDSA P-256)
+- 设备证书
+- CA 证书链
#### 何时使用
@@ -1303,11 +1347,11 @@ Certificate:
#### 操作步骤
-1. **点击删除按钮**:点击 **「🗑️ 删除凭证」** 按钮(红色)
+1. **点击删除按钮**:点击 **「删除凭证」** 按钮(红色)
2. **阅读警告**:系统弹出确认对话框:
```
- ⚠️ 警告:删除所有 PKI 凭证
+ 警告:删除所有 PKI 凭证
此操作将删除:
• 设备私钥
@@ -1327,7 +1371,7 @@ Certificate:
- 如果不确定,点击「取消」
4. **验证结果**:
- - 状态卡片更新为「🔒 未生成密钥」
+ - 状态卡片更新为「未生成密钥」
- 所有按钮重置为初始状态
- 「密钥管理」表格中 HTTPS 密钥行消失
@@ -1352,9 +1396,9 @@ Certificate:
#### 何时需要续期
-- ⏰ 证书即将过期(建议提前 **30 天**开始续期)
-- ⚠️ 状态卡片显示「即将过期」或剩余天数 < 30
-- 📅 根据公司 PKI 策略定期续期(如每年)
+- 证书即将过期(建议提前 **30 天**开始续期)
+- 状态卡片显示「即将过期」或剩余天数 < 30
+- 根据公司 PKI 策略定期续期(如每年)
#### 续期流程
@@ -1363,7 +1407,7 @@ Certificate:
如果私钥未泄露,可以保留密钥对,仅更新证书:
1. **生成新 CSR**:
- - 点击「📋 生成 CSR」(可以使用相同的 CN)
+ - 点击「生成 CSR」(可以使用相同的 CN)
- 复制 CSR 内容
2. **提交 CA 签发**:
@@ -1371,7 +1415,7 @@ Certificate:
- 获取新签发的证书
3. **安装新证书**:
- - 点击「📥 安装证书」
+ - 点击「安装证书」
- 粘贴新证书内容
- 系统会自动覆盖旧证书
@@ -1383,16 +1427,16 @@ Certificate:
如果怀疑私钥泄露,需要重新生成所有凭证:
-1. **删除旧凭证**:点击「🗑️ 删除凭证」
+1. **删除旧凭证**:点击「删除凭证」
2. **重新生成密钥对**:从「5.3.1」开始
3. **重新申请证书**:执行完整的 5.3 流程
#### 续期注意事项
-- ✅ 续期前可以继续使用旧证书(直到过期)
-- ✅ 新证书安装后立即生效,旧证书自动失效
-- ✅ CA 链通常不需要更新(除非 CA 体系变更)
-- ⚠️ 如果 CA 链也过期,需要同时更新 CA 链
+- 续期前可以继续使用旧证书(直到过期)
+- 新证书安装后立即生效,旧证书自动失效
+- CA 链通常不需要更新(除非 CA 体系变更)
+- 如果 CA 链也过期,需要同时更新 CA 链
#### 自动化续期(未来功能)
@@ -1403,6 +1447,64 @@ Certificate:
---
+## 任务五:配置包 (Config Pack)
+
+「配置包」区块用于在设备间安全地分发配置:将配置文件加密、签名后打包为 `.tscfg` 文件,只有持有对应设备证书的目标设备才能解密使用。适用于批量部署、远程下发配置等场景。
+
+### 5.5.1 配置包功能概览
+
+| 功能 | 说明 | 权限 |
+|------|------|------|
+| **导出设备证书** | 导出本设备的 HTTPS 证书(PEM)及指纹,供他人向本设备发送加密配置包 | admin |
+| **导入配置包** | 上传或粘贴 .tscfg 文件,验证签名后解密并保存到设备(加密存储) | admin |
+| **导出配置包** | 选择本地文件、填写目标设备证书,生成加密的 .tscfg 包发给目标设备 | 仅 Developer 设备 |
+| **查看配置包列表** | 按目录查看已存在的配置包文件及签名者、官方标记、状态 | admin |
+
+**状态卡片**:区块顶部显示当前设备类型、证书 CN、证书指纹、格式版本等;若尚未配置 mTLS 证书,部分功能可能不可用。
+
+### 5.5.2 导出设备证书
+
+**用途**:将本设备的证书发给需要向您发送加密配置的开发者或系统,以便对方在「导出配置包」时粘贴您的证书,生成只有本设备能解密的配置包。
+
+**步骤**:
+1. 点击 **「导出设备证书」**
+2. 弹窗中查看证书指纹 (SHA256)、证书 CN、证书 PEM
+3. 点击 **「复制到剪贴板」** 或自行复制 PEM 内容,通过安全渠道发送给对方
+
+### 5.5.3 导入配置包
+
+**用途**:接收他人或系统下发的 .tscfg 配置包,验证签名并解密后保存到设备。
+
+**步骤**:
+1. 点击 **「导入配置包」**
+2. 选择 .tscfg 文件,或粘贴 JSON 内容
+3. 可先点击 **「仅验证」** 检查签名与内容,再点击 **「导入」** 写入设备
+ **说明**:「仅验证」只校验配置包的签名和格式,**不会**将配置写入设备,适合在正式导入前确认来源与内容是否可信。
+4. 导入成功后,配置包会加密存储在设备上,可通过 `config.pack.content` 等 API 按需解密使用
+
+### 5.5.4 导出配置包(仅 Developer 设备)
+
+**用途**:选择本设备上的配置文件,用目标设备的证书加密并签名,生成 .tscfg 文件,供目标设备导入。
+
+**步骤**:
+1. 若设备非 Developer 类型,该按钮会提示「仅 Developer 设备可导出配置包」
+2. 点击 **「导出配置包」**,在弹窗中浏览并选择要打包的配置文件(可多选)
+3. 填写配置名称、描述,粘贴**目标设备**导出的证书 PEM
+4. 点击 **「生成配置包」**,将生成的 .tscfg 内容复制或下载后发送给目标设备
+
+### 5.5.5 查看配置包列表
+
+**用途**:按指定目录(如 `/sdcard/config`)列出已存在的配置包文件,查看文件名、大小、签名者、是否官方、状态等。
+
+**步骤**:点击 **「查看配置包列表」**,输入或使用默认目录路径,点击 **「刷新」** 即可查看列表。
+
+**列表字段说明**:
+- **签名者**:对该配置包进行签名的证书 CN,用于验证来源
+- **官方**:若签名来自系统信任的官方证书,会标记为「官方」,便于区分厂商下发的配置与自签名配置
+- **状态**:该配置包是否已应用、是否有效等
+
+---
+
## 安全存储 vs 文件密钥对比
**帮助您理解为什么 TianshanOS 默认使用安全存储(NVS)而非文件**。
@@ -1411,15 +1513,15 @@ Certificate:
| 特性 | 安全存储(NVS) | 文件密钥(SD 卡) |
|------|----------------|------------------|
-| **私钥保护** | ✅ 硬件 NVS 加密分区,难以提取 | ⚠️ 明文 PEM 文件,易被复制、泄露 |
-| **使用便捷性** | ✅ 只需记住密钥 ID,无需管理文件路径 | ❌ 需要记住文件路径,容易混淆 |
-| **密钥备份** | ⚠️ 需勾选「可导出」才能备份 | ✅ 可直接复制文件备份 |
-| **跨设备使用** | ❌ 密钥绑定单个设备 | ✅ 可复制到多个设备使用 |
-| **防止意外删除** | ✅ 需显式删除操作 | ⚠️ 文件系统错误可能导致丢失 |
-| **存储容量** | ⚠️ NVS 有限(约 8-32 个密钥) | ✅ SD 卡容量大 |
-| **访问速度** | ✅ 快速(NVS 读取) | ⚠️ 较慢(SD 卡 I/O) |
-| **安全性评分** | ⭐⭐⭐⭐⭐(5 星) | ⭐⭐(2 星) |
-| **推荐场景** | 🎯 **生产环境、长期使用、安全敏感** | 临时使用、密钥迁移、多设备共享 |
+| **私钥保护** | 硬件 NVS 加密分区,难以提取 | 明文 PEM 文件,易被复制、泄露 |
+| **使用便捷性** | 只需记住密钥 ID,无需管理文件路径 | 需要记住文件路径,容易混淆 |
+| **密钥备份** | 需勾选「可导出」才能备份 | 可直接复制文件备份 |
+| **跨设备使用** | 密钥绑定单个设备 | 可复制到多个设备使用 |
+| **防止意外删除** | 需显式删除操作 | 文件系统错误可能导致丢失 |
+| **存储容量** | NVS 有限(约 8-32 个密钥) | SD 卡容量大 |
+| **访问速度** | 快速(NVS 读取) | 较慢(SD 卡 I/O) |
+| **安全性评分** | 高(5 星) | 较低(2 星) |
+| **推荐场景** | **生产环境、长期使用、安全敏感** | 临时使用、密钥迁移、多设备共享 |
### 安全存储的优势
@@ -1443,10 +1545,10 @@ Certificate:
尽管安全存储更安全,以下场景可以使用文件密钥:
-- 🔄 **密钥迁移**:从其他设备导入已有密钥
-- 🧪 **临时测试**:临时使用,用完即删
-- 🔀 **多设备共享**:同一个密钥需要在多个设备使用
-- 📤 **外部工具**:需要在桌面 SSH 客户端(如 PuTTY、Terminal)使用
+- **密钥迁移**:从其他设备导入已有密钥
+- **临时测试**:临时使用,用完即删
+- **多设备共享**:同一个密钥需要在多个设备使用
+- **外部工具**:需要在桌面 SSH 客户端(如 PuTTY、Terminal)使用
**使用文件密钥的 CLI 命令**:
```bash
@@ -1504,7 +1606,7 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
**方法一:导出私钥(需提前设置)**
1. 生成密钥时勾选 **「允许导出私钥」**
-2. 生成后,点击「🔐 私钥」按钮
+2. 生成后,点击「私钥」按钮
3. 下载为 `.pem` 文件
4. 存储在安全的离线介质(加密 U 盘、密码管理器)
@@ -1521,7 +1623,7 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
#### Q4:删除密钥后还能恢复吗?
-**答案**:❌ **无法恢复**。
+**答案**:**无法恢复**。
**删除操作是永久性的**:
- 密钥从 NVS 完全清除
@@ -1529,10 +1631,10 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
- 唯一恢复方式:之前导出的私钥备份
**删除前的检查清单**:
-1. ✅ 确认该密钥没有部署到重要服务器
-2. ✅ 如果有部署,已完成撤销或移除
-3. ✅ 如果需要备份,已导出私钥
-4. ✅ 已通知其他可能使用该密钥的人员
+1. 确认该密钥没有部署到重要服务器
+2. 如果有部署,已完成撤销或移除
+3. 如果需要备份,已导出私钥
+4. 已通知其他可能使用该密钥的人员
**误删后的补救**:
- 如果有备份:通过 CLI 的 `key --import` 命令重新导入
@@ -1682,12 +1784,12 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
**原因**:只有通过 WebUI「部署」功能部署的主机会自动添加到此列表。
**不会出现在列表中的情况**:
-- ❌ 通过终端 CLI 的 `ssh --copyid` 部署
-- ❌ 手动复制公钥到服务器的 `authorized_keys`
-- ❌ 其他设备或工具部署的公钥
+- 通过终端 CLI 的 `ssh --copyid` 部署
+- 手动复制公钥到服务器的 `authorized_keys`
+- 其他设备或工具部署的公钥
**解决方法**:
-- 如果确实需要在 WebUI 中管理,重新通过 WebUI 的「部署」功能部署一次
+- 如果确实需要在 WebUI 中管理,可重新通过 WebUI 的「部署」功能部署一次;或使用「导入主机」导入包含该主机信息的 .tscfg 配置包,使列表与实际情况一致
- 或者仅通过 CLI 的 `hosts --deployed` 命令查看和管理
**设计说明**:
@@ -1697,6 +1799,24 @@ ssh --host 192.168.1.100 --user nvidia --key /sdcard/id_rsa --shell
---
+#### Q8b:导入主机或导入配置包时提示「签名验证失败」?
+
+**现象**:点击「导入主机」或「导入配置包」并选择/粘贴 .tscfg 后,提示签名验证失败或无法解密。
+
+**可能原因**:
+- .tscfg 文件损坏或复制不完整(缺少头尾、被截断)
+- 配置包不是用当前设备(或目标设备)所信任的证书签发的
+- 设备系统时间偏差过大,导致证书有效期校验失败
+- 粘贴的 JSON 格式错误(多余空格、缺少引号等)
+
+**解决方法**:
+1. **检查文件完整性**:重新从来源获取 .tscfg,确保包含完整的 `-----BEGIN ...-----` / `-----END ...-----` 等块,或重新导出
+2. **确认签发来源**:确认该配置包是由本机证书或您信任的官方/目标设备证书签发的;导入主机时若为「自加密」导出,需在同一台或拥有同一证书的设备上导入
+3. **校对设备时间**:在系统/网络页检查设备日期时间是否正确,必要时同步 NTP
+4. **仅验证**:在配置包导入弹窗中先点击「仅验证」,查看具体报错信息(如签名者、证书 CN),再根据提示排查
+
+---
+
### 7.3 已知主机指纹问题
#### Q9:「已知主机指纹」列表为空?
@@ -1733,24 +1853,24 @@ hosts --list --json
#### Q10:主机指纹不匹配警告如何处理?
-**现象**:连接时弹出红色警告「⚠️ 安全警告:主机指纹不匹配」。
+**现象**:连接时弹出红色警告「安全警告:主机指纹不匹配」。
**正确处理流程**(详见 4.4 章节):
-1. **🛑 立即停止**:不要盲目点击「更新主机密钥」
-2. **📞 联系管理员**:确认服务器是否重装或更换密钥
-3. **✅ 确认合法后**:点击「更新主机密钥」
-4. **❌ 无法确认时**:点击「取消」,排查网络安全
+1. **立即停止**:不要盲目点击「更新主机密钥」
+2. **联系管理员**:确认服务器是否重装或更换密钥
+3. **确认合法后**:点击「更新主机密钥」
+4. **无法确认时**:点击「取消」,排查网络安全
**错误示范**:
-- ❌ 看到警告就点「更新主机密钥」(可能中招中间人攻击)
-- ❌ 关闭警告继续连接(系统会阻止)
-- ❌ 忽视警告,认为是系统 Bug(这是重要的安全特性)
+- 看到警告就点「更新主机密钥」(可能中招中间人攻击)
+- 关闭警告继续连接(系统会阻止)
+- 忽视警告,认为是系统 Bug(这是重要的安全特性)
**安全提示**:
-- 🔴 主机指纹不匹配是**严重的安全事件**
-- 🔴 必须核实后才能继续
-- 🔴 如果频繁出现,可能网络环境不安全
+- 主机指纹不匹配是**严重的安全事件**
+- 必须核实后才能继续
+- 如果频繁出现,可能网络环境不安全
---
@@ -1805,12 +1925,12 @@ hosts --list --json
#### Q12:生成 CSR 按钮灰色不可用?
-**现象**:「📋 生成 CSR」按钮显示为灰色,无法点击。
+**现象**:「生成 CSR」按钮显示为灰色,无法点击。
**原因**:尚未生成密钥对。CSR 需要使用私钥签名,因此必须先有密钥对。
**解决方法**:
-1. 点击 **「🔑 生成密钥对」** 按钮
+1. 点击 **「生成密钥对」** 按钮
2. 等待密钥生成成功
3. 「生成 CSR」按钮会自动变为可用(蓝色)
@@ -1840,30 +1960,30 @@ hosts --list --json
4. 安装新签发的证书
**方法二:删除凭证重新开始**
-1. 点击「🗑️ 删除凭证」
+1. 点击「删除凭证」
2. 从「5.3.1 生成密钥对」开始重新执行完整流程
3. 确保 CSR、签发、安装使用的是同一个密钥对
**预防措施**:
-- ✅ 生成 CSR 后不要重新生成密钥对
-- ✅ 签发前确认 CSR 来源正确
-- ✅ 标记好文件名(如 `device-001.csr`、`device-001.crt`)
+- 生成 CSR 后不要重新生成密钥对
+- 签发前确认 CSR 来源正确
+- 标记好文件名(如 `device-001.csr`、`device-001.crt`)
---
#### Q14:证书状态显示"即将过期"?
-**现象**:状态卡片显示 ⚠️「即将过期」,剩余天数 < 30。
+**现象**:状态卡片显示「即将过期」,剩余天数 < 30。
**处理建议**:
-- 🟢 **30-15 天**:开始准备续期,不紧急
-- 🟡 **15-7 天**:尽快续期,避免影响服务
-- 🔴 **< 7 天**:立即续期,高优先级
+- **30-15 天**:开始准备续期,不紧急
+- **15-7 天**:尽快续期,避免影响服务
+- **< 7 天**:立即续期,高优先级
**续期流程**(保留密钥):
1. **生成新 CSR**:
- - 点击「📋 生成 CSR」
+ - 点击「生成 CSR」
- 可以使用相同的 CN(设备 ID)
- 复制 CSR 内容
@@ -1873,7 +1993,7 @@ hosts --list --json
3. **安装新证书**:
- 获取新签发的证书后
- - 点击「📥 安装证书」
+ - 点击「安装证书」
- 粘贴新证书内容
- 旧证书自动被覆盖
@@ -1882,10 +2002,10 @@ hosts --list --json
- 检查「剩余天数」已重置
**注意事项**:
-- ✅ 续期期间旧证书仍可用(直到过期)
-- ✅ 安装新证书后立即生效
-- ✅ CA 链通常不需要更新(除非 CA 本身过期)
-- ⚠️ 如果 CA 链也过期,需要同时更新 CA 链
+- 续期期间旧证书仍可用(直到过期)
+- 安装新证书后立即生效
+- CA 链通常不需要更新(除非 CA 本身过期)
+- 如果 CA 链也过期,需要同时更新 CA 链
---
@@ -1917,21 +2037,22 @@ hosts --list --json
#### Q16:admin 用户可以使用安全页面的所有功能吗?
-**答案**:✅ **是的**。
+**答案**:**是的**。
**admin 权限范围**:
-- ✅ 安全页面的所有功能
-- ✅ 系统、网络、文件页面
-- ❌ 终端、自动化、指令页面(需要 root 权限)
+- 安全页面的所有功能
+- 系统、网络、文件页面
+- 终端、自动化、指令页面需要 root 权限,admin 不可访问
**安全页面功能清单**(admin 可用):
-- ✅ 生成、删除、导出 SSH 密钥
-- ✅ 部署公钥到远程服务器
-- ✅ 撤销已部署的公钥
-- ✅ 管理已部署主机记录
-- ✅ 查看和删除已知主机指纹
-- ✅ 生成、安装、删除 HTTPS 证书
-- ✅ 生成 CSR、安装 CA 链
+- 生成、删除、导出 SSH 密钥
+- 部署公钥到远程服务器
+- 撤销已部署的公钥
+- 管理已部署主机记录(含导入主机配置)
+- 查看和删除已知主机指纹
+- 生成、安装、删除 HTTPS 证书
+- 生成 CSR、安装 CA 链
+- 配置包:导出设备证书、导入配置包、查看配置包列表
**如果需要 root 权限功能**:
- 请联系系统管理员,使用 root 账户登录
@@ -1941,7 +2062,7 @@ hosts --list --json
#### Q17:导出私钥时提示"权限不足"或按钮灰色?
-**现象**:点击「🔐 私钥」按钮时:
+**现象**:点击「私钥」按钮时:
- 按钮显示为灰色(disabled),无法点击
- 或点击后提示「此密钥不可导出私钥」
@@ -1968,9 +2089,9 @@ hosts --list --json
- 通过 WebUI「部署」功能管理,无需导出私钥
**设计理念**:
-- 🔒 私钥是最敏感的安全凭证,应尽量避免导出
-- 🔒 仅在确实需要备份或迁移时才导出
-- 🔒 默认不可导出,减少误操作泄露风险
+- 私钥是最敏感的安全凭证,应尽量避免导出
+- 仅在确实需要备份或迁移时才导出
+- 默认不可导出,减少误操作泄露风险
---
@@ -1986,16 +2107,16 @@ hosts --list --json
- `<项目>_<序号>`:如 `project_a_01`、`iot_device_001`
**避免的命名**:
-- ❌ `key1`、`test`、`temp`(无意义)
-- ❌ 中文或特殊字符(可能导致兼容性问题)
-- ❌ 过长的名称(不便于终端输入)
+- `key1`、`test`、`temp`(无意义)
+- 中文或特殊字符(可能导致兼容性问题)
+- 过长的名称(不便于终端输入)
#### 2. 密钥类型选择
**推荐策略**:
-- 🎯 **日常使用**:RSA 2048-bit(兼容性好、生成快)
-- 🎯 **高安全场景**:RSA 4096-bit(军事级加密,生成慢)
-- ⚠️ **ECDSA**:当前仅用于 HTTPS 证书,不用于 SSH
+- **日常使用**:RSA 2048-bit(兼容性好、生成快)
+- **高安全场景**:RSA 4096-bit(军事级加密,生成慢)
+- **ECDSA**:当前仅用于 HTTPS 证书,不用于 SSH
**容量规划**:
- RSA 2048:可存储约 12 个
@@ -2005,9 +2126,9 @@ hosts --list --json
#### 3. 私钥导出控制
**推荐策略**:
-- 🔒 **生产环境密钥**:不勾选「允许导出」,永久保存在设备
-- 🔓 **备份密钥**:勾选「允许导出」,定期备份到离线介质
-- 🧪 **测试密钥**:不勾选,丢失后重新生成
+- **生产环境密钥**:不勾选「允许导出」,永久保存在设备
+- **备份密钥**:勾选「允许导出」,定期备份到离线介质
+- **测试密钥**:不勾选,丢失后重新生成
**导出私钥的安全清单**:
- [ ] 确认导出是必要的(备份、迁移)
@@ -2019,9 +2140,9 @@ hosts --list --json
#### 4. 定期审查密钥
**建议频率**:
-- 🗓️ **每季度**:检查密钥列表,删除不再使用的密钥
-- 🗓️ **每半年**:审查已部署主机,撤销不需要的访问
-- 🗓️ **每年**:考虑轮换重要服务器的密钥
+- **每季度**:检查密钥列表,删除不再使用的密钥
+- **每半年**:审查已部署主机,撤销不需要的访问
+- **每年**:考虑轮换重要服务器的密钥
**审查检查项**:
- [ ] 哪些密钥长期未使用?
@@ -2050,7 +2171,7 @@ hosts --list --json
#### 2. 部署后立即测试
**流程**:
-1. 部署成功后,点击「🔍 测试」按钮
+1. 部署成功后,点击「测试」按钮
2. 确认连接成功
3. 如果失败,立即排查,不要留到以后
@@ -2062,9 +2183,9 @@ hosts --list --json
#### 3. 及时撤销不需要的访问
**场景**:
-- 🚫 项目结束,不再需要访问
-- 🔄 人员离职,撤销个人密钥
-- 🔒 服务器下线或迁移
+- 项目结束,不再需要访问
+- 人员离职,撤销个人密钥
+- 服务器下线或迁移
**操作**:
1. 在「已部署主机」列表点击「撤销」
@@ -2073,9 +2194,9 @@ hosts --list --json
#### 4. 密钥轮换计划
**推荐策略**:
-- 🔄 **关键服务器**:每年轮换一次密钥
-- 🔄 **一般服务器**:每 2-3 年或按需轮换
-- 🔄 **测试环境**:项目结束后轮换
+- **关键服务器**:每年轮换一次密钥
+- **一般服务器**:每 2-3 年或按需轮换
+- **测试环境**:项目结束后轮换
**轮换流程**:
1. 生成新密钥(新的 ID,如 `agx_2027`)
@@ -2106,9 +2227,9 @@ hosts --list --json
**铁律**:**永远不要忽视指纹不匹配警告**
**处理优先级**:
-1. 🔴 **第一优先**:核实服务器是否重装/更换密钥
-2. 🟡 **第二优先**:排查网络环境(是否在不安全网络)
-3. 🟢 **确认后**:才更新主机密钥
+1. **第一优先**:核实服务器是否重装/更换密钥
+2. **第二优先**:排查网络环境(是否在不安全网络)
+3. **确认后**:才更新主机密钥
**记录变更**:
- 记录谁更新了指纹、原因、时间
@@ -2133,10 +2254,10 @@ hosts --list --json
#### 1. 提前续期
**续期时间表**:
-- 📅 **证书有效期 > 30 天**:无需操作,定期检查
-- 📅 **30-15 天**:准备续期流程,联系 CA 或准备文档
-- 📅 **15-7 天**:执行续期,获取新证书并安装
-- 📅 **< 7 天**:紧急续期,高优先级
+- **证书有效期 > 30 天**:无需操作,定期检查
+- **30-15 天**:准备续期流程,联系 CA 或准备文档
+- **15-7 天**:执行续期,获取新证书并安装
+- **< 7 天**:紧急续期,高优先级
**自动提醒**(建议):
- 设置日历提醒(证书到期前 30 天)
@@ -2175,9 +2296,9 @@ hosts --list --json
#### 4. 定期检查证书状态
**检查频率**:
-- 🗓️ **每月**:打开安全页面,查看状态卡片
-- 🗓️ **每季度**:详细检查证书信息,确认无异常
-- 🗓️ **重大变更后**:验证证书仍然有效
+- **每月**:打开安全页面,查看状态卡片
+- **每季度**:详细检查证书信息,确认无异常
+- **重大变更后**:验证证书仍然有效
**检查项**:
- [ ] 状态是否为「已激活」
@@ -2237,15 +2358,15 @@ hosts --list --json
本文档涵盖了 TianshanOS 安全页面的所有功能和操作方法。作为 **admin 用户**,您可以使用这些功能管理 SSH 密钥、远程主机连接和 HTTPS 证书。
**建议您**:
-1. 📖 首次使用前完整阅读本文档
-2. 🧪 在测试环境练习各项操作
-3. 🔖 将本文档加入书签,便于随时查阅
-4. 📚 根据需要查阅相关技术文档深入学习
+1. 首次使用前完整阅读本文档
+2. 在测试环境练习各项操作
+3. 将本文档加入书签,便于随时查阅
+4. 根据需要查阅相关技术文档深入学习
**安全提醒**:
-- 🔐 妥善保管密钥和证书
-- 🚨 重视所有安全警告(主机指纹不匹配等)
-- 🔄 定期审查和更新密钥、证书
-- 📋 记录重要操作和变更
+- 妥善保管密钥和证书
+- 重视所有安全警告(主机指纹不匹配等)
+- 定期审查和更新密钥、证书
+- 记录重要操作和变更
如有问题或建议,请联系系统管理员或查阅项目文档库。
diff --git a/sdkconfig b/sdkconfig
index 1efca6a..1df10a4 100644
--- a/sdkconfig
+++ b/sdkconfig
@@ -370,7 +370,6 @@ CONFIG_SOC_WIFI_HW_TSF=y
CONFIG_SOC_WIFI_FTM_SUPPORT=y
CONFIG_SOC_WIFI_GCMP_SUPPORT=y
CONFIG_SOC_WIFI_WAPI_SUPPORT=y
-CONFIG_SOC_WIFI_TXOP_SUPPORT=y
CONFIG_SOC_WIFI_CSI_SUPPORT=y
CONFIG_SOC_WIFI_MESH_SUPPORT=y
CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y
@@ -1022,7 +1021,6 @@ CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000
#
# Hardware Settings
#
-CONFIG_ESP_HW_SUPPORT_FUNC_IN_IRAM=y
#
# Chip revision
@@ -1083,8 +1081,6 @@ CONFIG_RTC_CLK_SRC_INT_RC=y
# CONFIG_RTC_CLK_SRC_EXT_OSC is not set
# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set
CONFIG_RTC_CLK_CAL_CYCLES=1024
-CONFIG_RTC_CLK_FUNC_IN_IRAM=y
-CONFIG_RTC_TIME_FUNC_IN_IRAM=y
# end of RTC Clock Config
#
@@ -1194,9 +1190,9 @@ CONFIG_ESP_PHY_IRAM_OPT=y
#
# Power Management
#
-# CONFIG_PM_SLEEP_FUNC_IN_IRAM is not set
+CONFIG_PM_SLEEP_FUNC_IN_IRAM=y
# CONFIG_PM_ENABLE is not set
-# CONFIG_PM_SLP_IRAM_OPT is not set
+CONFIG_PM_SLP_IRAM_OPT=y
CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y
CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP=y
# end of Power Management
diff --git a/version.txt b/version.txt
index 1d0ba9e..2b7c5ae 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-0.4.0
+0.4.2