内网穿透是把局域网中的服务安全、稳定地暴露到公网的一种实用技巧。本文以 FRP为例,带你从原理到实战逐步搭建可用的穿透通道,包含服务端与客户端配置、常见问题排查以及性能与安全的优化建议。

1. 环境信息

  • 内网服务器: 192.168.0.77

  • 公网服务器: 47.101.219.86

2. 公网服务器的配置

2.1 下载并安装FRP Server

# 下载最新版本
wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz

# 解压
tar xzf frp_0.52.3_linux_amd64.tar.gz
cd frp_0.52.3_linux_amd64

# 创建系统用户
useradd -r -s /bin/false frp

# 创建目录
mkdir -p /opt/frp
cp frps frpc /opt/frp/
chmod +x /opt/frp/frps /opt/frp/frpc

# 复制配置文件
cp frps.toml /opt/frp/frps.toml
chown -R frp:frp /opt/frp

2.2 frp 的 Server的配置文件内容

# Server绑定地址
bindAddr = "0.0.0.0"
bindPort = 7000

# 仪表板配置
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "your_secure_password"  ## 最好是强密码

# 日志配置
log.to = "/var/log/frp/frps.log"
log.level = "info"
log.maxDays = 3

# Token认证(内网客户端必须匹配)
auth.token = "your_frp_secure_token_here"  ## token 可以随机生成
 
# 连接池配置
transport.maxPoolCount = 5

# TLS配置(可选但推荐)
# transport.tls.certFile = "/opt/frp/certs/server.crt"
# transport.tls.keyFile = "/opt/frp/certs/server.key"

2.3 systemd的服务配置

[Unit]
Description=FRP Server
After=network.target

[Service]
Type=simple
User=frp
WorkingDirectory=/opt/frp
ExecStart=/opt/frp/frps -c /opt/frp/frps.toml  
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

2.4 启动服务

# 创建日志目录
mkdir -p /var/log/frp
chown frp:frp /var/log/frp

# 启用并启动服务
systemctl daemon-reload
systemctl enable frps
systemctl start frps

# 查看状态
systemctl status frps

2.5 Nginx

upstream frp_server {
    server localhost:7000;
}

upstream frp_dashboard {
    server localhost:7500;
}

# HTTP重定向到HTTPS
server {
    listen 80;
    server_name xingkong.moldfun.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS服务
server {
    listen 443 ssl http2;
    server_name xingkong.moldfun.com;

    ssl_certificate /opt/frp/certs/your_domain.crt;
    ssl_certificate_key /opt/frp/certs/your_domain.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # 仪表板
    location / {
        proxy_pass http://frp_dashboard;
        proxy_set_header Host $host;
        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;
    }
}

3. 内网服务器的配置

3.1 frp 的客户端配置

# 同样下载并解压
wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz
tar xzf frp_0.52.3_linux_amd64.tar.gz

# 安装到系统目录
mkdir -p /opt/frpc
cp frp_0.52.3_linux_amd64/frpc /opt/frpc/
chmod +x /opt/frpc/frpc

# 创建用户
useradd -r -s /bin/false frpc
chown -R frpc:frpc /opt/frpc

3.2 frp 的配置文件

[root@kingdee /data/frpc]# cat frpc.toml 
serverAddr = "47.101.219.86"  ## 公网IP
serverPort = 7000
auth.token = "your_frp_secure_token_here"  ## token 必须要和服务端一直

# 日志配置
log.to = "/var/log/frp/frpc.log"
log.level = "info"
log.maxDays = 3

# 登录失败重试
loginFailExit = false
start = []

# ====== 穿透规则示例 ======

# 规则1: 穿透web (内网web端口)
[[proxies]]
name = "web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 9999 
remotePort = 8023

3.3 Systemd服务配置

[Unit]
Description=FRP Client
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=frpc
WorkingDirectory=/opt/frpc
ExecStart=/opt/frpc/frpc -c /opt/frpc/frpc.toml
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

3.4 启动客户端

mkdir -p /var/log/frp
chown frpc:frpc /var/log/frp

systemctl daemon-reload
systemctl enable frpc
systemctl start frpc

systemctl status frpc
journalctl -u frpc -f
## 参数的意思
[[proxies]]           # 开始定义一个代理规则
name = "web"          # 这个规则的名字(日志里会显示,无实际功能)
type = "tcp"          # 穿透类型:TCP(纯端口转发)
localIP = "127.0.0.1" # 内网服务的IP地址
localPort = 8023      # 内网服务运行的端口号
remotePort = 8023     # 公网服务器上暴露的端口号
```

**用个例子理解**:

你内网有一个服务跑在 `192.168.0.77:8023`(或localhost:8023)

配置这段规则后,流量走向是:
```
外部用户
    ↓
公网服务器 47.101.219.86:8023 (remotePort)
    ↓ [FRP隧道]
内网服务器 127.0.0.1:8023 (
:localPort)