FRP 内网穿透

视频说明:https://www.bilibili.com/video/BV1vT411w7YP

内网穿透

本地电脑上起了服务,其他人是访问不到的,借助服务器的公网IP,服务端帮助转发消息,其他人才能访问到本地电脑上的服务。

具体可以用来做什么

1、本地计算机上启动 web 服务,通过端口映射,别人通过公网和端口就能访问。

2、Windows 远程桌面连接,比如,从住的地方连接公司的电脑。(有安全风险,需要和公司报备)

3、SSH 远程连接到开发板内的 linux 系统。

向日葵的免费账户的带宽有限

我有1台腾讯的轻量云服务器

frp 文件下载:https://www.123pan.com/s/Lwn8Vv-ul2x.html
提取码:FAIM

winsw 文件下载:https://www.123pan.com/s/Lwn8Vv-Sl2x.html
提取码:bYeZ

frp 中文文档
https://gofrp.org/zh-cn/docs/
https://github.com/fatedier/frp/blob/dev/README_zh.md

服务端

服务端下载 frps

下载frp软件:https://github.com/fatedier/frp

服务端下载安装

比如

/opt/目录下

cd /opt/

下载64位0.44版本的,arm服务器要选arm版本,现在常见服务器都是amd64架构的,也就是x86的64位指令集架构。

wget https://github.com/fatedier/frp/releases/download/v0.44.0/frp_0.44.0_linux_amd64.tar.gz

服务端配置 frps

解压

tar -zxvf frp_0.44.0_linux_amd64.tar.gz

重命名,为了后面配置路径简单

mv frp_0.44.0_linux_amd64 frp

配置文件,服务端 frps 的 s 即 server,frpc 的 c 即 client。

vi  frps.ini

frps.ini 文件内容,默认即可

[common]
bind_port = 7000

也可以设置token,相当于设置了一个密码,例如

[common]
bind_port = 7000
token = abc123

服务端防火墙,放行端口7000、7001、6000、8080等需要的端口

启动服务端

正常启动

./frps -c ./frps.ini

服务端设置程序开机启动

在frps.service里写入内容,有时候会提示system目录不存在,那就先建目录

mkdir /usr/lib/systemd/system/
vi /usr/lib/systemd/system/frps.service

frps.service 内容

[Unit]
Description=frps service
After=network.target

[Service]
Type=simple
ExecStart=/opt/frp/frps -c /opt/frp/frps.ini

[Install]
WantedBy=multi-user.target

配置生效,启动,设置开机启动

systemctl daemon-reload
systemctl start frps
systemctl enable frps

查看状态

systemctl status frps

客户端

windows 客户端配置 frpc

Windows10 当然是amd64位架构的 frp_0.44.0_windows_amd64.zip

比如想在家远程公司电脑,在公司电脑上安装设置 frpc。

我喜欢在 C 盘下建一个sw的文件夹来存自己安装的程序,sw 即 software 的意思。

