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
相关推荐
笑不语1 分钟前
从共病网络到可解释 AI:同济医院 10 分 SCI 全流程复现(R 语言)
开发语言·人工智能·r语言
t***5442 分钟前
如何在 Dev-C++ 中设置 MinGW 和 Clang 的路径
java·前端·c++
yu85939583 分钟前
利用MATLAB进行木材图像去噪
开发语言·算法·matlab
拜托啦!狮子6 分钟前
安装EnsDb.Hsapiens.v86
java·服务器·前端
报错小能手11 分钟前
Swift EventBus讲解
开发语言·ios·swift
aq553560011 分钟前
GitSubmodule深度避坑指南
java·开发语言·php
雨声不在13 分钟前
家用版本maven的创建方法
java·maven
止语Lab15 分钟前
Go 的测试框架不想让你 TDD
开发语言·golang·tdd
yaoxin52112319 分钟前
391. Java 文件操作基础 - 方法链式调用
java·开发语言·python