内网穿透

5次阅读
没有评论

工具 核心特点 适用场景 技术门槛
frp 轻量、高性能,支持 TCP/UDP/HTTP/HTTPS,支持自定义域名、加密传输 开发测试、内网服务暴露 中等
nps 功能丰富,支持集群、用户管理、流量统计,适合企业 / 多设备场景 多设备穿透、团队共享 中等
ngrok2(衍生版) 基于 ngrok 改进,支持自定义服务器,适合需要 HTTPS 的场景 本地 HTTPS 服务测试、小程序开发 中等

FRP

不建议使用容器,使用本机端口号映射容器端口,就不会有端口问题

安装

// 获取资源
wget https://github.com/fatedier/frp/releases/download/v0.58.1/frp_0.58.1_linux_amd64.tar.gz
# 资源解压
tar -zxvf frp_0.58.1_linux_amd64.tar.gz
cd frp_0.58.1_linux_amd64

确保服务端和客户端的 版本一致

配置

配置服务端 frps:/root/frp_0.58.1_linux_amd64/frps.toml

# 创建文件
nano frps.toml
# 编辑配置
bindPort = 7000
auth.token = "you_stronge_token"
# 设置二级域名的主域
subdomainHost = "xxxxxxx.com"
vhostHTTPPort = 8080   # 用于 HTTP 协议的端口(可选,但建议保留)vhostHTTPSPort = 8443  # 用于 HTTPS 协议的端口

# 可选:Web 仪表板配置
webServer.addr = "0.0.0.0"
webServer.port = 7500   # 用来在启动服务后登录 IP 查看 "xxx:xxx:xxx:xxx:7500"
webServer.user = "admin"
webServer.password = "admin"

客户端 frpc:/home/Frp/frp_0.58.1_linux_amd64/frpc.toml

# frpc.toml
serverAddr = "xxx.xxx.xxx.xxx" # 公网 ip
serverPort = 7000
auth.token = "you_stronge_token" # 必须与服务端一致

# 配置 next.huixiangwuyou.com 映射到本地的 3000 端口
[[proxies]]
name = "next-app"
type = "https"
localPort = 5678   # 代理容器 3000
subdomain = "next" # 访问 next.huixiangwuyou.com

# 配置 fast.huixiangwuyou.com 映射到本地的 8000 端口
[[proxies]]
name = "fast-api"
type = "https"
localPort = 8123
subdomain = "fast" # 访问 fast.huixiangwuyou.com


# 你可以继续按照此格式添加其他子域名服务...
# 例如,为 dev.huixiangwuyou.com 添加配置
[[proxies]]
name = "market"
type = "https"
localPort = 443
# 若是服务端开启了二级域名功能 customDomains 不能使用,只能用 subdomain 
customDomains = ["market.huixiangwuyou.com"]

建议直接使用 http 模式,若是使用 https 模式还要考虑容器和配置,nginx 配置直接使用 http 的 80 端口

使用 https 方式

[[proxies]]  
name = "nginx_https"  
type = "https"  # 代理类型是 https  
customDomains = ["your-domain.com"]  
  
[proxies.plugin]  
type = "https2https"  # 插件类型是 https2https  
localAddr = "127.0.0.1:443"  
# 设置证书位置
crtPath = "/etc/nginx/ssl_cert/huixiangwuyou.com.pem"  
keyPath = "/etc/nginx/ssl_cert/huixiangwuyou.com.key"  
hostHeaderRewrite = "127.0.0.1"

创建 service 服务

apt install systemd

sudo nano /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
## 使用 systemd 命令管理 frps 服务
# 启动 frp
sudo systemctl start frps
# 停止 frp
sudo systemctl stop frps
# 重启 frp
sudo systemctl restart frps
# 查看 frp 状态
sudo systemctl status frps
# 设置 frps 开机自启动
sudo systemctl enable frps

连接原理

  • 核心组件与准备工作
    • FRP 服务端 (frps):需部署在 拥有公网 IP 的服务器 上,用于接收外网请求并转发给内网的 FRP 客户端
    • FRP 客户端 (frpc):运行在 内网设备 上,用于将本地服务暴露出去
    • 前期准备 :确保服务端和客户端的 版本一致,并准备好一台公网服务器(如阿里云、腾讯云等)并开放相关端口
  • 建立控制连接
    1. 客户端发起连接 :FRP 客户端启动后,会主动与 FRP 服务端 建立一个 TCP 长连接。此连接用于传输控制指令
    2. 身份认证:客户端连接时,通常需要验证一个预先配置好的token,确保连接合法性
  • 注册与服务暴露
    • 客户端通过控制连接,将其 要代理的内网服务信息 (如类型、本地端口等)注册到服务端。服务端随后会 开启对应端口的监听,等待外网用户的请求
  • 建立数据通道与传输
    1. 外网用户访问:用户访问服务端的公网 IP 和特定端口
    2. 服务端通知客户端 :服务端收到请求后,通过控制连接通知客户端 建立一个新的工作 TCP 连接
    3. 客户端建立数据通道 :客户端收到指令后,会 新建一条连接到内网本地服务的 TCP 连接 ,同时 建立一条到服务端的工作 TCP 连接,并将这两条连接绑定
    4. 服务端绑定连接 :服务端将 外部用户的请求连接 客户端建立的工作连接 绑定
    5. 数据转发:此后,数据便可在用户和内网服务之间通过 FRP 服务端和客户端建立的隧道进行传输

