【探索】基于WebSocket的内网穿透工具

国内的服务器除了挂个备案，不想再要了。而许多内网的服务需要在外网访问，内网穿透是必不可少的。但是用国外的服务器的话，需要过一层未知的东西，难免被误伤，融入汪洋大海也是必须的。之前折腾了一下通过套一层QUIC来伪装，不知道为什么，总是不稳定。寻寻觅觅，又找到一个特征少的内网穿透工具：ProxyNT 。ProxyNT 是一个用 python 编写的基于 WebSocket 的反向代理服务器，可以透过 NAT 和防火墙将本地服务器暴露到公网上，从原理看，套上一层 CDN 保护公网 ip 也是可以的。

服务端

反向代理服务

Copy
mkdir -p ~/app/proxynt && cd ~/app/proxynt && nano Dockerfile && nano docker-compose.yml
docker build -t limour/proxynt .
nano config.json
sudo docker-compose up -d

Copy
FROM python:3.9-alpine
RUN pip install -U proxynt
ENTRYPOINT ["nt_server", "-c", "/opt/config.json"]

Copy
version: '3.3'
services:
proxynt:
restart: unless-stopped
volumes:
- './config.json:/opt/config.json'
- '/etc/localtime:/etc/localtime:ro'
image: limour/proxynt

networks:
default:
external: true
name: ngpm

Copy
{
"port": 18888,
"log_file": "/dev/null",
"path": "/websocket_path",
"password": "helloworld",
"admin": {
"enable": true,
"admin_password": "new_password"
}
}

客户端

Copy
mkdir -p ~/app/proxynt && cd ~/app/proxynt
pip install -U proxynt -i https://pypi.tuna.tsinghua.edu.cn/simple
whereis nt_client
nano config.json
nt_client -c config.json # 测试
nano proxynt.service
sudo mv proxynt.service /etc/systemd/system/proxynt.service
sudo systemctl enable proxynt
sudo systemctl start proxynt
sudo systemctl status proxynt

Copy
{
"server": {
"url": "wss://limour.top:443/websocket_path",
"password": "helloworld"
},
"client_name": "home_pc",
"log_file": "/home/limour/app/proxynt/nt.log"
}

Copy
[Unit]
Description=proxynt
After=network.target
[Service]
ExecStart=/home/limour/miniconda3/bin/nt_client -c /home/limour/app/proxynt/config.json
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target

访问 https://limour.top:443/websocket_path/admin

看到客户端上线后，新建配置即可

附加 WebSSH

和上面的内网穿透配合，连接时 host 填proxynt, 可以保证内网 ssh 不暴露公网的同时，又能通过公网进行 ssh 连接。

Copy
mkdir -p ~/app/webssh && cd ~/app/webssh && nano docker-compose.yml
sudo docker-compose up -d

Copy
version: '3.3'
services:
webssh:
restart: unless-stopped
environment:
- GIN_MODE=release
- savePass=true
volumes:
- '/etc/localtime:/etc/localtime:ro'
image: jrohy/webssh:latest

networks:
default:
external: true
name: ngpm