使用国内服务器基于frp的内网穿透
发表于 2026-06-07 共 1504 字
分类于 记录

使用国内服务器基于frp的内网穿透

前言

校内某课程和华为云平台有合作,送了100元代金券,眼看就快要过期了,不用也是浪费,于是就下单了最便宜的Flexus L服务器,能用三个月。

华为云服务器订单

买的就是北京区域的服务器,虽然带宽不大,但是延迟肯定低啊,想到正好可以拿来做香橙派的内网穿透,这样哪怕在校外也可以畅快地连到内网了。

frp下载

首先到 https://github.com/fatedier/frp/releases 下载最新版的release。

压缩包解压后会发现里面有frps和frpc两个可执行文件,分别是服务端和客户端,还有对应的toml配置文件。

frp服务端部署

首先是服务端,也就是在云服务器,写服务端的配置frps.toml,我的需求是HTTP服务的内网穿透,示例如下:

bindPort = 7000
vhostHTTPPort = 8080
auth.token = "abc"

绑定端口7000用于和客户端通信,而8080端口是开放HTTP服务的端口,这两个端口都需要开放(华为云的安全组需要设置入站允许规则),这里的token是为了身份认证,保证让只有token正确的客户端才能连上。

配置写好后,使用以下命令启动服务端:./frps -c ./frps.toml

frp客户端部署

然后是客户端,对我来说就是需要被内网穿透的香橙派,写frpc.toml,示例如下:

serverAddr = "x.x.x.x"
serverPort = 7000
auth.token = "abc"

[[proxies]]
name = "web"
type = "http"
localPort = 6666
customDomains = ["www.yourdomain.com"]

这里的serverAddr和serverPort就是刚才云服务器的IP地址和设置的绑定端口,localPort是客户端的HTTP服务端口。token设置需要和服务端保持一致。

然后再启动客户端:./frpc -c ./frpc.toml

frp客户端运行成功

这样成功连接后,客户端这边的HTTP服务就可以在服务端的vhostHTTPPort端口被公网访问了。也就是说,访问 http://www.yourdomain.com:8080 即可访问到内网机器上的6666端口服务。

值得注意的是,这是我第一次使用国内的云服务器,刚开始我真的随手拿个域名配置了A记录,结果一访问发现:

域名未备案阻断

这是因为,虽然云服务器本身是实名的,但是只要使用中国大陆节点的服务器对外提供服务,域名就必须进行ICP备案,而我并没有备案的域名。

后来我发现其实可以不要域名,只需要把customDomains参数改成服务器IP,然后直接用IP访问就可以了:

customDomains = ["x.x.x.x"]

注册成系统服务

跑通之后,可以使用systemd把服务端和服务端注册成一个服务。

对于服务端,编辑/etc/systemd/system/frps.service文件,写入:

[Unit]
# 服务名称,可自定义
Description = frp server
After = network.target syslog.target
Wants = network.target

[Service]
Type = simple
# 启动frps的命令,需修改frps的路径
ExecStart = /path/to/frps -c /path/to/frps.toml

[Install]
WantedBy = multi-user.target

然后可以用systemctl管理:

# 启动frps
sudo systemctl start frps
# 停止frps
sudo systemctl stop frps
# 重启frps
sudo systemctl restart frps
# 查看frps状态
sudo systemctl status frps
# 设置frps开机自启
sudo systemctl enable frps

客户端frpc也是类似,写入一个/etc/systemd/system/frpc.service文件就行。

配置SSL

目前虽然是通了,但是没有HTTPS的话总感觉是不太安全。由于没用域名而是直接IP访问,需要申请一个纯IP的SSL证书。

考虑到就是给自己用的,为了方便起见,我直接就使用自签证书了,CA证书的创建方法可以看这一篇,然后用CA证书分发一个IP SSL证书,步骤如下:

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Shanghai/L=Shanghai/O=bjut/OU=IT/CN=x.x.x.x"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile ip_cert.ext

以上的x.x.x.x应替换为服务器的IP地址。完成后就会得到有效期十年(3650天)的证书server.crt和私钥server.key。

之后可以套一层nginx代理来实现HTTPS,比如说配置一个/etc/nginx/conf.d/http.conf

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name x.x.x.x;

    ssl_certificate /path/to/server.crt; # 证书路径
    ssl_certificate_key /path/to/server.key; # 私钥路径

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    location / {
        proxy_pass http://127.0.0.1:8080;

        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

由于是自签证书,以上操作建立在CA证书被系统信任的前提上,或者是软件忽略了证书校验,比如说部署xray的XHTTP协议就可以将TLSObject的pinnedPeerCertSha256设置为证书的SHA-256指纹来强制信任。

当然了,如果不用考虑备案问题,自然是直接申请域名证书更省事。

TCP/UDP类型的内网穿透

前面所述是HTTP协议的内网穿透,如果需要做其他协议的内网穿透,参考官方示例应该在客户端做如下的proxies配置(remotePort是服务端监听对应的端口):

TCP(如SSH服务):

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

UDP(如DNS服务):

[[proxies]]
name = "dns"
type = "udp"
localIP = "127.0.0.1"
localPort = 53
remotePort = 6000
筛选文章
类别选择 (分类/标签)
全屏 关闭