通过ngrok实现ssh连接本机电脑

从树莓派开始就一直想着有没有一种方法可以通过外网ssh连接内网中的树莓派,之前知道一个大概的思路,就是通过花生壳的类似内网穿透的服务。然而好几次尝试都失败了,最后直接知乎,搜到了ngrok这个神器,一次搞定。不得不感叹一下国外的开源环境确实比国内好很多,一些用中文怎么搜索都找不到答案的问题,换成英文搜索就会发现,老外早就给你写好解决办法了,就看你会不会用Google了。

关于ngrok

ngrok是国外的一个开源项目,可以把内网主机暴露在公网中,可以直接下载ngrok客户端版本,不过这样反向代理服务器在国外,所以ssh会比较慢。由于开源的原因,如果我们有一个公网的服务器,可以自己编译源码,将服务器部署到公网上,经过自己测试,延迟和普通的ssh基本一致。

解析域名

ngrok.shiwenhao.gq   -----> A记录到你的公网服务器
*.ngrok.shiwenhao.gq -----> CNAME记录到ngrok.shiwenhao.gq 

这里需要提一下,*.ngrok.shiwenhao.gq是三级泛域名,一般的域名的解析商的免费服务可能不支持三级泛域名解析,LZ使用的是腾讯的云解析服务,后果就是腾讯云封了我未备案的网站。

下载源码

ngrok分为服务端和客户端,请将源码下载在服务器上 github上下载源码,不说了。

生成证书

这部分不懂,借鉴别人的blog。

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 36500 -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 -days 36500 -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt 
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt 
cp device.key assets/server/tls/snakeoil.key

编译

由于ngrok是用go语言编写的,所以需要安装GO语言,ubuntu安装如下,安装完查看版本。

sudo apt-get install golang
go version

开始编译,服务器端一定是Linux版的,所以如果是在服务器上编译源码的话,如下

make release-server

客户端请选择对应的对应的客户端,如下

$ GOOS=linux GOARCH=amd64 make release-client
$ GOOS=windows GOARCH=amd64 make release-client
$ GOOS=linux GOARCH=arm make release-client

编译需要一段时间,来杯cafe吧。

部署

编译完成后,会生成ngrok和ngrokd执行文件,ngrokd对应服务器端,ngrok对应客户端。ngrokd在bin目录下,ngrok在不知道在bin的哪个子目录下,自己找吧。 通过rcp命令之类的东西将ngrok拉到客户端上

  • 服务器,可以通过nohup命令设置ngrok,避免退出终端后结束,具体请搜索nohup
./ngrokd -h
Usage of ./ngrokd:
  -domain string
        Domain where the tunnels are hosted (default "ngrok.com")
  -httpAddr string
        Public address for HTTP connections, empty string to disable (default ":80")
  -httpsAddr string
        Public address listening for HTTPS connections, emptry string to disable (default ":443")
  -log string
        Write log messages to this file. 'stdout' and 'none' have special meanings (default "stdout")
  -log-level string
        The level of messages to log. One of: DEBUG, INFO, WARNING, ERROR (default "DEBUG")
  -tlsCrt string
        Path to a TLS certificate file
  -tlsKey string
        Path to a TLS key file
  -tunnelAddr string
        Public address listening for ngrok client (default ":4443")

./ngrokd -domain=$NGROK_DOMAIN 
./ngrokd -domain=$NGROK_DOMAIN -httpAddr=":8080" -httpsAddr=":8081"
  • 客户端
vim ngrok.cfg

# 添加以下两行
# 第一行是将要绑定的域名+4443端口

server_addr: "ngrok.phpgao.com:4443"
trust_host_root_certs: true

# 帮助信息
./ngrok -h
Examples:
    ngrok 80
    ngrok -subdomain=example 8080
    ngrok -proto=tcp 22
    ngrok -hostname="example.com" -httpauth="user:password" 10.0.0.1

# 8080就是我们要转发的端口了
./ngrok -config=./ngrok.cfg 8080

# 指定协议和端口,不指定默认是 http+https
./ngrok -config=./ngrok.cfg -proto=tcp 22

# 指定子域名,不指定就会随机生成
./ngrok -config=./ngrok.cfg -subdomain=test 8080

如上,要是用ssh,请运行倒数第二个命令。 运行成功后截图, 然后

ssh user@ngrok.com -p36756

可以愉快的在家撸代码了。额