之前我在 也许你也用得上的技术,从零开始了解内网穿透 这篇文章中简要介绍了内网穿透的一些基本原理,便于普通人了解内网穿透。但实际上这并非一项标准的技术或是某些具体的应用,你甚至不能在维基百科中搜索到「内网穿透」。
因此我并没有具体介绍如何实施,或是推荐一些落地的方法、软件。但是有些小伙伴似乎对应用落地的具体操作很感兴趣。因此这篇我借助家中的一台群晖 NAS,展开聊聊我如何使用家庭服务器,以及我自己采用的内网穿透方案。
先从 NAS 开始
我这台群晖是 DS918+ 型号,没有升级过内存,只有预装的 4G,目前日常待机大概是 50% 的 RAM 占用,CPU 平时在 5% 上下。硬盘是 4 块 4TB 组了 RAID5 在用,目前占用 45%。
群晖中的服务,我最常使用的是这些:
- Cloud Sync:用于百度网盘同步,做百度盘的离线下载使用
- Synology Drive:群晖家自带的同步盘,代替了我使用多年的坚果云
- WebDAV Server:各类手机平板电视盒子等播放器读取视频资源时,较易兼容的协议
- Surveillance Station:家中的小蚁摄像机录像存储回放、直播
- Docker:一些常用的自托管服务,如 Nginx、DDNS、Bitwarden、Memos 等,也是我内网穿透方案的核心应用
还有用于日常离线下载的 Download Station 与偶尔听本地音频用的 Audio Station,这些功能相对简单且使用频率低,便不再展开。
接下来我逐个介绍。
具体使用方法
Cloud Sync
这是内置应用是一个可以将 NAS 磁盘文件,同步到诸如阿里云 OSS、腾讯云存储、百度网盘等等云存储的服务,且支持双向同步。我将其用作百度网盘的离线下载功能,只要在百度网盘与群晖中关联同一个目录,保持双向同步,那么转存其中的资源自然就会启动同步,没有 VIP 速度依然很慢,但好在是无感执行,适合不着急使用的资源。
同步成功后的资源,及时在群晖中转移到其他目录,百度网盘中的资源也会自动进行删除。目前还不支持阿里网盘,但是支持 WebDAV,因此理论上可以通过中间件比如 alist 这样的项目中转,实现阿里网盘的转存 + 离线下载。
Synology Drive
在使用群晖自带的同步盘之前,我一直是使用坚果云。工作需要,多台电脑间同步资料我经常要用到同步盘。偶尔给别人发送大文件的时候,由于近期资料都存储在坚果云,我就可以直接使用坚果云的分享功能,创建分享链接,开启游客权限,对方可以满速下载,且给我节约了每次再单独上传的时间。
Synology Drive 除了能够覆盖坚果云的功能以外,由于我 10TB 的空间,所以基本可以同时作为备份盘使用。而之前,坚果云不到 100GB 的小空间,只能做同步使用。
WebDAV Server
这是我主要的共享群晖空间内容所使用的协议。由于 Windows 与 Android 下的内网共享通常使用 SMB 协议,而 Apple 系列的硬件使用的是 NFS,但是一般不用于外网。因此为了统一协议与安全性,方便各个软件在各种网络环境下有着一致的访问体验,我选用了 WebDAV 服务。
配合 Nginx 的反向代理,我只需要在硬件中设置 https://webdav.a.com:81
这样的二级域名,就可以随时在各种播放器应用中访问到 NAS 中的片源或是资料。
Surveillance Station
使用 Surveillance Station 纯粹是个意外。该应用在群晖中并非完全免费,而是有两个免费的额度,但我完全够用了,因为我家只有一个摄像头。该应用的功能是可以对接一个使用 rtmp
协议推流的摄像头,解决摄像头直播、录制、观看回放等功能。
你可能会好奇,现在的家用网络摄像头不都有这些基本的功能吗?没错,但是那种网络摄像头大概有如下几个缺点:
- 延迟:由于数据经过厂家的服务器,相比起内网传输,直播与回放的速度都有很高的延迟;
- 隐私:我其实并不很注重个人信息的隐私,但唯独家中的网络摄像头,可能会暴露的不仅仅是我个人的数据,所以我希望它是本地运作的;
- 费用:网络摄像头的云存储基本都需要一定的费用,且给予的空间极小,数据存放在群晖中,我甚至可以看到一年前的录像;
- 功能:由于是一款商业软件,整体功能做的并不比其他家平台差,且我的摄像头是第一代小蚁,原本功能很单一,但是刷机后,通过该软件就可以实现很多自动监测性的功能。
可能因为隐私的关系,在家中没有用过网络摄像头的人会疑惑,这类产品的需求点到底在哪。对于我家来说,放在客厅的网络摄像头回放频率很高,且每次都是关键时候发挥作用,比如:
- 小孩子打架、吵架,或做错一些事情,想要看一些证据;
- 遥控器找不到了,包包找不到了,玩具找不到了……
我设置了记录 30 天,平时用来找东西基本够用了,目前占用 176GB。通过内网查看回放十分丝滑,4 倍速 16 倍速真正可以做到像传统闭路监控系统一样。
Docker
其实 Docker 应该单独一个大章节来写。因为单 Docker 中就托管了 5 个服务,接下来我将聊一下其中最常用的 3 个。
Bitwarden
这个开源的密码管理工具,是我把主力浏览器从 Chrome 更换到 Arc 时部署的。由于 Arc 谜一样的用户同步方式,我不敢轻易将账号密码也迁移过去。所以决定选用一个免费易用的跨平台解决方案,就是 Bitwarden。
最初我并没有自己托管,而是使用的官方服务器,但是软件在加载或是操作的时候,由于服务器的延迟,总是让整个操作都卡顿不已。后来我发现了社区用 rust 重写的 开源服务端 (官方的服务端资源消耗极大),可以托管在低配的硬件平台上,尝试后果然解决了卡顿的问题。目前已经是主力的密码管理工具。
Nginx proxy manager
只要用到 Nginx 的地方,我就会优先选择部署这个项目。比起原生 Nginx 让人眼花缭乱的配置文件,这个项目的 webui 几乎不需要说明就能让普通人上手操作。
给不清楚 Nginx 的同学简单解释一下:Nginx 通常是在服务器搭建网站的时候,将某个域名指向自身某个网站的目录,或是指向其自身或内网中的另外一个网站(反向代理)的软件,是一个入口软件。与其齐名的还有开源的 Apache、微软家的 IIS。
为什么我选择这个,我会在下边的公网方案章节解答。
DDNS-go
最后这个很重要,在做内网穿透的时候必不可少。由于家庭宽带每次重连后的 IP 都会变化,所以我们在公网上访问家中资源的时候,就不能每次都重新去查询 IP 进行连接,而是通过域名,与域名背后的 IP 进行连接。这个工具就是让你每一次宽带断线重连的时候,都依次更新一下你的域名背后指向的 IP。
这里有一个小建议,如果你申请的域名只在家中使用,那么在 DDNS 中只需要更新一个 *.a.com
这样的通配符域名即可,这样每次使用新的二级域名的时候,就直接使用,不需要像我一样再在这里逐个添加了:
外网访问方案
由于我的宽带有公网 IP,所以暴露服务到公网的方案有很多,不清楚这块的可以回去看 这篇 讲述公网 IP 重要性的。有些伙伴通过我上方部署的项目可能已经猜到了,我采用的是二级域名 + 反向代理 + DDNS 的方式,由于运营商不允许家庭宽带使用 80 与 443 端口,所以我使用公网的 81 端口代替 https 的 443 端口进行访问。
同时,因为 nginx 只是代理 http 流量比较方便,虽然 tcp/udp 流量也能转发,但是没有路由器直接,这类流量如果多绕一圈可能增加延迟。另外我在路由器中开启了 VPN 服务器,作为后备方案,用于临时访问内网中没有公开暴露的设备。所以整个家中的网络结构如下:
这套方案的优点如下:
- 优先使用常见的开源软件或协议,稳定,安全,穿透内网的时候不需要第三方工具,尤其是 L2TP VPN,Apple 全家桶原生支持;
- 使用域名与统一的 81 端口转发各种内网的服务方便我记忆,且使用带 UI 界面的 Nginx 开源项目很方便统一管理;
- 一些基于 http 的内网服务,经过 Nginx 的 https 代理后,访问更方便,可以避免部分浏览器提示页面不安全。
举个例子。比如我要将 Bitwarden 这个服务暴露在公网,具体的实现步骤是这样:
首先,在群晖的 Docker 中创建 Bitwarden 的新容器,成功后比如内网访问的地址是 http://10.0.0.249:3011
:
接着进入 Nginx Proxy Manager 的管理后台,增加一条反向代理规则,让域名 https://bitwarden.example.com
指向内网的 http://10.0.0.249:3011
,同时顺手自动申请一个免费 SSL 证书,让其可以通过 https 访问避免某些客户端出现一些奇怪的问题:
最后进入 DDNSgo 的管理后台,将 bitwarden.example.com
加入到列表中,保持 IP 时刻为最新:
稍等域名解析片刻后,即可通过域名 + 81 端口的方式访问:
对了,别忘记在路由器中提前映射好你的 81 端口到 Nginx 服务的 443 端口:
最后聊聊安全
有伙伴说,开放越多的端口,被攻击的面就越大。看起来是这样的,但其实像我这样只暴露 81 端口,然后通过反向代理的方式把服务公开出去,与暴露多个端口的形式是一样的。只是端口可以被扫描到,域名可能会被社工猜或者被爆破。
因此,并非暴露端口越多越不安全,而是你暴露了多少个服务在公网。攻击者始终是通过某个服务的最新漏洞,或是弱口令,进入你某个服务的内部,拿到该服务下的一些资料,比如一些密码,然后再渗透到你的一些其他的服务中。因为 docker 或是其他的一些服务,应用之间权限都是相互隔离的,现在已经很少有服务沦陷,服务器也被渗透的局面了,除非你喜欢用一样的密码,还被猜到了不同的入口。
再或者你的路由器(通常是带复杂功能的软路由)被侵入,攻击者有了网关权限后,通过抓包解包改包的方式攻击,那么整个内网都将被渗透。
看起来被攻击好像很容易,但其实你被攻击的概率极低:
- 一个应用通常不会有漏洞,即便有,也很少是致命的,甚至涉及不到隐私;
- 攻击者对普通用户的攻击通常是面性的扫描,一扫就是成千上万的 IP 一起扫,比如某个应用出现了漏洞,而这个应用通常使用 8989 端口,而懂映射的你在暴露服务到公网的时候不一定使用这个端口,且你所用的版本也不一定存在该漏洞;
- 退 100 万步说,即便真的被攻击者拿到了重要的权限,普通用户被窥隐私的概率也极小,通常是被当作僵尸网络使用。
而以上还都是你有公网 IP 的情况下,攻击者才勉强能实现,否则你根本没有机会暴露端口给公网。所有这类片伤型的攻击手段,都比不上你在网上随便下载软件后运行中马的概率高。如果你还是担心自己的服务被攻击,做到以下几条建议,从概率上来说,几乎可以杜绝被误伤:
- 无论使用哪类服务,账户都尽量使用不同的密码;
- 开源项目选择使用人数多的,商业软件也尽量选择大厂的,保持更新;
- 对于可以修改配置的托管应用,尽量不使用官方默认的端口号或是路径、用户名等;
- 别轻易得罪人。
以上是我在个人托管服务方面的一丝心得,与大家分享,希望能够给予一点启发。
,