CentOS7 基于 FRP 实现 Java Web 服务内网穿透实操记录

最近需要在外网访问内网 CentOS7 服务器上的 Java Web 服务(端口 7878),对比了几种内网穿透方案后,最终选择了 FRP------轻量、配置简单、稳定性高,全程实操下来踩了几个小坑,整理成这篇博客,方便自己后续回顾,也给有同样需求的朋友避坑。

先明确核心需求:内网 CentOS7 运行 Java Web 服务(端口 7878),通过公网服务器搭建 FRP 服务端,实现外网通过公网端口(最终确定 7891 端口,避免冲突)访问内网的 Java Web 服务。

一、前期准备

实操前必须准备好这 3 样东西,缺一不可:

    1. 一台拥有公网 IP 的服务器(我用的阿里云轻量应用服务器,CentOS7 系统,其他云厂商如腾讯云、华为云均可);
    1. 运行 Java Web 服务的内网 CentOS7 机器(确保 Java Web 服务正常启动,本地可通过 127.0.0.1:7878 访问);
    1. 公网服务器安全组、防火墙放行关键端口:7000(FRP 服务端与客户端通信端口)、7891(外网访问内网服务的端口)。

补充:FRP 版本选择 0.58.0(稳定版),对应 Linux amd64 版本,支持 x86_64 架构(实测可用,amd64 与 x86_64 本质是同一架构,无需担心兼容性)。

二、FRP 服务端(公网服务器)配置

服务端核心作用是接收外网请求,转发到内网客户端,步骤简单,全程可复制命令执行。

1. 下载并解压 FRP

登录公网服务器,执行以下命令,创建 FRP 目录、下载并解压安装包:

bash 复制代码
# 创建 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,无需复杂配置,只需要指定通信端口即可:

bash 复制代码
# 编辑配置文件
vi frps.toml

写入以下内容(直接复制,无需修改):

bash 复制代码
bindPort = 7000  # 服务端与客户端通信的端口,必须与客户端保持一致

3. 启动 FRP 服务端并设置开机自启

先测试启动,确认无报错后,再设置开机自启,避免服务器重启后 FRP 服务失效。

bash 复制代码
# 前台测试启动(看到 success 即说明启动成功)
./frps -c frps.toml

# 后台常驻启动(测试成功后执行,推荐)
nohup ./frps -c frps.toml > frps.log 2>&1 

设置开机自启(极简版配置,避免出现 Bad message 错误):

bash 复制代码
# 编辑服务文件
vi /etc/systemd/system/frps.service

写入以下内容(直接复制):

bash 复制代码
[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

执行以下命令,重载配置并启动、设置开机自启:

bash 复制代码
systemctl daemon-reload
systemctl start frps
systemctl enable frps

检查服务状态,看到 active (running) 即为成功:

bash 复制代码
systemctl status frps

三、FRP 客户端(内网 CentOS7 机器)配置

客户端核心作用是将内网 Java Web 服务(7878 端口)映射到公网服务端的 7891 端口,配置与服务端类似,但需注意区分 frpc(客户端)和 frps(服务端),避免混淆。

1. 下载并解压 FRP(与服务端同版本)

登录内网 CentOS7 机器,执行与服务端相同的下载解压命令(版本必须一致,否则无法通信):

bash 复制代码
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/域名、通信端口,以及内网服务的端口映射:

bash 复制代码
# 编辑客户端配置文件
vi frpc.toml

写入以下内容(重点修改 serverAddr 为你的公网服务器 IP 或域名):

bash 复制代码
# 公网服务端的 IP 或域名(必填,替换成自己的)
serverAddr = "你的公网IP/域名"
# 服务端与客户端通信端口,必须与服务端 bindPort 一致(7000)
serverPort = 7000

# 穿透通道配置(可自定义名称,不影响功能)
[[proxies]]
name = "java-web-7878"  # 通道名称,随便改,不重复即可
type = "tcp"  # 协议类型,Java Web 用 tcp 即可
localIP = "127.0.0.1"  # 本地 IP,固定 127.0.0.1 即可
localPort = 7878  # 内网 Java Web 服务的端口
remotePort = 7891  # 公网访问端口(避开被占用的端口,如 7890)

补充说明:name 字段只是通道的标记,方便后续查看日志、区分多个穿透服务,可任意修改(如改成 my-java-web),不影响穿透功能。

3. 启动 FRP 客户端并设置开机自启

同样先测试启动,再设置开机自启,步骤与服务端类似,但注意用 frpc 而非 frps:

bash 复制代码
# 前台测试启动(看到 success 即成功,可看到端口映射信息)
./frpc -c frpc.toml

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

设置开机自启(极简版,避免 Bad message 错误):

bash 复制代码
# 编辑客户端服务文件
vi /etc/systemd/system/frpc.service

写入以下内容(直接复制,注意路径正确):

bash 复制代码
[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

执行以下命令,重载配置并启动、设置开机自启:

bash 复制代码
systemctl daemon-reload
systemctl start frpc
systemctl enable frpc

检查客户端状态,看到 active (running) 即为成功:

bash 复制代码
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:公网端口被占用,穿透失败

原因:最初计划用公网 7890 端口,但该端口被公网服务器上的 Tomcat 占用,FRP 无法绑定该端口,启动报错 bind: address already in use。

解决:更换公网访问端口(本文改成 7891),修改客户端 frpc.toml 中的 remotePort 为新端口,同时在公网服务器安全组、防火墙放行新端口。

坑 4:混淆 frps 和 frpc

原因:将服务端的 frps 脚本用于客户端,导致启动失败,日志提示无法找到 frps 或配置错误。

解决:牢记「服务端用 frps,客户端用 frpc」,服务文件和启动命令都要对应,不能混淆。

六、总结

FRP 实现内网穿透的核心逻辑很简单:公网服务端监听通信端口(7000),内网客户端连接服务端,将内网服务端口(7878)映射到公网端口(7891),外网通过公网端口即可访问内网服务。

整个实操过程难度不大,重点注意 3 点:版本一致、端口不冲突、服务文件格式正确,避开本文提到的坑,基本能一次成功。

后续如果需要穿透多个内网服务,只需在客户端 frpc.toml 中添加多个 [[proxies]] 节点,配置不同的 name 和端口即可,非常灵活。

最后,记录一下常用命令,方便后续维护:

bash 复制代码
# 查看 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
相关推荐
萝卜白菜。2 小时前
TongWeb8.0支持JBoss Weld‌
java·java-ee
万邦科技Lafite2 小时前
淘宝关键词API接口获取分类商品信息指南
java·前端·数据库·开放api·淘宝开放平台
xxjj998a2 小时前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
小碗羊肉2 小时前
【从零开始学Java | 第二十五篇】TreeSet
java·开发语言
小江的记录本2 小时前
【Docker】 Docker 全平台部署(Linux / Windows / MacOS)与 前后端分离项目 容器化方案
java·linux·windows·http·macos·docker·容器
wjs20242 小时前
NumPy 从数值范围创建数组
开发语言
java1234_小锋2 小时前
Java高频面试题:ElasticSearch如何做性能优化?
java·开发语言·elasticsearch·面试
静心观复2 小时前
Lua 脚本是什么
开发语言·lua
m0_651593912 小时前
构建智能SKU系统:编码规则、元数据设计与DDD实战指南
java·大数据·数据库