解压到 C:\sw\目录下,也就是现在 frp 目录是 C:\sw\frp(需要把这个文件夹添加到病毒排除项

修改 frp 客户端的配置文件frpc.ini

[common]
server_addr = 127.0.0.1
server_port = 7000

[rdp7001]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 7001

修改第一句 server_addr127.0.0.1为云服务器的 IP 地址

如果服务端配置了 token,那客户端也要配置。

windows一般也不用ssh,删除内容,增加远程桌面的协议 rdp 的设置

即现在是

[common]
server_addr = 云服务器地址
server_port = 7000
token = abc123

[rdp7001]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 7001

🟢 “server_addr”是服务端 IP 地址,填入即可,

🟢 “server_port”为服务器端口,即 bind_port 的值,

🟢 “token”是你在服务器上设置的连接口令。

🟢 [rdp]:这个 rdp 是给服务起的名字,名字当然随意设置,就是服务名字不能重复(从服务端看来,一个端口一个名字),如果有多个远程桌面需要端口转发,可以起:[rdp7001]、[rdp7002]

这里用到了 2 个自定义规则,一个是 rdp,一个是 smb:

🍑RDP,即 Remote Desktop 远程桌面,Windows 的 RDP 默认端口是 3389,协议为 TCP,本条规则可以实现远程桌面连接。

🍑SMB,即 Windows 文件共享所使用的协议,默认端口号 445,协议 TCP,本条规则可实现远程文件访问。

在 window10 上启动 frpc 程序

注意:Microsoft Defender 会给 frpc.exe 软件报病毒,会给移除,需要还原。

打开 cmd 程序,比如 win + R,输入 cmd,我一般按 win 键,输入 cmd,右键“以管理员身份运行”

切换到 frpc 的目录

cd C:\sw\frp
frpc.exe -c frpc.ini

就启动了

win10 启动远程桌面:【设置】,【系统】,【远程桌面】,启动远程桌面

Windows 远程连接:

按 win 键,输入“远程桌面连接”

计算机:服务端公网IP地址:7001

用户名和密码,是 window 电脑的用户名和密码。

当然也可以把本地 web 服务通过云服务器访问

增加 web 配置即可

[webxxx]
type = tcp
local_ip = 127.0.0.1
local_port = 本地端口
remote_port = 映射到的服务器端口

现在完整的配置如下

[common]
server_addr = 云服务器地址
server_port = 7000
token = abc123

[rdp7001]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 7001

[web9090]
type = tcp
local_ip = 127.0.0.1
local_port = 8080
remote_port = 9090

windows 客户端设置程序开机启动

需要一个软件 winsw

https://github.com/winsw/winsw

Windows 服务包装器,WinSW 将任何应用程序作为一个 Windows 服务进行包装和管理。

WinSW 3可以在安装了 .NET Framework 4.6.1 或更高版本的Windows平台上运行。

对于没有 .NET 框架的系统,该项目提供基于 .NET 核心的本地64位和32位可执行文件。

因为 win11 自带 .Net 环境

所以下载 WinSW.NET461.exe

配置文件

WinSW.NET461.xml

<service>
  
  <!-- 服务ID,整个 window 系统中唯一-->
  <id>frpc</id>
  <!-- 服务的显示名字 -->
  <name>frpc</name>
  <!-- 服务描述 -->
  <description>FRP 客户端,用来实现内网穿透</description>
  
  <!-- Path to the executable, which should be started -->
  <!-- 想要启动的可执行程序的路径 -->
  <executable>C:\SW\frp\frpc.exe</executable>
  <!-- 携带的参数 -->
  <arguments>-c C:\SW\frp\frpc.ini</arguments>
  
  <!-- 第一次启动失败 60秒重启 -->
  <onfailure action="restart" delay="60 sec"/>
  <!-- 第二次启动失败 120秒后重启 -->
  <onfailure action="restart" delay="120 sec"/>
  <!-- 日志模式 -->
  <logmode>append</logmode>
  <!-- 指定日志文件目录(相对于WinSW.exe配置的路径) -->
  <logpath>C:\SW\frp\log</logpath>

</service>

将 exe 和 xml 文件放到同一个文件夹下

命令行运行,使用 WinSW-x64.exe

// 安装服务
WinSW-x64.exe install

// 卸载服务
WinSW-x64.exe uninstall

// 启动服务
WinSW-x64.exe start

// 停止服务
WinSW-x64.exe stop

// 重启服务
WinSW-x64.exe restart

// 查看状态
WinSW-x64.exe status

命令行运行,使用 WinSW.NET461.exe

// 安装服务
WinSW.NET461.exe install

// 卸载服务
WinSW.NET461.exe uninstall

// 启动服务
WinSW.NET461.exe start

// 停止服务
WinSW.NET461.exe stop

// 重启服务
WinSW.NET461.exe restart

// 查看状态
WinSW.NET461.exe status

按 win 键,输入“服务”,找到 frpc 服务,第一次要手动启动

启动失败,就去看看 frpc 的配置文件 frpc.ini 内容是否不匹配。

linux 客户端配置 frpc

注意版本

开发板一般是arm架构系统32/64位的linux系统,frp_0.44.0_linux_arm.tar.gzfrp_0.44.0_linux_arm64.tar.gz

比如

/opt/目录下

cd /opt/

下载

wget https://github.com/fatedier/frp/releases/download/v0.44.0/frp_0.44.0_linux_arm.tar.gz

解压

tar -zxvf frp_0.44.0_linux_arm.tar.gz

重命名,为了后面配置路径简单

mv frp_0.44.0_linux_arm frp

配置文件

修改配置文件 frpc.ini

[common]
server_addr = 服务端公网IP地址
server_port = 7000
token = abc123

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

运行客户端程序

./frpc -c ./frpc.ini

如果还有开发板客户端要连接,也就是服务端要用不同的端口帮忙转发,一个客户端用一个端口,比如新增加的开发板用 6001 端口,注意段端放开 6001 端口。

linux 客户端设置程序开机启动

为 frpc 配置 systemd 的service文件,有时候会提示system目录不存在,那就先建目录

mkdir /usr/lib/systemd/system/
vi /usr/lib/systemd/system/frpc.service

frpc.service 文件内容

[Unit]
Description=frpc
Wants=network-online.target
After=network.target network-online.target
Requires=network-online.target

[Service]
ExecStart=/opt/frp/frpc -c /opt/frp/frpc.ini
ExecStop=/bin/kill $MAINPID
Restart=always
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target

解释一下上面文件内容

  • Wants:本单元启动了,它“想要”的单元也会被启动。但是这个单元若启动不成功,对本单元没有影响。
  • Requires: 这个单元启动了,那么它“需要”的单元也会被启动; 它“需要”的单元被停止了,它自己也活不了。但是请注意,这个设定并不能控制启动顺序,因为它“需要”的单元启动也需要时间,若它“需要”的单元启动还未完成,就开始启动本单元,则本单元也无法启动,所以不建议使用这个字段。
  • OnFailure:若本单元启动失败了,那么启动这个单元作为折衷。
  • Before/After:指定启动顺序。
Wants=network-online.target #其中network.target代表有网路,network-online.target代表一个连通着的网络。

ExecStart=/opt/frp/frpc -c /opt/frp/frpc.ini #是要运行的命令,文件要绝对地址。

Restart=always #总是重启
RestartSec=5 #自动重启当前服务间隔的秒数
StartLimitInterval=0 #无限次重启,默认是10秒内如果重启超过5次则不再重启,设置为0表示不限次数重启

使frpc服务生效

systemctl daemon-reload
systemctl enable frpc
systemctl start frpc

查看状态

systemctl status frpc

远程 SSH 连接开发板就是:

使用SSH工具登录

  • 用户名,密码:就是开发板上的用户名和密码
  • IP地址:公网IP
  • 端口:6000

frp配置http

type = tcp 的配置

服务端不修改

客户端增加

frpc.ini

[common]
server_addr = 49.235.114.132
server_port = 7000
token = abc123

[web]
type = tcp
local_ip = 127.0.0.1
local_port = 48080
remote_port = 8080

type = http 的配置

服务端配置

frps.ini

[common]
bind_port = 7000
token = abc123
vhost_http_port = 8080

客户端配置

frpc.ini

[common]
server_addr = 49.235.114.132
server_port = 7000
token = abc123

[web-48080]
type = http
local_port = 48080
local_ip = 127.0.0.1

服务起名字

服务名字是随便取的,要求是不能重复。

当然一般可以起有意义的简短名字加上端口号

比如 rdp7002、web-48080

比如 kepserver 上的 OPCUA server 服务,我只知道本地端口 49320 转到服务端端口 49320

类似这样

[OPCUA-49320]
type = http
local_port = 49320
local_ip = 127.0.0.1
remote_port = 49320

内网服务外网访问

比如在内网服务器 192.168.10.8 上部署了一个服务 hello,端口 8080

想要能从外网通过公网 IP 访问

可以在客户端

[hello-8080]
type = tcp
local_ip = 192.168.10.8
local_port = 8080
remote_port = 8080

hello 相当于服务端的服务名字,不能重复,懒得起名可以使用 UUID

访问地址:外网IP:8080

Docker 启动和 toml 格式

Docker 启动服务端实践

文件夹

/app/frps
├── docker
│   ├── Dockerfile
│   └── frp
│       ├── frps
│       └── frps.toml
├── frps.toml
└── startup.sh

frps.toml

bindPort = 7000   #服务端监听端口
auth.method = "token"   #服务端连接身份认证,默认token
auth.token = "mytoken"   #服务端token密码

Dockerfile

FROM alpine:3.8

ENV VERSION 0.59.0
ENV TZ=Asia/Shanghai
ENV APP_DIR=/frp
WORKDIR $APP_DIR

COPY ./frp $APP_DIR

RUN apk add --no-cache tzdata \
    && ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone

VOLUME /frp

CMD /frp/frps -c /frp/frps.toml

构建

cd /app/frps/docker
docker build -t frps:1.0 .

启动命令 startup

docker run -d \
    --name frps \
    --restart always \
    -v /app/frps/frps.toml:/frp/frps.toml \
    --log-opt max-size=1m \
    --log-opt max-file=3 \
    frps:1.0

重启

docker restart frps

查看日志

docker logs -f frps

Docker 启动客户端实践

内网,所以先下载了对应文件,然后使用 Dockerfile 制作镜像。
优点:不使用 systemd 管理了,修改了 frpc.toml 后,docker 重启服务即可。

文件夹,只保留 frpc 和 frpc.toml 文件

/app/frpc/docker/frp
|-- frpc
 -- frpc.toml

Dockerfile

FROM alpine:3.8

ENV VERSION 0.59.0
ENV TZ=Asia/Shanghai
ENV APP_DIR=/frp
WORKDIR $APP_DIR

COPY ./frp $APP_DIR

RUN apk add --no-cache tzdata \
    && ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone

VOLUME /frp

CMD /frp/frpc -c /frp/frpc.toml

构建

cd /app/frpc/docker
docker build -t frpc:1.0 .

启动

docker run -d \
    --name frpc \
    --restart always \
    -v /app/frpc/frpc.toml:/frp/frpc.toml \
    --log-opt max-size=1m \
    --log-opt max-file=3 \
    frpc:1.0

重启

docker restart frpc
docker logs -f frpc

toml 格式配置文件

服务端 frpc.toml

serverPort = 7000
auth.method = "token"
auth.token = "服务端设置的token值"

客户端 frpc.toml

serverAddr = "公网IP"
serverPort = 7000
auth.method = "token"
auth.token = "服务端设置的token值"

[[proxies]]
name = "redis-36379"
type = "tcp"
localIP = "192.168.10.8"
localPort = 36379
remotePort = 36379

[[proxies]]
name = "redis-26379"
type = "tcp"
localIP = "192.168.10.8"
localPort = 26379
remotePort = 26379

上面配置是将内网的一个 Redis 服务映射出去,测试用的。

客户端和服务端版本,最好一致,不一致也能用。

posted @ 2022-08-21 21:31  ioufev  阅读(1142)  评论(0编辑  收藏  举报