「本文已参与低调务实优秀中国好青年前端社群的写作活动」
一、了解内网穿透
内网穿透又叫内网映射,功能是把内网IP映射到公网,使公网也能轻松访问所搭建的服务。
我在公司电脑上运行了一个web项目,现在希望所有人都能访问它。
很显然,只有公司的同事能通过]ip地址访问到页面,公司外的人访问不到。
这时候你有两种方案:一是把网站部署到服务器上,二就是用内网穿透了。
部署到服务器费不能实时刷新,改动一行代码都要打包上传,费时费力。
ps:👻内网映射方便的同时也会带来安全风险
内网穿透能干什么?
-
在外网演示你本地的web项目
-
手机测试移动端的网页
-
远程控制自己电脑
-
和朋友联机打游戏
...
穿透的过程
🌰以vue项目为例,你已经运行了项目,地址是http://localhost:8080
这时 “人在公司坐,活从天上来”,在客户那边的同事要给客户展示下开发进度。
你只要运行一下穿透的服务,然后把公网访问的地址发给同事,就能访问本地的 http://localhost:8080
DDNS 和 内网穿透
🌰
二、实现穿透
实现穿透就需要提供映射的服务端,这个服务端可以是网上免费的,也可以是自建的。
自建服务推荐两个开源项目 frp 和 ngrok
| 免费 | 自建 |
|---|---|
| ● 小米球 ● 花生壳 ● NATAPP ● cpolar ... ... | ● frp ● ngrok |
三、免费服务
免费服务通常有几个限制,也提供收费服务
- 需要注册账号
- 访问地址不固定
- 有访问时间限制
优势也非常明显,不需要服务器,使用方便等
网上还有很多内网映射服务商,自行搜索
免费服务的流程大同小异,都需要注册一个账号,下载客户端使用
🌰以小米球(ngrok.ciqiuwl.cn) 为例
💡 注意:小米球需要实名认证
-
注册账号 👉 manager.xiaomiqiu.com/reg
-
通过菜单【系统管理】 -> 【账户管理】-> 【我的账户】获取token
-
下载客户端(注意选择合适的版本) 👉 官网下载链接
-
修改配置配置
xiaomiqiu.confserver_addr: ngrok2.xiaomiqiu.cn:5432 trust_host_root_certs: true auth_token:把
auth_token改成自己的token,💥不要改动其他内容 -
运行
小米球一键启动工具.bat即可
四、用frp自建服务
重点说一下如何自建内网穿透。
偶尔用一次,我建议注册免费的服务即可
4.1 frp是什么?
frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。
| frp | |
|---|---|
| 官网 | gofrp.org/docs |
| github | github.com/fatedier/fr… |
| 下载地址 | github.com/fatedier/fr… |
| 开源协议 | Apache-2.0 |
首先需要一台公网服务器
😉 “我有个朋友,他恰好有一台”
4.2 下载安装包
frp的每个压缩包中都包含客户端和服务端两套文件,以文件名区分
- frpc 开头的文件是客户端(运行在需要穿透的机器)
- frps 开头的文件是服务端(运行在公网服务器)
我的环境如下,所以需要下载两个安装包
| 系统 | 安装包名 | |
|---|---|---|
| 需要穿透的机器 | Windows 10 64位 | frp_0.42.0_windows_amd64.zip |
| 公网服务器 | Linux CentOS 7 64位 | frp_0.42.0_linux_amd64.tar.gz |
4.3 配置服务端
在本地解压frp_0.42.0_linux_amd64.tar.gz,修改好配置再传到服务器
修改 frps.ini
[common]
bind_port = 7000
# 客户端和服务端必须使用相同的token才能建立连接
# 相当于连接密码,自由设置
token = 0jiklwLgXq
# http代理访问端口
vhost_http_port = 9999
# 以下参数可选
# -----------
# 开启数据仪表盘,端口7500
dashboard_port = 7500
# 数据仪表盘的用户名密码,默认为 admin
dashboard_user = admin
dashboard_pwd = admin
上传以下文件到服务器
│ frps
│ frps.ini
│ frps_full.ini
│ LICENSE
│
└─systemd
frpc开头的文件是客户端文件,服务器上用不到
增加执行权限
chmod +x frps
开放防火墙和安全组配置文件中的端口
- 7000:连接端口
- 7500:仪表盘端口
- 9999:web服务访问端口
我用的华为云,安全组策略如下。
4.4 配置客户端
解压frp_0.42.0_windows_amd64.zip
修改 frpc.ini
[common]
server_addr = 你的服务端IP
server_port = 7000
token = 0jiklwLgXq
[web]
type = http
# 需要穿透的本地端口
local_port = 8080
custom_domains = 你的服务端IP
4.5 运行
运行服务端
进入frp所在目录执行
./frps -c ./frps.ini
👆 如图表示运行成功
运行客户端
进入frp所在目录执行
./frpc -c ./frpc.ini
👆 如图表示运行成功
4.6 效果
web服务穿透
- 本地
localhoust:8080 - 穿透后
*.*.*.*:9999
仪表盘服务
五、扩展
5.1 frp还能做什么?
frpc_full.ini 是客户端全部配置示例
frps_full.ini 是服务端全部配置示例
frp根据不同配置提供不同服务,以下是官网提供的配置示例
5.2 动态端口脚本
问题 :怎样快速切换代理的本地端口号 ❓
frp运行时依赖配置文件
./frpc -c ./frpc.ini调用的frpc.ini
用node.js 写一个修改端口的脚本,保存为 D:\frp\frpPort.js
const fs = require('fs')
const readline = require('readline')
var exec = require('child_process').exec
// 修改成自己的路径
const path = 'D:\\frp\\frpc.ini'
const runFrp = 'D:\\frp\\frpc -c '
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('输入要穿透的端口号: ', port => {
let config = fs.readFileSync(path, 'utf-8').toString()
const key = "local_port = "
const newConfig = config.replace(new RegExp(`(?<=(${key}))\\d+`, 'g'), port || '8080')
fs.writeFileSync(path, newConfig)
exec(runFrp + path, (error, stdout, stderr) => {
console.log(stdout)
});
rl.close();
});
用正则替换端口,更好的方式是 ini 模块 const ini = require('ini')
但是需要 npm 安装,“可以但是没必要😝”
cmd运行脚本命令
node D:\frp\frpPort.js
没有报错信息表示穿透成功
截图时服务端已经运行
5.3 快速运行脚本
问题 :frp提供这么多服务,怎样快速切换 ❓
从配置文件下手,可以新建多个配置文件
🌰 举个栗子
frpc_web.ini:提供web穿透
frpc_file.ini :提供简单文件访问
然后写一个bat脚本来运行,保存为frpRun.bat
💥 注意保存时的编码选GB2312,否则乱码
💡 配合动态端口脚本
@echo off
echo 输入序号运行不同服务
echo 1 运行web穿透
echo 2 运行动态修改端口穿透
set /p var=请输入序号:
if "%var%"=="1" (
echo 运行web穿透...
@REM 下面改成你的路径
D:\frp\frpc -c D:\frp\frpc_web.ini
) else if "%var%"=="2" (
echo 运行动态修改端口穿透...
@REM 下面改成你的路径
node D:\frp\frpPort.js
) else (
echo 序号错误
)
pause
截图时服务端已经运行
5.4 Linux下的脚本
参考我的另一篇
六、报错处理
token in login doesn't match token from configuration
2022/05/11 16:50:52 [E] [service.go:340] token in login doesn't match token from configuration
2022/05/11 16:50:52 [W] [service.go:128] login to server failed: token in login doesn't match token from configuration
token in login doesn't match token from configuration
解决:检查token是否正确(尝试重新填写两边token)
login to server failed: dial tcp *.*.*.*:7000: connectex: No connection could be made because the target machine actively refused it.
2022/05/11 16:52:21 [W] [service.go:128] login to server failed: dial tcp *.*.*.*:7000: connectex: No connection could be made because the target machine actively refused it.
dial tcp :7000: connectex: No connection could be made because the target machine actively refused it.
解决:服务端没有运行
type [http] not support when vhost_http_port is not set
2022/05/11 17:02:58 [W] [control.go:179] [4f6d9375d6568b0e] [web] start error: type [http] not support when vhost_http_port is not set
解决:配置服务端的http端口
配置正确,连接不上?
尝试使用kcp配置
服务端
[common]
bind_port = 7000
kcp_bind_port = 7000
客户端
[common]
server_addr = 你的服务端ip
server_port = 7000
protocol = kcp
最后
🔥 注意安全!
🔥 安全!
🔥 全!