Files
dbx/docs/content/docs/ssh-tunnel.cn.mdx
T

184 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 隧道/代理
description: 通过 SSH 隧道、HTTP 隧道、SOCKS5 代理或 HTTP 代理连接内网数据库。
---
<Callout type="info">当数据库不能直接访问时,DBX 可以在连接窗口的 **隧道/代理** 页签里配置连接层。</Callout>
<Callout type="warning">
隧道实际运行在 DBX 后端所在的位置。桌面版中的“本地路径”和临时监听端口属于当前电脑;Docker/Web 版中的路径、网络出口和临时监听端口属于服务器或容器,不属于浏览器所在电脑。
</Callout>
DBX 支持三类隧道/代理:
| 类型 | 适用场景 |
| -------- | --------------------------------------------- |
| SSH 隧道 | 有跳板机、堡垒机或数据库服务器的 SSH 权限。 |
| 代理 | 网络环境要求通过 SOCKS5 或 HTTP CONNECT 代理。 |
| HTTP 隧道 | 只有内网 Web 服务器能访问数据库,不能使用 SSH/VPN。 |
对网络数据库来说,DBX 会先在当前运行环境中打开一个临时端口,让数据库驱动连接这个端口,再由隧道/代理层把数据库协议字节转发到真实目标。一个连接可以组合多层传输配置,DBX 会按照连接窗口中的顺序建立链路。
## 连接内配置与共享配置
你可以直接在单个连接的 **隧道/代理** 页签中填写配置,也可以前往 **设置 → 隧道** 创建共享配置:
- 共享配置支持 SSH、SOCKS5 / HTTP CONNECT 代理和 HTTP 隧道;
- 一个共享配置可以被多个数据库连接引用;
- 修改共享配置后,所有引用它的连接会在下次连接时使用新配置;
- SSH 测试会验证主机可达性和认证,代理测试会验证代理握手,并可填写目标 `host:port`;
- HTTP 隧道只有在转发真实目标流量时才会建立会话,因此共享配置页不提供独立测试。
如果某个连接需要不同凭据或特殊顺序,可以把共享配置从该连接中分离,再保存为连接专属配置。
## SSH 隧道
SSH 隧道是内置能力,不需要在终端里手动执行端口转发命令。
| 字段 | 说明 |
| ---------- | ------------------------------------------ |
| SSH 主机 | SSH 服务器的地址 |
| SSH 端口 | SSH 端口,默认 `22` |
| SSH 用户 | 登录 SSH 服务器的用户名 |
| 连接超时 | DBX 等待 SSH 连接建立的最长时间,默认 5 秒 |
<Tabs groupId="ssh-auth" items={['密钥认证(推荐)', '密钥+密码', '密码认证', '无凭据']}>
<Tab value="密钥认证(推荐)">
填写 DBX 后端可以读取的 SSH 私钥文件,例如 `~/.ssh/id_rsa`、`~/.ssh/id_ed25519`:
- **密钥路径**:桌面版可以浏览本机文件;Web 版需要手动填写服务器或容器内的路径。
- **密钥密码**:如果私钥设置了密码保护,在这里输入。
密钥认证比密码认证更安全,推荐优先使用。
</Tab>
<Tab value="密钥+密码">
以私钥为主要认证方式,密码作为回退。DBX 会先尝试密钥认证,如果服务器拒绝了密钥且仍支持密码认证,会自动回退到密码认证。
- **密钥路径**:浏览并选择私钥文件。
- **密钥密码**:如果私钥设置了密码保护,在这里输入。
- **密码**:输入 SSH 密码作为回退。
适用于密钥可能被临时撤销、或多跳隧道中不同跳板需要不同认证方式的场景。
</Tab>
<Tab value="密码认证">
直接输入 SSH 用户的登录密码。适用于允许密码登录的服务器。
</Tab>
<Tab value="无凭据">
只执行 SSH `none` 认证,不发送密码或私钥。仅适用于明确允许无凭据登录的 SSH 代理或特殊网关;服务器拒绝后不会回退到其他认证方式。
</Tab>
</Tabs>
### 主机密钥验证
DBX 会在发送凭据前验证 SSH 主机密钥。已知密钥从系统 `known_hosts` 和 DBX 数据目录中的 `known_hosts` 读取:
- 第一次连接到未知主机时,DBX 会显示指纹并要求明确接受;
- 可以只信任本次连接,也可以记住到 DBX 的 `known_hosts`;
- 已保存在 DBX `known_hosts` 中的主机密钥变化时,会弹出指纹对比。可以选择关闭、仅本次继续,或更新已保存指纹并继续。DBX 不会改写 `~/.ssh/known_hosts`,那里的不一致仍会直接拒绝;
- 如果确认窗口不可用、超时或被拒绝,连接会失败,并且不会发送密码或私钥。
### 允许局域网访问
<Callout type="warn">启用“允许局域网访问”会把 SSH 临时监听端口从 `127.0.0.1` 改为 `0.0.0.0`。这会扩大当前 DBX 运行环境的攻击面,只应在可信网络并配合防火墙使用。</Callout>
桌面版中,这意味着当前电脑可能被局域网设备访问。Docker/Web 版中,监听发生在服务器或容器内,是否能从容器外访问还取决于端口发布、容器网络和主机防火墙。
## 代理
如果当前网络要求通过代理访问数据库,可以添加代理层,而不是配置 SSH。
DBX 支持:
- SOCKS5 代理
- HTTP CONNECT 代理
- 可选代理用户名和密码
共享代理配置可以填写可选的测试目标,例如 `mysql.internal:3306`。不填写时,测试只验证代理端点和认证;最终数据库可达性仍以连接测试为准。
## HTTP 隧道
<Callout type="info">功能类型叫 HTTP 隧道。DBX 当前随代码提供的部署脚本是 `dbx_tunnel.php`,所以部署文件是 PHP 实现,但连接类型本身不是“PHP 隧道”。</Callout>
当数据库在内网中,外部只能访问一台内网 Web 服务器,并且不能使用 SSH/VPN 时,可以使用 HTTP 隧道。这类场景和 Navicat、SQL-Front 的 HTTP 隧道类似。
### 部署脚本
把 `deploy/dbx_tunnel.php` 上传到一台能访问目标数据库的 PHP Web 服务器。
在 PHP 服务器上配置环境变量:
| 变量 | 必填 | 说明 |
| -------------------------------- | ---- | -------------------------------------------- |
| `DBX_TUNNEL_TOKEN` | 是 | 共享 token。DBX 里填写同一个值。 |
| `DBX_TUNNEL_ALLOWED_HOSTS` | 否 | 允许连接的目标主机列表,逗号分隔,强烈建议配置。 |
| `DBX_TUNNEL_DIR` | 否 | 会话队列目录,默认使用临时目录。 |
| `DBX_TUNNEL_MAX_SESSION_SECONDS` | 否 | 会话最长生命周期,默认 `3600` 秒。 |
| `DBX_TUNNEL_PHP` | 否 | 当 PHP-FPM 没有 `fastcgi_finish_request` 时,用于启动 worker 的 PHP CLI 路径。 |
在 DBX 里添加 **HTTP 隧道** 层,并填写:
| 字段 | 说明 |
| -------------- | ------------------------------------------------------- |
| 隧道脚本 URL | `dbx_tunnel.php` 的 URL,例如 `https://example.com/dbx_tunnel.php` |
| 隧道 Token | `DBX_TUNNEL_TOKEN` 的值 |
| 隧道超时 | 打开 HTTP 隧道以及连接目标数据库的超时时间 |
数据库主机和端口要填写“PHP 服务器视角下能访问到的地址”,不一定是你本机能直接访问到的地址。
### HTTP 隧道流程
```text
DBX 数据库驱动
-> 127.0.0.1:<本地临时端口>
-> DBX HTTP 隧道客户端
-> HTTP POST 请求
-> Web 服务器上的 dbx_tunnel.php
-> PHP 发起到内网数据库的 TCP 连接
-> 数据库
```
具体协议是短 HTTP 轮询:
1. DBX 在当前运行环境中启动一个 TCP 监听端口。
2. 数据库驱动连接这个本地端口。
3. DBX 向 `dbx_tunnel.php` 发送 `open`,带上 session id、目标主机、目标端口和连接超时。
4. PHP 脚本校验 token 和 allow-list,然后启动 worker,worker 打开到数据库的 TCP socket。
5. 数据库驱动发出的字节由 DBX 通过 `write` 发给脚本。
6. DBX 通过 `read` 轮询脚本;脚本返回数据库响应字节后,DBX 写回本地数据库驱动连接。
7. 连接结束时,DBX 发送 `close`,PHP worker 关闭数据库 socket。
这个方案不需要部署 DBX Web,也不使用 WebSocket。
### 安全与限制
- 脚本 URL 建议使用 HTTPS。
- `DBX_TUNNEL_TOKEN` 应使用足够长的随机值。
- 建议配置 `DBX_TUNNEL_ALLOWED_HOSTS`,避免脚本变成通用内网 TCP 转发入口。
- 如果条件允许,限制脚本路径的公网访问范围。
- HTTP 隧道部署方便,但通常比直连、VPN、SSH 慢,因为它通过 HTTP 轮询和服务器端队列搬运数据库字节流。
- 如果和其他连接层一起使用,HTTP 隧道必须放在隧道/代理第一层,因为它是最外层网络边界。
- HTTP 隧道脚本拥有访问目标主机的能力,部署和日常使用应遵循[生产安全](/cn/docs/production-safety)中的最小暴露与凭据要求。
## 文件型数据库
Access 是文件型连接,不使用隧道/代理。DuckDB 通常也使用本地文件,所以只有当当前驱动类型确实需要网络端点时才需要配置隧道/代理。
SQLite 同样是文件数据库。本地 SQLite 文件仍然不会走 TCP 隧道。在桌面端,你可以为 SQLite 连接附加 SSH 跳板,用来打开 Linux amd64/arm64 **文件主机**上的远程 SQLite 文件。DBX 会在**最后一跳**上启动短生命周期 worker 并与它通信,而不会把 `.db` 拷回笔记本。路径字段是该文件主机上的绝对路径,不是本地文件选择器。
第一次会实际上传 worker 的测试/连接会先征求同意,并显示目标路径和摘要。可以选择仅会话使用(断开连接后删除远端文件)、持久保存在 `~/.cache/dbx/sqlite-worker/<digest>`,或指向预放置的二进制。桌面端从驱动管理安装 **SQLite SSH Worker** 时会一次拉齐 Linux x64 和 Linux ARM64 两份,连接时再按文件主机架构选用对应那一份上传。v1 不支持该远程路径上的 SQLCipher、可加载扩展和附加数据库。备份会把 SQLite 快照存到本机;还原从本机选择 SQLite 文件,再应用到文件主机上的数据库。
Oracle TNS 描述符可能包含多个故障转移地址,DBX 不会把它重写到单个临时端口,因此 TNS 模式不能和 SSH、代理或 HTTP 隧道组合。需要隧道时请改用 Service Name 或 SID 模式。
<Cards>
<Card title="创建连接" href="/cn/docs/getting-started">
在同一个连接窗口里配置数据库类型、隧道/代理、SSL 和连接颜色。
</Card>
<Card title="数据库支持" href="/cn/docs/databases">
查看哪些数据库是文件型、原生驱动、兼容协议或插件驱动。
</Card>
<Card title="生产安全" href="/cn/docs/production-safety">
规划最小权限、网络暴露、只读保护和生产写入流程。
</Card>
</Cards>