"/>
侧边栏壁纸
博主头像
PySuper 博主等级

千里之行,始于足下

  • 累计撰写 286 篇文章
  • 累计创建 17 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

内网穿透

PySuper
2023-06-24 / 0 评论 / 0 点赞 / 5 阅读 / 0 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

如果觉得 Ngrok 收费,可以尝试 开源免费的内网穿透方案,例如使用 Frp(Fast Reverse Proxy)。以下是 基于 Frp 的自建内网穿透方案(无需 Python 代码,更稳定高效),以及 Python 实现内网穿透的原理分析(适合技术探索,但生产环境不推荐)。

一、自建 Frp 内网穿透

免费、稳定,推荐

1. 原理简介

  • Frp 是开源的反向代理工具,通过在公网服务器(VPS)部署服务端,本地设备运行客户端,将本地端口映射到公网服务器的指定端口,实现内网穿透。

  • 支持多端口穿透(包括所有端口),支持 TCP、UDP、HTTP/HTTPS 等协议,性能稳定,配置灵活。

2. 所需条件

  • 一台公网 IP 的服务器(VPS)(例如阿里云、腾讯云,最低配置即可,按流量计费更划算)。

  • 本地电脑(客户端)公网服务器(服务端) 均需安装 Frp。

3. 操作步骤

步骤 1:购买并配置公网服务器
  • 购买 VPS:选择海外服务器(如 Linode、Vultr)或国内服务器(需备案),推荐 Ubuntu 系统。

  • 配置防火墙

# Ubuntu 示例(开放 7000、7001、80、443 等端口)
sudo ufw allow 7000/tcp
sudo ufw allow 7001/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
  • 开放 Frp 服务端默认端口(如 7000 用于通信,7001 用于 Web 管理,其他端口按需开放)。

步骤 2:在公网服务器安装 Frp 服务端
wget https://github.com/fatedier/frp/releases/download/v0.49.0/frp_0.49.0_linux_amd64.tar.gz
tar -zxvf frp_0.49.0_linux_amd64.tar.gz
cd frp_0.49.0_linux_amd64
  • 修改服务端配置文件(frps.ini)

[common]
bind_port = 7000       # 服务端与客户端通信的端口(必填)
dashboard_port = 7001  # Web 管理界面端口(可选)
dashboard_user = admin # 管理界面用户名(可选)
dashboard_pwd = admin  # 管理界面密码(可选)
  • 启动服务端

./frps -c frps.ini
  • 建议设置为系统服务(systemd),确保开机自启:

sudo cp frps.service /etc/systemd/system/  # 假设已创建服务文件
sudo systemctl enable frps
sudo systemctl start frps
步骤 3:在本地电脑安装 Frp 客户端
  • 下载 Frp:根据本地系统(Windows/macOS/Linux)选择对应版本,例如 Windows 的 frp_0.49.0_windows_amd64.zip

  • 解压并修改客户端配置文件(frpc.ini)

[common]
server_addr = 公网服务器IP  # 填写你的 VPS IP
server_port = 7000          # 对应服务端的 bind_port

# 示例 1:穿透本地 8080 端口到公网服务器的 80 端口(HTTP 服务)
[web]
type = tcp
local_ip = 127.0.0.1       # 本地服务 IP(通常为 localhost)
local_port = 8080          # 本地需穿透的端口
remote_port = 80           # 公网服务器映射的端口(需与防火墙开放的端口一致)

# 示例 2:穿透本地 3389 端口(远程桌面)到公网服务器的 3389 端口
[rdp]
type = tcp
local_port = 3389
remote_port = 3389

# 示例 3:穿透所有端口(TCP 全端口映射,谨慎使用!)
# 注意:全端口映射需服务端和客户端配置支持,且可能存在安全风险
[all-ports]
type = tcp
local_ip = 0.0.0.0        # 监听所有本地 IP
local_port = 1-65535       # 本地端口范围(所有端口)
remote_port = 10000-75535  # 公网服务器端口范围(需足够大且未被占用)
  • 启动客户端

  • Windows:双击 frpc.exe -c frpc.ini 或通过命令行启动。

  • Linux/macOS

./frpc -c frpc.ini
步骤 4:访问公网服务
  • 穿透后,通过 公网服务器IP:远程端口 访问本地服务。例如:

  • 本地 Web 服务:http://公网IP:80(对应示例 1)。

  • 远程桌面:连接 公网IP:3389(对应示例 2)。

二、Python 实现

内网穿透的原理(技术探索)

如果想通过 Python 代码实现内网穿透(适合学习原理,但生产环境不推荐,性能和稳定性较差),核心思路是 利用 socket 转发流量,分为以下步骤:

