frp内网穿透搭建

frp搭建内网穿透

frp简单、高效的内网穿透工具。

frp 是一款高性能的反向代理应用,专注于内网穿透。它支持多种协议,包括 TCP、UDP、HTTP、HTTPS 等,并且具备 P2P 通信功能。使用 frp,您可以安全、便捷地将内网服务暴露到公网,通过拥有公网 IP 的节点进行中转。

通过在具有公网 IP 的节点上部署 frp 服务端,您可以轻松地将内网服务穿透到公网,并享受以下专业特性:

  • 多种协议支持:客户端服务端通信支持 TCP、QUIC、KCP 和 Websocket 等多种协议。
  • TCP 连接流式复用:在单个连接上承载多个请求,减少连接建立时间,降低请求延迟。
  • 代理组间的负载均衡。
  • 端口复用:多个服务可以通过同一个服务端端口暴露。
  • P2P 通信:流量不必经过服务器中转,充分利用带宽资源。
  • 客户端插件:提供多个原生支持的客户端插件,如静态文件查看、HTTPS/HTTP 协议转换、HTTP、SOCKS5 代理等,以便满足各种需求。
  • 服务端插件系统:高度可扩展的服务端插件系统,便于根据自身需求进行功能扩展。
  • 用户友好的 UI 页面:提供服务端和客户端的用户界面,使配置和监控变得更加方便。

以上是frp官网的描述。虽然一直以来都惯性了VPN,自己也有云服务器,即使家里的使用环境,也可以使用ddns搭配VPN的办法实现内网服务访问。不过还是对frp内网穿透感兴趣,所以,自己有时间了,就尝试搭建一个内网穿透的服务。frp官网有详尽的说明文档,中文友好,非常方便。

搭建依赖环境

本文在阿里云ecs上搭建,操作系统环境为CentOS。FRP采用 Go 语言编写,支持跨平台,安装之前需要解决go语言依赖。非常简单,go语言部署参考官网

总共三步:

1 如果有系统有预装go语言环境,删除预装的go语言环境,下载并解压gog言程序包到系统目录。

1
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.23.4.linux-amd64.tar.gz

2 添加环境变量

1
2
3
4
5
export PATH=$PATH:/usr/local/go/bin
# 或者在/etc/profile.d目录下创建go.sh文件
vim /etc/profule.d/go.sh
export PATH=$PATH:/usr/local/go/bin
source /etc/profile

3 验证go语言版本信息

1
2
$ go version
go version go1.23.4 linux/amd64

搭建frp服务端

官网下载程序包,程序托管在github上,部署时最新的程序版本为v0.61.1,上传至服务器。需要注意的是,从 v0.52.0 版本开始,frp 开始支持 TOML、YAML 和 JSON 作为配置文件格式。

INI 已被弃用,并将在未来的发布中移除。新功能只能在TOML、YAML 或 JSON 中使用。所以,如果有参考以前的旧文档,或者是别人的部署案例,很多特性可能不会起作用。我的个人习惯,将自己用的程序放在/opt目录下。

1
2
3
4
5
6
7
8
9
10
11
wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
# 解压程序包
tar -zxvf frp_0.61.1_linux_amd64.tar.gz
# 目录结构
tree ./
./
├── frpc
├── frpc.toml
├── frps
├── frps.toml
└── LICENSE

非常简单,frps为服务端程序frps.toml为服务端配置文件,frpc为客户端程序,frpc.toml为客户端配置文件。接下来,只需要将服务端程序和配置文件移动到自己想要安装的目录,比如我部署的路径/opt/frps下。默认的服务端配置只有一行,默认端口7000,用于接收客户端连接。启动程序也非常简单,应用程序引用配置文件就可以。

1
2
3
bindPort = 7000
# 启动服务端
./frps -c ./frps.toml

到此为止,服务端就已经部署好了,不过这个启动方式,也太简单了,我们可以创建一个系统服务,让系统服务来完成服务启动,停止,开机自启动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vim /etc/systemd/system/frps.service

# 创建frp启动服务
[Unit]
Description = frp server
After = network.target syslog.target
Wants = network.target

[Service]
Type = simple
# 启动frps的命令,需修改为您的frps的安装路径
ExecStart = /opt/frps/frps -c /opt/frps/frps.toml

[Install]
WantedBy = multi-user.target

使用systemd管理frp服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 更新systemd服务
systemctl daemon-reload

# systemd管理frp

systemctl start frps # 启动服务
systemctl status frps # 查看服务状态
systemctl stop frps # 停止服务
systemctl enable frps # 开机自启动服务


systemctl status frps
● frps.service - frp server
Loaded: loaded (/etc/systemd/system/frps.service; disabled; vendor preset: disabled)
Active: active (running) since 日 2024-12-29 20:34:15 CST; 17h ago
Main PID: 10539 (frps)
Tasks: 5
Memory: 7.0M
CGroup: /system.slice/frps.service
└─10539 /opt/frps/frps -c /opt/frps/frps.toml

12月 29 20:34:15 dd-ali systemd[1]: Started frp server.

