frp:让你家里的电脑也可以被公网访问

一、缘起

想给小落同学加一些功能,但是小落同学买的是99元/年的阿里云ECS,配置很烂,基本上只能跑跑网页应用(还动不动内存不足,CPU超标)。

而我家里的电脑虽然是十年前的老电脑,至少有16G内存,比这个ECS强多了,因此想在这台电脑上部署一些服务,然后让这些服务通过ECS穿透到家里这台私网下的电脑,一方面让这台电脑可以继续发光发热,另一方面也可以再给小落同学加点功能特性。

二、缘倾FRP

晚上一个人在家没事,就去找了一下私网穿透的解决方案,Google出来一大堆,经筛选拟选用FRP来实现此需求。

FRP 是一个专注于内网穿透的高性能反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议,可以将内网服务通过具有公网 IP 节点的中转暴露到公网。

FRP 项目地址:https://github.com/fatedier/frp

What is frp?
frp is a fast reverse proxy that allows you to expose a local server located behind a NAT or firewall to the Internet. It currently supports TCP and UDP, as well as HTTP and HTTPS protocols, enabling requests to be forwarded to internal services via domain name.
frp also offers a P2P connect mode.

三、一些准备工作

小落同学所在的ECS安装的是Linux操作系统,而家里的电脑安装的则是Windows操作系统,因此需要将FRP服务端安装在Linux上,而FRP客户端则安装在Windows上。

1.配置ECS安全组

登录阿里云控制台,找到你的云服务器 ECS,并在该ECS的安全组里添加你需要放开的端口,暂定需要的端口区间为9000~9020。

2.配置ECS上的防火墙

需有公网 IP(阿里云ECS具备),开放所需端口。
拟使用:

  • 测试用的https端口:9443
  • 测试用的http端口区间:9000~9020。

如果你用ufw

sudo ufw allow 9443/tcp
sudo ufw allow 9000:9020/tcp
sudo ufw reload

如果你用firewalld

sudo firewall-cmd --zone=public --add-port=9443/tcp --permanent
sudo firewall-cmd --zone=public --add-port=9000-9020/tcp --permanent
sudo firewall-cmd --reload

3.下载FRP 程序

GitHub Releases 下载对应版本:

  • 服务端(Linux):选择当前最新版本

SSH登陆上阿里云ECS,开始下载、安装、配置。

mkdir -p /opt/frp
cd /opt/frp
# 下载最新版本(以v0.51.3为例,替换为实际版本)
wget https://github.com/fatedier/frp/releases/download/v0.65.0/frp_0.65.0_linux_amd64.tar.gz

# 解压
tar -zxvf frp_0.65.0_linux_amd64.tar.gz
cd frp_0.65.0_linux_amd64
  • 客户端(Windows):选择当前最新版本

你可以直接在浏览器上下载,浏览器上输入下面这个地址即可。
也可以命令行里用wget来下载。

wget https://github.com/fatedier/frp/releases/download/v0.65.0/frp_0.65.0_windows_amd64.zip

注:如果你的windows没安装wget的话,可以到这里下载 https://eternallybored.org/misc/wget/

将下载的 Windows 版本压缩包解压到任意目录(如e:\tools\utility\frp),目录中包含frpc.exe(客户端程序)和frpc.ini(配置文件)。

四、【成功】测试http配置

1.配置http

1)服务端配置

  • 编辑服务端配置文件frps.toml

修改frps.toml如下:

# 绑定监听地址(默认 `0.0.0.0` 代表监听所有 IP)
bindAddr = "0.0.0.0"

#  服务器监听端口(客户端需要通过该端口连接 FRP 服务器)
bindPort = 9000

# HTTP 端口(用于内网 HTTP 代理穿透)
vhostHTTPPort = 9001

# HTTPS 端口(用于内网 HTTPS 代理穿透)
# vhostHTTPSPort = 9443

# 子域名支持
# 可以通过 `subDomainHost` 解析动态子域名
# 例如:如果 `subDomainHost` 配置为 "example.com"
# 那么客户端可以使用 `test.example.com` 访问内网服务
subDomainHost = "oddmeta.net"  # 请替换为你的真实域名

# =============================================
# Web 控制台(Dashboard)配置
# =============================================
# 你可以通过 `http://你的公网IP:9200` 访问 FRP 管理面板
webServer.addr = "0.0.0.0"
webServer.port = 9020

# Web 控制台管理账号(可自定义)
webServer.user = "admin"
webServer.password = "xxxx"

# =============================================
# 身份验证(Authentication)配置
# =============================================
# 目前 FRP 支持 `token` 和 `oidc` 方式,我们选用token
# auth.method = "token"
# auth.token = "123-abc-123abc"   # 请自行修改,不要用我的

2)客户端配置

  • 编辑客户端配置文件frpc.toml

修改frpc.toml如下:

# 服务端地址(这里要填你有公网IP的服务器的IP或者是服务器的域名)
serverAddr = "47.116.14.194"
serverPort = 9000


# 认证方式
# auth.method = "token"
# auth.token = "123-abc-123abc"

[[proxies]]
name = "test_http"
type = "http"
localPort = 9001
subdomain = "oddtts"

2. 测试http模式

1)启动服务端

# 前台启动(测试用,关闭终端则停止)
./frps -c ./frps.toml

# 后台启动(推荐,使用nohup)
nohup ./frps -c ./frps.ini > frps.log 2>&1 &

2)验证服务端控制台

访问 http://47.116.14.194:9020 输入面板用户名密码,能看到界面即启动成功。

3)启动客户端

打开cmd或 PowerShell,切换到 FRP 目录:

cd e:\tools\utility\frp

启动客户端:

frpc.exe -c frpc.ini

若看到start proxy success说明连接成功。

