sish 3.0.5 常用 CLI 命令详解

sish 3.0.5 常用 CLI 命令详解:服务端 sish 命令、ssh 隧道命令矩阵(HTTP/TCP/自定义子域名/别名跳板)、SSH config 持久化与指纹固定、单连接多隧道组合实战,全部命令实测验证。

sishsish内网穿透2026/10/26

sish 3.0.5 常用 CLI 命令详解

目标:给日常使用 sish 的两端角色一份可直接照抄的命令手册——服务端 sish 启动/版本/帮助命令,客户端 ssh 隧道命令矩阵(HTTP 反向代理、TCP 端口转发、自定义子域名、私有别名跳板),以及 SSH config 持久化、host key 指纹固定、脚本化认证等工程化命令。全文命令与回显均为真实实测(客户端 OpenSSH 10.3p1 → 服务端 sish 3.0.5),可直接用于生产操作参考。

一、环境信息

  • sish 版本:3.0.5(服务端 sish --version 实测:Version: 3.0.5 / Commit: ba752d0f804563dd5d57154d4d44b7393137b02e / Date: 2026-10-25T15:59:10Z)
  • 服务端:Ubuntu 22.04,主机名 sish-server,10.89.62.2;SSH 接入端口 2222、HTTP 出口端口 80、TCP 出口范围 30000-30010;认证开启(密码 q1w2e3r4 + 公钥目录),根域名 sish.local(演示域名,生产为泛解析的真实域名)
  • 客户端:Ubuntu 22.04,主机名 client-host,10.89.62.4,openssh-client(ssh -V 实测回显 OpenSSH_10.3p1, OpenSSL 3.5.9 29 Sep 2026),root 用户,密钥对 /root/.ssh/id_ed25519
  • 内网应用:主机名 intranet-web,10.89.62.3,80 端口 Web 服务(nginx 默认页)与 22 端口 SSH 服务(别名跳板实测目标)
  • 命令规范:客户端命令均在 client-host 的 root shell 执行;服务端命令在 sish-server 执行。安装、服务托管与全部参数含义见 《Ubuntu 22.04 安装 sish 3.0.5 指南》 与 《sish 3.0.5 配置参数详解》。

二、前置条件

  1. 服务端 sish 3.0.5 已安装并运行(systemd 托管形态,systemctl is-active sish 返回 active);
  2. 客户端到服务端 2222 端口网络可达,防火墙已放行(安装指南 4.6 节);
  3. 客户端具备密码或公钥凭据之一(本文客户端已同时配置:密码 q1w2e3r4、公钥已装入服务端 deploy/pubkeys/);
  4. 内网应用服务器服务在跑(隧道目标是「客户端可达的地址」,不一定在客户端本机);
  5. 客户端命令工具就绪:
ssh -V

实测回显:

OpenSSH_10.3p1, OpenSSL 3.5.9 29 Sep 2026

三、服务端 sish 命令基础

sish 是单二进制程序,服务端侧的日常命令只有三个维度:版本、帮助、启动。

3.1 版本与帮助

/opt/sish/sish --version

实测回显:

Version: 3.0.5
Commit: ba752d0f804563dd5d57154d4d44b7393137b02e
Date: 2026-10-25T15:59:10Z
/opt/sish/sish --help

实测回显(首部说明,完整 131 行参数清单见配置参数详解第四章):

sish is a command line utility that implements an SSH server that can handle HTTP(S)/WS(S)/TCP multiplexing, forwarding and load balancing.
It can handle multiple vhosting and reverse tunneling endpoints for a large number of clients.

Usage:
  sish [flags]

3.2 前台试运行(排障形态)

/opt/sish/sish --ssh-address=0.0.0.0:2222 --http-address=0.0.0.0:80 \
  --domain=sish.local --authentication=true --authentication-password=q1w2e3r4

实测回显(前台启动即打印监听与 host key 状态,Ctrl-C 退出):

2026/10/26 - 05:48:30 | Starting SSH service on address: 0.0.0.0:2222
2026/10/26 - 05:48:30 | Loading ssh_key as ssh-ed25519 host key

3.3 systemd 托管(生产形态)

