HTTP隧道不能直接连ClickHouse,必须通过支持HTTP CONNECT的正向代理(如Nginx)中转;ClickHouse仅响应标准HTTP请求,不解析隧道二进制流或CONNECT隧道。
HTTP隧道不能直接连ClickHouse,必须走代理中转
clickhouse原生不支持http隧道协议,它的http接口只响应标准get/post请求(如/?或/query),不解析隧道封装的二进制流或connect隧道。所以你不能像用htc/hts直连ssh或rdp那样,把clickhouse端口(默认8123)塞进http隧道里就通——它压根不认这种“套娃”流量。
真正可行的路径是:让ClickHouse继续跑在8123(或443),再用一个**支持HTTP CONNECT的正向代理**(如Nginx、Squid、Caddy)暴露在防火墙允许的80/443端口上,并配置它把CONNECT请求转发到ClickHouse服务;客户端则通过curl -x或requests.Session().proxies走该代理发起HTTPS/HTTP请求。
- ClickHouse本身不处理隧道,只处理标准HTTP请求体里的SQL
- 所谓“HTTP隧道连ClickHouse”,本质是“HTTP代理 + ClickHouse HTTP接口”,不是隧道协议直通
- 如果你强行用
hts -F localhost:8123 80,客户端发来的会是隧道协议头(非标准HTTP),ClickHouse直接返回400 Bad Request或静默断连
用Nginx做正向代理转发ClickHouse请求(推荐方案)
Nginx能干净地扮演“防火墙友好型入口”:监听443,校验域名或IP白名单,再把合法请求透传给内网ClickHouse的8123。它不依赖客户端装额外工具,浏览器、curl、Python脚本全都能用。
关键配置片段(/etc/nginx/conf.d/clickhouse.conf):
upstream clickhouse_backend {
server 127.0.0.1:8123;
}
server {
listen 443 ssl;
server_name ck.example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
location / {
proxy_pass http://clickhouse_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
- 必须启用
ssl,否则企业防火墙可能放行80但拦截无证书的443连接 -
proxy_pass后面不能带尾部/(即写成http://clickhouse_backend/会改写URI,导致ClickHouse找不到/路由) - 别漏掉
X-Forwarded-For,否则ClickHouse日志里所有IP都是127.0.0.1
客户端怎么发请求?别用curl -T,要用-X POST
很多人试过curl -x http://proxy:3128 http://ck.example.com:8123/?query=SELECT%201失败,是因为没意识到:代理模式下,URL里的host:port会被代理忽略,真正起作用的是-x指定的代理地址,以及请求头里的Host字段。
正确写法(以HTTPS代理为例):
curl -x https://proxy.company.com:8080 \
-H "Host: ck.example.com" \
-X POST \
--data-urlencode "query=SELECT 1" \
https://ck.example.com/
-
-x指向你的公司HTTP代理(不是ClickHouse地址),且协议要匹配(https://代理需支持TLS隧道) -
https://ck.example.com/只是占位URL,实际请求发给代理,由代理根据Host头转发 - ClickHouse要求
query参数必须用POSTbody提交,GET只支持极简查询(且易被WAF截断) - 如果代理不支持HTTPS CONNECT(比如老旧Squid),换用
http://代理+自签名证书,并加--insecure
为什么不用SOCKS5或htc/hts?因为ClickHouse不兼容
SOCKS5或htc这类工具依赖底层TCP流转发,适合Telnet、RDP、SSH等长连接协议。但ClickHouse的HTTP接口是短连接、有状态解析(依赖HTTP方法、Header、Body分界),而SOCKS5隧道只是“字节管道”,不理解HTTP语义。
- 用
socks5://127.0.0.1:1080配Pythonrequests,发出去的仍是标准HTTP请求,但代理层无法做Host路由或TLS卸载,容易触发403或证书错误 -
htc -F 8888 target:80 && curl http://localhost:8888/...看似绕开防火墙,实则多了一层无效封装,ClickHouse收到的是畸形HTTP(含隧道头) - 企业级防火墙对SOCKS5 CONNECT行为越来越敏感,
1080端口常被主动阻断,而443上的标准HTTPS流量几乎畅通无阻
真正卡点从来不是“能不能通”,而是“通了之后ClickHouse能不能正确解析请求”。绕过防火墙只是第一步,协议对齐才是关键。