1. 原理概述

  • 公网服务器作为中转站:本地客户端(内网设备)与公网服务器建立长连接,公网服务器接收外部请求后,通过该连接将数据转发给本地客户端,实现反向代理。

  • 核心模块socket(网络通信)、threading(多线程处理并发连接)。

2. 简单实现示例(TCP 单端口穿透)

公网服务器端代码(server.py)
import socket
import threading

# 公网服务器监听端口(需开放防火墙)
SERVER_PORT = 7000
# 本地客户端 IP(需提前通过客户端注册)
LOCAL_IP = "192.168.1.100"  # 假设本地客户端 IP
LOCAL_PORT = 8080           # 本地需穿透的端口

def handle_client(client_sock):
    # 与本地客户端建立连接
    local_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        local_sock.connect((LOCAL_IP, LOCAL_PORT))
    except Exception as e:
        client_sock.sendall(b"Local connection failed")
        client_sock.close()
        local_sock.close()
        return

    # 转发数据(客户端 <-> 本地服务)
    def forward_to_local():
        while True:
            data = client_sock.recv(1024)
            if not data:
                break
            local_sock.sendall(data)
        client_sock.close()
        local_sock.close()

    def forward_to_client():
        while True:
            data = local_sock.recv(1024)
            if not data:
                break
            client_sock.sendall(data)
        client_sock.close()
        local_sock.close()

    # 启动双向转发线程
    threading.Thread(target=forward_to_local).start()
    threading.Thread(target=forward_to_client).start()

def main():
    server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_sock.bind(("0.0.0.0", SERVER_PORT))
    server_sock.listen(5)
    print(f"Server listening on port {SERVER_PORT}...")

    while True:
        client_sock, addr = server_sock.accept()
        print(f"New connection from {addr}")
        threading.Thread(target=handle_client, args=(client_sock,)).start()

if __name__ == "__main__":
    main()
本地客户端代码(client.py)
import socket

# 公网服务器 IP 和端口
SERVER_IP = "公网服务器IP"
SERVER_PORT = 7000

def main():
    # 与公网服务器建立长连接(保持心跳)
    while True:
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((SERVER_IP, SERVER_PORT))
            print("Connected to server")
            # 保持连接(心跳机制,防止断开)
            while True:
                sock.sendall(b"heartbeat")
                sock.recv(1024)
        except Exception as e:
            print(f"Connection failed: {e}")
            sock.close()

if __name__ == "__main__":
    main()

3. 代码原理说明

  1. 公网服务器端

  • 监听指定端口,接收外部请求(如浏览器访问)。

  • 与本地客户端建立连接,通过 多线程双向转发数据(外部请求 → 公网服务器 → 本地服务;本地响应 → 公网服务器 → 外部客户端)。

  1. 本地客户端

  • 主动连接公网服务器,维持长连接(需添加心跳机制防止断开)。

  • 作为数据接收端,将公网服务器转发的数据传递给本地服务。

  1. 局限性

  • 仅支持单端口穿透,多端口需为每个端口创建独立连接。

  • 无身份验证,存在安全风险(需手动添加 token 校验)。

  • 性能差:Python 的 socket 转发效率低,无法处理高并发或大流量场景。

三、方案对比与建议

方案

优点

缺点

适用场景

Frp

开源免费、多端口支持、稳定高效

需自建公网服务器

生产环境、长期使用

Python 代码

原理简单、适合学习

性能差、功能简陋、不安全

技术探索、临时测试

Ngrok

无需自建服务器、即开即用

免费版限制多、收费

短期测试、个人演示

四、注意事项

  1. 安全风险

  • 全端口穿透可能暴露内网服务,建议仅穿透必要端口,并在公网服务器设置防火墙规则。

  • 使用 Frp 时,建议启用 token 认证TLS 加密(参考 Frp 官方文档)。

  1. 性能优化

  • Frp 支持 TCP 复用压缩 等优化配置,可提升传输效率。

  • 公网服务器选择与本地网络延迟低的节点(如国内服务器优先选择阿里云上海/北京节点)。

  1. 替代方案

  • 若需更简单的免费方案,可尝试 Netcat(nc)Serveo(无需服务器,但稳定性较差)。

总结

  • 推荐优先使用 Frp:配置简单、功能完善,适合长期稳定的内网穿透需求。

  • Python 实现仅用于学习:生产环境中不建议使用,如需自定义功能,可基于 Frp 源码进行二次开发。

如果需要进一步优化配置或解决问题,可以提供具体环境信息(如系统版本、网络架构),我会给出更详细的方案!

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区