Chisel 是一个快速的 TCP/UDP 隧道,通过 HTTP 传输,并使用 SSH 加密。单一可执行文件同时包含客户端和服务端。使用 Go (golang) 编写。Chisel 主要用于穿透防火墙,但也可以用于为你的网络提供安全端点。

crypto/ssh)--min/max-retry-interval 调整);keepalive ping 超时,因此可检测到静默失效的连接(休眠/唤醒、NAT 超时、服务端重启)并重新建立ssh -o ProxyCommand,从而通过 HTTP 提供 SSH查看 最新版本,或使用 curl https://i.jpillora.com/chisel! | bash 立即下载并安装。
二进制文件使用最新的 Go 版本构建,这设定了最低操作系统版本:Windows 10 / Server 2016、macOS 12、Linux 内核 3.2、FreeBSD 12.2。对于较旧的系统(例如 Windows 7),请使用 v1.8.1 版本 或更早版本。
```sh
docker run --rm -it jpillora/chisel --help
镜像是多架构的,并发布到 Docker Hub(`jpillora/chisel`)和 GitHub Container Registry(`ghcr.io/jpillora/chisel`)。
### Fedora
该软件包由 Fedora 社区维护。如果您遇到与 RPM 使用相关的问题,请使用此[问题跟踪器](https://bugzilla.redhat.com/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&classification=Fedora&component=chisel&list_id=11614537&product=Fedora&product=Fedora%20EPEL)。```sh
sudo dnf -y install chisel
$ go install github.com/jpillora/chisel@latest
## 演示
你可以在几分钟内运行自己的演示服务器(旧的 Heroku 演示已随 Heroku 免费套餐的取消而消失)。[`example/fly.toml`](https://github.com/jpillora/chisel/blob/HEAD/example/fly.toml) 可将此 `chisel server` 部署到 [fly.io](https://fly.io) 的免费额度:```sh
$ chisel server --port $PORT --backend http://example.com
# listens on $PORT, proxies normal web requests to http://example.com
在 example/ 目录下使用 fly launch --copy-config 进行部署,然后通过隧道连接到服务器旁运行的任何服务,例如:```sh
$ chisel client https://.fly.dev 3000
在浏览器中访问应用的 URL 时,会命中服务器的默认后端代理,并显示 [example.com](http://example.com) 的副本。
## 用法
<!-- render these help texts by hand,
or use https://github.com/jpillora/md-tmpl
with $ md-tmpl -w README.md -->
<!--tmpl,code=plain:echo "$ chisel --help" && go run main.go --help | sed 's#0.0.0-src (go1\..*)#X.Y.Z#' -->``` plain
$ chisel --help
Usage: chisel [command] [--help]
Version: X.Y.Z
Commands:
server - runs chisel in server mode
client - runs chisel in client mode
Read more:
https://github.com/jpillora/chisel
$ chisel server --help
Usage: chisel server [options]
Options:
--host, Defines the HTTP listening host – the network interface
(defaults the environment variable HOST and falls back to 0.0.0.0).
--port, -p, Defines the HTTP listening port (defaults to the environment
variable PORT and falls back to port 8080).
--key, (deprecated use --keygen and --keyfile instead)
An optional string to seed the generation of a ECDSA public
and private key pair. All communications will be secured using this
key pair. Share the subsequent fingerprint with clients to enable detection
of man-in-the-middle attacks (defaults to the CHISEL_KEY environment
variable, otherwise a new key is generate each run).
--keygen, A path to write a newly generated PEM-encoded SSH private key file.
If users depend on your --key fingerprint, you may also include your --key to
output your existing key. Use - (dash) to output the generated key to stdout.
--keyfile, An optional path to a PEM-encoded SSH private key. When
this flag is set, the --key option is ignored, and the provided private key
is used to secure all communications. (defaults to the CHISEL_KEY_FILE
environment variable). Since ECDSA keys are short, you may also set keyfile
to the inline key string itself, exactly as printed by --keygen (a base64
string with a "ck-" prefix); no extra base64 encoding is needed.
--authfile, An optional path to a users.json file. This file should
be an object with users defined like:
{
"<user:pass>": ["<addr-regex>","<addr-regex>"]
}
when <user> connects, their <pass> will be verified and then
each of the remote addresses will be compared against the list
of address regular expressions for a match. Patterns are NOT
anchored by default: "10.0.0.1:80" also matches
"210.0.0.1:8080", and "." matches any character. Anchor your
patterns, e.g. "^10\.0\.0\.1:80$". The empty string ""
matches every address. Addresses will
always come in the form "<remote-host>:<remote-port>" for normal remotes,
"R:<local-interface>:<local-port>" for reverse port forwarding
remotes, and "socks" for SOCKS5 proxy access. Note that SOCKS5
access previously bypassed this list; existing authfiles which
should allow SOCKS5 must add an entry matching "socks" (the
empty wildcard "" matches everything, including "socks"). This
file will be automatically reloaded on change. Reloads apply
to new connections and to new tunnels of connected clients;
established tunnels are not interrupted.
--auth, An optional string representing a single user with full
access, in the form of <user:pass>. It is equivalent to creating an
authfile with {"<user:pass>": [""]}. If unset, it will use the
environment variable AUTH.
--keepalive, An optional keepalive interval. Since the underlying
transport is HTTP, in many instances we'll be traversing through
proxies, often these proxies will close idle connections. You must
specify a time with a unit, for example '5s' or '2m'. Defaults
to '25s' (set to 0s to disable).
--backend, Specifies another HTTP server to proxy requests to when
chisel receives a normal HTTP request. Useful for hiding chisel in
plain sight. --proxy is accepted as an alias for this flag.
--socks5, Allow clients to access the internal SOCKS5 proxy. See
chisel client --help for more information.
--reverse, Allow clients to specify reverse port forwarding remotes
in addition to normal remotes.
--tls-key, Enables TLS and provides optional path to a PEM-encoded
TLS private key. When this flag is set, you must also set --tls-cert,
and you cannot set --tls-domain.
--tls-cert, Enables TLS and provides optional path to a PEM-encoded
TLS certificate. When this flag is set, you must also set --tls-key,
and you cannot set --tls-domain.
--tls-domain, Enables TLS and automatically acquires a TLS key and
certificate using LetsEncrypt. Setting --tls-domain requires port 443.
You may specify multiple --tls-domain flags to serve multiple domains.
The resulting files are cached in the "$HOME/.cache/chisel" directory.
You can modify this path by setting the CHISEL_LE_CACHE variable,
or disable caching by setting this variable to "-". You can optionally
provide a certificate notification email by setting CHISEL_LE_EMAIL.
--tls-ca, a path to a PEM encoded CA certificate bundle or a directory
holding multiple PEM encode CA certificate bundle files, which is used to
validate client connections. The provided CA certificates will be used
instead of the system roots. This is commonly used to implement mutual-TLS.
--pid Generate pid file in current working directory
-v, Enable verbose logging
--help, This help text
Signals: The chisel process is listening for: a SIGINT or SIGTERM to begin a graceful shutdown (a second signal forces an immediate exit), a SIGUSR2 to print process stats, and a SIGHUP to short-circuit the client reconnect timer
Version: X.Y.Z
Read more: https://github.com/jpillora/chisel
<!--/tmpl-->
<!--tmpl,code=plain:echo "$ chisel client --help" && go run main.go client --help | sed 's#0.0.0-src (go1\..*)#X.Y.Z#' -->``` plain
$ chisel client --help
Usage: chisel client [options] <server> <remote> [remote] [remote] ...
<server> is the URL to the chisel server.
<remote>s are remote connections tunneled through the server, each of
which come in the form:
<local-host>:<local-port>:<remote-host>:<remote-port>/<protocol>
■ local-host defaults to 0.0.0.0 (all interfaces).
■ local-port defaults to remote-port.
■ remote-port is required*.
■ remote-host defaults to 127.0.0.1 (server localhost).
■ protocol defaults to tcp.
which shares <remote-host>:<remote-port> from the server to the client
as <local-host>:<local-port>, or:
R:<local-interface>:<local-port>:<remote-host>:<remote-port>/<protocol>
which does reverse port forwarding, sharing <remote-host>:<remote-port>
from the client to the server's <local-interface>:<local-port>.
example remotes
3000
example.com:3000
3000:google.com:80
192.168.0.5:3000:google.com:80
socks
5000:socks
R:2222:localhost:22
R:socks
R:5000:socks
stdio:example.com:22
1.1.1.1:53/udp
When the chisel server has --socks5 enabled, remotes can
specify "socks" in place of remote-host and remote-port.
The default local host and port for a "socks" remote is
127.0.0.1:1080. Connections to this remote will terminate
at the server's internal SOCKS5 proxy. When the server also
has --authfile set, SOCKS5 access requires an entry matching
the token "socks" in the user's address list.
When the chisel server has --reverse enabled, remotes can
be prefixed with R to denote that they are reversed. That
is, the server will listen and accept connections, and they
will be proxied through the client which specified the remote.
Reverse remotes specifying "R:socks" will listen on the server's
default socks port (1080) and terminate the connection at the
client's internal SOCKS5 proxy.
When stdio is used as local-host, the tunnel will connect standard
input/output of this program with the remote. This is useful when
combined with ssh ProxyCommand. You can use
ssh -o ProxyCommand='chisel client chiselserver stdio:%h:%p' \
[email protected]
to connect to an SSH server through the tunnel.
Options:
--fingerprint, A *strongly recommended* fingerprint string
to perform host-key validation against the server's public key.
Fingerprint mismatches will close the connection.
Fingerprints are generated by hashing the ECDSA public key using
SHA256 and encoding the result in base64.
Fingerprints must be 44 characters containing a trailing equals (=).
Legacy MD5 colon fingerprints (deprecated) are still accepted,
but only in their full 16-octet form; truncated prefixes are
rejected.
--auth, An optional username and password (client authentication)
in the form: "<user>:<pass>". These credentials are compared to
the credentials inside the server's --authfile. defaults to the
AUTH environment variable.
--keepalive, An optional keepalive interval. Since the underlying
transport is HTTP, in many instances we'll be traversing through
proxies, often these proxies will close idle connections. You must
specify a time with a unit, for example '5s' or '2m'. Defaults
to '25s' (set to 0s to disable).
--max-retry-count, Maximum number of times to retry before exiting.
Defaults to unlimited.
--min-retry-interval, Minimum wait time before retrying after a
disconnection. Defaults to 1 second.
--max-retry-interval, Maximum wait time before retrying after a
disconnection. Defaults to 5 minutes.
--proxy, An optional HTTP CONNECT or SOCKS5 proxy which will be
used to reach the chisel server. Authentication can be specified
inside the URL. Credentials must be URL-encoded; for example a
"#" in the password must be written as "%23".
For example, http://admin:[email protected]:8081
or: socks://admin:[email protected]:1080
The socks://, socks5:// and socks5h:// schemes are equivalent:
DNS is always resolved by the proxy.
--header, Set a custom header in the form "HeaderName: HeaderContent".
Can be used multiple times. (e.g --header "Foo: Bar" --header "Hello: World")
--hostname, Optionally set the 'Host' header (defaults to the host
found in the server url).
--sni, Override the ServerName when using TLS (defaults to the
hostname).
--tls-ca, An optional root certificate bundle used to verify the
chisel server. Only valid when connecting to the server with
"https" or "wss". By default, the operating system CAs will be used.
--tls-skip-verify, Skip server TLS certificate verification of
chain and host name (if TLS is used for transport connections to
server). If set, client accepts any TLS certificate presented by
the server and any host name in that certificate. This only affects
transport https (wss) connection. Chisel server's public key
may be still verified (see --fingerprint) after inner connection
is established.
--tls-key, a path to a PEM encoded private key used for client
authentication (mutual-TLS).
--tls-cert, a path to a PEM encoded certificate matching the provided
private key. The certificate must have client authentication
enabled (mutual-TLS).
--pid Generate pid file in current working directory
-v, Enable verbose logging
--help, This help text
Signals:
The chisel process is listening for:
a SIGINT or SIGTERM to begin a graceful shutdown
(a second signal forces an immediate exit),
a SIGUSR2 to print process stats, and
a SIGHUP to short-circuit the client reconnect timer
Version:
X.Y.Z
Read more:
https://github.com/jpillora/chisel
加密始终处于启用状态。启动 chisel 服务器时,它会生成一个内存中的 ECDSA 公钥/私钥对。服务器启动时会显示公钥指纹(base64 编码的 SHA256)。除了生成随机密钥外,服务器还可以通过 --keyfile 选项指定密钥文件。客户端连接时,也会显示服务器的公钥指纹。客户端可以使用 --fingerprint 选项强制指定某个指纹。旧版 MD5 指纹仍然被接受,但必须是完整的 16 字节冒号分隔形式——截断的前缀会被拒绝。更多信息请参阅上面的 --help。
服务器还会在身份验证之前限制入站 websocket 消息大小(CHISEL_WS_READ_LIMIT,默认 512 KiB),因此未经身份验证的对等方无法用超大的消息耗尽内存。默认值远超 x/crypto/ssh 的 256 KiB 最大传输数据包,因此任何有效的 SSH 数据包都不会被拒绝。只有 0 会禁用该限制;负值会回退到安全默认值。
通过 --authfile 选项,服务器可以提供一个 user.json 配置文件来创建接受用户的列表。然后客户端使用 --auth 选项进行身份验证。示例身份验证配置文件请参阅 users.json。更多信息请参阅上面的 --help。
关于 authfile 行为的说明:
^ 和 $ 锚定它们(服务器在加载时会警告未锚定的模式)。空字符串 "" 匹配所有内容。socks 的条目控制。破坏性变更:SOCKS5 之前完全绕过 authfile;使用 --authfile 运行 --socks5 的服务器必须向应保留代理访问权限的用户授予 socks(通配符 "" 条目仍然有效)。user:pass)的身份验证字符串现在在服务器和客户端上都是致命启动错误——此前它们会静默禁用身份验证。--auth 指定的用户在 authfile 重载后仍然存在,并在与文件用户发生名称冲突时胜出。在内部,这是通过 SSH 提供的 Password 身份验证方法完成的。在此了解有关 crypto/ssh 的更多信息:http://blog.gopheracademy.com/go-and-ssh/。会话打开/关闭(包含用户、源地址和远程目标)以及失败的登录尝试都会以 info 级别记录。
最简单的安全设置是 --tls-domain,它会自动签发 LetsEncrypt 证书(需要 443 端口和指向服务器的 DNS 记录):```sh
chisel server --port 443 --tls-domain chisel.example.com --auth user:pass
chisel client --auth user:pass https://chisel.example.com R:2222:localhost:22
要使用您自己的证书(自签名或内部 CA),请生成密钥/证书对,并将两侧指向正确的文件:```sh
chisel server --port 443 --tls-key key.pem --tls-cert cert.pem
chisel client --tls-ca ca.pem https://chisel.example.com 3000
对于双向 TLS,还需将 --tls-ca 传给服务器,并将 --tls-cert/--tls-key 传给每个客户端。请注意,TLS 从外部包装 chisel 的传输;内部的 SSH 层仍会进行加密和身份验证,因此无论是否使用 TLS,--fingerprint 验证都有效。
在终端打印一个新的私钥
chisel server --keygen -
# or save it to disk --keygen /path/to/mykey
启动你的 chisel 服务器
jpillora/chisel server --keyfile '<ck-base64 string or file path>' -p 9312 --socks5
连接你的 chisel 客户端(使用服务器的指纹)
chisel client --fingerprint '<see server output>' <server-address>:9312 socks
将你的 SOCKS5 客户端(如操作系统/浏览器)指向:
<client-address>:1080
现在你拥有了一条通过 HTTP 的加密、经过身份验证的 SOCKS5 连接
注意:如果服务器还使用了 --authfile,用户需要一个与令牌 socks 匹配的条目才能使用代理(请参阅 身份验证)。
要让特定客户端充当 SOCKS 出口节点,请授予其反向 SOCKS 监听器地址(R:socks 监听服务器的 127.0.0.1:1080):```json
{
"exituser:password": ["^R:127\.0\.0\.1:1080$"]
}
The input content is empty — no chunk text was provided after "INPUT:". Please supply the actual chunk 23 content so I can translate it.```sh
chisel server --reverse --authfile users.json
chisel client --auth exituser:password <server-address> R:socks
# server-side consumers point SOCKS5 clients at 127.0.0.1:1080,
# and their traffic exits via the chisel client's network
See also the step-by-step reverse tunneling example.
chisel works through CDNs that support WebSockets. For Cloudflare: enable WebSockets, proxy (orange-cloud) the DNS record, and connect clients with https://. The CDN terminates TLS, but the inner SSH layer means --fingerprint validation still authenticates your chisel server end-to-end — the CDN cannot read or modify tunneled traffic. Keep --keepalive at its 25s default to stay under CDN idle timeouts, and note that proxies which strip Upgrade headers cannot carry chisel at all.
Less common knobs are environment variables, all read with a CHISEL_ prefix (e.g. CHISEL_WS_TIMEOUT=10s):
HOST、PORT、AUTH 以及 CHISEL_KEY/CHISEL_KEY_FILE 已在上述 --help 文本中说明。
由于需要 WebSockets 支持:
github.com/jpillora/chisel/share contains the shared packagegithub.com/jpillora/chisel/server contains the server packagegithub.com/jpillora/chisel/client contains the client package1.0 - 初始版本1.1 - 将简单对称加密替换为 ECDSA SSH1.2 - 新增 SOCKS5(服务端)和 HTTP CONNECT(客户端)支持1.3 - 新增反向隧道支持1.4 - 新增任意 HTTP 头支持1.5 - 新增反向 SOCKS 支持(作者 @aus)1.6 - 新增客户端 stdio 支持(作者 @BoleynSu)1.7 - 新增 UDP 支持1.8 - 迁移到 scratch Docker 镜像1.9 - 升级到 Go 1.21。从 --key 种子切换到使用 --key{gen,file} 的 P256 密钥字符串(作者 @cmenginnz)1.10 - 升级到 Go 1.22。在发布版本中新增 、 和 。修复错误的版本比较。从 1.11.x 或更早版本升级时,有四项变更可能需要您采取行动:
--authfile(自 v1.11.7 起强制执行):需要继续保持代理访问权限的用户需要一个匹配令牌 socks 的 authfile 条目(通配符 "" 仍可继续工作)。参见 认证。被拒绝的请求会在服务端记录为 Denied connection to socks (ACL)。--fingerprint:截断的旧版 MD5 指纹会被拒绝。请使用服务端和客户端打印的完整 SHA256 指纹(完整的 16 字节 MD5 冒号形式仍被接受,但已弃用)。--auth 值必须为 <user>:<pass> — 不含冒号的字符串现在会在启动时失败,而不是静默禁用认证。--max-retry-count 的 chisel client 现在在连接尝试耗尽时以非零状态退出;检查 $? 的脚本和 systemd 的 Restart=on-failure 单元会注意到这一点。MIT © Jaime Pillora
| Variable | 端 | 默认值 | 用途 |
|---|
WS_TIMEOUT | 客户端 | 45s | WebSocket 握手超时 |
SSH_TIMEOUT | 客户端 | 30s | SSH 握手超时 |
CONFIG_TIMEOUT | 服务端 | 10s | 等待客户端的配置请求 |
SSH_WAIT | 两侧 | 35s | 新隧道等待活动连接的时间 |
PING_TIMEOUT | 两侧 | keepalive 间隔 | keepalive ping 回复超时(若 --keepalive 0 则不发送 ping) |
DIAL_TIMEOUT | 出口节点 | 30s | 隧道目标的 TCP 拨号超时 |
WS_READ_LIMIT | 两侧 | 524288 | 最大入站 WebSocket 消息字节数(0 = 无限制;负数 = 默认) |
WS_BUFF_SIZE | 两侧 | Go 默认值 | WebSocket 读写缓冲区大小 |
UDP_MAX_SIZE | 两侧 | 9012 | 最大 UDP 数据包字节数 |
UDP_DEADLINE | 出口节点 | 15s | UDP 流读取截止时间和空闲清理期限 |
UDP_MAX_CONNS | 出口节点 | 100 | 每个隧道的最大并发 UDP 流数 |
SHUTDOWN_GRACE | 服务端 | 5s | 关闭时 HTTP 请求排空时间 |
.rpm.deb.apk1.11 - 升级到 Go 1.25.1。更新所有依赖。1.12 -(未发布)可靠性与安全性改进:
CHISEL_PING_TIMEOUT),因此死连接会在睡眠/唤醒、NAT 超时和服务端重启后及时重连--socks5 + --authfile 一起使用时,SOCKS5 访问现在需要匹配 socks 的 authfile 条目(通配符 "" 条目仍可继续工作)--fingerprint 必须是完整的 SHA256 形式(或完整的 16 字节 MD5 冒号形式)--auth user)现在会导致启动时致命错误,而不是静默禁用认证CHISEL_DIAL_TIMEOUT,默认 30s)CHISEL_SHUTDOWN_GRACE);第二次信号将强制退出CHISEL_UDP_MAX_CONNS)CHISEL_WS_READ_LIMIT)--max-retry-count 耗尽时,客户端以非零状态退出;新增 --min-retry-interval(默认 1s);--proxy 接受 socks5://go install 构建会报告其真实版本;会话和失败登录会在 info 级别记录latest / X / X.Y 标签