V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
saytesnake
V2EX  ›  程序员

无外网的内网机器,如何正确实现内网穿透?

  •  
  •   saytesnake · 2021-05-14 01:58:50 +08:00 · 2303 次点击
    这是一个创建于 1291 天前的主题,其中的信息可能已经有所发展或是发生改变。
    内网穿透方面,相信无论是 frp 或 nps 都比较常用且易用了,不过目前有这个需求,用户的网络:

    内网 A 服务器(无法访问外网) 192.168.1.100
    内网 B 服务器(内外网均可访问) 192.168.1.253
    公网 C 服务器,8.8.8.8

    现在是想访问 192.168.1.100 的 3306 端口也就是 mysql 的,目前 Google 查询的做法大致是这样,以比较流行的 frp 为例,

    1 、「内网 A 服务器 192.168.1.100 」 配置 frpc 走 socks5 代理到 192.168.1.253 ,引出一个远程端口如 3307 端口;

    2 、在「内网 B 服务器 192.168.1.253 」同时配置 frps 与 frpc,frps 做 socks5 代理提供给「内网 A 服务器 192.168.1.100 」用,然后如常配置 frpc 走「公网 C 服务器,8.8.8.8 」,当然也可以自行搭建其它的 socks5 代理。

    总感觉这样子十分繁琐...而且性能、稳定性上未知,这个需上生产环境,量会比较多,但需求是一样的,就是安全地访问无公网 IP,且无法上网的内网数据库服务器。

    OpenVPN,如果在用户的网络如「内网 B 服务器 192.168.1.253 」这样的安装 OpenVPN 客户端,仅点对点(通过 tun 的虚拟网卡 ip )可以互相访问,通过路由可以让「内网 B 服务器 192.168.1.253 」访问到「公网 C 服务器,8.8.8.8 」所处的局域网 /内网,但这个跟我们的需求反过来了,是我们要访问别人而不是让别人访问我们...

    WireGuard 估计也是类似吧...不知道各位大神是否有好的建议或者是正在实践中的。
    第 1 条附言  ·  2021-05-14 11:34:39 +08:00
    frp 的 local_ip 可直接填写数据库服务器的 ip,问题解决。
    28 条回复    2021-05-14 19:27:14 +08:00
    irytu
        1
    irytu  
       2021-05-14 02:09:06 +08:00 via iPhone
    Wireguard server 跑在 B 就完事了
    Lentin
        2
    Lentin  
       2021-05-14 02:10:48 +08:00 via iPhone
    openvpn 把路由指一下应该就行了吧
    chust
        3
    chust  
       2021-05-14 02:41:09 +08:00 via iPhone
    直接在 B 服务器上设置 frpc 的 local IP 为 A 的 IP 就行了吧,A 上不需要跑 frpc,B 上也不需要跑 frps 。我一直都是这么用的
    ericls
        4
    ericls  
       2021-05-14 03:14:28 +08:00 via iPhone
    iptables + ip route 直接 nat 一个端口出来?
    kav2007
        5
    kav2007  
       2021-05-14 07:14:21 +08:00 via Android
    比较安全的方法还是 vpn 。
    从 C 到 B 建 vpn; 在 C 上加一条路由 192.168.1.100/32 指向 B 。然后在 B 做 iptables ACL 访问控制和 SNAT 。
    如果 A 和 B 之间需要加密传输,可以再建一条 vpn 。
    wd
        6
    wd  
       2021-05-14 07:19:21 +08:00 via iPhone
    a,b 看着不是可以互通么?所以你只需要在 b 上面暴露一个端口,然后把对这个端口的访问转发给 a 就行。
    araaaa
        7
    araaaa  
       2021-05-14 07:19:41 +08:00
    对 192.168.1.253 穿透,然后在 192.168.1.253 上面做 nat 转发到 192.168.1.100
    simplove
        8
    simplove  
       2021-05-14 09:22:04 +08:00
    B 上面跑 frpc,同时运行 PortTunnel 端口映射。指向 A 的 IP 和端口
    no1xsyzy
        9
    no1xsyzy  
       2021-05-14 09:37:09 +08:00
    B 能直接访问 A 的话,你 X->C->B->A 只有 C->B 段需要反连
    但是 frp 没有安全性,TLS 只有机会加密来着;且依赖 C 的安全性

    用 wg/ov 的话,X 和 B 都连到 C 然后在 C 和 B 上都做 ipv4 forwarding 和 NAT 即可,这是简单的多层路由问题
    也依赖 C 的安全性

    还有一种就是在 B 上开 wg/ov 入口,再用 frp 把这个入口转到 C 上去
    不依赖 C 的安全性
    1041412569
        10
    1041412569  
       2021-05-14 09:39:05 +08:00
    明显可以用 WireGuard 啊,ABC 组大内网,让流量由 A 经 B 到 C 。
    stille
        11
    stille  
       2021-05-14 11:25:07 +08:00
    frpc 客户端安装到 192.168.1.253 上

    frpc.ini

    [mysql]
    type = tcp
    local_ip = 192.168.1.100
    local_port = 3306
    remote_port = 随意 3306 也可以 33306

    8.8.8.8:33306 访问你的 mysql
    saytesnake
        12
    saytesnake  
    OP
       2021-05-14 11:31:33 +08:00
    @chust
    @stille

    谢谢,可能是我有点落伍了,我以为 local_ip 只能填写能上外网的服务器。
    saytesnake
        13
    saytesnake  
    OP
       2021-05-14 11:33:11 +08:00
    @kav2007 主要是 VPN 方式还面临一个问题,如果几个用户的内网都是 192.168.1.x,也依赖给虚拟网卡 IP 做一个端口转发的问题。
    saytesnake
        14
    saytesnake  
    OP
       2021-05-14 11:37:10 +08:00
    @no1xsyzy
    @1041412569

    因为考虑到可能好几个用户,内网段可能都是 192.168.1.x,组网后直连或者 P2P 就面临这个问题,当然可以利用虚拟网卡的 IP 给对应的服务器的端口做转发,就是显得略繁琐一点。
    uncat
        15
    uncat  
       2021-05-14 11:43:45 +08:00
    基于 SSH 即可.
    1. 配置 B 基于密钥 SSH 登陆
    2. 配置 A 基于密钥 SSH 登陆
    3. 添加如下配置到如下路径的文件最前面:`~/.ssh/config`, 请根据具体情况更新尖括号内的内容

    Host database
    User <A 的用户名>
    HostName <A 的内网 IP 地址>
    ProxyJump <B 的用户名>@<B 的公网 IP 地址>
    LocalForward 127.0.0.1:13306 127.0.0.1:3306

    4. 打开两个命令行窗口
    5. 在窗口 1 执行: `ssh database`,保持窗口 1 登陆连接的状态. 在窗口 2 执行: `nc -vz localhost 13306`
    6. 如果窗口 2 显示 connected. 就可以了
    7. 你本地访问 13306 就等于访问 A 的 3306 了
    uncat
        16
    uncat  
       2021-05-14 11:47:33 +08:00
    配置示例:

    Host database
    User todo
    HostName 192.168.1.100
    ProxyJump todo@todo
    LocalForward 127.0.0.1:13306 127.0.0.1:3306

    好处:
    生产环境不需要依赖任何第三方的工具. 避免生产环境的污染带来的安全风险. 基于 SSH 的密钥验证的安全性保证. 安全可靠.
    uncat
        17
    uncat  
       2021-05-14 11:50:18 +08:00
    PS:
    1. 这份配置是添加到你本地.
    2. 你需要添加你的公钥到 A 服务器和 B 服务器.
    uncat
        18
    uncat  
       2021-05-14 11:52:57 +08:00
    这是 SSH 自带的功能. 详细请阅读: `man ssh_config` 中关于: ProxyJump 和 LocalForward 两个 options 的文档. 软一峰先生关于 SSH 的文章也可以读一下: https://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html
    no1xsyzy
        19
    no1xsyzy  
       2021-05-14 12:15:54 +08:00
    @saytesnake 是说有若干个不同的子网均配置了 192.168.1.0/24 网段吗?

    他们之间不需要互通就是 wg point-to-site,根据不同用户切配置就行。

    如果他们需要互通,就是 NAT,把子网映射到另一部分去,比如可以对两个 192.168.1.0/24 子网
    A: 192.168.1.0/24 = 10.1.1.0/24
    B: 192.168.1.0/24 = 10.1.2.0/24
    这样 A 可以通过 10.1.2.0/24 来访问 B,B 可以通过 10.1.1.0/24 来访问 A
    但我只知道这种 NAT 的存在,因为几乎不用我也不知道怎么做。因为这个 NAT 并不节约 IP 资源实际上并没多少人这么搞
    no1xsyzy
        20
    no1xsyzy  
       2021-05-14 12:20:40 +08:00
    @uncat 你还要把 B 的 sshd 端口 frp 到 C 上
    saytesnake
        21
    saytesnake  
    OP
       2021-05-14 13:53:53 +08:00
    @no1xsyzy 是的,如果用于生产,多用户下几个甚至几十个 192.168.1.0/24 或其它同段的,NAT to NAT 十分不适合。WG 研究得不多,且遇到 MS 全家桶用户的情况下,v0.3.14 版本的简陋客户端还不知道是否稳定,没有 Linux 端的灵活性了。
    saytesnake
        22
    saytesnake  
    OP
       2021-05-14 13:56:14 +08:00
    @uncat 谢谢,这个方式是可行的,但遇到 Windows 系的就麻烦了,话说我有不少实践,Windows 的 netsh 端口转发,即便是 2016 的版本也经常不明原因失效,IP helper 的工作原理不懂。
    kav2007
        23
    kav2007  
       2021-05-14 14:04:35 +08:00
    @saytesnake 去年出过一个小米实习生,是把内网服务器 FRP 穿透到公网,服务器被黑。在生产环境慎用 FRP 到公网。即使个人使用 FRP,也要注意防范风险。穿透 RDP 、NAS 到公网被黑,中勒索病毒,网上也有不少人中招。
    VPN 是商用成熟可靠的技术。VPN 隧道建立之后网络可达就行,不需要分别再配端口转发
    uncat
        24
    uncat  
       2021-05-14 14:34:45 +08:00
    @no1xsyzy 是的, 我理解错了楼主关于: `内网 B 服务器(内外网均可访问)' 的意思, 以为 B 有公网 IP.

    如果是 B 没有公网 IP, 但可以访问内网和公网. 有一台具备公网 IP 的服务器 C. 解决思路:

    1. 将 B 的 22 端口通过 FRP 绑定到 C 上, 假设是 C 上的 1428 端口
    2. C 服务器禁止公网访问 1428 端口
    3. 添加如下配置到如下路径的文件最前面:`~/.ssh/config`, 请根据具体情况更新尖括号内的内容

    Host c
    User <C 的用户名>
    HostName <C 的公网 IP 地址>

    Host b
    User <B 的用户名>
    HostName 127.0.0.1
    Port: 1428
    ProxyJump c

    Host database
    User <A 的用户名>
    HostName <A 的内网 IP 地址>
    ProxyJump b
    LocalForward 127.0.0.1:13306 127.0.0.1:3306

    4. 打开两个命令行窗口
    5. 在窗口 1 执行: `ssh database`,保持窗口 1 登陆连接的状态. 在窗口 2 执行: `nc -vz localhost 13306`
    6. 如果窗口 2 显示 connected. 就可以了
    7. 你本地访问 13306 就等于访问 A 的 3306 了
    uncat
        25
    uncat  
       2021-05-14 14:36:50 +08:00
    因为 FRP 映射的 SSH 端口是完全公网不可见的. 因此, 这里的安全性也是相对可靠的. FYI @kav2007
    uncat
        26
    uncat  
       2021-05-14 14:38:00 +08:00
    @saytesnake 是的. 如果你是为了远程访问 RDP 协议还好. 如果 B 这台是 Windows 的确就不好搞了.
    saytesnake
        27
    saytesnake  
    OP
       2021-05-14 14:51:54 +08:00
    @kav2007 这个是清楚的,其实正确配置 stcp,问题都不大,错不在 frp 本身,而是本身服务器的安全性。
    kav2007
        28
    kav2007  
       2021-05-14 19:27:14 +08:00 via Android
    @uncat ssh 开启公钥登录,关闭密码登录,再改个非标端口,安全性还算可以。
    @saytesnake
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6002 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 03:20 · PVG 11:20 · LAX 19:20 · JFK 22:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.