如何自建NAS以及玩出花(三):NAS的公网访问
NAS的公网访问
一、公网与内网
所谓公网(Public Network)是全球范围内可以自由访问的互联网,它实现了不同的ISP(Internet Service Provider,互联网服务提供商,也就是常说的联通、移动、网通等公司)之间的互联互通。而内网(或者叫私网 Private Network)则通常指的是在一个组织内部使用的网络,不会直接对外开放。
查询公网IP地址最简单的方式,就是通过百度直接搜索IP地址,它会返回一个IP地址,这个IP地址就是你上网所使用的公网IP。
通过百度查询的公网IP地址
我们平时使用网络服务,无论是浏览网页还是观看视频,实际上都是通过公网IP进行访问,但是人是很难记忆公网IP,所以现在而因为服务的改变,需要访问的公网IP还需要随着用户的地理位置而改变,这就催生出了DNS系统(这也是我之前一直研究的方向)。
DNS是一个分布式数据库,主要用于存储公网IP与域名之间的映射,同时提供查询服务。在Linux上可以使用dig
命令来查看DNS的解析结果。这对于NAS来说是挺重要的,如果你不想每一次通过网页登录NAS或者通过很麻烦的方式给别人分享自己的资源,那一个域名就变得非常有用了。
不过域名在国内还是需要进行备案审核才可以使用,像是写这个文章的网站就是单纯的只能通过IP地址进行访问,这个是不需要进行审核的。当然你如果只是自己使用,那还有其他方式可以绕过这个限制,比如修改hosts文件,这个之后再说。
dig命令的使用方法,能看到查询百度的域名返回了IP地址
说回到内网,我们最常见的内网就是家里的路由器。当你在家办理宽带的时候,运营商会提供一个猫(调制解调器,Modem),但一般人还是会为了WiFi自己再买一个路由器,这时候WiFi路由器、你的各种接入网络的设备互相之间形成一个网络,这个网络就是内网。
一般家庭网络拓扑图,如果你的家庭网路不是这样,那一般也不用看我的废话了
在Windows Termianl中的PowerShell输入ipconfig /all
,就可以查看自己现在使用的电脑的内网IP地址了
命令结果:IPv4地址现在就是内网地址
在Linux上输入ifconfig
,也可以查看内网IP地址
inet的内容就是内网地址,这些网桥都是docker创建的,不用在意
二、这为什么会成为一个问题
我使用NAS的大部分使用场景,其实都是在内网中,很少的一部分是在公网访问内网,外部访问的场景虽然说很少,但却十分有用,比如有时候我们想通过NAS下载一个电影,如果无法访问的话那就只能等到下班回家再进行操作了,公网访问无疑会给NAS使用带来不一样的体验。
但在公网访问内网,这为什么会成为一个问题?主要还是因为我们现在使用的IPv4协议的公网地址有限,大约是43亿个,而这些IP地址已经在2019年就已经全部耗尽了。要上网就需要公网IP,而现在公网IP地址早就全部分配完了,怎么现在办理宽带也还是能上网呢?这里就使用了NAT技术(Network Address Translation,网络地址转换),简单说就是通过端口映射的方式把一个公网IP分给好多个人使用。好处是上网的人多了,坏处就是NAT会修改IP报文的源地址和目的地址,这就造成不通过特殊方法就没法在外部访问内网了(实际上网络问题会更加复杂,即使能访问运营商也不愿意让你这么做)。
而绕过这些限制,允许通过公网访问位于内网的服务器的行为,就叫做内网穿透。(是不是很形象)
三、内网穿透方案
1.花生壳
花生壳是国内最早开始做内网穿透的服务商之一,远程桌面的向日葵也是这家公司做的。技术方案是内网穿透+DDNS,赠送一个免费的花生壳二级域名,可以省下一个域名钱,但是速度较慢,价格较高(毕竟要挣钱啊)听说花生壳还有一个硬件,操作比较简单,附赠穿透流量,具体可以自己去看一看。
花生壳价格
2.QC
这是群辉官方提供的外网访问方案,但是如果跟着咱这个教程走,那必然是没有的,而且速度一般。
3.DDNS+端口映射
这个方案搞好了也挺好,问题就是你需要有口才。这需要你去打电话到你的ISP(联通、移动之类的),告诉他你需要一个公网IP,通常会拒绝你,这时候你就需要口才了,一般的理由就是家里安装监控了,需要外网访问。实在不行咱就工信部投诉部见。这种方式我没有操作过,而且也会越来越严格,毕竟公网IP少嘛,给一个少一个,一般给你的公网IP也是一个动态的公网IP,一段时间后就会变化。解决方法就是购买一个域名,让然后使用DDNS(动态DNS,在IP地址发生改变的时候自动更新DNS记录)自动更新,这时候你只要通过域名访问就可以保证一定能是当前的公网IP地址了。
这个方案需要申请公网IP、一个域名、使用DDNS,还需要一个功能强的路由器,还要有良好的网络安全习惯,毕竟你这不做好防护就相当于在公网上裸奔啊。
优点就是速度快,能够用到家用带宽的上行极限。有一个自己的域名也挺不错,什么设备都可以使用。
缺点就是80和443端口无法访问,还需要你会使用端口映射。
4.IPv6DNS
IPv6是下一代的互联网协议,就是因为当时IPv4的地址已经捉襟见肘了,所以这一次IPv6地址直接干到128位,据说可以为地球上的每一个沙子都分配一个IPv6地址,你的每一个设备都可以有一个IPv6的公网地址,甚至有些防护策略就是利用IPv6地址过多的特性,直接在海量的地址上随机跳跃,你想扫描搜索都是做不到的。
这种方案类似第三个方案,啥都好,缺点就是20年了,还是这个B样。
IPv6测试
你可以在这个网站上看看你家里的宽带是否支持IPv6:IPv6测试
5.云服务+frp内网穿透
这也是我目前使用的内网穿透方案,价格相对便宜,速度一般,但是好在所有的环节都是自己掌握的。
实现原理就是购买云服务器(腾讯云、阿里云、华为云都可以),这些云服务器会送你一个固定的公网IP地址让你用来访问,我们再通过frp将这些流量映射到内网的端口上,这样就是实现了内网穿透。
用于内网穿透的云服务器不要求性能,只要有个网络就可以,当然你也可以使用云服务器干一些其他的事情,对于内网穿透这个功能来说,云服务器的性能不重要。
下面我就主要介绍一下第五种方案(因为我只弄过第五种)
四、购买云服务器
云服务器的购买我选择的是阿里云,主要是因为阿里云有99元一年的优惠
直接注册阿里云账户(用支付宝就可以),如果是新用户的话应该还有更便宜的方案。选购的准则就是算力存储都不重要,网络带宽最重要,因为使用的是云服务器的准发,所以云服务器的网络带宽决定了你在公网访问的速度。
方案选择ECS就可以,这是最标准的云服务器。
配置选择
地区选择距离你所在城市最近的地区,因为我现在居住在北京,所以自然就选择北京了,这个选项决定了云服务器的物理机房位置。如果选择的位置较远,会比较影响延迟(一般不会影响速度,因为本来也没多大)
操作系统选择Ubuntu即可,和自己的NAS系统保持一致,这里注意一下云服务器的Ubuntu默认是没有图形化界面的,要使用SSH登录。
存储空间大小用不到,默认即可。
网络类型也不用管,虚拟交换机是当你购买了很多云服务器,需要在一起组成集群时通过内网(云服务器的内网)访问的时候才会用到的,就购买一个不需要管。
网络带宽这个方案是固定的,不限流量3M/S,翻译过来就是375KB/S,这个速度看电影和超大文件同步就不用想了,能比百度云盘快点。如果你恰巧很有钱,那你可以选择不用这个优惠套餐,直接自己定制云服务器,配置方案与上面都相同即可,网络带宽可以选择按量付费,每GB-0.8元,但是带宽速度可以顶到100M/S,通常只是看看照片,同步点小文件,控制控制NAS这些,一个月都可能用不到1G。
注意要勾选分配公网IP啊,虽然目前是免费的,但是你不勾选那就不给你的。
点击下一步,要求选择安全组,所谓的安全组你可以理解为防火墙,选择需要开启的端口就可以了,目前主要是SSH(22端口)就可以,后续我们再添加服务的时候再开启。
最后选择密码设置即可,注意密码要选择一个复杂的,并且自己要记住了,如果你忘记了密码就要重置云服务器,所有在上面部署的服务都会被删除。
登录凭证中的密钥对是由阿里云自动生成的公钥和私钥,使用后就可以免密SSH登录,安全性也更高,只要你的私钥不泄露,不论是谁拿到公钥都没有用。这里使用的大名鼎鼎的非对称加密,具体原理可以参看:非对称加密算法,不过我选择的是自定义密码,不用担心,后续我们会自己生成公钥和私钥,将所有的SSH登录都改成免密登录,使用自定义密码只是方便。
用户登录名选择如果怕麻烦可以选择ecs-user,这就相当于普通用户,一些操作还需要sudo
命令进行提权,我是直接选择的root用户。
阿里云服务器的购买到这里就可以结束了,如果有不懂的可以详细查看阿里云的官方购买文档
99元/年的购买链接我也放这里了:如果没有的话阿里云官网首页很好找的。
打开阿里云网页右上角中的控制台,就可以看到你购买的云服务器了,还有公网IP
后续我们就通过这个公网IP去访问云服务器。
五、云服务器访问以及vim使用
云服务器访问
在Windows终端,我比较喜欢实用Windows Terminal,这个直接在Microsoft 商店可以直接下载,点击链接查看,当然你也可以选择自己喜欢的终端工具,比如Cmder、SecureCRT、XShell、PuTTY等,但我感觉这些都不如Windows Terminal好看。这个终端工具可是像VSCode一样巨硬少有的干的人事。
Windows Terminal的具体使用可以参看文档:Microsoft Learn
这个终端的美化也是指的一说,不过那是后话了。
打开终端,选择Windows PowerShell,输入ssh
ssh
如果你显示的是上图的样子,说明你已经可以使用ssh了,Windows10以上的系统应该已经默认安装SSH服务了,如果没有的话,那就上网上搜索一下Windows安装ssh,这里给个教程。
这里教一下SSH登录的方法
ssh 192.168.1.1 -l root -p 22 # 写法1
ssh root@192.168.1.1 -p 22 # 写法2
上面是ssh的两种写法,效果都是一样的,记得将上面的参数替换成自己的。192.168.1.1这个是你想登录的远程服务器IP地址,root则是你想要登录的账户,-p
参数控制的是登录的端口,如果不写,那默认就是22端口,因为22端口(大家都用SSH登录)太常见了,放在公网的服务器会被很多人扫描(尝试链接),他们一般不会扫描所有的端口,而是选择这些非常常见的服务器的端口,所以后需更改这个默认端口。
这样我们就是实现了云服务器的SSH访问,后续你SSH访问自己的NAS也是一样。
进入到云服务器后,我们先使用apt升级一下,阿里云服务器默认使用的是阿里云景象,如果你是按流量付费的,不用担心,云服务器内网链接是不消耗流量的。
apt update && apt upgrade -y # apt升级
apt install openssh-server # 安装SSH服务
apt install vim # 安装vim服务
执行完上上面的命令后,我们就可以学习一下vim了。
vim的使用
vim是一个文件编辑器,通常所有的Linux都会内置vi,但是现在使用最多的是vim,vim和vi操作是相同的,vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。
vim的操作方式
不要被这个表吓到了,其实vim很简单,同时也很复杂,我们只需要学习到能够修改配置文件就可以了。
首先我们进入到/etc/ssh目录,这里是ssh服务器配置文件的位置,ls
一下,看到sshd_config这个就是我们需要修改的配置文件了,但是先使用cp
命令备份一下,防止因为瞎操作把配置文件搞坏。之后就可以使用vim去编辑这个文件了。
cd /etc/ssh #跳转到配置文件目录
ls # 查看一下文件
cp sshd_config sshd_config_bak # 对sshd_config文件进行备份
vim sshd_config # 使用vim修改sshd_config文件
如果你的最后一条命令中sshd_config的名字输错了,vim也会打开一个文件,但这个文件只是vim新建的名字错误的文件。这样你也知道如何使用vim创建文件了吧。
如果你是用的root用户,那你可以直接修改sshd_config文件,因为root用户拥有最高权限,但是假如你是普通用户,那就需要加上sudo
命令,因为sshd_config文件是root用户创建的,普通用户可以访问,但是没有修改权限,别到时候修改完成了因为权限不够没法保存,那就尴尬了。
刚进来的页面应该是这样的
这里你就能看到vim的优点了,ssh的配置文件使用#
作为注释,介绍了ssh的基本配置,还有一些配置被注释掉了,不要以为这没用,其实这些注释掉的配置是ssh的默认配置,当你需要修改某个默认配置的的时候,最好就是直接删除注释符号#
,修改后面的参数即可。
在vim中,我们可以通过方向键去操作光标(HJKL
按键也可以,当然对于初学者实在不友好,不过也能看出vim的设计原则就是尽量减少手腕的移动,放弃鼠标),键盘上的PageUp
和PageDown
按键可以整页的移动。这时候你是无法对文件进行任何操作的,这个状态称为命令模式,顾名思义,你可以输入一些vim的命令来进行快捷操作。
按下按键i
,进入编辑模式,在这个模式下,就和平常使用的编辑器一样,可以对文件进行删除修改等操作。再按一下ESC
按键,就可以退出编辑模式,回到命令模式。
下面介绍一些vim常用的命令:
u
:撤回上一次的修改
dd
:删除光标所在的一行
/ + word
:搜索字符,这在改配置文件的时候很有用
:w
:保存
:q
:退出
:q!
:强制退出
每次退出前一定要保存,否则是不会更改的。
就这么多即可,当然vim还有很多功能,具体参看:菜鸟教程
六、SSH配置(NAS和云服务器都要有)
学会了vim后,我们就可以开始进行SSH的配置了。
SSH配置
主要需要修改的SSH配置有:默认端口、RSA登录、公钥登录、关闭密码登录。就这么多,是不是很简单?
Port 22 # 设置默认端口,要改到一个不常用的端口,最好大于1024
RSAAuthentication yes # 开启RSA
PubkeyAuthentication yes # 开启公钥登录
PermitRootLogin yes # 可选,允许root用户登录
#PasswordAuthentication no # 这个不要着急修改,这是关闭密码登录的,如果你修改了又没有配置好公钥就没法登录了
注意1,我们可以使用命令模式中的/
按键快速定位到需要修改的位置。
注意2,如果修改了默认端口,云服务器的安全组(包括系统自身的防火墙ufw,忘了的可以看上一篇)对应端口也要开启。之后再把22端口关闭就行。
修改成功后执行下面的命令重启ssh,载入配置文件。
sudo service ssh restart # 如果是云服务器则执行这个
sudo systemctl restart sshd # 如果是自己的NAS则执行这个
# 区别是应为云服务器本质上是虚拟机,与实机的启动方式不同,所以没有systemctl服务
这样我们就成功修改了ssh的配置,今后基本上说有的配置文件都是这样修改,如果有不同我会说明出来。
创建密钥对
下面要创建属于我们自己的密钥对了,切换到自己的NAS上,我们要在NAS上创建密钥文件。
使用ssh-keygen
命令,安装ssh的时候应该也会一并安装,使用ssh-keygen
可以选择秘钥的加密算法,我选择的是ed25519,基本原理就是使用数学中的椭圆曲线,拥有更好的安全性和性能。
注意,OpenSSH在6.5之后的版本才加入ed25519的支持,可以使用ssh -V
命令查看版本。
ssh-keygen -a 256 -t ed25519
1. -a 256安全强度
2. -t 选择算法,dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa ,‘-sk’的两个算法请忽视,需要安全固件
选择位置,某人是你的.ssh目录,如果生成成功,你也需要到这个目录下去寻找生成的秘钥。
可以选择输入密码,最好也输入一下
之后等待一会就能看到生成的密钥文件了。
其中id_ed25519是私钥文件,id_ed25519.pub则是公钥文件
使用scp上传密钥到服务器
只需要上传公钥就好,千万不要把私钥上传,而且私钥也要保证没有泄露,保存在一个安全的地方。
公钥和私钥看起来是这样的
实际上,不需要scp
上传文件也可以,直接复制公钥的内容,在云服务器上再创建一个文件,写入复制的公钥内容也是可以的。私钥需要放在自己的机器上,如果是Linux则是/home/$USER/.ssh路径下,如果是Windows则是在C:\Users\$USER\.ssh路径下。
不过为了熟悉一下scp
命令,我们还是试着上传一下吧,公钥需要上传到云服务器的/root/.ssh目录下,注意现在是使用root登录的,所以需要放到/root/.ssh下,如果你是使用自己的用户名,则需要放到/home/$USER/.ssh目录下。
scp [可选参数] file_source file_target
scp root@192.168.1.1:/root/.ssh /home/$USER/.ssh/id_25519.pub # 样例,注意修改成自己的参数,
scp
的file_source地址和file_target地址格式相同,用户名@IP地址:绝对路径,-r
参数是递归,可以传输文件夹,否则传输的只是一个文件,如果把上面的样例目的地址和源地址互换,就变成从云服务器下载到本地了。scp
命令的详细介绍请看:scp
成功传输后,执行下列命令,复制公钥文件,命名为 “authorized_keys”
cat /root/.ssh/id_ed25519.pub > /root/.ssh/authorized_keys
之后修改文件权限,如果文件的权限不正确,ssh无法读取公钥文件,那也是没办法登录的。
chmod 700 ~/.ssh
chmod 400 ~/.ssh/id_ed25519
chmod 600 ~/.ssh/authorized_keys
搞定后,重启SSH服务,退出,重新登录试一试,如果再次登录不需要输入密码了,那就说明配置成功了,可以将sshd_config中的PasswordAuthentication
修改为no,阻止密码登录。
这样,SSH服务就配置好了,不光是云服务器,我建议NAS也使用同样的步骤操作一遍,当然密钥对可以使用同一个,但这样安全性会大大降低,如果你的私钥泄露,那你所有的机器都变得不安全了。
七、frp配置
frp 是一个开源、简洁易用、高性能的内网穿透和反向代理软件,支持 tcp, udp, http, https等协议。frp 项目在github上开源了,所以我们可以直接下载:地址
release的命名规则:软件名-版本号-系统-指令集,通常情况下是这样,所以云服务器应该选择frp_0.58.0_linux_arm64.tar.gz,请根据自己所使用的系统进行选择,下载后进行解压。
tar -zxvf frp_0.58.0_linux_arm64.tar.gz
命令行的下载可以使用curl命令或者wget命令,复制下载地址接口,如果下载速度太慢,那就上gitee寻找一下。
wget https://github.com/fatedier/frp/releases/download/v0.58.0/frp_0.58.0_linux_arm64.tar.gz #方案1 curl https://github.com/fatedier/frp/releases/download/v0.58.0/frp_0.58.0_linux_arm64.tar.gz #方案2
frp分为server端和client端,配置文件不相同,server端放在有公网IP的服务器上,client端放在想要进行内网穿透的NAS上。由于内网服务缺乏公网 IP 地址,因此无法直接被公网的用户访问。用户通过访问服务端的 frps,frp 负责根据请求的端口或其他信息将请求路由到相应的内网机器,从而实现通信。
frp的配置文件现在使用的是toml结构,所以如果你遇到了问题,需要修改配置文件,上网查找一些教程,他们可能用的是以前的配置,这是现在的程序无法读取的,这一点要注意。
文件解压后如下
frpc和frpc.toml是client端的程序和配置文件,frps和frps.toml是server端的程序和配置文件。
先把frpc和frps设置为可执行程序:
sudo chmod +x frpc # NAS 上
sudo chmod +x frps # 云服务器上
Server端配置
修改云服务器上的frps.toml
bindPort = 7500 # 绑定的端口,这个是NAS与云服务器之间的frp交换握手用的,默认是7500,一定要改成自己的啊
auth.token = "passwd" # 握手用的token,建议设置,否则任何人都可以和你的frp握手,记住这个token,frpc的配置文件也要用到
# web服务器配置文件,建议开启
webServer.addr = "0.0.0.0"
webServer.port = 7000 # 修改
webServer.user = "admin" # 修改
webServer.password = "password" # 修改
allowPorts = [{start = 7100, end = 7500}] # 非必须,这会把你的端口映射限制在一定范围
最简单的frps配置文件,只需要第一行就可以了,我也建议添加auth.token以提高安全性,,注意端口和token都要改成自己的。
web服务器非必选项,但是开启后会给你一个web页面,上面展示了所有frp端口的状态,这个配置的端口、用户名和密码要改成自己的。
配置完成后,好要记得修改ufw防火墙与云服务器的安全组,允许你开放的端口可以访问
我们使用命令行启动一下进行测试,在你解压的frp文件夹内执行:
./frps -c ./frps.toml
应该会直接显示日志了,再打开浏览器访问一下配置文件中的web服务器地址,如果成功,说明配置已经生效,如果配置不成功会在打印出来的日志中说明。
按下Ctrl+C
终止程序
Client端配置
client端配置方法与server端相同,只不过要稍微复杂点
修改NAS上的frpc.toml
serverAddr = "公网IP" # 云服务端的公网IP
serverPort = 7500 # 云服务绑定的端口,也就是你在frps.toml中的bindPort
auth.token = "passwd" # token,与frps.toml相同
# frpc一样提供一个能查看内网状态的web服务器
webServer.addr = "内网IP"
webServer.port = 7000
webServer.user = "admin"
webServer.password = "password"
# 端口映射配置
[[proxies]]
name = "ssh" # 映射名字,起名随意
type = "tcp" # 协议,通常网页、SSH等都是tcp协议
localIP = "127.0.0.1" # 127.0.0.1是回环地址,也是本地NAS的地址
localPort = 22 # 需要提供公网访问的端口
remotePort = 7100 #如果frps中设置了allowPorts那么也要在这个范围内
最重要的就是端口映射配置,每当你需要映射一个端口,需要增加一个端口映射配置。
这个例子的含义本质上就是将你NAS上的22端口映射到公网IP的7100端口上,你就可以使用SSH访问公网IP+remotePort(本例子是7100),这与你在内网访问内网地址+22端口是相同的。
我们使用命令行启动一下进行测试,在你解压的frp文件夹内执行:
./frpc -c ./frpc.toml
按下Ctrl+C
终止程序
添加systemctl开机开机自启动
上面的启动测试可以看到,当我们按下按下Ctrl+C
程序就终止了,现在我们想将这个执行程序固定下来,并且能够让他开机自启动,那就是使用systemctl服务。
注意:云服务器是没有systemctl服务的,当然并不是说不能安装使用,可以根据自己的报错问题寻找解决教程
如果不想的话那就使用
nohup ./frps -c ./frps.toml &
把这个服务器挂在在后台,这样退出终端也没问题,如果你想停止就使用kill
命令+ps
命令搜索进程号kill掉
首先我们创建一个systemctl服务的配置文件,注意位置在/etc/systemd/system/,基本上之后所有的systemctl配置文件都在这个地方。
sudo vim /etc/systemd/system/frpc.service
写入内容,根据自己的服务器更改对应的配置
[Unit]
# 服务名称,可自定义
Description = frp server
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
# 启动frps的命令,需修改为您的frps的安装路径
ExecStart = /path/to/frps -c /path/to/frps.toml
[Install]
WantedBy = multi-user.target
After表示在哪个服务之后启动,这里是网络服务器和日志服务,Wants表示依赖于哪个服务,这里是网络服务
service的type表示的是启动方式,simple即可,表示ExecStart字段启动的进程为主进程,ExecStart是启动脚本。
WanteBy表示该服务所在的 Target。
vim使用:wq
保存并退出
填写好后使用sudo systemctl daemon-reload
命令重新载入systemctl配置文件
sudo systemctl start frpc.service
,启动服务,如果没有任何回应,那就说明启动成功
sudo systemctl restart frpc.service
, 重启服务
sudo systemctl status frpc.service
, 查看服务状态
sudo systemctl enable frpc.service
, 将frpc.service设置为开机自启动
这样frp就算是配置好了,如果后续有其他服务需要公网访问,也是一样的操作。
这里给出了frp的中文官方文档:frp
总结
经过以上的步骤,基本已经解决了NAS的外网访问问题,也可以通过SSH服务对NAS进行操作。剩下的就是怎么把NAS玩出花了,下面我会介绍一些NAS所用到的服务,想有什么可以选择这看。