防火墙配置

1
2
firewall-cmd --permanent --add-port=7000/tcp
firewall-cmd --complete-reload

客户端配置

frp程序包里的frpc和frpc.toml复制到电脑任意目录。运行参考服务端程序,程序文件引用配置文件。

windows 环境代理配置

假如我需要在windows下运行代理应用,并且把windows本机的远程暴露出去,可以配置如下:

1
2
3
4
5
6
7
8
9
serverAddr = "x.x.x.x"      # 服务器地址
serverPort = 7000 # 远程服务器端口

[[proxies]]
name = "windows-desktop" # 自定义本地客户端名字
type = "tcp"
localIP = "127.0.0.1" # 这里是代理windows本机的远程,所以这里是回环地址
localPort = 3389
remotePort = 6000 # 自定义frp服务端需要转发的端口
  • localIP 和 localPort 配置为需要从公网访问的内网服务的地址和端口。
  • remotePort 表示在 frp 服务端监听的端口,访问此端口的流量将被转发到本地服务的相应端
    口。

客户端配置了远程转发的端口,服务端防火墙需要放通对应端口,同理,阿里云安全组也要放通这些策略。

启动程序,cmd运行,切换到程序目录:

1
frpc.exe -c frpc.toml

终端上回显启动frpc服务,尝试连接服务器,登录服务器,添加代理,代理成功等日志输出。至此,已经把内网服务器内网穿透到公网了。可以直接从公网访问内网服务器的远程桌面。mstsc 服务器IP:6000即可。

这个运行窗口也显得实在不够好看,那可以把运行程序写成一个批处理,取个名字吧,StartFrpc.bat,注册系统服务,这样就方便了。为了方便,直接把bat放在frpc程序目录好了,参考如下:

1
2
3
4
5
6
7
8
@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
REM
cd C:\frp
frpc.exe -c frpc.toml
exit

因为我们知道frpc的进程就是frpc.exe,所以,可以补充一个简单的bat脚本,直接放在frpc程序目录,用于结束frpc服务。

1
2
3
4
5
@echo off
echo killing process frpc ......
taskkill /F /IM frpc.exe
echo process closed.
pause

taskkill直接停止frpc进程即可。

windows frpc 注册系统服务

把frpc程序注册成系统服务,使用sc命令创建服务是可以的,不过运行服务会一直报错,包含运行参数也报错,所以换了另外一个方案,可以成功,需要使用一个程序winsw。winsw也是一个exe程序,托管在github。下载链接
1、下载WinSW-x64.exe,直接把文件放frpc程序目录。重命名为frpc-winsw.exe。
2、在程序文件创建配置文件frpc-winsw.xml。

1
2
3
4
5
6
7
8
9
10
11
12
13
<service>
<id>frpc</id>
<name>frpc</name>
<description>frp client managered by winsw</description>
<executable>C:\frp\frpc.exe</executable>
<arguments>-c C:\frp\frpc.toml</arguments>
<log mode="roll-by-size">
<sizeThreshold>10485760</sizeThreshold>
<keepFiles>3</keepFiles>
</log>
<onfailure action="restart" />
<startmode>Automatic</startmode>
</service>

3、注册服务

1
2
3
PS C:\frp> .\Frpc-Winsw.exe install
Installing service 'frpc (frpc)'...
Service 'frpc (frpc)' was installed successfully.

可以看到服务已经注册完成。

4、启动服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
C:\WINDOWS\system32>net start frpc
frpc 服务正在启动 .
frpc 服务已经启动成功。


C:\WINDOWS\system32>sc query frpc

SERVICE_NAME: frpc
TYPE : 10 WIN32_OWN_PROCESS
STATE : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

C:\WINDOWS\system32>

使用sc命令查询frpc服务状态。

同样,使用winsw启停服务可以参考:

1
2
3
4
PS C:\frp> .\Frpc-Winsw.exe stop
Stopping service 'frpc (frpc)'...
Service 'frpc (frpc)' stopped successfully.
PS C:\frp>
Command Description
install Installs the service.
uninstall Uninstalls the service.
start Starts the service.
stop Stops the service.
restart Stops and then starts the service.
status Checks the status of the service.
refresh Refreshes the service properties without reinstallation.
customize Customizes the wrapper executable.
dev Experimental commands.

使用方法可以参考官网文档。

使用windows net命令启停服务:

1
2
3
4
5
6
7
8
C:\WINDOWS\system32>net start frpc
frpc 服务正在启动 .
frpc 服务已经启动成功。


C:\WINDOWS\system32>net stop frpc
frpc 服务正在停止.
frpc 服务已成功停止。

注册成系统服务后,开机实现开机自启动。接下来就方便了。这次记录为使用windows系统作为代理客户端部署,使用linux部署更加方便,习惯使用systemd创建服务,和服务端一样。本次搭建到此为止,换一篇继续实践frp的其它功能特性。


frp内网穿透搭建
https://ywmy.xyz/2024/12/30/frp内网穿透搭建/
作者
ian
发布于
2024年12月30日
许可协议