frp 配置反向代理实现 内网穿透

什么是内网穿透

核心原理

你的本地设备(如家里的电脑、公司的服务器)通常通过路由器/NAT设备上网,只拥有(如192.168.x.x)。外网无法直接访问这些内网IP,因为:

  • 路由器有防火墙功能,会拦截外部主动发起的连接
  • 内网IP在公网上不可路由

内网穿透就是打通这个”墙”,让外网流量能够到达内网设备。

常见实现方式

方式 原理 例子
反向代理 内网主动连接公网服务器,建立隧道,流量通过隧道转发 FRP、Ngrok、花生壳
VPN/虚拟组网 组建虚拟局域网,让外网设备获得内网身份 WireGuard、ZeroTier、Tailscale
DDNS+端口映射 如果有公网IP,直接做路由器端口转发 路由器设置虚拟服务器
云服务器中转 数据先发到云服务器,再转发到内网 自建转发服务

配置方案

本文章需要配置的是 实现内网穿透:

  • frps(服务端):部署在有公网IP的ECS上(如阿里云)
  • frpc(客户端):部署在本地CentOS虚拟机中
  • 流程:本地frpc主动连接ECS上的frps → 建立加密隧道 → 外网用户访问ECS的端口 → frps通过隧道转发给frpc → 到达本地服务
1
[外网用户] → [ECS公网IP:7500] → [frps] ═══隧道═══ [frpc] → [本地Ollama:11434]

下载并安装frps(ECS+本地Centos虚拟机)

1
2
3
4
5
#下载
wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz
#解压
tar -zxvf frp_0.61.0_linux_amd64.tar.gz
cd frp_0.61.0_linux_amd64

编写服务端配置文件frps.toml(ECS)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat > frpc.toml << 'EOF'
# 服务端监听地址(0.0.0.0表示监听所有网卡)
bindAddr = "0.0.0.0"
# 服务端监听端口(frpc会连接这个端口)
bindPort = 7000

# 身份验证(必须设置,防止被他人滥用)
auth.method = "token"
auth.token = "your_secure_token_here" # 改成复杂密码

# Web 管理面板(可选,用于查看连接状态)
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin123"

# 允许代理的端口范围(根据你的服务调整)
allowPorts = [
{ start = 6000, end = 7000 }
]

EOF

auth.token可以使用openssl生成

1
2
3
4
5
# 生成32位随机字符串
openssl rand -base64 32

# 示例输出:
# W8vX2kLmN9pQr4StUv3WxYz5AbCdEfGhIjKlMnOpQr=

放开ecs上安全组和防火墙的相应端口

安全组

端口 用途 授权对象
7000 frp服务端通信端口 0.0.0.0/0
7500 Web管理面板(可选) 0.0.0.0
6000-7000 代理端口范围 0.0.0.0/0

防火墙

1
2
3
4
sudo firewall-cmd --permanent --add-port=7000/tcp
sudo firewall-cmd --permanent --add-port=7500/tcp
sudo firewall-cmd --permanent --add-port=6000-7000/tcp
sudo firewall-cmd --reload

启动fprs

1
2
3
4
5
6
7
8
# 前台启动(测试用)
./frps -c ./frps.toml

# 后台启动(生产用)
nohup ./frps -c ./frps.toml > frps.log 2>&1 &

# 查看日志
tail -f frps.log

编写客户端配置文件frpc.toml(本地Centos虚拟机)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat > frps.toml << 'EOF'
# 服务端地址(ECS的公网IP)
serverAddr = "x.x.x.x" # 你的ECS公网IP
serverPort = 7000

# 身份验证(必须与服务端一致)
auth.method = "token"
auth.token = "your_secure_token_here" # 必须和服务端相同

# 给这个客户端起个名字
user = "local-ollama"

# 代理配置:将本地Ollama暴露到公网
[[proxies]]
name = "ollama"
type = "tcp"
localIP = "127.0.0.1"
localPort = 11434 # 本地Ollama端口
remotePort = 6000 # 公网访问端口(ECS的6000端口)

# 可选:再暴露SSH
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6001

EOF

启动frpc

1
2
3
4
5
6
7
8
# 前台启动(测试)
./frpc -c ./frpc.toml

# 后台启动
nohup ./frpc -c ./frpc.toml > frpc.log 2>&1 &

# 查看日志
tail -f frpc.log

测试(ollama)

1
2
3
4
5
# 直接访问本地Ollama
curl http://127.0.0.1:11434/api/tags

# 通过FRP访问
curl http://ECS公网IP:6000/api/tags