日常工作中时常会遇到远程操作的问题,两台机器都不具有公网ip,这时候通过ssh连接就会产生一些麻烦,下面是我解决这个问题的方法。
服务端
由于两台机器都不具有公网ip,因此使用ngrok,ngrok需要用到一个具有公网ip的服务器。ngrok自己也提供服务,但是从境内访问官方提供的服务器具有令人难以忍受的延迟。本文中在自己的服务器上搭建了ngrok服务。
先把域名解析到服务器。
这里我的域名是wangjiebao.com
,做了泛解析,把ngrok.wangjiebao.com
和*.ngrok.wangjiebao.com
解析到ngrok服务器。
编译ngrok
我的vps系统是Ubuntu 14.04。
安装必要的工具。
sudo apt-get install build-essential golang mercurial git
其次需要安装golang,注意golang的版本必须为1.3以上。1
2
3$ sudo add-apt-repository ppa:gophers/archive
$ sudo apt-get update
$ sudo apt-get install golang-1.9-go
注意默认的安装位置是/usr/lib/go-1.9/bin
需要将它添加到系统路径里。cd /usr/bin/
unlink go
ln -s /usr/lib/go-1.9/bin/go go
获取ngrok源码
git clone https://github.com/inconshreveable/ngrok.git ngrok
生成证书
1 | NGROK_DOMAIN="wangjiebao.com" |
编译
sudo make release-server release-client
这里默认的release client编译的是linux amd64对应的客户端。当客户端的环境变换时,需要分别编译,方法如下。1
2
3
4
5
6
7
8
9
10
11
12
13
14$ GOOS=linux GOARCH=amd64 make release-client
$ GOOS=windows GOARCH=amd64 make release-client
$ GOOS=linux GOARCH=arm make release-client
Linux 平台 32 位系统:GOOS=linux GOARCH=386
Linux 平台 64 位系统:GOOS=linux GOARCH=amd64
Windows 平台 32 位系统:GOOS=windows GOARCH=386
Windows 平台 64 位系统:GOOS=windows GOARCH=amd64
MAC 平台 32 位系统:GOOS=darwin GOARCH=386
MAC 平台 64 位系统:GOOS=darwin GOARCH=amd64
ARM 平台:GOOS=linux GOARCH=arm
编译后ngrok/bin文件夹下有ngrok、ngrokd 两个可执行文件。其中ngrokd是服务器端的程序,ngrok是linux客户端的程序。其余平台下的客户端程序在对应的文件夹下。
运行服务
sudo ./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="wangjiebao.com" -httpAddr=":8081" -httpsAddr=":8082"
到这一步,ngrok 服务已经跑起来了,可以通过屏幕上显示的日志查看更多信息。httpAddr、httpsAddr 分别是 ngrok 用来转发 http、https 服务的端口,可以随意指定。ngrokd 还会开一个 4443 端口用来跟客户端通讯(可通过 -tunnelAddr=”:xxx” 指定),如果你配置了 iptables 规则,需要放行这三个端口上的 TCP 协议。
现在访问http://pub.ngrok.wangjiebao.com:8081 , 可以看到这样一行提示:Tunnel pub.ngrok.wangjiebao.com:8081 not found
由于设置了泛解析,因此pub可以换成其他任意的单词。
客户端
现在服务端已经配置完成,还需要在内网上的机器运行客户端,以便将内网的机器连接上服务器。
将之前在服务器上编译好的文件拷贝到客户机上。
编写配置文件
编写一个配置文件,起名为ngrok.cfg1
2server_addr: wangjiebao.com:4443
trust_host_root_certs: false
运行客户端
指定子域、要转发的协议和端口,以及配置文件,运行客户端:./ngrok -subdomain pub -proto=tcp -config=ngrok.cfg 22
如果需要转发的是HTTP,改为
./ngrok -subdomain pub -proto=http -config=ngrok.cfg 80
当tunnel status显示online,说明已经连接上服务器
配置Docker
正常的机器这个时候应该已经可以通过任意一台机器使用ssh root@ngrok.wangjiebao.com -p 123456
来访问内网机器的端口。
其中端口号会在客户端的运行界面给出
但是我在配置docker container的时候发现访问总是被拒绝。
由于不知道docker container的密码,密码使用
passwd
指令修改过。
最后发现问题的根源在于Docker container上没有安装sshd服务。
安装ssh server
apt-get install openssh-server
启动与重启ssh server
启动ssh server:sudo /etc/init.d/ssh start
重启ssh server:sudo service ssh restart
查看服务是否运行:netstat -aunpt
编辑配置文件
配置文件位于/etc/ssh/sshd_config
将配置文件中的PermitRootLogin without-password
改为PermitRootLogin yes
通过ssh访问客户机
现在已经全部配置完成,可以愉快地玩耍了。在任意一台联网的机器上,都可以使用ssh root@ngrok.wangjiebao.com -p 123456
来访问内网机器的端口。
其中端口号会在客户端的运行界面给出