利用公网IP+内网穿透访问本地服务

2025.09.06更新

当前NPS已有非常严重的安全问题,攻击者可能绕过账户密码在管理界面设置代理将你的机器作为跳板机,如果在NPS管理中出现不是自己设置的配置,必须马上关闭NPS服务,以避免损失。本人被消耗了450G流量,所幸攻击者并未攻击局域网内的其他机器可能是没有价值罢,而是通过穿透客户端作为跳板访问外网,因此损失较小。本文中NPS相关章节已删除,警钟长鸣。

点对点与C/S方案

上回说到异地组网的方案,虽然免费,高速,但是随着长时间的使用,也出现了一些问题。

  1. 设备要支持开启客户端
    这其实不是一个大问题,电脑和手机可以开启客户端是理所当然的,这部分设备带出门也可以使用,而其他无法开启客户端的设备也可以通过路由器进行组网,这部分设备一般不会带出门,影响不大。我其实就是不想每次都要点开客户端
  2. 对网络环境的要求较高
    虽然有一端是IPV6公网的设备,但如果你正处于较差的网络环境中(例如商场、咖啡店和酒店的公共WiFi),此时开启点对点穿透,可能会出现无法连接上服务提供商的节点,或者打洞失败的情况。以ZeroTier和Tailscale举例,如果打洞失败,则会使用自身的节点直接转发,但此时的速度就无法保证了。因此,点对点的穿透方案较为适合在多个固定的地点部署,实现多个地点之间的异地组网。
  3. 对客户端的审查风险
    如果你在公司或者安全要求较高的地点打开点对点内网穿透,虽然管理人员无法获取你与另一边的传输内容,但是可以探测到你正在使用此类服务,从而对你发出警告。我真的被警告过 所以,一个公网IPV4服务器还是很有必要的,可以弥补点对点内网穿透没有覆盖的情境,我将这种需求总结为两点:
  4. 高通用性——哪里都能用
  5. 低流量——在无法点对点穿透的场景使用,频率较低,降低公网服务器的使用成本
    通过两种方法共同覆盖自己的访问需求,从我的实际应用来说,大流量交换的需求在家进行,离开路由器则使用公网服务。

内网穿透

接下来就是内网穿透的方案,由于有公网服务器的参与,这部分的原理较为简单,现存的软件都比较轻量化,试用过后,我觉得Frp和NPS是其中较为好用的两种。两者略有不同,可以按需选择。

首先是NPS,NPS的端口配置部分在服务器上,客户端只作为一个终端连接上服务器。这种架构比较适合个人用户控制名下的所有客户端,可以先将客户端连接到服务器,再决定要穿透哪些服务,或者随时关闭服务。

Frp的配置方法和NPS相反,所有的配置文件存储在客户端,服务器则负责提供内网穿透服务供客户端使用。这种架构比较适合将内网穿透服务公开给非特定的人群使用,有需要的用户都可以通过鉴权或非鉴权的方式登录到服务器,自行配置内网穿透服务,在配置的层面做到互不干扰。

(2025.09.06更新)在内网穿透的C/S架构中,暴露于公网的服务端受到攻击的概率远高于位于局域网的客户端,对服务端的软件安全性提出的更高的要求。并且,局域网内设备的价值一般也远高于仅提供公网出口的服务端。因此,如果配置文件在服务端,则管理端被攻击后,攻击者可以随意访问局域网内设备,反之,如果配置在客户端,就算服务端被攻破,攻击者也只能使用服务端的穿透服务,局域网并没有对攻击者开放出更多内容。现在想来,在有公网IP的服务端配置固然比无法随时访问的客户端配置方便,但是在安全性方便牺牲太多,还是Frp的架构较为合理。

Frp

本章介绍如何配置Frp。

  1. 下载文件
    通过wget或其他方式将安装包传输至服务器并解压

    1
    2
    3
    4
    # 在github页面找一个最新链接
    wget https://github.com/fatedier/frp/releases/download/v0.64.0/frp_0.64.0_linux_amd64.tar.gz
    mkdir frp
    tar -zxvf frp_0.64.0_linux_amd64.tar.gz -C frp
  2. 配置服务端
    根据官方的frps_full_example.toml文件,修改frps.toml,此处提供一个最简服务端配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    bindPort = 7000

    # 修改开放的服务端DashBoard端口和账户密码,DashBoard仅能查看当前在线的客户端
    webServer.addr = "0.0.0.0"
    webServer.port = 7500
    webServer.user = "admin"
    webServer.password = "admin"

    # 鉴权token
    auth.method = "token"
    auth.token = "12345678"
  3. 启动服务端
    建议先通过命令启动服务端看看效果,如果配置不对此处会报错

    1
    ./frps -c ./frps.toml

    如果步骤正确,则执行命令后,可以通过IP:Port访问面板。但是,此时frps运行于前台,这显然不是持久化的方案,我们需要将frps转为一个服务,通过systemd管理,以下为官方文档的内容

    1
    vim /etc/systemd/system/frps.service
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [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
    1
    2
    3
    4
    5
    6
    7
    8
    # 启动frp
    sudo systemctl start frps
    # 停止frp
    sudo systemctl stop frps
    # 重启frp
    sudo systemctl restart frps
    # 查看frp状态
    sudo systemctl status frps
  4. 配置客户端
    客户端配置文件为frpc.toml。同样,此处提供一个最简的TCP单端口代理的配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    serverAddr = "x.x.x.x"
    serverPort = 7000

    # token需要和服务端配置一致,否则无法连接
    auth.method = "token"
    auth.token = "12345678"

    # 将本地443端口映射到服务端的443端口
    [[proxies]]
    name = "https"
    type = "tcp"
    localIP = "127.0.0.1"
    localPort = 443
    remotePort = 443
  5. 启动客户端
    参考步骤3,将其中的frps改为frpc即可,相信看到这里的你肯定会的。

Author: Links
Link: http://blog.taiho.cc/post/Nat/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.