余白

frp 内网穿透实践

简介

frp(Fast Reverse Proxy)是一个高性能的反向代理工具,用于内网穿透,可以将内网服务暴露到公网。

应用场景

  • 访问家庭 NAS
  • 远程访问公司内网服务器
  • 开发调试 Webhook
  • 建立远程桌面连接

工作原理

[公网服务器]
    |
    | ← frps (服务端,监听公网端口)
    |
[路由器/防火墙]
    |
    | ← frpc (客户端,连接服务端)
    |
[内网机器] ← 你的服务运行在这里

安装

下载

# GitHub 下载(选择对应架构)
# https://github.com/fatedier/frp/releases

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

# ARM64
wget https://github.com/fatedier/frp/releases/download/v0.58.1/frp_0.58.1_linux_arm64.tar.gz

# 解压
tar -xzf frp_*.tar.gz
cd frp_*/

目录结构

frp/
├── frps          # 服务端程序
├── frpc          # 客户端程序
├── frps.ini      # 服务端配置
├── frpc.ini      # 客户端配置
└── systemd/      # systemd 服务文件

服务端配置(公网服务器)

基本配置

编辑 frps.ini:

[common]
# 绑定端口
bind_port = 7000

# 认证令牌(需与客户端一致)
token = your_token_here

# Dashboard(可选,Web 管理界面)
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = admin_password

# 日志
log_file = ./frps.log
log_level = info
log_max_days = 3

启动服务端

# 直接运行
./frps -c frps.ini

# 后台运行
nohup ./frps -c frps.ini &

Systemd 服务(推荐)

编辑 /etc/systemd/system/frps.service:

[Unit]
Description=frp server
After=network.target

[Service]
Type=simple
ExecStart=/opt/frp/frps -c /opt/frp/frps.ini
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable frps
sudo systemctl start frps

客户端配置(内网机器)

基本配置

编辑 frpc.ini:

[common]
# 服务端地址
server_addr = your_server_ip
server_port = 7000

# 认证令牌(需与服务端一致)
token = your_token_here

# 日志
log_file = ./frpc.log
log_level = info

常用穿透示例

1. SSH 内网穿透

# 访问内网服务器的 SSH
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

使用:ssh -p 6000 user@server_ip

2. Web 服务穿透

# HTTP 服务
[web]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains = yourdomain.com

# HTTPS 服务
[web_https]
type = https
local_ip = 127.0.0.1
local_port = 443
custom_domains = yourdomain.com

3. TCP 端口穿透

# MySQL 数据库
[mysql]
type = tcp
local_ip = 127.0.0.1
local_port = 3306
remote_port = 13306

# Redis
[redis]
type = tcp
local_ip = 127.0.0.1
local_port = 6379
remote_port = 16379

4. 本地文件服务

# 文件服务
[samba]
type = tcp
local_ip = 127.0.0.1
local_port = 445
remote_port = 14445

5. RDP 远程桌面(Windows)

[rdp]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 13389

启动客户端

# 直接运行
./frpc -c frpc.ini

# 后台运行
nohup ./frpc -c frpc.ini &

Systemd 服务

编辑 /etc/systemd/system/frpc.service:

[Unit]
Description=frp client
After=network.target

[Service]
Type=simple
ExecStart=/opt/frp/frpc -c /opt/frp/frpc.ini
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable frpc
sudo systemctl start frpc

进阶配置

负载均衡

[common]
server_addr = server1
server_port = 7000

# 多个服务端
proxy_groups
name = "lb"
type = "load_balance"
servers = 
    - server_addr = server1
      server_port = 7000
    - server_addr = server2
      server_port = 7000

健康检查

[web]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains = yourdomain.com

# 健康检查
health_check_type = http
health_check_url = /
health_check_interval_s = 10
health_check_max_failed = 3
health_check_removable = true

TCP 多路复用

[common]
# 服务端
tcp_mux = true
tcp_mux_keepalive_interval = 60

加密与压缩

[common]
# 客户端
transport.use_encryption = true
transport.use_compression = true

限流

[web]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains = yourdomain.com

# 带宽限制(单位:KB/s)
bandwidth_limit = 1024
bandwidth_limit_mode = client

子域名泛解析

服务端配置:

[common]
subdomain_host = yourdomain.com

# 需要 DNS 解析
# *.yourdomain.com -> server_ip

客户端配置:

[web]
type = http
local_ip = 127.0.0.1
local_port = 80
subdomain = blog
# 访问地址:blog.yourdomain.com

HTTPS 穿透

方法一:本地 HTTPS

[web_https]
type = https
local_ip = 127.0.0.1
local_port = 443
custom_domains = yourdomain.com

# 不验证本地证书
plugin = https2http
plugin_local_addr = 127.0.0.1:80

方法二:frp 处理证书

[web_https]
type = https
local_ip = 127.0.0.1
local_port = 443
custom_domains = yourdomain.com

# frp 自动从 Let's Encrypt 获取证书

完整示例

服务端 (frps.ini)

[common]
bind_port = 7000
token = my_secret_token
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = admin123

# HTTP/HTTPS
vhost_http_port = 8080
vhost_https_port = 8443

# 日志
log_file = /var/log/frps.log
log_level = info
log_max_days = 7

# TCP 多路复用
tcp_mux = true

客户端 (frpc.ini)

[common]
server_addr = your_server_ip
server_port = 7000
token = my_secret_token

# 加密压缩
transport.use_encryption = true
transport.use_compression = true

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

# Web
[web]
type = http
local_ip = 127.0.0.1
local_port = 3000
custom_domains = yourdomain.com

# MySQL
[mysql]
type = tcp
local_ip = 127.0.0.1
local_port = 3306
remote_port = 13306

常用命令

# 服务端
./frps -c frps.ini           # 启动
./frps verify -c frps.ini    # 验证配置

# 客户端
./frpc -c frpc.ini           # 启动
./frpc reload -c frpc.ini    # 重载配置
./frpc stop                  # 停止

防火墙配置

服务端(开放端口)

# Ubuntu/Debian
sudo ufw allow 7000/tcp  # frp 控制端口
sudo ufw allow 6000/tcp  # SSH 穿透
sudo ufw allow 8080/tcp  # HTTP 穿透
sudo ufw allow 7500/tcp  # Dashboard

# CentOS/RHEL
sudo firewall-cmd --permanent --add-port=7000/tcp
sudo firewall-cmd --permanent --add-port=6000/tcp
sudo firewall-cmd --reload

客户端

通常不需要开放防火墙,只要能访问服务端即可。


安全建议

  1. 使用 token 认证:服务端和客户端 token 必须一致
  2. 限制端口暴露:只暴露必要的端口
  3. 启用加密:transport.use_encryption = true
  4. 启用压缩:transport.use_compression = true
  5. 定期更新:使用最新版 frp 修复安全漏洞
  6. 不推荐暴露 SSH:使用密钥登录 + 更换默认端口

常见问题

1. 连接失败

# 检查服务端是否运行
sudo systemctl status frps

# 检查端口是否开放
sudo netstat -tlnp | grep 7000

# 检查防火墙
sudo ufw status

2. 日志位置

# 服务端
tail -f /var/log/frps.log

# 客户端
tail -f ./frpc.log

3. 更新配置后重载

# 服务端
sudo systemctl restart frps

# 客户端
./frpc reload -c frpc.ini

参考链接