有这么个场景,我在家里服务器上只开了 80 和 443 端口用于 web 服务,可以通过域名从公网访问。现在我在公司,出于调试目的,需要访问服务器上的 MySQL 数据库,但又不希望暴露服务器上的 3306 端口到公网上,所以希望能通过已有的 web 服务进行 3306 端口的远程访问,但又能进行无感交互。

所谓的无感交互,举个例子:如果只是对数据库管理,那其实可以采用 web 数据库管理工具,比如 phpMyAdmin 进行管理,但我这边需要建立 jdbc 连接,所以用 web 数据库管理工具是行不通的,类似于 webshell 和 shell 的区别。

经过查阅资料,一个工具进入了我的视野:movsb/http2tcp by 桃子

其实原理很简单,就像代理一样:

http2tcp principle http2tcp principle

我用的是 http2tcp 的 websocket 分支,实测效果很好。当然,实际上用的时候,不直接把 http2tcp server 的 HTTP 端口暴露,而是放在 nginx 后面,由 nginx 做反向代理,这样就能走 HTTPS/WSS 了。

客户端:

http2tcp -c -l :13306 -d $MYSQL_SERVER_HOST:3306 -e https://$DOMAIN/$REMOTE_URI -t $MY_TOKEN

服务端:

http2tcp -s -l :8080 -t $MY_TOKEN

Nginx:

server {
    listen 443 ssl http2;
    server_name $DOMAIN;
    ...
   
    location = /$REMOTE_URI {
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_read_timeout 600s;
        proxy_pass http://127.0.0.1:8080/;
    }

}