[转]调试利器-SSH隧道
在开发微信公众号或小程序的时候,由于微信平台规则的限制,部分接口需要通过线上域名才能正常访问。但我们一般都会在本地开发,因为这能快速的看到源码修改后的运行结果。但当涉及到需要调用微信接口时,由于不和你在同一个局域网中的用户是无法访问你的本地开发机的,就必须把修改后的代码重新发布到线上域名所在的服务器才能去验证结果。每次修改都重新发布很繁琐也很浪费时间。
本文将教你如何通过 SSH 隧道把本地服务映射到外网,以方便调试,通常把这种方法叫内网穿透。
阅读完本文后,你能解决以下常见问题:
- 开发微信公众号等应用时把本地服务映射到外网,加速调试流程;
- 把你正在开发的本地服务分享给互联网上其它人访问体验;
- 在任何地方通过互联网控制你家中在局域网里的电脑;
最终目的
把运行在本地开发机上的 HTTP 服务映射到外网,让全世界都能通过外网 IP 服务到你本地开发机上的 HTTP 服务。例如你本地的 HTTP 服务监听在 127.0.0.1:8080
,你有一台公网 IP 为 12.34.56.78
的服务器,通过本文介绍的方法,可以让全世界的用户通过 http://12.34.56.78:8080
访问到你本地开发机上的 HTTP 服务。
总结成一句话就是:把内网端口映射到外网。
前提条件
为了把内网服务映射到外网,以下资源为必须的:
- 一台有外网 IP 的服务器;
- 能在本地开发机上通过
ssh
登入到外网服务器。
要满足以上条件很简单:
- 对于条件1:购买一台低配 Linux 服务器,推荐国外的 DigitalOcean;
- 对于条件2:对于 Mac、Linux 开发机是内置了 ssh 客户端的,对于 Windows 可以安装 Cygwin。
实现原理
要实现把内网端口映射到外网,最简单的方式就是通过 SSH 隧道。
SSH 隧道就像一根管道,能把任何2台机器连接在一起,把发送到其中一台机器的数据通过管道传输到另一台机器。假如已经通过 SSH 隧道把本地开发机和外网服务器连接在了一起,外网服务器端监听在 12.34.56.78:8080
,那么所有发给 12.34.56.78:8080
的数据都会通过 SSH 隧道原封不动地传输给本地开发机的 127.0.0.1:8080
,如图所示:
也就是说,去访问 12.34.56.78:8080
就像是访问本地开发机的 127.0.0.1:8080
,本地开发机上的 8080 端口被映射到了外网服务器上的 8080 端口。
如果你的外网服务器 IP 配置了域名解析,例如 yourdomin.com
会通过 DNS 解析为 12.34.56.78
,那么也可以通过 yourdomin.com:8080
去访问本地开发机上的服务。
这样就做到了访问外网地址时其实是本地服务返回的结果。
通过 SSH 隧道传输数据时,数据会被加密,就算中间被劫持,黑客也无法得到数据的原内容。
所以 SSH 隧道还有一个功能就是保证数据传输的安全性。
实现步骤
把本地开机和外网服务器通过 SSH 隧道连接起来就和在本地开发机 SSH 登入远程登入到外网服务器一样简单。
先来回顾以下 SSH 远程登入命令,假如想在本地远程登入到 12.34.56.78
,可以在本地开发机上执行以下命令:
1 |
ssh username@12.34.56.78 |
而实现 SSH 隧道只需在本地开发机上执行:
1 |
ssh -R 8080:127.0.0.1:8080 username@12.34.56.78 |
如果想同时映射多个端口则可以执行:
1 |
ssh username@12.34.56.78 -R 8080:127.0.0.1:8080 -R 8081:127.0.0.1:8081 |
可以看出实现 SSH 隧道的命令相对于 SSH 登入多出来 -R 8080:127.0.0.1:8080
,多出的这部分的含义是:
在远程机器(12.34.56.78
)上启动 TCP 8080端口监听着,再把远程机器(12.34.56.78
)上8080端口映射到本地的127.0.0.1:8080
。
执行完以上命令后,就可以通过 12.34.56.78:8080
去访问本地的 127.0.0.1:8080
了。
通常把这种技术叫做 SSH 远程端口转发(remote forwarding)。
其实不限于只能把本地开发机上运行的服务映射到外网服务器上去,还可以把任何本地开发机可以访问的服务映射到外网服务器上去。例如在本地开发机上能访问 github.com:80
,在本地开发机上执行:
1 |
ssh -R 8080:github.com:80 username@12.34.56.78 |
就能通过 12.34.56.78:8080
去访问 github.com:80
了。
保持运行
在执行完上面介绍的 SSH 隧道命令后,你会发现登入到了外网服务器上去了,如果你登出外网服务器,就会发现 12.34.56.78:8080
无法访问了。导致这个问题的原因是你登出外网服务器时,在外网服务器上本次操作对应的 SSH 进程也跟着退出了,而这个退出的进程曾负责监听在 8080 端口进行转发操作。
为了让 SSH 隧道一直保持在后台执行,有以下方法。
通过 SSH 自带的参数
SSH 还支持这些参数:
- N参数:表示只连接远程主机,不打开远程shell;
- T参数:表示不为这个连接分配TTY;
- f参数:表示连接成功后,转入后台运行;
因此要让 SSH 隧道一直保持在后台执行,可以通过以下命令:
1 |
ssh -NTf -R 8080:127.0.0.1:8080 username@12.34.56.78 |
通过 AutoSSH
SSH 隧道是不稳定的,在网络恶劣的情况下可能随时断开。如果断开就需要手动去本地开发机再次向外网服务器发起连接。
AutoSSH 能让 SSH 隧道一直保持执行,他会启动一个 SSH 进程,并监控该进程的健康状况;当 SSH 进程崩溃或停止通信时,AutoSSH 将重启动 SSH 进程。
使用AutoSSH 只需在本地开发机上安装 AutoSSH ,方法如下:
- Mac 系统:
brew install autossh
; - Linux 系统:
apt-get install autossh
;
安装成功后,在本地开发机上执行:
1 |
autossh -N -R 8080:127.0.0.1:8080 username@12.34.56.78 |
就能完成和上面一样的效果,但本方法能保持 SSH 隧道一直运行。
可以看出这行命令和上面的区别在于把 ssh
换成了 autossh
,并且少了 -f
参数,原因是 autossh 默认会转入后台运行。
常见问题
如果你遇到通过以上方法成功启动 SSH 隧道后,还是无法访问 12.34.56.78:8080
,那么很有可能是外网服务器上的 SSH 没有配置对。为此你需要去外网服务器上修改 /etc/ssh/sshd_config
文件如下:
1 |
GatewayPorts yes |
这个选项的意思是,SSH 隧道监听的服务的 IP 是对外开放的 0.0.0.0,而不是只对本机的 127.0.0.1。不开 GatewayPorts 的后果是不能通过 12.34.56.78:8080
访问,只能在外网服务器上通过 127.0.0.1:8080
服务到本地开发机的服务。
修改好配置文件后,你还需要重启 sshd 服务来加载新的配置,命令如下:
1 |
service sshd restart |
如果使用以上方法还是无法访问 12.34.56.78:8080
,请检查你外网服务器的防火墙配置,确保 8080 端口是对外开放的。
其它代替方案
除了 SSH 隧道能实现内网穿透外,还有以下常用方法。
frp
frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议。
frp 有以下特性:
- frp 比 SSH 隧道功能更多,配置项更多;
- frp 也需要一台外网服务器,并且需要在外网服务器上安装 frps,在本地开发机上安装 frpc;
ngrok
ngrok 是一个商用的内网穿透工具,它有以下特点:
- 不需要有外网服务器,因为 ngrok 会为你提供;
- 只需要在本地开发机安装 ngrok 客户端,和注册 ngrok 账户;
- 按照服务收费;
这些代替方案的缺点在于都需要再额外安装其它工具,没有 SSH 隧道来的直接。
想了解更多可以访问它们的主页。
(原文地址:http://wuhaolin.cn/2017/11/03/%E8%B0%83%E8%AF%95%E5%88%A9%E5%99%A8-SSH%E9%9A%A7%E9%81%93/)
[转]调试利器-SSH隧道的更多相关文章
- 调试利器:SSH隧道
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 本文作者:ivweb 吴浩麟 原文出处:IVWEB社区 未经同意,禁止转载 在开发微信公众号或小程序的时候,由于微信平台规则的限制,部分接口需 ...
- [视频教程]利用SSH隧道进行远程腾讯云服务器项目xdebug调试
我的远程服务器是腾讯云的ubuntu系统机器,本地我的电脑系统是deepin的系统,使用的IDE是vscode.现在就来使用本地的IDE来调试腾讯云中为网站项目实现逻辑是访问网站域名后,请求被转发给腾 ...
- SSH隧道应用, 突破网络限制
文/怡文圣美 这篇文章可以帮你解决下面三个问题: 不能直连服务器, 要先登陆跳板机, 造成客户端工具无法连接服务器. 服务器没有公网IP, 且只允许公司IP访问, 要在家里操作要先远程桌面到工作机再登 ...
- 利用SSH隧道技术穿越内网访问远程设备
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/11899478.html 通常,我们用于调试的计算机无法远程访问位于局域网中的待调试设备. ...
- Reveal1.5破解,iOS_UI调试利器Reveal最新版本破解方法
Reveal1.0.7破解 1.官网下载最新版Reveal,拖动应用程序中,运行一次2.下载16进制编辑器"0xED" for mac(http://dl.vmall.com/c0 ...
- Windows GUI代码与Windows消息问题调试利器
Windows GUI代码与Windows消息问题调试利器 记得很久前有这么一种说法: 人类区别于动物的标准就是工具的使用.同样在软件开发这个行业里面,对于工具的使用也是高手和入门级选手的主要区别,高 ...
- ssh隧道(端口转发)
本地转发: ssh -Nf -L [bind_address:]port:host:hostport sshServer -Nf 后台运行 -L 本地转发 [bind_address] 绑定本地地址, ...
- 手机H5 web调试利器——WEINRE (WEb INspector REmote)
手机H5 web调试利器--WEINRE (WEb INspector REmote) 调试移动端页面,优先选择使用chrome浏览器调试,如果是hybrid形式的页面,可以使用chrome提供的ch ...
- 通过 SSH 隧道方式图形化连接 AIX 服务器
跳转到主要内容 登录 (或注册) 中文 [userid] IBM ID: 密码: 保持登录. 单击提交则表示您同意developerWorks 的条款和条件. 查看条款和条件. 需要一个 IBM ID ...
随机推荐
- provisional headers are shown 知多少
前言 请求里面provisional headers are shown(显示临时报头) 出现的情况很多,但原因是多样的. 如果你去直接匹配关键字搜索,得到的结果可能与你自己的情况大相径庭. 网上大部 ...
- XOR and Favorite Number CodeForces - 617E -莫队-异或前缀和
CodeForces - 617E 给n个数, m个询问, 每次询问问你[l, r]区间内有多少对(i, j), 使得a[i]^a[i+1]^......^a[j]结果为k.(注意 i ! = j) ...
- AE插入音乐
将音乐文件(如MP3文件)直接拖拽到工程里就可以. 然后添加到合成里. 点击内容预览 ,就自动播放了. 在合成窗口里面,我们可以对于音频文件进行拖动,以及裁剪等操作,但是需要注意的是AE里面不能预览声 ...
- django rest_framework 序列化组件详解
为什么要用序列化组件 当我们做前后端分离的项目,我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿到 ...
- [UVA227][ACM/ICPC WF 1993]Puzzle (恶心模拟)
各位大佬都好厉害…… 这个ACM/ICPC1993总决赛算黄题%%% 我个人认为至少要绿题. 虽然算法上面不是要求很大 但是操作模拟是真的恶心…… 主要是输入输出的难. 对于ABLR只需要模拟即可 遇 ...
- 【学习笔记】python2的print和python3的print()
python2.x和3.x中的输出语句有着明显不同 2.x中的print不是个函数,输出格式如下 Python 2.7.12+ (default, Aug 4 2016, 20:04:34) [GCC ...
- Qt控制台例子
功能:实现通过命令行方式保存文件 #include <QCoreApplication> #include <iostream> #include <QString> ...
- 反编译安卓apk以及jar包
https://www.jianshu.com/p/c9b553cf2b51 https://blog.csdn.net/bzlj2912009596/article/details/78268896
- Egret引擎的常用倒计时
直接上代码, private timeControl() { let timer: egret.Timer = segret.Timer(); timer.addEventListener(egret ...
- java第一次课
package java第一周学习2; 达达20173435 信1705-2 import java.text.SimpleDateFormat; import java.util.Date; pub ...