Document NSSM (fawno/nssm.cc rebuild) as an alternative to WinSW for wrapping frpc/ser2net, with a WinSW-vs-NSSM recommendation. Add gensiot as a native RFC 2217 client alongside pySerial, noting it is optional for a server-only deployment. Update references. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
13 KiB
FRP 客户端部署指南
本文统一说明 Linux 与 Windows 串口服务器上的 frpc 部署。两种系统使用相同的 TOML 代理配置语义;差异只在安装目录、文件权限和服务管理方式。
一、共用概念与配置
1. 版本与连接参数
先确认现有 frps 的版本,再从 FRP 官方发布页 下载版本匹配、架构正确的客户端。精确匹配服务端版本是最简单稳妥的部署策略。本文使用 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 忽略,仅保存在本地):
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 <env>)小节。
串口服务推荐只监听回环地址,代理中相应使用 localIP = "127.0.0.1",让本机串口服务不直接暴露到 LAN,由 frpc 主动连接本地监听端口并转发流量。
3. 单端口代理示例
Linux 和 Windows 均可使用同一份 TOML 结构;只需让 localPort 与本机 RFC 2217 服务实际监听端口一致。
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,只调整本地侧即可:
[[proxies]]
name = "windows-com3-rfc2217"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7001
remotePort = 2217
4. 四端口代理示例
保留同一组顶层连接参数,为每个通道添加一个 [[proxies]] 块:
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,然后安装二进制并创建配置目录:
sudo install -m 0755 frpc /usr/local/bin/frpc
sudo install -d -m 0750 /etc/frp
2. 创建专用账户
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:
sudoedit /etc/frp/frpc.toml
再把真实值放入服务器上的环境变量文件 /etc/frp/frpc.env(内容与仓库根目录 .env 相同):
sudoedit /etc/frp/frpc.env
FRP_SERVER_ADDR=your-frps-host.example.com
FRP_SERVER_PORT=21315
FRP_AUTH_TOKEN=your-frps-token
真实令牌只在 frpc.env 中;frpc.toml 只含模板,不含明文。仅允许 root 修改、frpc 组读取二者:
sudo chown root:frpc /etc/frp/frpc.toml /etc/frp/frpc.env
sudo chmod 0640 /etc/frp/frpc.toml /etc/frp/frpc.env
前台手动测试时,可先加载环境变量再运行:
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:
[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
加载、启用并启动服务:
sudo systemctl daemon-reload
sudo systemctl enable --now frpc
sudo systemctl status frpc --no-pager
查看日志:
sudo journalctl -u frpc -n 100 --no-pager
日志应显示每个代理均已成功注册并启动。
三、Windows 部署
1. 准备归档目录
从 FRP 官方发布页 下载与已部署 frps 版本和 Windows 目标架构匹配的压缩包(通常为 frp_*_windows_amd64.zip),并采用以下布局:
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 会话注入环境变量,再检查配置并通过交互日志确认认证、远端端口和本地串口后端都能工作:
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:
<service>
<id>frpc</id>
<name>FRP Client</name>
<description>FRP tunnel for the local RFC 2217 server</description>
<executable>%BASE%\frpc.exe</executable>
<arguments>-c "%BASE%\frpc.toml"</arguments>
<workingdirectory>%BASE%</workingdirectory>
<env name="FRP_SERVER_ADDR" value="your-frps-host.example.com" />
<env name="FRP_SERVER_PORT" value="21315" />
<env name="FRP_AUTH_TOKEN" value="your-frps-token" />
<logpath>%BASE%\logs</logpath>
<log mode="roll" />
<onfailure action="restart" delay="10 sec" />
<resetfailure>1 hour</resetfailure>
</service>
将上面三个 <env> 的值替换为真实值(与本地 .env 保持一致)。frpc 启动时会用这些进程环境变量渲染 frpc.toml 中的 {{ .Envs.* }} 模板。真实令牌因此保存在该 XML 中,而 frpc.toml 只含模板、无明文。
创建 XML 后立即收紧其 ACL(若服务以 LocalSystem 运行):
icacls C:\frp\frpc-service.xml /inheritance:r
icacls C:\frp\frpc-service.xml /grant:r "SYSTEM:(R)" "Administrators:(F)"
若改用专用服务账户,应相应调整 ACL,使该账户可读,同时避免普通本地用户读取令牌。
随后在提升权限的 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
安装后可继续使用系统服务工具检查,并配置延迟自动启动:
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(Non-Sucking Service Manager)是另一个把控制台程序包装成 Windows 服务的常用工具,特点是命令行/GUI 都很简单。上游 NSSM 本体停在 2014 年的 2.24;fawno/nssm.cc 用 GitHub Actions 重新编译,提供较新的 32/64 位构建(如 v2.24.1,2024 年)。
安装服务并注入与 .env 相同的三个变量:
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(含
<env>)是纯文本,正好与本手册的{{ .Envs.* }}模板衔接。本手册默认使用 WinSW。 - 若偏好交互式一条条命令或 GUI、不打算把服务定义纳入版本管理——用 NSSM 更快。
同样的两种方式也适用于把原生 ser2net.exe 或 hub4com 包装为服务,只需替换可执行文件与参数。
四、暴露面、防火墙与安全边界
1. 回环监听与 Windows 防火墙
当 RFC 2217 服务只绑定 127.0.0.1,且 frpc.exe 主动建立出站连接时,通常不需要添加 Windows 入站防火墙规则。Windows 主机只需能够出站访问 FRPS_HOST:21315。
只有在串口服务确实必须监听 LAN 接口时,才添加范围严格的入站规则,例如:
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 侧只负责把本地回环监听转发出去。相关取舍见 安全说明。