内网穿透神器-Serveo

服务器

浏览数:206

2019-2-1

Serveo.net 如果访问不了,可以看文章后面的官网截图。

Serveo 的功能:将局域网内的服务端口开放到因特网上,实现通过外网访问内网的需求;在 Setveo 官网 https://serveo.net 上的解释是:Expose local servers to the internet, No installation, no signup; 即 将本地服务向公网开发,后面是它的广告词 — 不用安装,无需注册。

最简单的用法

如果你的本地电脑启动了11000端口的web服务,现在想要通过互联网域名让别人访问,只需要在你的电脑上输入 ssh -R 80:localhost:11000 serveo.net 即可,之后会在下方打印一个访问你的服务的域名,例如:

首先,我在本地启动一个jupyter notebook服务(当然其他的服务也可以),服务端口号为 11000:jupyter notebook --ip=0.0.0.0 --port=11000,现在就可以通过地址 localhost:11000 访问 jupyter notebook 的本地服务了:

现在,在你的机子上输入:ssh -R 80:localhost:11000 serveo.net

首先,如果是初次输这条命令,会询问你是否相信传送过来的RSA钥匙指纹,选择 yes,之后就会用绿字给你提供一个网址,你用这个网址给任何一台能够访问互联网的电脑,在浏览器中输入该域名(在上面的例子中,我将输入 https://utrius.serveo.net, 你所生成的域名的一定不一样),就可以访问你电脑上的服务了:

如果你觉得目的已经达到,下面的就可以不用看了。

具体的参考手册

基本用法

开放本地服务

ssh -R 80:localhost:3000 serveo.net

其中 -R 使用格式为: ssh -R remote_socket:host:hostport serveo.net

该命令会使本机和 serveo.net 建立 ssh 连接,并且和 serveo.net 进行协商:

本 机 : “喂,serveo.net,以后发送到你的 remote_socket 的请求,直接转发给 host:hostport 行不行,就不劳烦您亲自处理了!”
serveo.net: “好哒,你告诉其他人,要访问这项特殊的服务,就使用这个子域名就ok了,子域名是:XXX.serveo.net”

之后,发送给 remote_socket 的请求就会全部转发给 host:hostport

开放局域网内其他服务器的服务

通常来说,host 基本上是 localhost ,但也可以是与本机在同一局域网的一台服务器。

例如,与我同在一个局域网有台服务器 192.168.1.250 开启了服务端口 10010,我们输入ssh -R 80:192.168.1.250:10010 serveo.net,就可以通过提供的子域名访问本局域网内的其他服务器的服务。

划重点:我们不仅可以开放自己的服务,只要本机能够在局域网内所获取的所有服务,都能够开放给外网

不过通过亲测,速度会比本地服务慢,毕竟发送给 serveo.net 的请求要先通过 ssh 隧道转发给本机,本机再转发给目标服务器,其单向过程中多了一次转发过程,一个来回就多了两次。

一次开启多个端口服务

注意:开启多个端口部分是 serveo.net 官网上所称的具有的功能,不过经过亲测,给出的两个域名访问的都是第一个端口所对应的服务,所以,我总觉得哪里不对,各位可以自己亲自试试。

比如除了 11000 的 jupyter notebook 服务外,我们在 11001 也开启了新的服务(如果觉得开启个web服务比较困难,可以直接用命令 python -m http.server 11001 即可),之后输入命令:

ssh -R 80:localhost:11000 -R 80:localhost:11001 serveo.net

输出为:

选择特殊的子域名

之前 serveo.net 提供给我们的访问域名是根据你的 IP 地址,你所提供的 SSH 用户名以及当前还能够分配的子域名综合计算之后,反馈给你的,所以你重新运行命令后,通常能够得到相同的子域名。你也可以指定子域名:

ssh -R incubo:80:localhost:11000 serveo.net
等价于:
ssh -R incubo.serveo.net:80:localhost:11000 serveo.net

可以看到,返回给我们的子域名就是 incubo.serveo.net。通过该网址就可以访问了。

不过,如果指定的子域名已经被占用,那么会有如下提示:

修改 SSH 用户名以获得不同的子域名:

我们通过3次命令进行实验:

第一次:ssh -R 80:localhost:11000 foo@serveo.net
第二次:ssh -R 80:localhost:11000 fff@serveo.net
第三次:ssh -R 80:localhost:11000 -l fff serveo.net

可以看出:第一次和第二次相比,由于修改了用户名,所以得到的子域名不相同;而第二次和第三次的结果是完全相同的;

直接连接内网服务器的 ssh 服务

我们可以将 serveo.net 主机视为一个跳板,使我们的终端能够直接通过ssh访问内网服务器,假设在内网 192.168.1.250 上有 ssh 服务,我们可以通过用户名 linux_fhb 进行登录,将该 ssh 服务开放的方法为:

ssh -R myalias:22:192.168.1.250:22 serveo.net

注:如果 myalias 不成功,换一个子域名再进行尝试;

结果如下:

之后我们就可以通过 myalias 进行 ssh 连接了:

ssh -J serveo.net linux_fhb@myalias

实验结果为:

其中参数 -J 的解释为:

This is a shortcut to specify a ProxyJump configuration directive.

该参数在 OpenSSH 的 7.3客户端版本中引入,如果是之前的版本,可以使用下面的命令进行替代(不过还是建议升级比较方便快捷):

ssh -o ProxyCommand="ssh -W myalias:22 serveo.net" linux_fhb@myalias

普通TCP端口的转发

如果你需要对除了 80,443,22 这些端口之外的端口进行包转发,被转发的将是原始的 TCP 包。(在这种情况下,我们就没必要指定子域名了),完成下面这个实验一个需要3步:

  1. 打开本地的 12355 TCP端口服务:nc -l 12355 ;至于网络工具 nc 怎么用,各位可以查资料,不过大家这里照着写就可以了;
  2. 开启 serveo.net 的端口转发功能:ssh -R 12355:localhost:12355 serveo.net
  3. 测试:nc serveo.net 12355

实验结果如下:

其中从上到下的终端分别对应步骤1、2、3,最后发现,终端3发送的 ni hao a 被显示到了终端1,说明 serveo.net 实现了转发功能;

如果你指定 serveo.net 的端口为0,则将随机分配一个可用的端口号(如果指定端口号,可能因该端口已经被占用而开启失败),命令为:ssh -R 0:localhost:12355 serveo.net

可以看到,serveo 给我们分配的随机端口号是 40985

连接端口 443

有时候,22连接端口被禁止了。你可以 连接到 443 端口:

ssh -p 443 -R 80:localhost:8888 serveo.net

注:这个啥用我也不太清楚,猜测应该是能够通过443端口进行ssh连接。

保持连接不断开

如果连接长时间空闲,会自动断开,所以我们需要发送“心跳包”以保持连接,保持连接的命令为:

ssh -o ServerAliveInterval=60 -R 80:localhost:11000 serveo.net

自动重连接

使用 autossh 命令可以创建更加“顽强”的通道。

autossh -M 0 -R 80:localhost:11000 serveo.net

autossh 的具体用法可查看 https://www.everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh/

自定义域名

注:这部分由于没有域名,所以没有试验过,见谅!

如果你想用自己已有的域名或者是子域名,你首先需要 SSH key pair。如果你没有key pair,可以使用 ssh-keygen 程序可以生成。

之后,使用 ssh-keygen -l,可以打印出你的ssh 指纹,形式类似于:

2048 SHA256:pmc7ZRv7ymCmghUwHoJWEm5ToSTd33ryeDeps5RnfRY no comment (RSA)

上面例子的指纹为:SHA256:pmc7ZRv7ymCmghUwHoJWEm5ToSTd33ryeDeps5RnfRY

之后,你需要为你的域名或子域名添加两条DNS记录(DNS如何添加请自行搜索):

  1. 一条记录指向 159.89.214.31,该 IP 地址即为 serveo.net 的公网 IP;
  2. 为了使 SSH key 生效,需要添加这么一段文本:authkeyfp=[fingerprint]。在上面的例子中,DNS 记录的形式为:authkeyfp=SHA256:pmc7ZRv7ymCmghUwHoJWEm5ToSTd33ryeDeps5RnfRY

在修改完DNS记录后,你就可以像下面这样使用了:

ssh -R subdomain.example.com:80:localhost:11000 serveo.net

当你访问 subdomain.example.com 时, Serveo 将会从你的DNS 服务器获取刚才填写的文本记录,只有你所提供的公钥和记录的 ssh 指纹一致,你的请求才会被转发。

替代方案

ngrok

Serveo 是 ngrok 的替代方案。Serveo 就是受 ngrok 启发所开发出来的,因此两者有很多相似之处。Serveo 相较于 ngrok 的最大优势是Serveo使用你的 SSH 客户端,这样你就没有必要安装其他的客户端程序了。

其他的区别比如Serveo免费连接及提供子域名(ngrok 需要一点点钱),Serveo 在终端中请求检查和重播(ngrok 使用 web 接口)。注:由于没用过 ngrok,对最后一句话不太理解。

OpenSSH Server

使用 OpenSSH ,你必须要自己配置和维护一台服务器。它也需要处理 HTTPS 以及子域名的产生,这两点使 SSH 端口转发机制的设置变得复杂。

如果 Serveo 没有满足你的需求,该指南 也许对你使用 OpenSSH 有所帮助。

自己架设服务

上面的免费版本仅用于体验,仅供个人使用,每个实例最多同时拥有3个隧道。不过,我通过实验,发现至少能同时开5个隧道,应该可以开更多,我没有再试了,下面是实验的结果:

如果你打算将 Serveo 进行商用,或是是需要一次使用多于3个隧道,你可以发送邮件 trevor@serveo.net 联系开发者。

下载 serveo 服务程序

Linux 版本

Mac 版本

Windows 版本

使用方法

可以通过命令行对服务软件进行设置,使用 -h 查看帮助文档:

./serveo -h

-private_key_path

首先,你需要需要指定用于建立 SSH 连接的密钥路径。密钥路径应该是 /etc/ssh/ssh_host_rsa_key 或者是 $HOME/.ssh/id_rsa中的一个,根据实际所在位置运行下面中的一条命令(如果这两个位置都没有的话,你要使用 ssh-keygen 生成密钥,使用命令为 ssh-keygen -t rsa -f ssh_host_rsa_key)。
设置方法为:

./serveo -private_key_path=/etc/ssh/ssh_host_rsa_key

或者是

./serveo -private_key_path=$HOME/.ssh/id_rsa

-port,-http_port,-https_port

这些参数指定 Serveo 哪些端口视为 SSH, HTTP, HTTPS 连接的服务端口:

./serveo -private_key_path=ssh_host_rsa_key -port=22 -http_port=80 -https_port=443

./serveo -private_key_path=ssh_host_rsa_key -port=2222 -http_port=8080 -https_port=8443

-cert_dir

如果提供 HTTPS 服务的话,需要改参数。指定的目录中需要包含 TLS 证书以及 keys。例如,一个 cert_dir 可能包含如下的文件:abc.crt,   abc.key,   foo.crt,   foo.key

证书文件的后缀必须是 .crt,keys 文件后缀必须是 .key。证书除后缀外的命名可以随意,但是证书和keys文件的文件名需要相同(即:abc.{crt, key} 必须同时存在)。可以使用通配符证书,证书也支持多个 DNS 名称。

./serveo -cert_dir=certs

-domain

该参数指定在没有给定域名时,默认的域名:

./serveo -domain=example.com

-disable_telemetry

开发者为了调试需要,会打印一些基本事件的报告(例如程序开启,包转发开始等),指定该选项,这些信息将不再打印。

后记

局域网IP地址(内部)的动态分配问题:如果提供服务的服务器 IP 地址在局域网内部变了(例如,路由器动态分配地址,服务器在断网后可能局域网内的IP被重新分配),那么服务一定是不可用的,因为就算你在该局域网内,不知道服务器新分配的 IP 照样不能访问服务器,更何况是远端机子。

局域网对外的公网IP改变了(如果局域网的网络提供商没有提供静态IP,那每次分配给局域网的公网IP都是会变化的),那么意味着本机与 serveo.net 的 SSH 必定已经断开过,而我们是通过本机与serveo.net的SSH隧道访问内网服务的,除非SSH服务重连,否则内网服务也将断开。

能力有限,如果有任何写得不对的地方,可在评论区提出,多谢多谢!

官网截图

原文地址:https://www.jianshu.com/p/d0b3991a9ce1