使用

  • 公网 ip+8080 访问:此访问方式是用于没有域名的情况,只能通过 http 访问
  • 域名 +8443 访问:xxx.com:8443, 可以通过 http 和 https 访问,但是多了个端口号不美观
  • 直接域名访问:使用 nginx 反向代理服务器的 8443 端口号转向内网服务器
server {listen       [::]:80;
       listen       443 ssl;
       listen       [::]:443 ssl;
       server_name  www.next.huixiangwuyou.com next.huixiangwuyou.com;

       ssl_certificate     /etc/nginx/ssl_cert/huixiangwuyou.com.pem;
       ssl_certificate_key  /etc/nginx/ssl_cert/huixiangwuyou.com.key;

       ......

       location / {
             # 代理到本机的 frp 服务上
             proxy_pass https://127.0.0.1:8443;
             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;
             proxy_ssl_verify off;

              # 以下为常用代理参数
             proxy_connect_timeout 60s;
             proxy_read_timeout 600s;
             proxy_send_timeout 600s;
             proxy_buffering off;
      }
 }

连接数据库

frp 支持内网穿透的外网访问端口, 建议加密,不要直接暴露在公网上

frps.toml 基本不需要额外修改

# frpc.toml - 客户端配置
serverAddr = "your-frps-server.com"
serverPort = 7000
auth.token = "your_auth_token"

[[proxies]]
name = "mysql"
type = "tcp"  # 使用 TCP 协议
localIP = "192.168.3.3"  # 内网 MySQL 服务器 IP
localPort = 3306         # 内网 MySQL 端口
remotePort = 13306       # 公网服务器映射端口

# 启用传输加密(可选)transport.useEncryption = true
transport.useCompression = true

# 带宽限制(可选)bandwidthLimit = "1MB"
bandwidthLimitMode = "client"
# 限定 ip 白名单
allowedIps = ["your-client-ip/32", "another-ip/32"]

STCP(安全 TCP)模式

# 内网 MySQL 服务器 frpc.toml
[[proxies]]
name = "mysql-stcp"
type = "stcp"
localIP = "192.168.3.3"
localPort = 3306
sk = "your-secret-key"  # 密钥,双方保持一致

# 访问端 frpc.toml(需要在另一台机器上运行)[[visitors]]
name = "mysql-visitor"
type = "stcp"
serverName = "mysql-stcp"
sk = "your-secret-key"
bindAddr = "127.0.0.1"
bindPort = 3307

如果两端都能建立直接连接,可以使用 P2P 模式减少延迟:

# 内网 Redis 服务器
[[proxies]]
name = "redis-xtcp"
type = "xtcp"
localIP = "192.168.3.4"
localPort = 6379
sk = "redis-secret"

# 访问端(需要安装 frp)[[visitors]]
name = "redis-xtcp-visitor"
type = "xtcp"
serverName = "redis-xtcp"
sk = "redis-secret"
bindAddr = "127.0.0.1"
bindPort = 6379

常见问题排除方式

常遇到的就是逻辑没问题,就是没通内网,就要弄清楚排查过程

# 首先排查的就是 frp 的两个配置上是否有问题,然后排查下一步
确定域名访问的地址是外网 IP,然后通过 nginx 经过指定的 8080、8443 端口映射了内网的 80、443 端口,然后由内网的 nginx 映射到指定端口和文件
# 排查访问是否到外网服务器
# eg: 例如排查域名是否通过了本地的 8080 端口
curl -v -H "Host: word.huixiangwuyou.com" http://127.0.0.1:8080
# 同样的方式排查下内网,是否访问了 80 端口
curl -v -H "Host: word.huixiangwuyou.com" http://127.0.0.1:80

常见问题

  • 页面重定向:检查 nginx 配置
  • 404 页面:重启 nginx 配置
  • 无服务:检查服务是否开启 | 端口是否正常 sudo netstat -tlnp | grep :8001
  • 网站使用 https 访问服务报 502:将 nginx 上的[::] 443 去除掉就可以访问了
  • journalctl -u frps -f 查看服务端日志
    • tail -n 50 /var/log/frps/frps.log 查看最新 50 条记录(路径主要看你的 frps.toml 设置的路径)
  • journalctl -u frpc -f 查看客户端服务日志
    • tail -n 50 /var/log/frpc/frpc.log 同理

正文完
 0
评论(没有评论)
验证码