内网穿透的概念
内网穿透,即 NAT 穿透,网络连接时术语,计算机是局域网内时,外网与内网的计算机节点需要连接通信,有时就会出现不支持内网穿透。——来自百度百科。
简单来说,就是让互联网(外网)的设备能访问局域网(内网)的设备提供的服务,这里的设备通常是电脑。
内网穿透的应用场景
对开发人员来说,一个典型的应用场景就是针对第三方授权(通常是 oauth2.0)和支付回调的开发调试。通过内网穿透工具将第三方 SDK 的回调地址映射到本机开发环境,从而实现实时调式。
其次是节约部署成本(通常是公网服务器费用)。通过将应用部署在本机,再利用内网穿透工具对外提供服务,这样就能,既节约服务器租用费用,又能提升服务器的硬件配置。
本文适用于第一种情况,即低频率开发调式用。
内网穿透的搭建工具
1、ngrok
这是一个国外的穿透工具,1.0 版本是开源的,目前 2.0 以上版本已经闭源,并且提供免费和收费的服务。
2、frp
这是一个国内的开源工具,目前最新版本为 0.26.0,有比较详尽的中文文档,并且一直在维护更新。
由于 frp 一直开源,并且维护积极、更新频繁,再加上中文文档加持,本文最终选择了 frp 作为搭建工具。
注:frp 自主搭建需要一个有公网 ip 的服务器,本文使用阿里云 ECS。
frp 下载和版本选择
官方 github release 地址,目前最新版本是 0.26.0
版本选择说明:
- frp_0.26.0_darwin_amd64.tar.gz —— 适用于 Mac OS 系统
- frp_0.26.0_freebsd_386.tar.gz —— 适用于 FreeBSD 32 位系统
- frp_0.26.0_freebsd_amd64.tar.gz —— 适用于 FreeBSD 64 位系统
- frp_0.26.0_linux_386.tar.gz —— 适用于 Linux 32 位系统
- frp_0.26.0_linux_amd64.tar.gz —— 适用于 Linux 64 位系统
- frp_0.26.0_linux_arm.tar.gz —— 适用于 Linux 32 位嵌入式系统
- frp_0.26.0_linux_arm64.tar.gz —— 适用于 Linux 64 位嵌入式系统
- frp_0.26.0_linux_mips.tar.gz
- frp_0.26.0_linux_mips64.tar.gz
- frp_0.26.0_linux_mips64le.tar.gz
- frp_0.26.0_linux_mipsle.tar.gz
- frp_0.26.0_windows_386.zip —— 适用于 Windows 32 位系统
- frp_0.26.0_windows_amd64.zip —— 适用于 Windows 64 位系统
本文服务器系统为 CentOS7 64 位,选择了 frp_0.26.0_linux_adm64.tar.gz;本机系统为 Mac OS X,于是选择了 frp_0.26.0_darwin_amd64.tar.gz。
下载方式:
1、直接点击链接,使用浏览器下载到本机。利用 ssh 工具连接到阿里云 ECS,再使用 lrzsz 工具的 rz 命令将 frp_0.26.0_linux_amd64.tar.gz 上传到服务器,而压缩包 frp_0.26.0_darwin_amd64.tar.gz 直接在本机解压。
注:ssh 工具、lrzsz 实用工具的安装和用法可自行搜索。
2、终端命令方式
2.1、服务器
使用 wget 下载
wget https://github.com/fatedier/frp/releases/download/v0.26.0/frp_0.26.0_linux_amd64.tar.gz
解压
tar -xzvf frp_0.26.0_linux_amd64.tar.gz
2.2、本机
使用 curl 下载
curl -O https://github.com/fatedier/frp/releases/download/v0.26.0/frp_0.26.0_darwin_amd64.tar.gz
解压
tar -xzvf frp_0.26.0_darwin_amd64.tar.gz
frp 压缩包文件说明
每个压缩包解压后都包含以下文件和一个 systemd 文件夹:
- frpc —— 客户端可执行二进制文件
- frpc_full.ini —— 包含全部配置项的客户端配置文件
- frpc.ini —— 客户端使用的配置文件,包含最简配置
- frps —— 服务端可执行二进制文件
- frps_full.ini —— 包含全部配置项的服务端配置文件
- frps.ini —— 服务端使用的配置文件,包含最简配置
- systemd —— 文件夹,用于将 frpc 和 frps 添加为服务的配置,linux 下使用 systemd 作为守护程序、mac os 使用 launchd 作为守护程序
注:服务端只需用到 frp_0.26.0_linux_amd64 目录下的 frps 相关文件,本机(客户端)只需用到 frp_0.26.0_darwin_amd64 目录下的 frpc 相关文件。
服务端配置和启动
1、在服务器上打开 frps.ini:
vi frps.ini
注:确保当前已进入工作目录 /root/frp_0.26.0_linux_amd64/。
2、配置 frps 要监听的端口:按下 i 进入编辑模式,在末尾增加一行:vhost_http_port = 8080,使 frps.ini 最终配置如下:
[common]
bind_port = 7000
vhost_http_port = 8080
注:vhost_http_port 监听的端口不能被占用,否则会导致 frps 不能启动,端口可根据实际需要修改;bind_port 端口为 frp 服务端和客户端连接通信的端口,默认为 7000。
3、保存配置并退出:按下 Esc,输入:wq。
4、启动 frps 程序:
./frps -c ./frps.ini
注:如遇 permission denied 错误,表明 frps 可能没有运行权限,则先赋权:
chmod 700 frps
然后再次执行启动命令。
客户端配置和启动
1、在本机进入 frp_0.26.0_darwin_amd64 目录,打开 frpc.ini 文件;
2、以配置访问内网的 web 服务(常见情形)为例,最终修改 frpc.ini 如下:
[common]
server_addr = x.x.x.x
server_port = 7000
[web]
type = http
local_ip = 127.0.0.1
local_port = 3000
注:x.x.x.x 为运行 frps 的服务器公网 ip,local_port 为本机启动 web 服务对应的端口,请根据实际情况修改。
3、启动 frpc 程序:
sudo ./frpc -c ./frpc.ini
注:此时 frpc 会通过 7000 端口尝试与 frps 建立通信连接,如果一切顺利,则终端会提示连接成功;但实际情况却显示连接失败,因为还少了两个步骤:
一、需要登录阿里云控制台将 7000 端口加入阿里云 ECS 安全组的入站规则里面,同理还需将 8080 端口加入。具体操作参考:添加安全组规则;
二、将 7000 和 8080 加入服务器防火墙规则,具体操作参考:CentOS7 使用 firewalld 打开关闭防火墙与端口。
当一切就绪,frpc 启动并连接成功后,打开浏览器输入 http://x.x.x.x:8080 就能访问到本机 http://127.0.0.1:3000 的服务(当然本机 web 服务需要处于启动状态)。
至此,一个最简配置的基于 frp 的内网穿透便搭建完成,更多配置和用法,请参考官方文档:frp 官方中文文档。
扩展:将服务端 frps 添加为 service
通过上面在终端直接启动 frps 的方式,会占用终端,并且停止和重启等管理操作也不方便。
为了方便管理 frps 的启动、停止、重启和开机自启,我们需要将 frps 添加为系统 service,通过 systemd 守护程序来管理。
在 frp_0.26.0_linux_amd64 目录里的 systemd 目录下,已经为我们准备好了添加 service 的模板:
- frpc.service
- frpc@.service
- frps.service —— 服务端使用此模板
- frps@.service
1、进入目录 /root/frp_0.26.0_linux_amd64/systemd,编辑 frps.service:
cd /root/frp_0.26.0_linux_amd64/systemd
vi frps.service
2、将 user=nobody 改为 user=root,并保存;
注:root 表示运行 frps 的用户。
3、其中服务运行配置项为:ExecStart=/usr/bin/frps -c /etc/frp/frps.ini,我们需要将二进制文件 frps 复制或移动到到 /usr/bin 目录,配置文件 frps.ini 复制或移动到 /etc/frp 目录,而 /etc/frp 目录不存在,需要手动创建一个。
3.1、复制 frps 到 /usr/bin 目录:
cp ~root/frp_0.26.0_linux_amd64/frps /usr/bin
3.2、创建 frp 目录,并复制 frps.ini 到 /etc/frp 目录:
cd /etc
mkdir frp
cp ~root/frp_0.26.0_linux_amd64/frps.ini /etc/frp
4、将 frps.service 移动到 /etc/systemd/system 目录:
mv ~root/frp_0.26.0_linux_amd64/systemd/frps.service /etc/systemd/system
5、完成以上步骤,我们就可以愉快使用 systemctl 管理 frps 了:
启动 frps:
systemclt start frps
停止 frps:
systemclt stop frps
重启 frps:
systemctl restart frps
查看 frps 状态:
systemctl status frps
开机启动 frps:
systemctl enable frps
同样地本机也可以通过这种方式将客户端程序 frpc 添加为 service 进行管理,不同的是 Mac OS 使用的是 launchd 而非 systemd 来管理,具体操作方法请自行搜索,但如果仅仅是作为开发调试的低频使用目的,仿佛没有必要将客户端添加到 frpc,毕竟终端一条启动命令就可以搞定。更多实战经验分享请参考:我的个人博客