[返回首页](../README.md) # FRP 客户端部署指南 本文统一说明 Linux 与 Windows 串口服务器上的 `frpc` 部署。两种系统使用相同的 TOML 代理配置语义;差异只在安装目录、文件权限和服务管理方式。 ## 一、共用概念与配置 ### 1. 版本与连接参数 先确认现有 `frps` 的版本,再从 [FRP 官方发布页](https://github.com/fatedier/frp/releases) 下载版本匹配、架构正确的客户端。精确匹配服务端版本是最简单稳妥的部署策略。本文使用 TOML;FRP 从 v0.52.0 开始支持 TOML 配置。 从现有 `frpc` 配置或 `frps` 管理信息中取得以下值: - `serverAddr`:`frps` 地址; - `serverPort`:`frpc` 连接 `frps` 的控制/隧道端口,本部署为 `21315`; - `auth.token`:用于认证代理注册的共享令牌。 ### 2. 用 `.env` 保存真实地址与令牌 真实地址和令牌不应写死进 `frpc.toml`,也不应提交到版本库。frpc 支持在配置里用 Go 模板读取环境变量,因此本手册把真实值集中放在仓库根目录的 `.env`,配置文件只引用变量名。 `.env`(真实值,已被 `.gitignore` 忽略,仅保存在本地): ```dotenv FRP_SERVER_ADDR=your-frps-host.example.com FRP_SERVER_PORT=21315 FRP_AUTH_TOKEN=your-frps-token ``` 仓库另附可提交的占位模板 `.env.example`;将其复制为 `.env` 后填入真实值即可。配置文件中对应写成 `{{ .Envs.FRP_SERVER_ADDR }}` 等模板,frpc 启动时用**进程环境**里的同名变量渲染。 注意:frpc 不会自动读取仓库根目录的 `.env`。该文件只是真实值的本地清单;部署时必须把这些变量注入 frpc 进程,具体见后文 Linux(systemd `EnvironmentFile`)与 Windows(WinSW ``)小节。 串口服务推荐只监听回环地址,代理中相应使用 `localIP = "127.0.0.1"`,让本机串口服务不直接暴露到 LAN,由 `frpc` 主动连接本地监听端口并转发流量。 ### 3. 单端口代理示例 Linux 和 Windows 均可使用同一份 TOML 结构;只需让 `localPort` 与本机 RFC 2217 服务实际监听端口一致。 ```toml serverAddr = "{{ .Envs.FRP_SERVER_ADDR }}" serverPort = {{ .Envs.FRP_SERVER_PORT }} auth.token = "{{ .Envs.FRP_AUTH_TOKEN }}" [[proxies]] name = "ser2net-rfc2217-1" type = "tcp" localIP = "127.0.0.1" localPort = 2217 remotePort = 2217 ``` 如果 Windows 上的 hub4com 或其他串口服务监听本机端口 `7001`,只调整本地侧即可: ```toml [[proxies]] name = "windows-com3-rfc2217" type = "tcp" localIP = "127.0.0.1" localPort = 7001 remotePort = 2217 ``` ### 4. 四端口代理示例 保留同一组顶层连接参数,为每个通道添加一个 `[[proxies]]` 块: ```toml serverAddr = "{{ .Envs.FRP_SERVER_ADDR }}" serverPort = {{ .Envs.FRP_SERVER_PORT }} auth.token = "{{ .Envs.FRP_AUTH_TOKEN }}" [[proxies]] name = "ser2net-rfc2217-1" type = "tcp" localIP = "127.0.0.1" localPort = 2217 remotePort = 2217 [[proxies]] name = "ser2net-rfc2217-2" type = "tcp" localIP = "127.0.0.1" localPort = 2218 remotePort = 2218 [[proxies]] name = "ser2net-rfc2217-3" type = "tcp" localIP = "127.0.0.1" localPort = 2219 remotePort = 2219 [[proxies]] name = "ser2net-rfc2217-4" type = "tcp" localIP = "127.0.0.1" localPort = 2220 remotePort = 2220 ``` ### 5. 三类端口不要混淆 - `serverPort = 21315`:FRP 控制/隧道端口,供 `frpc` 连接 `frps`,不是串口应用对外访问端口。 - `localPort`:串口服务器本机的 RFC 2217 监听端口;本指南中通常绑定在 `127.0.0.1`。 - `remotePort`:由 `frps` 主机对外打开、供远程 RFC 2217 客户端连接的应用端口。 例如 `localPort = 7001`、`remotePort = 2217` 表示 `frpc` 从本机回环端口 `7001` 取流量,而外部客户端连接 `frps` 主机的 `2217` 端口。 ### 6. `frps` 侧要求 若 `frps` 配置了 `allowPorts`,必须允许所选 `remotePort`;四端口示例需加入 `2217-2220`。`frps` 所在主机的防火墙还应: - 允许入站 TCP `21315`,供 `frpc` 建立控制连接; - 允许每个已配置的入站 TCP `remotePort`; - 尽量把公开串口端口限制为可信客户端源地址,而不是向整个互联网开放。 ## 二、Linux 部署 ### 1. 安装 `frpc` 从匹配 `frps` 版本和目标架构的 Linux FRP 发布包中解压 `frpc`,然后安装二进制并创建配置目录: ```bash sudo install -m 0755 frpc /usr/local/bin/frpc sudo install -d -m 0750 /etc/frp ``` ### 2. 创建专用账户 ```bash getent group frpc >/dev/null || sudo groupadd --system frpc id frpc >/dev/null 2>&1 || sudo useradd \ --system \ --gid frpc \ --home-dir /nonexistent \ --shell /usr/sbin/nologin \ frpc ``` 如果账户已存在,用 `id frpc` 核实。后续 systemd 单元明确以 `frpc:frpc` 运行。 ### 3. 写入配置与环境变量文件 将“共用概念与配置”中的单端口或四端口 TOML(使用 `{{ .Envs.* }}` 模板)写入 `/etc/frp/frpc.toml`: ```bash sudoedit /etc/frp/frpc.toml ``` 再把真实值放入服务器上的环境变量文件 `/etc/frp/frpc.env`(内容与仓库根目录 `.env` 相同): ```bash sudoedit /etc/frp/frpc.env ``` ```dotenv FRP_SERVER_ADDR=your-frps-host.example.com FRP_SERVER_PORT=21315 FRP_AUTH_TOKEN=your-frps-token ``` 真实令牌只在 `frpc.env` 中;`frpc.toml` 只含模板,不含明文。仅允许 `root` 修改、`frpc` 组读取二者: ```bash sudo chown root:frpc /etc/frp/frpc.toml /etc/frp/frpc.env sudo chmod 0640 /etc/frp/frpc.toml /etc/frp/frpc.env ``` 前台手动测试时,可先加载环境变量再运行: ```bash set -a; . /etc/frp/frpc.env; set +a /usr/local/bin/frpc -c /etc/frp/frpc.toml ``` ### 4. 配置依赖 `ser2net` 的 systemd 服务 创建 `/etc/systemd/system/frpc.service`: ```ini [Unit] Description=FRP client for ser2net RFC 2217 Wants=network-online.target ser2net.service After=network-online.target ser2net.service [Service] Type=simple User=frpc Group=frpc EnvironmentFile=/etc/frp/frpc.env ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.toml Restart=on-failure RestartSec=5s NoNewPrivileges=true PrivateTmp=true ProtectHome=true ProtectSystem=strict [Install] WantedBy=multi-user.target ``` 加载、启用并启动服务: ```bash sudo systemctl daemon-reload sudo systemctl enable --now frpc sudo systemctl status frpc --no-pager ``` 查看日志: ```bash sudo journalctl -u frpc -n 100 --no-pager ``` 日志应显示每个代理均已成功注册并启动。 ## 三、Windows 部署 ### 1. 准备归档目录 从 [FRP 官方发布页](https://github.com/fatedier/frp/releases) 下载与已部署 `frps` 版本和 Windows 目标架构匹配的压缩包(通常为 `frp_*_windows_amd64.zip`),并采用以下布局: ```text C:\frp\frpc.exe C:\frp\frpc.toml C:\frp\frpc-service.exe C:\frp\frpc-service.xml C:\frp\logs\ ``` 将“共用概念与配置”中的同一份 TOML(使用 `{{ .Envs.* }}` 模板)写入 `C:\frp\frpc.toml`。无需因为操作系统不同而改变代理结构;只需确保 `localPort` 与 Windows 上实际运行的 RFC 2217 服务监听端口一致。真实地址与令牌不写进 `frpc.toml`,而通过环境变量注入(手动测试见下方,服务方式见 WinSW 小节)。 ### 2. 验证并交互运行 在安装服务前先在当前 PowerShell 会话注入环境变量,再检查配置并通过交互日志确认认证、远端端口和本地串口后端都能工作: ```powershell Set-Location C:\frp $env:FRP_SERVER_ADDR = 'your-frps-host.example.com' $env:FRP_SERVER_PORT = '21315' $env:FRP_AUTH_TOKEN = 'your-frps-token' .\frpc.exe verify -c .\frpc.toml .\frpc.exe -c .\frpc.toml ``` `verify` 只检查配置,不能证明认证成功、`remotePort` 已被允许或串口后端可用;这些必须从交互运行日志确认。 ### 3. 使用 WinSW 安装服务 `frpc.exe` 是控制台程序,不应直接用 `sc.exe create` 作为服务安装方式。将稳定版本的 WinSW 可执行文件重命名为 `C:\frp\frpc-service.exe`,并创建 `C:\frp\frpc-service.xml`: ```xml frpc FRP Client FRP tunnel for the local RFC 2217 server %BASE%\frpc.exe -c "%BASE%\frpc.toml" %BASE% %BASE%\logs 1 hour ``` 将上面三个 `` 的值替换为真实值(与本地 `.env` 保持一致)。frpc 启动时会用这些进程环境变量渲染 `frpc.toml` 中的 `{{ .Envs.* }}` 模板。真实令牌因此保存在该 XML 中,而 `frpc.toml` 只含模板、无明文。 创建 XML 后立即收紧其 ACL(若服务以 LocalSystem 运行): ```bat icacls C:\frp\frpc-service.xml /inheritance:r icacls C:\frp\frpc-service.xml /grant:r "SYSTEM:(R)" "Administrators:(F)" ``` 若改用专用服务账户,应相应调整 ACL,使该账户可读,同时避免普通本地用户读取令牌。 随后在提升权限的 PowerShell 中安装并启动: ```powershell New-Item -ItemType Directory -Force C:\frp\logs C:\frp\frpc-service.exe install C:\frp\frpc-service.exe start C:\frp\frpc-service.exe status ``` 安装后可继续使用系统服务工具检查,并配置延迟自动启动: ```bat sc.exe query frpc sc.exe qc frpc sc.exe config frpc start= delayed-auto ``` `sc.exe` 要求 `start=` 后保留空格。`frpc` 可以先于本地 RFC 2217 服务启动并稍后重连,但在本地监听器就绪前,外部连接会失败。延迟自动启动和 WinSW 的失败重启策略有助于处理开机时 USB 枚举较慢的情况。 ### 4. 备选:使用 NSSM [NSSM](https://nssm.cc/)(Non-Sucking Service Manager)是另一个把控制台程序包装成 Windows 服务的常用工具,特点是命令行/GUI 都很简单。上游 NSSM 本体停在 2014 年的 2.24;[fawno/nssm.cc](https://github.com/fawno/nssm.cc) 用 GitHub Actions 重新编译,提供较新的 32/64 位构建(如 `v2.24.1`,2024 年)。 安装服务并注入与 `.env` 相同的三个变量: ```bat nssm install frpc "C:\frp\frpc.exe" -c "C:\frp\frpc.toml" nssm set frpc AppDirectory "C:\frp" nssm set frpc AppEnvironmentExtra FRP_SERVER_ADDR=your-frps-host.example.com FRP_SERVER_PORT=21315 FRP_AUTH_TOKEN=your-frps-token nssm set frpc AppStdout "C:\frp\logs\frpc.log" nssm set frpc AppStderr "C:\frp\logs\frpc.log" nssm set frpc AppRestartDelay 10000 nssm set frpc Start SERVICE_DELAYED_AUTO_START nssm start frpc ``` NSSM 默认在被管进程异常退出时自动重启;`AppRestartDelay` 以毫秒为单位设置重启前延迟。令牌此时保存在服务配置(注册表)中,仅管理员可读,因此 `frpc.toml` 依旧只含模板。修改可用 `nssm edit frpc` 打开 GUI,或用 `nssm set` 逐项调整。 **推荐取舍**:两者都远优于直接用 `sc.exe create` 包装控制台程序。 - 若希望服务定义可版本化、随仓库走、便于复制到多台机器——**优先 WinSW**:其 XML(含 ``)是纯文本,正好与本手册的 `{{ .Envs.* }}` 模板衔接。本手册默认使用 WinSW。 - 若偏好交互式一条条命令或 GUI、不打算把服务定义纳入版本管理——**用 NSSM** 更快。 同样的两种方式也适用于把原生 `ser2net.exe` 或 `hub4com` 包装为服务,只需替换可执行文件与参数。 ## 四、暴露面、防火墙与安全边界 ### 1. 回环监听与 Windows 防火墙 当 RFC 2217 服务只绑定 `127.0.0.1`,且 `frpc.exe` 主动建立出站连接时,通常不需要添加 Windows 入站防火墙规则。Windows 主机只需能够出站访问 `FRPS_HOST:21315`。 只有在串口服务确实必须监听 LAN 接口时,才添加范围严格的入站规则,例如: ```powershell New-NetFirewallRule ` -DisplayName 'RFC2217 from operations subnet' ` -Direction Inbound ` -Action Allow ` -Protocol TCP ` -LocalPort 2217 ` -RemoteAddress '192.0.2.0/24' ` -Profile Domain,Private ``` 推荐的回环专用配置不要添加此规则。 ### 2. `frps` 防火墙与访问控制 无论客户端运行在 Linux 还是 Windows,`frps` 主机都需要与前文一致的控制端口、`remotePort`、`allowPorts` 和防火墙配置。尤其应对每个公开串口端口设置可信源 IP 白名单;不能因为 `frpc` 已认证就认为远程串口访问者也已认证。 ### 3. 令牌与 TLS 的范围 - `auth.token` 仅认证 `frpc` 向 `frps` 注册代理的权限;它不会认证连接公开 `remotePort` 的最终用户。 - FRP 传输 TLS 保护的是 `frpc` 到 `frps` 这一段。普通公开 TCP 代理不会因此自动加密或认证外部客户端到 `FRPS_HOST:remotePort` 的连接。 - 本部署直接暴露该 TCP 端口,并在 `frps` 侧集中处理访问控制(源 IP 白名单、防火墙,必要时叠加 VPN);frpc 侧只负责把本地回环监听转发出去。相关取舍见 [安全说明](security.md)。