最近需要在外网访问内网 CentOS7 服务器上的 Java Web 服务(端口 7878),对比了几种内网穿透方案后,最终选择了 FRP——轻量、配置简单、稳定性高,全程实操下来踩了几个小坑,整理成这篇博客,方便自己后续回顾,也给有同样需求的朋友避坑。
先明确核心需求:内网 CentOS7 运行 Java Web 服务(端口 7878),通过公网服务器搭建 FRP 服务端,实现外网通过公网端口(最终确定 7891 端口,避免冲突)访问内网的 Java Web 服务。
一、前期准备
实操前必须准备好这 3 样东西,缺一不可:
-
1. 一台拥有公网 IP 的服务器(我用的阿里云轻量应用服务器,CentOS7 系统,其他云厂商如腾讯云、华为云均可);
-
2. 运行 Java Web 服务的内网 CentOS7 机器(确保 Java Web 服务正常启动,本地可通过 127.0.0.1:7878 访问);
-
3. 公网服务器安全组、防火墙放行关键端口:7000(FRP 服务端与客户端通信端口)、7891(外网访问内网服务的端口)。
补充:FRP 版本选择 0.58.0(稳定版),对应 Linux amd64 版本,支持 x86_64 架构(实测可用,amd64 与 x86_64 本质是同一架构,无需担心兼容性)。
二、FRP 服务端(公网服务器)配置
服务端核心作用是接收外网请求,转发到内网客户端,步骤简单,全程可复制命令执行。
1. 下载并解压 FRP
登录公网服务器,执行以下命令,创建 FRP 目录、下载并解压安装包:
# 创建 FRP 安装目录
mkdir -p /usr/local/frp && cd /usr/local/frp
# 下载 FRP 0.58.0 版本(amd64,兼容 x86_64)
wget https://github.com/fatedier/frp/releases/download/v0.58.0/frp_0.58.0_linux_amd64.tar.gz
# 解压安装包
tar -zxvf frp_0.58.0_linux_amd64.tar.gz
# 进入解压后的目录
cd frp_0.58.0_linux_amd64
2. 配置 FRP 服务端(frps.toml)
FRP 服务端配置文件为 frps.toml,无需复杂配置,只需要指定通信端口即可:
# 编辑配置文件
vi frps.toml
写入以下内容(直接复制,无需修改):
# 1. 基础监听配置
bindPort = 7000 # 客户端连接的服务端端口,必须与客户端保持一致
vhostHTTPPort = 7890 # 公网http访问端口
bindAddr = "0.0.0.0" # 监听所有网卡,确保外网能连
# --- 添加鉴权配置 ---
[auth]
# 这里的字符串就是你的密码,两端必须一致
token = "这里填写一个复杂的密码_123456"
# 5. Web 管理面板 (可选,方便查看状态)
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin@2026"
maxPortsPerClient = 0
3. 启动 FRP 服务端并设置开机自启
先测试启动,确认无报错后,再设置开机自启,避免服务器重启后 FRP 服务失效。
# 前台测试启动(看到 success 即说明启动成功)
./frps -c frps.toml
# 后台常驻启动(测试成功后执行,推荐)
nohup ./frps -c frps.toml > frps.log 2>&1
设置开机自启(极简版配置,避免出现 Bad message 错误):
# 编辑服务文件
vi /etc/systemd/system/frps.service
写入以下内容(直接复制):
[Unit]
Description=FRP Server
After=network.target
[Service]
ExecStart=/usr/local/frp/frp_0.58.0_linux_amd64/frps -c /usr/local/frp/frp_0.58.0_linux_amd64/frps.toml
[Install]
WantedBy=multi-user.target
执行以下命令,重载配置并启动、设置开机自启:
systemctl daemon-reload
systemctl start frps
systemctl enable frps
检查服务状态,看到 active (running) 即为成功:
systemctl status frps
三、FRP 客户端(内网 CentOS7 机器)配置
客户端核心作用是将内网 Java Web 服务(7878 端口)映射到公网服务端的 7891 端口,配置与服务端类似,但需注意区分 frpc(客户端)和 frps(服务端),避免混淆。
1. 下载并解压 FRP(与服务端同版本)
登录内网 CentOS7 机器,执行与服务端相同的下载解压命令(版本必须一致,否则无法通信):
mkdir -p /usr/local/frp && cd /usr/local/frp
wget https://github.com/fatedier/frp/releases/download/v0.58.0/frp_0.58.0_linux_amd64.tar.gz
tar -zxvf frp_0.58.0_linux_amd64.tar.gz
cd frp_0.58.0_linux_amd64
2. 配置 FRP 客户端(frpc.toml)
客户端配置是核心,需要指定公网服务端的 IP/域名、通信端口,以及内网服务的端口映射:
# 编辑客户端配置文件
vi frpc.toml
写入以下内容(重点修改 serverAddr 为你的公网服务器 IP 或域名):
serverAddr = "公网ip或域名"
serverPort = 7000
# --- 添加鉴权配置 ---
[auth]
token = "这里填写一个复杂的密码_123456" # 必须和服务端完全一样
[[proxies]]
name = "java-web"
type = "http"
localIP = "127.0.0.1"
localPort = 7878 # 本地web服务端口
# 加上你希望绑定的域名
customDomains = ["公网ip或域名"]
补充说明:name 字段只是通道的标记,方便后续查看日志、区分多个穿透服务,可任意修改(如改成 my-java-web),不影响穿透功能。
3. 启动 FRP 客户端并设置开机自启
同样先测试启动,再设置开机自启,步骤与服务端类似,但注意用 frpc 而非 frps:
# 前台测试启动(看到 success 即成功,可看到端口映射信息)
./frpc -c frpc.toml
# 后台常驻启动
nohup ./frpc -c frpc.toml > frpc.log 2>&1
设置开机自启(极简版,避免 Bad message 错误):
# 编辑客户端服务文件
vi /etc/systemd/system/frpc.service
写入以下内容(直接复制,注意路径正确):
[Unit]
Description=FRP Client
After=network.target
[Service]
ExecStart=/usr/local/frp/frp_0.58.0_linux_amd64/frpc -c /usr/local/frp/frp_0.58.0_linux_amd64/frpc.toml
[Install]
WantedBy=multi-user.target
执行以下命令,重载配置并启动、设置开机自启:
systemctl daemon-reload
systemctl start frpc
systemctl enable frpc
检查客户端状态,看到 active (running) 即为成功:
systemctl status frpc
四、测试穿透效果
服务端和客户端都启动成功后,即可测试外网访问:
在任意外网设备(手机、电脑)的浏览器中输入:http://公网IP:7891
如果能正常访问到内网 Java Web 服务的页面,说明穿透成功;若无法访问,参考下面的常见问题排查。
五、实操踩坑记录(重点避坑)
全程实操下来,踩了 3 个常见坑,整理出来,避免大家重复踩坑:
坑 1:systemctl enable 报错 Failed to execute operation: Bad message
原因:服务文件(frps.service / frpc.service)格式错误,CentOS7 的 systemd 对配置文件格式非常挑剔,字段过多或格式不规范都会报错。
解决:使用极简版服务文件(本文中提供的版本),删除多余字段,只保留核心配置,复制粘贴后再执行命令即可。
坑 2:客户端与服务端版本不一致,无法通信
原因:服务端下载的 FRP 版本与客户端不一致,导致通信失败,客户端日志会提示版本不匹配。
解决:确保服务端和客户端下载的是同一版本(本文用的 0.58.0),下载链接完全一致。
坑 3:公网端口被占用,穿透失败
原因:最初计划用公网 7891 端口,但该端口被公网服务器上的 Tomcat 占用,FRP 无法绑定该端口,启动报错 bind: address already in use。
解决:更换公网访问端口(本文改成 7890)
坑 4:混淆 frps 和 frpc
原因:将服务端的 frps 脚本用于客户端,导致启动失败,日志提示无法找到 frps 或配置错误。
解决:牢记「服务端用 frps,客户端用 frpc」,服务文件和启动命令都要对应,不能混淆。
六、总结
FRP 实现内网穿透的核心逻辑很简单:公网服务端监听通信端口(7000),内网客户端连接服务端,将内网服务端口(7878)映射到公网端口(7891),外网通过公网端口即可访问内网服务。
整个实操过程难度不大,重点注意 3 点:版本一致、端口不冲突、服务文件格式正确,避开本文提到的坑,基本能一次成功。
后续如果需要穿透多个内网服务,只需在客户端 frpc.toml 中添加多个 [[proxies]] 节点,配置不同的 name 和端口即可,非常灵活。
最后,记录一下常用命令,方便后续维护:
# 查看 FRP 服务状态(服务端/客户端)
systemctl status frps
systemctl status frpc
# 重启 FRP 服务
systemctl restart frps
systemctl restart frpc
# 查看 FRP 日志(排查错误)
tail -f /usr/local/frp/frp_0.58.0_linux_amd64/frps.log
tail -f /usr/local/frp/frp_0.58.0_linux_amd64/frpc.log
9023

被折叠的 条评论
为什么被折叠?



