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
客户端
通常不需要开放防火墙,只要能访问服务端即可。
安全建议
- 使用 token 认证:服务端和客户端 token 必须一致
- 限制端口暴露:只暴露必要的端口
- 启用加密:
transport.use_encryption = true - 启用压缩:
transport.use_compression = true - 定期更新:使用最新版 frp 修复安全漏洞
- 不推荐暴露 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