1. 内网穿透的概念及方法

  1. 由于IP资源数量限制以及防火墙等原因,一般来说,我们的物联网设备和私有服务器都是没有公网IP地址的,因此也无法通过外部网络直接访问,只有公有云服务商或者专线接入的用户,才有有限的独立的公网IP地址可供访问。在这种情况下,如果我们要通过个人电脑、私人服务器提供网络服务,或者需要从公共网络访问并管理我们的物联网设备,就需要有内网穿透的功能,使我们的服务器与物联网设备提供的服务(如文件服务、FTP、网站服务或者SSH远程管理功能等)可以穿过防火墙,能够从公共网络进行访问。<br /> 实现跨网络访问的方法较多:
  • 如果单纯要进行windows桌面远程管理,可以使用远程桌面TeamViewer工具,但该软件为商用软件,并且功能有很多限制
  • 也可以使用商用的蒲公英或者其他VPN工具搭建VPN,通过虚拟化的本地网络进行访问
  • 也可以使用商用的花生壳软件提供的内网穿透功能,但是价格昂贵并且功能限制较多
  • 此外,可以通过开源工具ngrok、frp等进行内网穿透服务器搭建,由于ngrok自版本2之后不再开源,本文选择了目前更为流行的frp工具。

    1. 要实现内网穿透,你需要有一台拥有公有IP地址的服务器,在目前云服务器价格持续走低的情况下,拥有一台独立的低配置的云服务器对个人来说并非难事,其成本也远低于其他商用软件如花生壳等。本文以下步骤均以拥有固定IP地址的公网云服务器以及在局域网内的服务器为前提,其中,云服务器安装了Ubuntu18.04版本的linux操作系统,本地私有服务器安装了Windows 10系统,为了充分模拟各种情况,本地服务器还通过WSL运行了Ubuntu18.04系统。拓扑简图如下:

image.png