4)测试http

在Windows命令行下执行

curl -v http://oddtts.oddmeta.net:9001

看返回的内容是否正确。

注:不要在浏览器里测试,因为浏览器测试可能会自动转到https,导致你只有看到一个502报错。

五、测试https配置

1.配置https模式

1)服务端配置

编辑Linux服务端上的配置文件frps.toml

# 绑定监听地址(默认 `0.0.0.0` 代表监听所有 IP)
bindAddr = "0.0.0.0"

#  服务器监听端口(客户端需要通过该端口连接 FRP 服务器)
bindPort = 9000

vhostHTTPPort = 9001
vhostHTTPSPort = 443

subDomainHost = "oddmeta.net"  # 请替换为你的真实域名

# =============================================
# Web 控制台(Dashboard)配置
# =============================================
# 你可以通过 `http://你的公网IP:9200` 访问 FRP 管理面板
webServer.addr = "0.0.0.0"
webServer.port = 9020
webServer.user = "admin"
webServer.password = "1234"

# =============================================
# 身份验证(Authentication)配置
# =============================================
# 目前 FRP 支持 `token` 和 `oidc` 方式,我们选用token
auth.method = "token"
auth.token = "oddmeta-net-FRP-20251014"   # 请自行修改,不要用我的

2)客户端配置

编辑Windows客户端上的配置文件frpc.toml

serverAddr = "47.116.14.194"
serverPort = 9000

##################################
# 连接协议
##################################
transport.protocol = "tcp"
auth.method = "token"
auth.token = "odd-meta-net-test-20251014"

##################################
# 服务1:oddtts
##################################
[[proxies]]
name = "oddtts"
type = "https"
localPort = 9001
subdomain = "oddtts"

[proxies.plugin]
type = "https2http"
localAddr = "127.0.0.1:9001"

# HTTPS certificate related configuration
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"

##################################
# 服务2:oddasr
##################################
[[proxies]]
name = "oddasr"
type = "https"
localPort = 9002
subdomain = "oddasr"

[proxies.plugin]
type = "https2http"
localAddr = "127.0.0.1:9002"

# HTTPS certificate related configuration
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"

3. 测试https模式

Linux上启动服务端:./frps -c frps-https.toml
Windows上启动客户端:frpc -c frpc-https.toml
浏览器访问两个服务:
https://oddtts.oddmeta.net:9443
https://oddasr.oddmeta.net:9443

至此,整个frp的配置,以及私网代理的功能都OK了!
但是存在一个问题是,由于Linux服务器上的443端口已经被使用了,所以frps上只能配一个非标准的https端口(9443),这让人看上去很不爽。所以我们需要再给它打一个补丁,把9443给去掉。

4. nginx反向代理补丁

在你的nginx目录下(如:/www/server/panel/vhost/nginx)手动创建一个配置,用于给frp做个反向代理。让服务可以外部访问的地址可以从 https://oddtts.oddmeta.net:9443 变成 https://oddtts.oddmeta.net

这个是实测OK的一个配置文件。

vi frp.oddmeta.conf

往这个配置文件里输入以下内容

server {
    listen 443 ssl;  # 监听 443 端口(HTTPS 默认端口)
    server_name oddtts.oddmeta.net;  # 仅处理该域名的流量(精准匹配,不影响其他域名)

    # 1. SSL 证书配置(复用 FRP 客户端证书,确保域名匹配)
    ssl_certificate              /www/server/panel/vhost/cert/oddmeta.com/fullchain.pem;
    ssl_certificate_key          /www/server/panel/vhost/cert/oddmeta.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;  # 支持的 SSL 协议(避免旧协议漏洞)
    ssl_prefer_server_ciphers on;  # 优先使用服务端密码套件

    # 2. 核心:将流量转发到 FRP 的 9443 端口
    location / {
        proxy_pass https://oddtts.oddmeta.net:9443;  # 转发目标:FRP 服务端的 9443 端口(本地地址,无需公网暴露)


        # 关键1:强制传递客户端访问的域名(oddtts.oddmeta.net),覆盖默认值
        proxy_set_header Host $host;
        # 关键2:禁用 Nginx 对 Host 头的重写(部分版本会自动添加端口,导致域名异常)
        proxy_set_header X-Forwarded-Host $host;
        # 关键3:传递真实客户端 IP 和协议(可选,但确保链路完整)
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 关键4:跳过 FRP 自签证书验证(必须保留,否则 SSL 握手失败)
        proxy_ssl_verify off;
        # 关键5:指定 SSL 协议版本,避免 FRP 不支持的旧协议
        proxy_ssl_protocols TLSv1.2 TLSv1.3;
        # 关键6:强制 Nginx 忽略 upstream 的域名验证(针对 FRP 虚拟主机机制)
        proxy_ssl_server_name on;

    }

    # 可选:配置访问日志(便于排查问题)
    access_log /www/wwwlogs/frp-access.log;
    error_log /www/wwwlogs/frp-error.log;
}

重新加载nginx

nginx -s reload

重新打开一个浏览器,输入 https://oddtts.oddmeta.net ,这样就可以用这个域名访问你内网电脑上的服务了。

六、结语

整个FRP的测试跑通了,咱日后就可以将 自己内网电脑上的一些服务 暴露到 公网,从而实现从任意网络环境访问到你位于内网的服务器了,这样原先许多因服务器配置差而无法加到小落同学的功能就可以重新考虑起来了,整个思路也开阔起来了。
如果你也跟我一样因为买不起高配的服务器,只能做一些低配硬件的应用的话,也严重向你推荐一下FRP。

而我自己又可以重新来思考一下可以为小落同学做点什么了,不过得慢慢来,因为最近实在有点忙。

Leave a comment

Your email address will not be published. Required fields are marked *