# 隧道/代理

> 通过 SSH 隧道、HTTP 隧道、SOCKS5 代理或 HTTP 代理连接内网数据库。

Source: https://dbxio.com/cn/docs/ssh-tunnel

Language: zh-CN

Relative links resolve against https://dbxio.com/cn/docs/ssh-tunnel.



当数据库不能直接访问时，DBX 可以在连接窗口的 

**隧道/代理**

 页签里配置连接层。

隧道实际运行在 DBX 后端所在的位置。桌面版中的“本地路径”和临时监听端口属于当前电脑；Docker/Web 版中的路径、网络出口和临时监听端口属于服务器或容器，不属于浏览器所在电脑。

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 秒 |

### 密钥认证（推荐）

填写 DBX 后端可以读取的 SSH 私钥文件，例如 `~/.ssh/id_rsa`、`~/.ssh/id_ed25519`：

* **密钥路径**：桌面版可以浏览本机文件；Web 版需要手动填写服务器或容器内的路径。
* **密钥密码**：如果私钥设置了密码保护，在这里输入。

密钥认证比密码认证更安全，推荐优先使用。

### 密钥+密码

以私钥为主要认证方式，密码作为回退。DBX 会先尝试密钥认证，如果服务器拒绝了密钥且仍支持密码认证，会自动回退到密码认证。

* **密钥路径**：浏览并选择私钥文件。
* **密钥密码**：如果私钥设置了密码保护，在这里输入。
* **密码**：输入 SSH 密码作为回退。

适用于密钥可能被临时撤销、或多跳隧道中不同跳板需要不同认证方式的场景。

### 密码认证

直接输入 SSH 用户的登录密码。适用于允许密码登录的服务器。

### 无凭据

只执行 SSH `none` 认证，不发送密码或私钥。仅适用于明确允许无凭据登录的 SSH 代理或特殊网关；服务器拒绝后不会回退到其他认证方式。

### 主机密钥验证

DBX 会在发送凭据前验证 SSH 主机密钥。已知密钥从系统 `known_hosts` 和 DBX 数据目录中的 `known_hosts` 读取：

* 第一次连接到未知主机时，DBX 会显示指纹并要求明确接受；
* 可以只信任本次连接，也可以记住到 DBX 的 `known_hosts`；
* 已保存在 DBX `known_hosts` 中的主机密钥变化时，会弹出指纹对比。可以选择关闭、仅本次继续，或更新已保存指纹并继续。DBX 不会改写 `~/.ssh/known_hosts`，那里的不一致仍会直接拒绝；
* 如果确认窗口不可用、超时或被拒绝，连接会失败，并且不会发送密码或私钥。

### 允许局域网访问

启用“允许局域网访问”会把 SSH 临时监听端口从 

`127.0.0.1`

 改为 

`0.0.0.0`

。这会扩大当前 DBX 运行环境的攻击面，只应在可信网络并配合防火墙使用。

桌面版中，这意味着当前电脑可能被局域网设备访问。Docker/Web 版中，监听发生在服务器或容器内，是否能从容器外访问还取决于端口发布、容器网络和主机防火墙。

## 代理

如果当前网络要求通过代理访问数据库，可以添加代理层，而不是配置 SSH。

DBX 支持：

* SOCKS5 代理
* HTTP CONNECT 代理
* 可选代理用户名和密码

共享代理配置可以填写可选的测试目标，例如 `mysql.internal:3306`。不填写时，测试只验证代理端点和认证；最终数据库可达性仍以连接测试为准。

## HTTP 隧道

功能类型叫 HTTP 隧道。DBX 当前随代码提供的部署脚本是 

`dbx_tunnel.php`

，所以部署文件是 PHP 实现，但连接类型本身不是“PHP 隧道”。

当数据库在内网中，外部只能访问一台内网 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 模式。

### [创建连接](/cn/docs/getting-started)

在同一个连接窗口里配置数据库类型、隧道/代理、SSL 和连接颜色。

### [数据库支持](/cn/docs/databases)

查看哪些数据库是文件型、原生驱动、兼容协议或插件驱动。

### [生产安全](/cn/docs/production-safety)

规划最小权限、网络暴露、只读保护和生产写入流程。

