FRP实现内网穿透

一、FRP 基础概念

FRP(Fast Reverse Proxy)是一款高性能的反向代理应用,主要用于内网穿透,可以将内网中的服务暴露到公网。其核心组件包括:

  • frps(FRP Server):部署在有公网 IP 的服务器上,负责管理和转发客户端的连接。
  • frpc(FRP Client):部署在需要暴露服务的内网机器上,通过 frps 进行连接和转发。

二、系统架构与角色定位

  • A:本地 Windows 机器,可能需要通过中转服务器访问目标服务器 C。
  • B:中转服务器,运行 CentOS,IP 为 117.62.206.56,部署 frps。
  • C:目标服务器,运行 Ubuntu,部署 frpc,需要将其服务通过 frps 暴露给 A。

三、下载与解压 FRP

1. 在 B 服务器(CentOS)上下载 FRP Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 登录到 B 服务器
ssh your_user@117.62.206.56

# 下载 FRP
wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz

# 解压压缩包
tar -zxvf frp_0.61.0_linux_amd64.tar.gz

# 移动到 /usr/local/frp 目录
sudo mkdir -p /usr/local/frp
sudo mv frp_0.61.0_linux_amd64/* /usr/local/frp/

# 切换到 frp 目录
cd /usr/local/frp

在 B 服务器上的目录结构如下:

1
2
3
4
5
6
.
├── /usr/local/frp/
│ ├── frps
│ ├── frps.toml
│ └── logs/
│ └── frps.log

2. 在 C 服务器(Ubuntu)上下载 FRP Client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 登录到 C 服务器
ssh your_user@your_ubuntu_server_ip

# 下载 FRP
wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz

# 解压压缩包
tar -zxvf frp_0.61.0_linux_amd64.tar.gz

# 移动到 /usr/local/frp 目录
sudo mkdir -p /usr/local/frp
sudo mv frp_0.61.0_linux_amd64/* /root/data1/frp/

# 切换到 frp 目录
cd /root/data1/frp

在 C 服务器上的目录结构如下:

1
2
3
4
5
6
.
├── /root/data1/frp/
│ ├── frpc
│ ├── frpc.toml
│ └── logs/
│ └── frpc.log

四、配置 FRP

1. 配置 frps(在 B 服务器)

/usr/local/frp 目录下创建或编辑 frps.toml 配置文件:

1
bindPort = 7000

2. 配置 frpc(在 C 服务器)

/usr/local/frp 目录下创建或编辑 frpc.toml 配置文件:

1
2
3
4
5
6
7
8
9
serverAddr = "117.62.206.56"  # 此处换成自己中转服务器B的IP即可
serverPort = 7000

[[proxies]]
name = "test-tcp"
type = "tcp"
localIP = "10.16.63.150"
localPort = 12359
remotePort = 6000

五、设置 FRP 为系统服务

1. 在 B 服务器(CentOS)上设置 frps 为系统服务

创建 frps.service 文件在 /etc/systemd/system/ 目录下:

1
sudo vim /etc/systemd/system/frps.service

添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=FRP Server Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/frp/frps -c /usr/local/frp/frps.toml
Restart=on-failure
User=root
# 如果不想以 root 用户运行,可以创建一个专用用户,如 frp

[Install]
WantedBy=multi-user.target

然后,重新加载 systemd 并启动服务:

1
2
3
4
5
6
7
8
9
10
11
# 重新加载 systemd
sudo systemctl daemon-reload

# 启动 frps 服务
sudo systemctl start frps

# 设置开机自启
sudo systemctl enable frps

# 检查服务状态
sudo systemctl status frps

2. 在 C 服务器(Ubuntu)上设置 frpc 为系统服务

创建 start_frpc.sh 文件在 /root/data1/frp 目录下:

1
2
touch start_frpc.sh
chmod +x start_frpc.sh

start_frpc.sh文件的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/bin/bash

# 配置文件路径
FRPC_CONFIG="/root/data1/frp/frpc.toml"

# frpc 二进制文件路径
FRPC_BINARY="/root/data1/frp/frpc"

# 检查 frpc 是否已经在运行
FRPC_PROCESS=$(ps aux | grep "[f]rpc -c $FRPC_CONFIG")

case $1 in
start)
if [ -n "$FRPC_PROCESS" ]; then
echo "frpc is already running."
else
echo "Starting frpc..."
$FRPC_BINARY -c $FRPC_CONFIG &
echo "frpc started with PID: $!"
fi
;;
stop)
FRPC_PID=$(ps aux | grep "[f]rpc -c $FRPC_CONFIG" | awk '{print $2}')
if [ -n "$FRPC_PID" ]; then
echo "Stopping frpc (PID: $FRPC_PID)..."
kill $FRPC_PID
echo "frpc stopped."
else
echo "frpc is not running."
fi
;;
restart)
echo "Restarting frpc..."
$0 stop
sleep 2
$0 start
;;
status)
FRPC_PID=$(ps aux | grep "[f]rpc -c $FRPC_CONFIG" | awk '{print $2}')
if [ -n "$FRPC_PID" ]; then
echo "frpc is running (PID: $FRPC_PID)"
else
echo "frpc is not running."
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac

运行脚本文件:

1
2
3
4
./start_frpc.sh start
./start_frpc.sh stop
./start_frpc.sh restart
./start_frpc.sh status