Skip to content
heywjiPublic

About

图形化工具:本机 SSH 经 Cloudflare Tunnel 公开,关闭窗口即停止隧道和 SSH。

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

24 Commits

Folders and files

Repository files navigation

CF SSH

图形化的本机 SSH 发布工具。它在这台电脑上启动 SSH,只用 Cloudflare Tunnel 把连接转到公网。关掉窗口后,Cloudflare Tunnel 和这次启动的 SSH 都会停掉。

下载

已编译的程序在 Releases:

文件 系统
cfssh-windows-amd64.exe Windows 64 位
cfssh-macos.zip macOS Apple 芯片,解压后打开里面的 CF SSH.app
cfssh-provision.json 需要我远程协助时下载,和上面的程序放在同一个文件夹

需要我远程协助? 下载对应系统的程序和 cfssh-provision.json,放进同一个文件夹(macOS 放在 CF SSH.app 旁边,并先执行上面的 xattr 命令,否则系统会把 app 挪到临时位置运行,找不到这个文件),打开程序,输入你自己的电脑登录密码,点「启动」,然后告诉我一声。我会通过 remote-control-helper.jiwenkang.com 连进来。协助结束后关掉窗口,连接就断开了。同一时间只能帮一个人,请先和我约好再打开。

macOS 请用这个 app,不要双击单独的可执行文件。从浏览器下载后如果系统拦住,在终端执行:

xattr -dr com.apple.quarantine ~/Downloads/cfssh-macos.zip ~/Downloads/CF\ SSH.app
open ~/Downloads/CF\ SSH.app

Windows 上如果 SmartScreen 拦截,点「仍要运行」。API 令牌不要贴进窗口,只写在配置文件的 api_token 里。

程序本身只支持 Windows 和 macOS。连进来的客户端可以是任何系统,只要安装 cloudflared,然后 ssh 你的主机名。

主要在 Windows 上用,也支持 macOS。程序是一个 Go 二进制,运行时不用再装 Python、Node 或 Docker。第一次启动时,如果系统里没有 cloudflared,它会从 Cloudflare 的 GitHub 发布页下载官方程序。

临时的 trycloudflare.com 地址只能转发网站,不能转发 SSH。所以需要:

  • 一个 Cloudflare 账号
  • 一个已经把 DNS 托管在 Cloudflare 的域名

它会做什么

  1. 安装或使用本机的 OpenSSH。Windows 上会启用系统自带的 OpenSSH Server 功能。macOS 使用系统自带的 sshd,单独起一个实例,不动系统的「远程登录」。
  2. SSH 默认只听 127.0.0.1 上的一个端口(默认 2222)。不在路由器上做端口映射,也不打开入站防火墙。
  3. 用预配好的隧道令牌(或高级界面里的 API 令牌)启动远程管理的 Cloudflare Tunnel,把 主机名 指到本机 SSH。只有 cloudflared 真正连上 Cloudflare 之后,窗口才显示「运行中」。
  4. 创建 Cloudflare Access 应用,并给客户端发一把服务令牌。连接时不用收邮箱验证码。
  5. 生成本机密钥 ~/.ssh/cfssh_ed25519,并把公钥写入 authorized_keys。Windows 管理员还会写入 administrators_authorized_keys。
  6. 关闭窗口、进程退出,或者点「停止」时,停掉 cloudflared 和这次启动的 SSH。

云端的隧道和 DNS 记录会留着,下次启动直接复用。程序不会在关机后自动再开 SSH。

更详细的原理(macOS 和 Windows 上各自怎么起 SSH、断线后怎么自动重连)见 docs/how-it-works.md。

令牌权限

打开 API 令牌页面,创建自定义令牌,勾选这些权限:

范围 权限
账户 Cloudflare Tunnel / Cloudflare One Connectors,编辑
账户 Access: Apps and Policies,编辑
账户 Access: Service Tokens,编辑
区域 DNS,编辑

区域资源选你要用来公开 SSH 的那个域名。令牌保存在本机配置里,文件权限是 0600:

  • macOS:~/.config/cfssh/config.json
  • Windows:%AppData%\cfssh\config.json

第一次使用时,把仓库里的 config.example.json 复制到上面的位置,改名为 config.json,然后填写:

字段 说明
api_token 上面创建的 API 令牌
account_id / zone_id / zone_name 必填,缺了无法启动。用 cfssh provision -token <API令牌> -list 查看
subdomain / hostname hostname 就是 subdomain.zone_name,例如 ssh.example.com
tunnel_name 隧道名。tunnel_id 留空,程序会按名字新建或复用

service_token_* 字段不用填,程序会自动生成并写回这个文件。macOS 上填完执行 chmod 600 ~/.config/cfssh/config.json。

使用

分成两个角色。运营方(你,持有 Cloudflare API 令牌)先为每台机器预配一次,生成一个 cfssh-provision.json;客户拿到 cfssh 和这个文件后,只需输入自己的登录密码。客户机器上永远不会出现你的 API 令牌。

运营方:预配一台机器(命令行)

# 先看看令牌能用哪些账户和域名
cfssh provision -token <API令牌> -list