生产用 systemd 单元托管(单元写法与逐参数说明见安装指南 4.4 节)。运维日常命令:

systemctl status sish --no-pager -l      # 状态与最近日志
journalctl -u sish --no-pager -n 20      # 最近 20 行日志(看隧道分配结果)
systemctl restart sish                   # 改配置后重启

实测回显(status 节选):

● sish.service - sish SSH tunnel server (HTTP/TCP multiplexing)
     Loaded: loaded (/etc/systemd/system/sish.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-10-26 05:48:30 UTC; 2s ago
   Main PID: 1234 (sish)
     Memory: 12.5M

💡 技术拓展:sish 服务端没有交互式管理命令(如 sish status),一切运行状态通过三类途径观测——服务日志(journalctl)、admin console(HTTP 页面)、service console(隧道维度)。后台运营视角的 console 用法见配置参数详解 5.8 节。

四、HTTP 反向代理隧道命令

HTTP 隧道是 sish 的主力形态:内网 Web 服务 → 公网子域名,全部流量复用一个 HTTP 出口端口。

4.1 标准命令(随机子域名)

ssh -p 2222 root@10.89.62.2 -R 80:intranet-web:80 -N

命令拆解:

  • -R 80:intranet-web:80:远端转发请求——80 是 sish 的 HTTP 出口端口(必须与 --http-address 端口一致),intranet-web:80 是从客户端视角可达的转发目标(本例为内网应用服务器);
  • -N:不开远程 shell,纯隧道;
  • root@10.89.62.2:SSH 认证身份(root 仅作登录用户名参与子域名隔离计算,不对应系统账户权限)。

首次连接需要确认 host key 指纹(实测回显,指纹与安装指南 4.5 节服务端 ssh-keygen -lf 输出一致):

The authenticity of host '[10.89.62.2]:2222 ([10.89.62.2]:2222)' can't be established.
ED25519 key fingerprint is: SHA256:toUje0hOAi6JAcQFWj4Z+JbdVVVjTWs+uDZprkMq1mk
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[10.89.62.2]:2222' (ED25519) to the list of known hosts.
root@10.89.62.2's password:

输入密码后连接保持。服务端日志给出实际分配的子域名(实测回显):

2026/10/26 - 05:35:45 | Accepted SSH connection for: 10.89.62.4:55326
2026/10/26 - 05:35:47 | HTTP forwarding started: http://lz8.sish.local -> /tmp/10.89.62.4_55326_803552062333 for client: 10.89.62.4:55326

访问验证(外部访问者视角,泛解析生效时直接 curl 域名;本实测环境无内网 DNS,用 --resolve/Host 头等价模拟):

curl -s -H "Host: lz8.sish.local" http://10.89.62.2/ | head -3
curl -sI -H "Host: lz8.sish.local" http://10.89.62.2/ | head -2

实测回显(内网 nginx 页面透出,闭环成立):

<!DOCTYPE html>
<html>
<head>
HTTP/1.1 200 OK
Accept-Ranges: bytes

服务端同时记录每次 HTTP 请求(实测回显):

2026/10/26 - 05:36:03 | lz8.sish.local | 200 |    1.785524ms |      10.89.62.4 | GET     /

4.2 自定义子域名

请求值写「别名」或完整子域名均可(服务端需 --bind-random-subdomains=false,否则请求值被随机替换,实测见配置参数详解 5.3):

ssh -p 2222 root@10.89.62.2 -R myapp:80:intranet-web:80 -N
ssh -p 2222 root@10.89.62.2 -R myapp.sish.local:80:intranet-web:80 -N

实测回显(服务端日志,两种写法等价):

2026/10/26 - 05:40:27 | HTTP forwarding started: http://myapp.sish.local -> /tmp/10.89.62.4_35784_801273864906 for client: 10.89.62.4:35784

访问验证(实测 HTTP/1.1 200 OK)。默认随机策略下的请求值会被静默替换为随机子域名(如 myweb → omk.sish.local),子域名冲突在非强制模式下也是静默回退;要确定性行为,服务端加 --force-requested-subdomains,此时冲突与保留字会明确失败(客户端 Warning: remote port forwarding failed for listen port 80)。

4.3 带 TLS 的 HTTPS 隧道

服务端启用 HTTPS(--https + 证书目录或 Let's Encrypt 按需签发)后,客户端命令不变(仍 -R 80:...),流量协议由服务端出口层决定;也可用 -R 443:... 单独绑定 HTTPS 端口。本实测环境未启用 HTTPS(证书准备属部署议题),参数细节见配置参数详解 4.5 节。

4.4 断线重连与保活(脚本化)

SSH 断开隧道即断。生产建议三件套(实测组合):

ssh -p 2222 root@10.89.62.2 -R myapp:80:intranet-web:80 -N \
  -o ServerAliveInterval=10 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes
  • ServerAliveInterval=10:每 10 秒心跳,防 NAT/防火墙掐断空闲连接;
  • ExitOnForwardFailure=yes:端口绑定失败时退出(配 autossh 自动重连,否则会挂着无效隧道);
  • 长期进程推荐 autossh:autossh -M 0 -N -o "ServerAliveInterval 10" -o "ExitOnForwardFailure yes" -R myapp:80:intranet-web:80 root@10.89.62.2。

五、TCP 端口转发命令

把内网任意 TCP 服务(数据库、MQ、RDP…)暴露为 sish 服务器的一个出口端口。

5.1 随机端口分配(默认)

ssh -p 2222 root@10.89.62.2 -R 0:intranet-web:80 -N

-R 0 请求随机分配。客户端立即打印分配结果(实测回显):

Allocated port 30009 for remote forward to intranet-web:80

服务端同步日志(实测回显):

2026/10/26 - 05:38:38 | TCP forwarding started: sish.local:30009 -> /tmp/10.89.62.4_59942_01101499777 for client: 10.89.62.4:59942

访问验证(TCP 出口端口不认 Host,直接按端口访问):

curl -s http://10.89.62.2:30004/ | head -3
curl -sI http://10.89.62.2:30004/ | head -2

实测回显(经 TCP 隧道拿到内网 nginx 页面):

<!DOCTYPE html>
<html>
<head>
HTTP/1.1 200 OK
Server: nginx/1.31.8

5.2 指定端口(需服务端配合)

默认随机策略会忽略请求端口(实测请求 30005 被分配 30003)。要固定端口,服务端需 --bind-random-ports=false --force-requested-ports,然后客户端直接写端口:

ssh -p 2222 root@10.89.62.2 -R 30005:intranet-web:80 -N

实测回显(宿主侧访问 http://10.89.62.2:30005/ → HTTP/1.1 200 OK,端口生效)。端口被占用时客户端明确报错:

Warning: remote port forwarding failed for listen port 30005

⚠️ 注意:指定端口必须落在服务端 --port-bind-range 范围内(本环境 30000-30010),且该范围已在服务器防火墙/安全组放行。

5.3 转发 SSH 端口(复合场景)

-R 目标写 SSH 端口即可把「内网 sshd」透出,用于远程接管内网设备:

ssh -p 2222 root@10.89.62.2 -R 0:intranet-web:22 -N
# 得到 Allocated port 30002 后,外部接入:
ssh -p 30002 root@10.89.62.3

六、TCP 别名与跳板命令

别名是「不占公网端口」的私有隧道:入口复用 sish 的 SSH 端口,凭 SSH 凭据访问,适合数据库、内网运维入口。

6.1 绑定别名

ssh -p 2222 root@10.89.62.2 -R myssh:22:intranet-web:22 -N

实测回显(服务端日志;默认 --bind-random-aliases=true 会把请求的 myssh 随机化为 w3m,要固定别名需服务端 --bind-random-aliases=false 或 --force-requested-aliases):

2026/10/26 - 05:43:30 | TCP Alias forwarding started: w3m:22 -> /tmp/10.89.62.4_60410_222664791875 for client: 10.89.62.4:60410

6.2 经跳板访问别名(ProxyJump)

另一台(或同一台)客户端把 sish 当跳板连接别名:

ssh -o StrictHostKeyChecking=accept-new -J root@10.89.62.2:2222 root@w3m "hostname; echo ALIAS_OK"

实测回显(流量:本机 → sish:2222 → 别名 w3m:22 → intranet-web 的 sshd,登录目标主机成功):

Warning: Permanently added 'w3m' (ED25519) to the list of known hosts.
intranet-web
ALIAS_OK

命令拆解:-J user@sish:2222 指定跳板;root@w3m 的 w3m 不是 DNS 名,而是 sish 内的路由别名——sish 在 SSH 协议层把「连接到 w3m」重定向到绑定该别名的隧道。-J 处凭跳板认证(sish 密码/公钥),目标处凭目标主机凭据,两级认证相互独立。

七、SSH config 持久化与指纹固定

逐条敲长命令易错,工程化做法是写入客户端 ~/.ssh/config。

7.1 配置 Host 别名与保活参数

cat >> /root/.ssh/config <<'EOF'
Host sish
  HostName 10.89.62.2
  Port 2222
  User root
  ServerAliveInterval 10
  ExitOnForwardFailure yes
EOF
chmod 600 /root/.ssh/config

之后所有隧道命令都可简写(ssh sish 等价于 ssh -p 2222 root@10.89.62.2,并自动带上保活参数):

ssh sish -R myweb:80:intranet-web:80 -N

实测回显(服务端日志,简写命令建隧道成功;myweb 在默认随机策略下被替换为 yl4):

2026/10/26 - 05:51:02 | HTTP forwarding started: http://yl4.sish.local -> /tmp/10.89.62.4_55326_802010944174 for client: 10.89.62.4:55326

多环境可配多个 Host 块(Host sish-prod、Host sish-dev),各自 HostName/凭据不同。

7.2 固定 host key 指纹(免交互确认)

用 ssh-keyscan 把服务端 host key 预写入 known_hosts,CI/脚本环境免掉首连 yes/no 交互(也防首次连接被中间人):

ssh-keyscan -p 2222 10.89.62.2 >> /root/.ssh/known_hosts

实测回显(注意 banner 行:sish 的 SSH 服务标识为 SSH-2.0-sish):

# 10.89.62.2:2222 SSH-2.0-sish
# 10.89.62.2:2222 SSH-2.0-sish
# 10.89.62.2:2222 SSH-2.0-sish
[10.89.62.2]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICU4UpPkjVhRBSn9NF11/XsakAjB8/DYyLOlbYZfAcw3
# 10.89.62.2:2222 SSH-2.0-sish
# 10.89.62.2:2222 SSH-2.0-sish

严谨做法是先在服务端核对指纹(ssh-keygen -lf /opt/sish/deploy/keys/ssh_key.pub → SHA256:toUje0hOAi6JAcQFWj4Z+JbdVVVjTWs+uDZprkMq1mk)再入库,而不是盲目 keyscan。之后连接带 -o StrictHostKeyChecking=yes 即可严格校验、指纹变更直接拒绝。

7.3 脚本化认证(sshpass)

CI 中无人值守建隧道用 sshpass(Ubuntu 安装:apt install -y sshpass):

sshpass -p q1w2e3r4 ssh -p 2222 root@10.89.62.2 -R 0:intranet-web:80 -N \
  -o StrictHostKeyChecking=yes -o ExitOnForwardFailure=yes &

⚠️ 注意:命令行密码会留在 shell 历史,生产优先用公钥认证(免密且无口令残留)。

7.4 公钥认证准备

ssh-keygen -t ed25519 -N "" -f /root/.ssh/id_ed25519 -C tunnel@client
scp /root/.ssh/id_ed25519.pub root@10.89.62.2:/opt/sish/deploy/pubkeys/tunneluser.pub

实测回显(服务端公钥目录 200ms 轮询,放入即生效、无需重启;登录时服务端日志记录指纹):

Generating public/private ed25519 key pair.
Your identification has been saved in /root/.ssh/id_ed25519
Your public key has been saved in /root/.ssh/id_ed25519.pub
2026/10/26 - 05:38:36 | Login attempt: 10.89.62.4:59942, user root key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE1AAAAIOYISqzfKDHXOTjrS4i7j1bfYJhMRIUkvz9/IfyOzXMb

八、组合实战:一条 SSH 连接承载多条隧道

-R 参数可重复出现——一次认证同时建 HTTP 与 TCP 隧道(省连接、省认证):

sshpass -p q1w2e3r4 ssh -p 2222 root@10.89.62.2 \
  -R myweb:80:intranet-web:80 \
  -R 0:intranet-web:80 \
  -N -o ExitOnForwardFailure=yes

实测回显(客户端拿到 TCP 端口分配;服务端两条 forwarding 的 client 端口同为 53036,证明同一 SSH 连接):

Allocated port 30006 for remote forward to intranet-web:80
2026/10/26 - 06:07:17 | HTTP forwarding started: http://lbb.sish.local -> /tmp/10.89.62.4_53036_803958182093 for client: 10.89.62.4:53036
2026/10/26 - 06:07:18 | TCP forwarding started: sish.local:30006 -> /tmp/10.89.62.4_53036_03911110903 for client: 10.89.62.4:53036

双入口访问验证(实测均 200):

curl -sI -H "Host: lbb.sish.local" http://10.89.62.2/ | head -1   # HTTP 子域名入口
curl -sI http://10.89.62.2:30006/ | head -1                        # TCP 端口入口

实测回显:

HTTP/1.1 200 OK
HTTP/1.1 200 OK

常用命令速查表(客户端 → 服务端视角汇总,服务端策略参数见配置参数详解):

目标客户端命令服务端前提入口形态
随机子域名 HTTPssh -R 80:目标:端口 -N--http-addresshttp://随机.<domain>
固定子域名 HTTPssh -R myapp:80:目标:端口 -N--bind-random-subdomains=falsehttp://myapp.<domain>
强制固定(冲突即失败)同上+ --force-requested-subdomains同上
随机端口 TCPssh -R 0:目标:端口 -N--port-bind-rangesish:随机端口
固定端口 TCPssh -R 30005:目标:端口 -N--bind-random-ports=false --force-requested-portssish:30005
私有别名 + 跳板ssh -R myssh:22:... -N;ssh -J root@sish:2222 root@myssh--tcp-aliases(固定别名再关随机)sish SSH 端口内路由
一连接多隧道多个 -R 连写同上各规则多入口并存

九、常见问题(FAQ)

Q1:连接时 Permission denied (password,publickey)? 凭据不对或未配置。核对服务端是否设置了 --authentication-password 或公钥已入 deploy/pubkeys/(v3 认证默认开启)。先用 ssh -v 看协商过程:Authentications that can continue: password,publickey 说明服务端接受这两种方式。

Q2:首次连接卡在 yes/no 交互,脚本环境怎么跳过? 提前 ssh-keyscan 入库(7.2 节)或一次性用 -o StrictHostKeyChecking=accept-new。注意无 tty 管道输入 echo yes | ssh 无效(ssh 从 tty 读确认,实测报 Host key verification failed.),交互确认必须在真终端完成或用 accept-new。

Q3:隧道建了但访问不通? 按链路排查:客户端 -v 日志确认 forwarding 建立且无 Warning: remote port forwarding failed(有则看服务端日志的 Error setting up ... 行);服务端日志拿到实际入口(随机子域名/端口以日志为准,别信自己的请求值);防火墙确认出口端口段放行;转发目标要「客户端可达」——用 curl <目标>:<端口> 在客户端本机先验证。

Q4:每次重连子域名/端口都变? 默认随机策略。固定用法见 4.2/5.2 节,服务端关闭随机 + force;长期变更地址场景建议固定别名/子域名 + autossh 重连。

Q5:Warning: remote port forwarding failed 但连接还在? 绑定失败不影响连接本身,这条隧道是空壳。加 -o ExitOnForwardFailure=yes 让失败即退,配合 autossh 才能自动重建(4.4 节)。

Q6:客户端 -R 的目标写 localhost 和写内网 IP 有区别吗? 转发动作由 sish 服务端「回连」客户端侧执行,目标只要客户端可达即可:写 localhost:8080 转发客户端本机服务,写 intranet-web:80 转发客户端可达的内网他机服务(本文实测即后者)。这是 sish 客户端「同时充当内网出口」的常用姿势。

十、参考链接