yaport
v0.1.2
Published
丫口是一个本机运行的 Web UI 和 CLI,用 SSH 读取远程机器当前监听中的 TCP/UDP 端口。
Readme
丫口 (yaport)
丫口是一个本机运行的 Web UI 和 CLI,用 SSH 读取远程机器当前监听中的 TCP/UDP 端口。
English documentation is available below: English.
适合什么场景
- 快速查看远程机器的监听端口、监听地址、协议、状态、进程和 PID。
- 通过 OpenSSH alias 连接机器,例如
ssh erya对应--host erya。 - 通过一层或两层跳板机连接目标机器,底层使用 OpenSSH
ProxyJump。 - 目标机器或跳板机需要 SSH 密码时,可以在 GUI 填写,也可以通过 CLI 环境变量传入。
- 面板和 CLI 都能配置连接超时、命令超时,适合慢链路或两层跳板机。
- 如果远程机器有 nginx、OpenResty、Tengine 或 Caddy 配置,丫口会把能匹配端口的外部入口 URL 展示在端口行里。
- 当前选中的机器会复用 OpenSSH ControlMaster 连接,降低两层跳板和密码认证的重复握手成本。
丫口只做只读查询,不扫描网段,也不修改远程机器配置。
安装
全局安装:
pnpm add -g yaport也可以直接用 pnpm dlx:
pnpm dlx yaport本地开发运行:
pnpm install
pnpm dev启动 Web UI
yaport
yaport --host 127.0.0.1 --port 5173
yaport --data-file .yaport/machines.json
yaport --no-open默认行为:
yaport会启动本机 server,并自动打开网页。- 默认监听
127.0.0.1:5173。 - 默认机器配置目录按顺序查找
./.yaport、~/.yaport,命中即使用其中的machines.json,不合并;都不存在时创建当前目录的./.yaport/machines.json。 --no-open适合脚本、agent、远程 shell,不自动打开浏览器。
通过 CLI 添加机器
GUI 能添加机器,但大量机器用 CLI 更快。add-machine 是非交互式命令,适合 agent 和脚本使用。
OpenSSH alias,等价于 ssh erya:
yaport add-machine --host erya --json明确指定用户和端口:
yaport add-machine --name Prod --host 10.0.0.5 --user root --port 2222 --json目标机器密码使用环境变量传入:
TARGET_PASSWORD='[redacted-target-password]' yaport add-machine \
--name Prod \
--host 10.0.0.5 \
--user root \
--password-env TARGET_PASSWORD \
--json一层跳板机:
JUMP_PASSWORD='[redacted-jump-password]' TARGET_PASSWORD='[redacted-target-password]' yaport add-machine \
--name Prod \
--host prod.internal \
--user app \
--password-env TARGET_PASSWORD \
--connect-timeout 30 \
--command-timeout 90 \
--jump1-host jump.internal \
--jump1-user ops \
--jump1-password-env JUMP_PASSWORD \
--json两层跳板机:
yaport add-machine \
--name DeepTarget \
--host target.internal \
--user app \
--jump1-host jump-a.internal \
--jump1-user ops \
--jump2-host jump-b.internal \
--jump2-user edge \
--json常用参数:
| 参数 | 说明 |
| --- | --- |
| --name <name> | UI 里展示的机器名称;留空时默认用 user@host:port。 |
| --host <host> | SSH host、IP 或 OpenSSH alias。 |
| --user <user> | SSH 用户。OpenSSH alias 已配置时可以省略;--host 是 IP 地址时必须填写。 |
| --port <port> | SSH 端口。OpenSSH alias 已配置时可以省略。 |
| --password-env <env> | 从环境变量读取目标机器 SSH 密码。 |
| --connect-timeout <seconds> | SSH 连接超时。可选值:8、15、30、60。默认 15。 |
| --command-timeout <seconds> | 本机等待命令完成的总超时。可选值:12、30、45、90。默认 45。 |
| --jump1-host <host> | 第一层跳板机。 |
| --jump2-host <host> | 第二层跳板机。 |
| --jumpN-user <user> | 第 N 层跳板机 SSH 用户。 |
| --jumpN-port <port> | 第 N 层跳板机 SSH 端口。 |
| --jumpN-password-env <env> | 从环境变量读取第 N 层跳板机密码。 |
| --json | 输出稳定 JSON,不输出密码。 |
| --data-file <path> | 指定机器配置文件,跳过默认两层查找。 |
建议:
- agent 和脚本优先使用
--json。 - 密码优先使用
--password-env和--jumpN-password-env,不要把密码直接放进命令参数。 - 使用 OpenSSH alias 时,
--user和--port可以留空。 - 使用 IP 地址连接目标机器或跳板机时,必须填写对应用户。
- 两层跳板或密码认证握手较慢时,建议使用
--connect-timeout 30 --command-timeout 90。
配置开机自启
丫口可以安装为当前用户的系统服务,不需要 sudo。macOS 使用 LaunchAgent,Linux 使用 systemd user service。服务启动时会带 --no-open,不会开机自动弹浏览器。
yaport service install --port 5173 --json
yaport service status
yaport service uninstall常用参数:
| 参数 | 说明 |
| --- | --- |
| install | 写入并启动用户级服务。 |
| uninstall | 停止并移除用户级服务。 |
| status | 调用 launchctl 或 systemctl --user 查看状态。 |
| --host <host> | 服务监听地址,默认 127.0.0.1。 |
| --port <port> | 服务监听端口,默认 5173。 |
| --data-file <path> | 服务使用的机器配置文件;不传时仍按 ./.yaport、~/.yaport 查找。 |
| --json | install / uninstall 输出稳定 JSON。 |
端口信息
丫口通过本机 OpenSSH 登录远程机器,并读取:
ss -H -lntup:监听中的 TCP/UDP 端口。ps -ww -p <pid> -o pid=,args=:尽量补全进程命令行。nginx -T/openresty -T/tengine -T//etc/caddy/Caddyfile:对应代理进程正在监听且配置可读时,推断外部入口。
ss 会先执行;拿到 PID 后,ps 和代理配置读取会并发执行。丫口只在 ss 结果里看到 nginx、OpenResty、Tengine 或 Caddy 进程时才读取对应配置,避免拖慢普通机器刷新。任意一个失败都不会影响端口清单。
表格展示:
- 协议:TCP / UDP。
- 监听地址。
- 端口号。
- 状态。
- 进程名称或完整命令行。
- PID。
- 外部入口。
外部入口
当代理配置可读时,丫口会按端口匹配外部入口。
nginx / OpenResty / Tengine 规则:
listen 443 ssl或端口443展示为https://server_name。- 其他端口展示为
http://server_name:port。 server_name _、空值、变量域名不展示。- 配置读不到不会影响端口清单,只显示“无外部入口”。
Caddy 规则:
- 读取
/etc/caddy/Caddyfile的站点块地址。 example.com展示为https://example.com。http://example.com:8080展示为http://example.com:8080。_、变量地址、纯端口地址、通配地址暂不展示。
外部入口按机器缓存 5 分钟,包括短时间缓存读取失败,避免静默刷新时重复等待慢失败。 不同来源会显示不同小图标:nginx / OpenResty / Tengine / Caddy。
Web UI 行为
- 添加机器表单默认折叠。
- 添加机器时可以选择“连接超时”和“命令超时”。
- 连接名称可选,留空时默认用主机信息;Host 是 IP 地址时用户必填,OpenSSH alias 可以留空。
- 机器卡片右侧可以打开本机 Terminal,并用该机器配置执行
ssh。已保存密码不会写入命令行。 - 左侧机器列表在页面滚动时固定在左侧,也可以折叠成窄栏。
- 右键机器卡片可以编辑或删除连接配置;编辑时密码框留空表示保留原密码。
- TCP / UDP 指标卡带开关,默认开启,用于过滤下方记录。
- “监听端口”指标卡可以按端口分组。
- “进程”指标卡可以按进程分组。
- 切换机器时按机器粒度保留上次结果,不会把上一台机器的端口展示到当前机器。
- 当前选中的机器会使用 OpenSSH
ControlMaster=auto和ControlPersist=5m,ss、ps、代理配置读取、手动刷新和 1 分钟自动刷新会复用同一条 SSH master connection。 - 未选中机器的后台静默刷新不启用连接复用,避免维护过多后台连接。
- 网页在前台活跃时,选中机器默认每 1 分钟静默刷新,未选中机器默认每 5 分钟静默刷新。
- 机器列表和当前选中机器会写入
sessionStorage,刷新页面后能先看到本地缓存,再等待 server 返回最新数据。
数据与安全
- 机器配置目录默认按顺序查找
./.yaport、~/.yaport,命中即使用其中的machines.json,不合并;都不存在时创建当前目录的./.yaport/machines.json。 - 配置文件以
0600权限写入。 - API 和 CLI JSON 输出不会返回已保存的 SSH 密码。
- 密码目前是本机明文保存;如果不想落盘,优先使用 SSH key 或 OpenSSH alias。
- 丫口只从远程机器读取端口、进程和代理配置,不会写远程文件。
远程机器要求
- 本机需要可用的 OpenSSH
ssh命令。 - 远程机器需要有
ss命令。 - 进程命令行和 PID 是否完整,取决于当前 SSH 用户权限。
- 外部入口依赖远程机器能执行或读取对应代理配置。
本地开发
pnpm install
pnpm dev
pnpm test
pnpm build打包后的 CLI 入口:
pnpm build
node bin/yaport.js --helpEnglish
Yaport is a local Web UI and CLI for reading currently listening TCP/UDP ports on remote machines through SSH.
Yaport is read-only. It does not scan networks and does not modify remote machine configuration.
Use Cases
- Inspect listening ports, listen addresses, protocols, states, processes, and PIDs on remote machines.
- Connect through OpenSSH aliases, for example
ssh eryamaps to--host erya. - Connect through one or two jump hosts via OpenSSH
ProxyJump. - Support SSH passwords for both target machines and jump hosts, from the GUI or CLI environment variables.
- Configure connection and command timeouts from both the UI and CLI for slow links or two-hop jump paths.
- Infer public-facing nginx, OpenResty, Tengine, and Caddy URLs and show them next to matching listening ports.
- Reuse an OpenSSH ControlMaster connection for the currently selected machine to reduce repeated handshakes on slow jump paths.
Installation
Install globally:
pnpm add -g yaportOr run it with pnpm dlx:
pnpm dlx yaportFor local development:
pnpm install
pnpm devStart the Web UI
yaport
yaport --host 127.0.0.1 --port 5173
yaport --data-file .yaport/machines.json
yaport --no-openDefault behavior:
yaportstarts the local server and opens the Web UI automatically.- The default bind address is
127.0.0.1:5173. - The default machine config directory lookup checks
./.yaportfirst, then~/.yaport. The first hit wins and Yaport uses that directory'smachines.json; files are not merged. If neither directory exists, Yaport creates./.yaport/machines.json. - Use
--no-openfor scripts, agents, or remote shells.
Add Machines from the CLI
The GUI can add machines, but the CLI is faster for repeated setup. add-machine is non-interactive and works well from agents and scripts.
OpenSSH alias, same as ssh erya:
yaport add-machine --host erya --jsonExplicit user and port:
yaport add-machine --name Prod --host 10.0.0.5 --user root --port 2222 --jsonTarget password from an environment variable:
TARGET_PASSWORD='[redacted-target-password]' yaport add-machine \
--name Prod \
--host 10.0.0.5 \
--user root \
--password-env TARGET_PASSWORD \
--jsonOne jump host:
JUMP_PASSWORD='[redacted-jump-password]' TARGET_PASSWORD='[redacted-target-password]' yaport add-machine \
--name Prod \
--host prod.internal \
--user app \
--password-env TARGET_PASSWORD \
--connect-timeout 30 \
--command-timeout 90 \
--jump1-host jump.internal \
--jump1-user ops \
--jump1-password-env JUMP_PASSWORD \
--jsonTwo jump hosts:
yaport add-machine \
--name DeepTarget \
--host target.internal \
--user app \
--jump1-host jump-a.internal \
--jump1-user ops \
--jump2-host jump-b.internal \
--jump2-user edge \
--jsonCommon options:
| Option | Description |
| --- | --- |
| --name <name> | Display name in the UI. When omitted, Yaport uses user@host:port. |
| --host <host> | SSH host, IP address, or OpenSSH alias. |
| --user <user> | SSH user. Omit it when an OpenSSH alias already defines User; required when --host is an IP address. |
| --port <port> | SSH port. Omit it when an OpenSSH alias already defines Port. |
| --password-env <env> | Read the target machine SSH password from an environment variable. |
| --connect-timeout <seconds> | SSH connection timeout. Choices: 8, 15, 30, 60. Default: 15. |
| --command-timeout <seconds> | Total local command timeout. Choices: 12, 30, 45, 90. Default: 45. |
| --jump1-host <host> | First jump host. |
| --jump2-host <host> | Second jump host. |
| --jumpN-user <user> | SSH user for jump host N. |
| --jumpN-port <port> | SSH port for jump host N. |
| --jumpN-password-env <env> | Read jump host N's password from an environment variable. |
| --json | Print deterministic JSON. Passwords are never printed. |
| --data-file <path> | Use a specific machine config file and skip the default two-level lookup. |
Recommendations:
- Use
--jsonfrom agents and scripts. - Prefer
--password-envand--jumpN-password-env; avoid putting passwords directly in process arguments. - Omit
--userand--portwhen--hostis an OpenSSH alias. - IP targets and IP jump hosts must include a user.
- For slow two-hop jump paths or password handshakes, use
--connect-timeout 30 --command-timeout 90.
Autostart Service
Yaport can install a user-level service without sudo. macOS uses LaunchAgent, and Linux uses a systemd user service. The installed service starts with --no-open, so it does not open a browser automatically after login.
yaport service install --port 5173 --json
yaport service status
yaport service uninstallCommon options:
| Option | Description |
| --- | --- |
| install | Write and start the user-level service. |
| uninstall | Stop and remove the user-level service. |
| status | Show status through launchctl or systemctl --user. |
| --host <host> | Service bind host. Default: 127.0.0.1. |
| --port <port> | Service bind port. Default: 5173. |
| --data-file <path> | Machine config file used by the service. Without this, Yaport still checks ./.yaport, then ~/.yaport. |
| --json | Print deterministic JSON for install / uninstall. |
Port Inventory
Yaport logs in through local OpenSSH and reads:
ss -H -lntup: listening TCP/UDP ports.ps -ww -p <pid> -o pid=,args=: full process command lines when available.nginx -T/openresty -T/tengine -T//etc/caddy/Caddyfile: proxy configuration, when the matching proxy process is listening and the config is readable, to infer external routes.
ss runs first. After PIDs are available, ps and proxy config reads run concurrently. Yaport only reads proxy config when the ss result already shows nginx, OpenResty, Tengine, or Caddy, so ordinary machines do not pay extra refresh latency. Either one may fail without breaking the port list.
The table shows:
- Protocol: TCP / UDP.
- Listen address.
- Port.
- State.
- Process name or full command line.
- PID.
- External routes.
External Routes
When proxy configuration is readable, Yaport matches external routes by port.
nginx / OpenResty / Tengine rules:
listen 443 sslor port443is shown ashttps://server_name.- Other ports are shown as
http://server_name:port. server_name _, empty names, and variable names are ignored.- If config cannot be read, the port list still works and the UI shows no external route.
Caddy rules:
- Yaport reads site block addresses from
/etc/caddy/Caddyfile. example.comis shown ashttps://example.com.http://example.com:8080is shown ashttp://example.com:8080._, variable addresses, port-only addresses, and wildcard addresses are ignored for now.
External routes are cached per machine for 5 minutes, including short-lived failure caching, so silent refreshes do not repeatedly wait on slow config reads. Routes include a small source icon for nginx, OpenResty, Tengine, or Caddy.
Web UI Behavior
- The add-machine form is collapsed by default.
- The add-machine form lets you choose connection timeout and command timeout.
- The connection name is optional. When omitted, Yaport uses the host information. IP hosts require a user; OpenSSH aliases can omit it.
- The right side of each machine card opens the local Terminal and runs
sshwith that machine's connection settings. Stored passwords are not written into the command line. - The left machine list stays fixed while the page scrolls and can collapse into a narrow rail.
- Right-click a machine card to edit or delete that connection config. During edits, leaving password fields blank keeps the existing password.
- TCP and UDP metric cards include switches, both enabled by default, to filter visible records.
- The listening-port metric card can group the table by port.
- The process metric card can group the table by process.
- Switching machines keeps the selected machine's own cached result; it never shows another machine's ports as stale data.
- The selected machine uses OpenSSH
ControlMaster=autoandControlPersist=5m;ss,ps, proxy config reads, manual refresh, and 1-minute auto refresh reuse the same SSH master connection. - Background refreshes for unselected machines do not use connection reuse, so Yaport does not keep extra background master connections open.
- While the page is visible, the selected machine refreshes silently every 1 minute, and unselected machines refresh silently every 5 minutes.
- The machine list and selected machine ID are stored in
sessionStoragefor immediate visibility after page reload.
Data and Security
- Machine config directory lookup checks
./.yaportfirst, then~/.yaport. The first hit wins and Yaport uses that directory'smachines.json; files are not merged. If neither directory exists, Yaport creates./.yaport/machines.json. - The config file is written with
0600permissions. - API responses and CLI JSON output never return stored SSH passwords.
- Passwords are currently stored locally in plain text. Prefer SSH keys or OpenSSH aliases if you do not want passwords on disk.
- Yaport only reads remote ports, processes, and proxy configuration. It does not write remote files.
Remote Requirements
- Local machine: OpenSSH
ssh. - Remote machine:
ss. - Process command lines and PIDs depend on the SSH user's permissions.
- External routes require the matching proxy config command or file to be executable or readable on the remote machine.
Development
pnpm install
pnpm dev
pnpm test
pnpm buildPackaged CLI entry:
pnpm build
node bin/yaport.js --help