ngrok+nginx实现windows远程桌面连接

前言

最近想在公司远程连接家里的电脑,但苦于现在的家庭网络没有独立ip,导致无法通过ip直连。

作为一个程序员,这怎么能难倒我们,通过网上搜索找到以下几个解决方法
1、打电话给运营商让给外网ip

这个方法随着ip4资源越来越少,估计越来越不现实

2、通过网络穿透,类似花生壳或ngrok这些服务,把局域网服务通过服务器暴露给外网调用。

此方案靠谱,本人最后选择了自建ngrok服务搭建网络穿透。

NGROK简介

官方的解释为

ngrok 是一个反向代理,它创建从公共端点到本地运行的 Web 服务的安全隧道。 ngrok 捕获并分析隧道上的所有流量,以供以后检查和重放。

简单来说,你个人本地web服务,通过与ngrok的服务建立隧道连接,然后别人就可以通过访问ngrok服务来访问你的本地服务了。

ngrok的git地址: https://github.com/inconshreveable/ngrok

ngrok的官网: https://ngrok.com/

商业版本的ngrok已经到2.0了,但是源码并不开源,开源的只是1.0。官方也不建议使用1.0,因为客户端和服务器都存在严重的可靠性问题,包括内存和文件描述符泄漏以及崩溃。

使用ngrok有两种方法

  • 直接使用官方ngrok服务,服务端是现成的,分为国外和国内,我们只需安装客户端即可,操作手册参见ngrok官网
  • 使用ngrok1.0git源码 ,自行编译和搭建ngrok服务端和客户端。

本人最后采用了编译ngrok源码的方式,搭建服务端和客户端,并最后实现windows远程连接。

NGROK的安装

网上的相关资料比较多,这里就不展开说了,本人参考了以下两篇。
云服务器搭建自己的ngrok服务-实现内网穿透
https://cloud.tencent.com/developer/article/1100382

个人最后总的命令如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 设置域名
NGROK_DOMAIN=ngrok.oxxx.com

# 使用openssl证书域名跳过,本人最后采用阿里云免费证书的方式 具体可以参考 https://blog.csdn.net/qq_42063179/article/details/120620693
# 证书的替换方式为:
xxx.pem > assets/server/tls/snakeoil.crt
xxx.pem > assets/client/tls/ngrokroot.cr
xxx.key > assets/server/tls/snakeoil.key

# openssl genrsa -out rootCA.key 2048
# openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -out rootCA.pem
# openssl genrsa -out device.key 2048
# openssl req -new -key device.key -subj "/CN=$NGROK_DOMAIN" -out device.csr
# openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000

# cat rootCA.pem > assets/client/tls/ngrokroot.crt
# cat device.crt > assets/server/tls/snakeoil.crt
# cat device.key > assets/server/tls/snakeoil.key

# 关闭模块
go env -w GO111MODULE=off

# 开启模块,使用代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct


#编译服务端 linux 64位 服务器
GOOS=linux GOARCH=amd64 make release-server

# 编译客户端 64位windows客户端:
GOOS=windows GOARCH=amd64 make release-client
#编译客户端 mac 64 位 客户端
GOOS=darwin GOARCH=amd64 make release-client
#编译客户端 linux 64 位客户端
GOOS=linux GOARCH=amd64 make release-client

# 启动服务
nohup /opt/soft/ngrok/bin/ngrokd -tlsKey=/opt/soft/ngrok/assets/server/tls/snakeoil.key -tlsCrt=/opt/soft/ngrok/assets/server/tls/snakeoil.crt -domain="ngrok.xxx.com" -httpAddr=":9101" -httpsAddr=":9104" -tunnelAddr=":9103" > /opt/soft/ngrok/logs/ngrok.log 2>&1 &
tail -f /opt/soft/ngrok/logs/ngrok.log


# 进入客户端ngrok目录
cd ngrok
# 新增客户端配置文件 ngrok.cfg
vi ngrok.cfg

#ngrok.cfg 文件内容
server_addr: "ngrok.xxx.com:9103"
trust_host_root_certs: false
tunnels: #可定义多个域名
test1:
subdomain: "test1" #定义服务器分配域名前缀
proto:
http: 8089 #映射端口,不加ip默认本机

mstsc: # windows 远程桌面
remote_port: 4499
proto:
tcp: 3389 #映射端口,不加ip默认本机

# 启动客户端
./ngrok -config=ngrok.cfg -log=ngrok.log start test2

# 访问远程左面地址
ngrok.xxx.com:4499

安装避坑指南

1、使用go编译ngrok卡住
因为go需要依赖第三方工程,由于伟大的长城在,网络不通畅,可以关闭模块或配置代理,都有效。

1
2
3
4
5
6
# 关闭模块
go env -w GO111MODULE=off

# 开启模块,使用代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

2、openssl证书认证错误

1
ngrok certificate relies on legacy Common Name field, use SANs instead

这是因为common name field 模式计划删除了20年都没删除,go语言在1.15之后之后不再支持。

解决方式吗,要么降低go语言版本(不推荐),要么使用推荐的SAN替换(本人没跑通),要么直接使用现成的证书(本人使用了阿里云的免费证书)

1、阿里云免费证书申请参见 2022阿里云免费SSL证书申请全过程(图文详解)

2、证书下载方式为其他,下载后替换如下
xxx.pem > assets/server/tls/snakeoil.crt
xxx.pem > assets/client/tls/ngrokroot.cr
xxx.key > assets/server/tls/snakeoil.key

WINDOWS 远程桌面开启&ngrok客户端配置

如何开启远程桌面,这个网上较多,可以参考如何使用远程桌面
如果处于安全考虑,可以修改远程桌面端口,可参考 修改远程桌面端口

ngrok 客户端配置,可参考 使用ngrok实现远程桌面连接