2. frp安装与基础配置

  1. frp的安装与配置很简单,在[frp项目官网](https://github.com/fatedier/frp)(或者从我们的[frp国内镜像](https://www.wesinx.cn:30443/weizy0219/frp))的release页面下载需要的已经编译好的二进制文件,注意,下载好的frp是包括服务器frps和客户端frpc的,在服务端只需要气动frps而在客户端只需要启动frpc,在我们的服务器和客户端操作分别如下。<br /> 由于一般云服务器供应商对服务器端口均进行了限制,为了保证本文后续配置顺利进行,需要在云服务器安全组中开放以下端口,并在后续要提供其他服务时根据情况进行开放,如果服务器自身也启用了防火墙服务,那么下列端口还需要在服务器防火墙配置中再配置一次以予以放行:
  • 7000 用于frp服务器和客户端之间进行数据交换
  • 8000 用于提供http服务
  • 7019~7021 用于提供被动式的ftp服务
  • 7022 用于提供ssh远程管理服务
  • 7389 用于windows客户端远程桌面管理

本文后续配置中均假设云服务器ip地址为123.123.123.123,实际配置中需要根据真实ip地址修改,同时,本位假设已经拥有一个www.domain.cc域名通过A记录解析至123.123.123.123,因此在配置时均通过域名代替ip地址。这样的好处是如果服务器进行更换,不需要再在每台客户端中配置并更换服务器的ip地址。

2.1 服务器端frp安装与配置(frps)

  1. 通过ssh方式远程连接云服务器后,通过以下命令下载并安装frps
  1. //下载安装包
  2. wget https://github.com/fatedier/frp/releases/download/v0.34.3/frp_0.34.3_linux_amd64.tar.gz
  3. //解压安装包
  4. tar -xvf frp_0.34.3_linux_amd64.tar.gz
  5. //使用nano或者vim打开解压后的frps.ini文件并做以下最简单的配置以供测试
  6. # frps.ini
  7. [common]
  8. bind_port = 7000
  9. //通过以下命令启动frps
  10. ./frps -c ./frps.ini

上述启动方式仅用于调试,在断开ssh连接后服务会自动关闭,服务器与客户端自启动方式见后文详细配置说明。

2.2 Windows 客户端frp安装与访问(frpc)

下载windows版本客户端并解压,打开 frpc.ini 文件进行配置。

  • 在server_addr部分输入域名或者ip地址均可,这里使用域名
  • 为了进行测试,需要windows打开远程管理服务功能,在windows文件资源管理器中,右键点击此电脑选择“管理”,选择“高级系统设置”,选择“远程”,选择“允许远程连接到此电脑”。此功能仅用于windows 10专业版及以上,家庭版是不具备此功能的,可以通过后续方法搭建ftp服务器进行测试。 ```bash

    frpc.ini

    [common] server_addr = www.domain.cc server_port = 7000

[rdp] type = tcp local_ip = 127.0.0.1 local_port = 3389 remote_port = 7389

  1. 在当前目录下打开 `windows powershell` 输入以下命令以启动客户端,如果服务器连接成功,会有 `start proxy successful` 字样提醒:
  2. ```bash
  3. > .\frpc.exe -c .\frpc.ini
  1. 在第三台电脑上,通过快捷键 `win+R` 启动命令提示框,输入 `mstsc` ,输入 `www.domain.cc:7389` 输入用户名和密码(安装了frpc客户端电脑的用户名和密码),即可远程打开windows客户端电脑进行管理。可以看到,在这种条件下,第三方电脑通过公网云服务器的7389端口,访问了windows客户端的3389远程桌面端口,实现了windows电脑端口的内网穿透功能。

2.3 Linux客户端frp安装与访问(frpc)

在windows10服务器的WSL子系统下(或者独立的Linux系统亦可),安装frp客户端并进行访问。需要注意的是,windows10的Ubuntu子系统,默认没有打开root用户远程ssh权限,需要先进性设置。

  1. //打开ssh配置文件
  2. sudo nano /etc/ssh/sshd_config
  3. //修改以下位置,然后保存:
  4. Port = 22 # 去掉前面的#号,启用22端口
  5. ListenAddress 0.0.0.0 #去掉前面的#号
  6. PasswordAuthentication yes # 将 no 改为 yes 表示使用帐号密码方式登录
  7. PermitRootLogin yes #允许root用户远程登录
  8. //重启sshd服务:
  9. dpkg-reconfigure openssh-server #用于安装RSA_KEY,选择使用现有配置文件keep old...
  10. sudo service ssh restart #重启SSH服务
  11. sudo service ssh status #查看SSH服务状态,应为running

执行以下命令下载并配置运行frp客户端。

  1. //下载安装包
  2. wget https://github.com/fatedier/frp/releases/download/v0.34.3/frp_0.34.3_linux_amd64.tar.gz
  3. //解压安装包
  4. tar -xvf frp_0.34.3_linux_amd64.tar.gz
  5. //使用nano或者vim打开解压后的frpc.ini文件并做以下配置以启用ssh功能
  6. # frpc.ini
  7. [common]
  8. server_addr = www.domain.cc
  9. server_port = 7000
  10. [ssh]
  11. type = tcp
  12. local_ip = 127.0.0.1
  13. local_port = 22
  14. remote_port = 7022
  15. //通过以下命令启动frps
  16. ./frps -c ./frps.ini

通过第三方计算机终端访问 ssh -p 7022 root@www.domain.cc ,输入密码后即可通过ssh方式访问linux主机(此处为windows服务器的wsl子系统)。

3. frp配置文件说明

  1. 在下载解压后的文件中,分别有 `frpc_full.ini` `frps_full.ini` 两个配置文件示例,包括了大部分功能的配置方法,在frp官网中也提供了大量[配置案例](https://github.com/fatedier/frp#oidc-authentication)。可供参考。

3.1 通过token加密frp

上文所述的frp是不安全的,在没有加密的情况下,任何人都可以使用你的frp服务器进行内网穿透服务。为此,frp提供了token和OpenID加密方式进行加密,要使用token加密,只需要在服务器端的 frps.ini 配置文件和客户端的 frpc.ini 文件中增加同样的token配置项即可。

  1. #frps.ini
  2. [common]
  3. authentication_method = token
  4. token = 12345678
  5. #frpc.ini
  6. [common]
  7. token = 12345678

此外,也可以采用通过环境变量取代配置文件明文密码的方式进行参数配置及加密,参考配置如下:

  1. # frpc.ini
  2. [common]
  3. server_addr = {{ .Envs.FRP_SERVER_ADDR }}
  4. server_port = 7000
  5. [ssh]
  6. type = tcp
  7. local_ip = 127.0.0.1
  8. local_port = 22
  9. remote_port = {{ .Envs.FRP_SSH_REMOTE_PORT }}

3.2 配置http端口及域名服务

  1. 服务端配置http服务端口及域名主机。
  1. # frps.ini
  2. [common]
  3. #http端口服务
  4. vhost_http_port = 8000
  5. #配置主机域名后,可以在客户端配置子域名进行访问
  6. subdomain_host = domain.com

如果客户端要配置http子域名,可以采用如下配置,这样可以通过test.domain.com:8000访问客户机的80端口:

  1. # frpc.ini
  2. [web]
  3. type = http
  4. local_port = 80
  5. subdomain = test

如果客户端要配置独立的域名,可以采用如下配置,并把 www.mydomain.com 域名解析到服务器的ip地址上,即可通过如下配置,以 www.mydomain.com:8000 访问客户机80端口:

  1. [web]
  2. type = http
  3. local_port = 80
  4. custom_domains =www.mydomain.com

3.3 配置ftp服务(内网ftp服务器被动模式)

对于在局域网中搭建的 ftp 服务器,需要通过被动模式,才能穿过防火墙供外部 ftp 客户端访问,以 FileZilla Server 为例,在服务器配置时,需要配置以下被动模式,在本例中, ftp 服务器使用21端口,被动端口定义为7018~7020。
image.png
在客户端作如下配置,其中ftp用于配置ftp服务器,ftp1~3用于配置被动端口,配置后可以通过7021端口访问客户端21端口的ftp服务:

  1. [ftp]
  2. type = tcp
  3. local_ip = 127.0.0.1
  4. local_port = 21
  5. remote_port=7021
  6. [ftp1]
  7. type = tcp
  8. local_ip = 127.0.0.1
  9. local_port = 7018
  10. remote_port = 7018
  11. [ftp2]
  12. type = tcp
  13. local_ip = 127.0.0.1
  14. local_port = 7019
  15. remote_port = 7019
  16. [ftp3]
  17. type = tcp
  18. local_ip = 127.0.0.1
  19. local_port = 7020
  20. remote_port = 7020

3.4 配置管理页面

frp可以通过程序内置的管理页面进行管理,要配置服务端管理页面,需要配置相应的 dashboard 参数。如下配置后,可以访问frp服务器的7500端口,通过设置的用户名和密码管理frps服务器。

  1. //frps.ini
  2. [common]
  3. dashboard_port = 7500
  4. dashboard_user = admin
  5. dashboard_pwd = admin

要管理与配置客户端参数,需要对 frpc.ini 做如下配置,配置后,可以通过在客户端本地7400端口管理并配置frp客户端。

  1. //frpc.ini
  2. [common]
  3. admin_addr = 127.0.0.1
  4. admin_port = 7400
  5. admin_user = admin
  6. admin_pwd = admin

4.配置frp开机启动

4.1 在Ubuntu通过systemd下配置frps为系统服务

新的Ubuntu系统通过systemd来管理服务以替代传统的init,关于systemd的入门教程,可以参考阮一峰博客的文章要配置frps为系统服务,可以按照如下步骤进行操作.

  1. //1. /usr/frp目录并复制frps frps.ini 文件到其中,本步骤仅为后续操作方便。
  2. //2. 在/lib/systemd/system/目录下新建frps.service文件并写入以下内容,这也是service一类文件的标准写法。
  3. [Unit]
  4. Description=Frp Server Service
  5. After=network.target
  6. [Service]
  7. Type=simple
  8. User=root
  9. Restart=on-failure
  10. RestartSec=5s
  11. ExecStart=/usr/frp/frps -c /usr/frp/frps.ini
  12. [Install]
  13. WantedBy=multi-user.target
  14. //以上操作完成后,可以通过Ubuntu系统的systemctl命令操作frps服务
  15. sudo systemctl enable frps.service # 设置开机启动,根据 install 建立软链
  16. sudo systemctl disable frps.service # 取消开机启动,根据 install 移除软链
  17. sudo systemctl daemon-reload # 重新加载配置,修改 systemd 配置执行
  18. systemctl status frps # 查看 frps 服务状态
  19. systemctl cat frps # 查看 frps 服务配置
  20. sudo systemctl start frps # 启动 frps 服务
  21. sudo systemctl stop frps # 停止 frps 服务

4.2 在Windows系统下通过配置任务计划来配置 frpc 开机自启动

利用批处理文件和任务计划来启动程序是windows下常规操作,在 frp 目录下新建一个 start.bat 批处理文件。

  1. @echo off
  2. :home
  3. frpc -c frpc.ini
  4. goto home

上述脚本会在服务中断后自动重启服务(一旦frpc退出,就回到home行重新开始),一个简单的方式是对上述脚本新建一个快捷方式并放置在以下目录中,就可以开机自动启动,但每次开机都会有windows命令行出现。
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 因此还是通过配置任务计划更好一些。

搜索任务计划程序,打开windows任务计划程序。新建一个基本任务,“常规”栏名称可以随意填写,在运行时选择不管用户是否登录都运行,并且选择使用最高权限运行和隐藏。在“触发器”栏中选择启动时。在“操作”栏中选择新建操作,程序指向 start.bat 位置,起始位置指向脚本目录。任务配置完成后,系统在开机时即可自动运行。
创建任务1.png创建任务2.png创建任务3.png

4.3 利用 WINSW 将frp注册为windows系统服务以实现自启动

WINSW 是一个可以把任何(几乎)windows程序注册成windows系统服务的工具软件,[下载WINSW] 并保存在frp目录下,为了方便起见,将WINSW重命名为 myfrpc.ext ,并在同一目录下新建一个 myfrpc.xml 文件,添加内容如下:

  1. <service>
  2. <id>frpc</id>
  3. <name>Frpc</name>
  4. <description>This service runs frp client system with configuration</description>
  5. <env name="JENKINS_HOME" value="%BASE%"/>
  6. <executable>D:\services\frp\frpc.exe</executable>
  7. <arguments>-c frpc.ini</arguments>
  8. <onfailure action="restart" delay="15 sec"/>
  9. <onfailure action="restart" delay="30 sec"/>
  10. <log mode="roll"></log>
  11. </service>

其中, executable 指向 frpc.exe 所在目录, arguments 为运行参数, onfailure 设置了两次重启机会,来保证服务可以正常启动。在命令行中运行 myfrpc.exe(即重命名后的winsw.exe文件) 来管理服务:

./myfrpc.exe install #注册服务,winsw会自动找到同一目录下的xml文件并注册其中的程序
./myfrpc.exe uninstall #取消服务
./myfrpc.exe start #启动服务
./myfrpc.exe stop #停止服务
./myfrpc.exe status #查看服务状态
./myfrpc.exe restart #重启服务

这样就将frpc注册为windows系统服务,在windows任务管理器的服务栏中可以看到该服务。