# 为一台机器预配,生成 sidecar 文件
cfssh provision -token <API令牌> -zone example.com -subdomain ssh -tunnel-name cfssh-客户A

这一步会创建/复用隧道、发布 DNS、建好 Access 服务令牌,并把隧道令牌和公网主机名(不含 API 令牌)写进 cfssh-provision.json。每台机器建议用不同的 -subdomain 和 -tunnel-name,这样各有各的公网地址和隧道。

把生成的 cfssh-provision.json 和 cfssh(或 cfssh.exe、macOS 的 CF SSH.app)放在同一目录发给客户即可。

客户:只填密码

  1. 把 cfssh.exe 和旁边的 cfssh-provision.json 一起运行。程序检测到 sidecar 后,界面只剩一个「当前用户密码」输入框。
  2. 填写当前用户的登录密码并再输入一次。Windows 上就是当前 Windows 用户的登录密码,别人 SSH 进来时要用同一个。程序只向系统核对,不写入任何文件,也不修改密码。
    • 不知道自己的密码? 如果当前用户是这台电脑的管理员(本地账户),窗口里会出现「不知道当前密码?给 <用户> 设置一个新密码」。勾选后输入新密码,启动前会再确认一次,然后把这个 Windows 账户的登录密码改成新密码(以后登录这台电脑也用它)。新密码用 Windows DPAPI 加密后交给提权进程,不以明文落盘。域账户和微软账户不支持。
  3. 点「启动」。Windows 会弹出 UAC,macOS 弹管理员密码框。
  4. 启动后窗口里给出连接命令,发给要登录的人。关掉窗口就停掉隧道和 SSH。

没有 cfssh-provision.json 时,程序会打开完整的高级界面(运营方也可以在那里图形化地验证令牌、选域名、一键启动,令牌仍只读取自本机配置文件 api_token,不显示在窗口里)。

客户端 ~/.ssh/config 类似:

Host ssh.example.com
    User 你的用户名
    ProxyCommand cloudflared access ssh --hostname %h --service-token-id '客户端 ID' --service-token-secret '客户端密钥'
    IdentityFile ~/.ssh/cfssh_ed25519

连接时只输入系统密码。服务令牌已经写在这条命令里,不用再收邮箱验证码。

把「只监听 127.0.0.1」留着。这样就算本机防火墙被改过,局域网也连不上这个 SSH。

关掉之后

  • cloudflared 会被结束。
  • macOS 上,程序自己拉起的 sshd 会被结束,系统原来的 SSH 服务不动。
  • Windows 上会停掉 OpenSSH 服务,并把 sshd_config 还原。安装程序自带的 OpenSSH 入站防火墙规则会被删掉,避免 22 端口裸露在网上。
  • 如果从任务管理器强制结束窗口进程,旁边的 helper 发现父进程没了,也会停掉隧道和 SSH。正在安装 OpenSSH 时关掉窗口,安装进程同样会被停掉。

没有显卡驱动的 Windows

多数云服务器和虚拟机只有 Microsoft Basic Display Adapter,没有可用的 OpenGL。

  • 客户窗口(旁边有 cfssh-provision.json 时)在 Windows 上用系统原生控件绘制,不需要 OpenGL,任何 Windows 都能打开。
  • 高级窗口(运营方用,没有 sidecar 时)仍然基于 Fyne,需要 OpenGL。没有时会弹窗说明原因并退出。运营方可以改用命令行 cfssh provision,或在有显卡驱动的电脑上打开高级窗口。确实需要在这类机器上打开高级窗口的话,可以把 mesa-dist-win 的 x64/opengl32.dll、x64/libgallium_wgl.dll 放到 cfssh.exe 旁边,并设置 GALLIUM_DRIVER=llvmpipe 后启动。

编译

只支持 Windows 和 macOS,在其他系统上编译会直接报错。

macOS:安装 Xcode 命令行工具,然后 make build(或 make build-macos-app 生成 CF SSH.app)。

Windows:两种方式都行。

  • 在 macOS 上交叉编译:brew install mingw-w64,然后 make build-windows,得到 dist/cfssh.exe。
  • 在 Windows 上:安装 Go 和 MSYS2/mingw-w64 的 gcc,然后在该环境里执行:
set CGO_ENABLED=1
go build -ldflags "-H windowsgui" -o dist\cfssh.exe .\cmd\cfssh

-H windowsgui 用来隐藏旁边的黑色控制台。不加也能用。

cmd/cfssh/rsrc_windows_amd64.syso 是由 cmd/cfssh/cfssh.manifest 编出来的 Windows 资源(现代控件样式、高 DPI),Go 编译 Windows 版时会自动链接。改了 manifest 后执行 make winres 重新生成。

安全

公网入口是 Cloudflare Access 的服务令牌,不是把 22 端口挂到网上。服务令牌和 API 令牌都在 config.json 里,不要把这个文件交给别人。

Windows 版会接管系统 OpenSSH 服务。关闭程序时这个服务会停。如果你本来就在用系统 OpenSSH,关闭本程序后需要自己再把它启动起来。

About

图形化工具:本机 SSH 经 Cloudflare Tunnel 公开,关闭窗口即停止隧道和 SSH。

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages