V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
yangxuan8282
V2EX  ›  问与答

求推荐内网穿透方式

  •  
  •   yangxuan8282 · 2017-05-21 22:46:48 +08:00 · 9770 次点击
    这是一个创建于 2736 天前的主题,其中的信息可能已经有所发展或是发生改变。

    家里用的是电信无线宽带(4G)没有公网 IP,树莓派上有几个网页,想在外网访问只能考虑内网穿透,因为手里已经有 vps 所以倾向于用现有的资源,不太想用花生壳这一类付费的,想请大家推荐一下哪种方式比较好

    我知道的几种方式:

    • ssh tunnel

    • dog-tunnel lite

    • frp

    • ngrok

    • n2n

    • 花生壳

    前三个都试过,ngrok 和 n2n 还没尝试

    ssh 隧道最方便,也不用装其它软件,不过速度一般;狗洞 lite 是用过的里面最满意的,自带 kcp,对丢包明显的线路来说很适合,速度不错,不过有个问题是电信无线宽带不是很稳定,一旦断网重连狗洞 lite 就会报错说端口已占用,必须把 server 端退掉重新开才行,所以经常得手动重连; frp 感觉配置有点繁琐,还得在配置文件里配置域名,多个站点的情况下不清楚怎么配置

    第 1 条附言  ·  2017-05-22 20:15:07 +08:00
    感谢大家的回答,特别是 @wwqgtxx 的指导
    既然狗洞 lite 断线重连的问题暂时解决了,就打算先继续用下去了,毕竟速度是试过的各种内网穿透方式里最快的
    我把完整的配置脚本放在 gist 上了,如果有遇到类似问题的用户可以参考一下
    - 先下载脚本到 client 上,也就是你想暴露到公网的设备
    - 然后分别下载狗洞 lite 的 binary file 到 server 和 client 的 `/usr/local/bin/` 目录,然后给执行权限 `chmod +x dog-tunnel`,可执行文件的下载地址在脚本第 6 行和第 7 行 ( 狗洞官方的可执行文件中 arm 版我记得在树莓派上没运行成功,所以重新编译了,如果你想自己编译可以参考下这里: https://github.com/yangxuan8282/docker-image/blob/master/dog-tunnel )
    - 再在第 31 到 38 行填入你服务器的信息
    - 最后执行,在 client 上输入:bash dtunnel_systemd.sh

    第 2 条附言  ·  2017-05-24 23:19:03 +08:00

    经过一天的测试发现用 systemd 管理狗洞 lite 后还是会出现连接问题,不过不是端口已占用引起的,为了解决这个问题加了一个 crontab,用 curl 每小时检测检测一下网站是否在线,不在线的话就重启 http-dtunnel.service 如果你的网络也是很不稳定的话可以手动加一下:

    在 client 上输入:

    sudo crontab -e
    

    然后在文件最下面加入($URL替换为你的网址):

    0 * * * * curl $URL -s -f -m 5 -o /dev/null || systemctl restart http-dtunnel
    

    不过说到底用脚本只是临时的解决方案,肯定不如修改 dog-tunnel lite 程序本身来解决问题来的彻底,不过我不会编程,也只能先这么样了,只好等作者修复,或者熟悉 golang 的 v 友可以去看看有没有思路解决

    顺便再贴一个配置 ssh 隧道 systemd 的脚本:

    https://gist.github.com/yangxuan8282/27f9293b2f852c9bfd37f4de02184952

    50 条回复    2018-11-11 16:12:29 +08:00
    majinjing3
        1
    majinjing3  
       2017-05-21 22:49:52 +08:00 via Android   ❤️ 1
    推荐 frp,配置这个多看看就好了,
    majinjing3
        2
    majinjing3  
       2017-05-21 22:50:30 +08:00 via Android
    ngrok 新版本已经闭源了,看版本有 bug,不建议使用,
    anyele
        3
    anyele  
       2017-05-21 23:15:01 +08:00 via Android
    frp 确实可以,但配置要研究下才搞得懂
    yangxuan8282
        4
    yangxuan8282  
    OP
       2017-05-21 23:19:29 +08:00
    frp 是可以,昨天试了一下把 novnc 转发到公网,能在浏览器里操作 raspbian 的桌面环境,不过有点不太理解为何还得在 client 端配置域名,按说只管端口转发不就行了吗
    v1024
        5
    v1024  
       2017-05-21 23:50:01 +08:00 via iPhone
    再用 ngrok 免费服务做远程 SSH 管理,因为不需要自己的服务器,非常稳定,但速度慢。另外使用 frp 做其他服务的隧道,也很稳定,都推荐。
    tyhunter
        6
    tyhunter  
       2017-05-22 00:01:55 +08:00
    ngrok 很稳定,转发了 aria2-RPC 就可以远程遥控 aria2 下载美剧了
    4ier
        7
    4ier  
       2017-05-22 00:03:31 +08:00 via Android
    推荐 frp,配置简单
    yangxuan8282
        8
    yangxuan8282  
    OP
       2017-05-22 00:14:13 +08:00
    @tyhunter 问下是用的 ngrok v1 还是 v2,是自己搭建的服务器吗
    fzinfz
        9
    fzinfz  
       2017-05-22 00:19:05 +08:00   ❤️ 1
    zerotier,成熟的商业产品,开源,全平台客户端,官方提供 12 台 root server (也可以自建)
    上手简单,只要 2 步:
    客户端: https://www.zerotier.com/download.shtml
    加入测试网络 8056c2e21c000001 或者自建: https://my.zerotier.com/network
    yangxuan8282
        10
    yangxuan8282  
    OP
       2017-05-22 00:54:27 +08:00
    @fzinfz 看了下这个好像有点类似 vpn,似乎没有暴露到公网的功能,不过还是谢谢了
    fzinfz
        11
    fzinfz  
       2017-05-22 01:00:34 +08:00
    @yangxuan8282 VPS 上 nginx 或 haproxy 弄个反代就好了
    joyqi
        12
    joyqi  
       2017-05-22 01:18:45 +08:00
    paubrk
        13
    paubrk  
       2017-05-22 02:58:36 +08:00
    frp 域名不是必须,不要配置 http 相关参数就行了
    yangxuan8282
        14
    yangxuan8282  
    OP
       2017-05-22 07:24:42 +08:00
    @paubrk 不配置 http 参数的话,那 type 是填成 tcp 吗
    wwqgtxx
        15
    wwqgtxx  
       2017-05-22 08:24:23 +08:00
    @yangxuan8282
    [rdp]
    privilege_mode = true
    type = tcp
    local_ip = 127.0.0.1
    local_port = 3389
    use_encryption = true
    use_gzip = true
    remote_port = 53389

    类似于如上参数,另外我的 frp 是 0.9.3 版本的,如果你用最新的 0.10 版本的话,自行把 privilege_mode 去掉
    paubrk
        16
    paubrk  
       2017-05-22 08:29:41 +08:00
    @yangxuan8282 是的,因为 http 协议基于 tcp 协议
    yangxuan8282
        17
    yangxuan8282  
    OP
       2017-05-22 09:09:48 +08:00
    @wwqgtxx
    我是用的 0.10 版本,按着你的配置文件改了一下,但是改了之后访问不了


    server 端配置文件

    ```
    root@localhost:~/repos/frp/frp_0.10.0_linux_amd64# cat frps.ini
    # frps.ini
    [common]
    bind_port = 7000
    ```

    client 端配置文件

    ```
    pi@raspberrypi:~/frp_0.10.0_linux_arm $ cat frpc.ini
    # frpc.ini
    [common]
    server_addr = $SERVER_IP
    server_port = 7000
    type = tcp
    local_ip = 127.0.0.1
    local_port = 80
    use_gzip = true
    remote_port = 80
    ```

    不知道是哪里有问题
    wwqgtxx
        18
    wwqgtxx  
       2017-05-22 09:48:16 +08:00 via iPhone
    @yangxuan8282 你好好看看官方的配置文件事例,frpc 配置文件不是这么写的
    Tink
        19
    Tink  
       2017-05-22 10:06:27 +08:00
    这几天也有同样的需求,准备试试狗洞,frp 不是很满意
    yangxuan8282
        20
    yangxuan8282  
    OP
       2017-05-22 10:17:20 +08:00 via iPhone
    对比了一下打开 novnc 的速度,狗洞比 frp 快很多,如果网络稳定的话,狗洞 lite 应该是目前最合适的方案
    wwqgtxx
        21
    wwqgtxx  
       2017-05-22 10:24:54 +08:00 via iPhone   ❤️ 1
    client 端配置文件应该这样写

    ```
    [common]
    server_addr = $SERVER_IP
    server_port = 7000
    [http]
    type = tcp
    local_ip = 127.0.0.1
    local_port = 80
    use_compression=true
    remote_port = 80
    ```
    wwqgtxx
        22
    wwqgtxx  
       2017-05-22 10:27:34 +08:00 via iPhone
    @yangxuan8282
    @Tink
    dog-tunnel lite 的断线后端口已占用也是个蛋疼的坑
    Tink
        23
    Tink  
       2017-05-22 10:29:22 +08:00
    @wwqgtxx #22 感觉这个得写个脚本不停的测试,发现断了之后把进程杀了再重启
    wwqgtxx
        24
    wwqgtxx  
       2017-05-22 10:34:05 +08:00 via iPhone
    @Tink 这也是我从 dt lite 转向 frp 的原因,至于 kcp,实在不行用 kcptun 套一层就行了嘛
    chinajik
        25
    chinajik  
       2017-05-22 11:07:33 +08:00
    frp 可以自动增加节点,做跳板机很好
    Pepsigold
        26
    Pepsigold  
       2017-05-22 17:04:44 +08:00 via iPhone
    @fzinfz 这个可以,正在用
    yangxuan8282
        27
    yangxuan8282  
    OP
       2017-05-22 17:40:44 +08:00
    @wwqgtxx 按你后来给的配置试了一下可以了,我以为 `[http]` 只是说明,不起实际作用
    wwqgtxx
        28
    wwqgtxx  
       2017-05-22 18:00:25 +08:00
    @yangxuan8282 带方括号的在 ini 文件中为代码段,如果是说明的话,应该用井号注释才对
    yangxuan8282
        29
    yangxuan8282  
    OP
       2017-05-22 18:00:53 +08:00
    @Tink
    @wwqgtxx
    狗洞断线重连后端口已占用这个 bug 确实挺难受的
    下午尝试了一下用 systemd 管理狗洞,用两个脚本分别控制狗洞的启动和停止
    直接运行两个脚本可以正常启停,不过到了 systemd 里一启动就退了,也没看到什么报错

    下面两个脚本分别是启动和停止狗洞的,为了防止出现端口已占用的情况,启动前先把 server 上之前的狗洞给停了再启动,停止的脚本也是把 server 和 client 都停了

    ```
    pi@raspberrypi:~ $ cat /usr/local/bin/dtunnel-up.sh
    #!/bin/bash
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl stop dtunnel-server
    sleep 3
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl start dtunnel-server
    /usr/bin/screen -dmS dtunnel /usr/local/bin/dog-tunnel -service $SERVER_IP:1234 -v -action 127.0.0.1:80 -encrypt -xor $XOR -local :80 -pipe 5 -r
    ```

    ```
    pi@raspberrypi:~ $ cat /usr/local/bin/dtunnel-down.sh
    #!/bin/bash
    #set -e
    /usr/bin/screen -S dtunnel -X quit
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl stop dtunnel-server
    ```

    下面是 client 上狗洞的 systemd,启动和停止分别执行上面两个脚本,可惜用 systemd 运行就不行了,运行 sudo systemctl start http-dtunnel 后查看也没开 screen 会话,直接运行 sudo /usr/local/bin/dtunnel-up.sh 的话会建立一个名为 dtunnel 的会话,然后在会话里连接 server

    ```
    pi@raspberrypi:~ $ cat /etc/systemd/system/http-dtunnel.service
    [Unit]
    Description=Dog tunnel for http
    After=network.target

    [Service]
    ExecStart=/usr/local/bin/dtunnel-up.sh
    ExecStop=/usr/local/bin/dtunnel-down.sh
    Restart=always
    RestartSec=60

    [Install]
    WantedBy=multi-user.target
    ```
    wwqgtxx
        30
    wwqgtxx  
       2017-05-22 18:07:53 +08:00
    @yangxuan8282 在 systemd 脚本中就不要用 screen 了,这样 systemd 会直接认为你的程序已经退出了
    wwqgtxx
        31
    wwqgtxx  
       2017-05-22 18:09:03 +08:00
    而且 systemd 的进程管理默认是用 cgroups 的,所以他可以强行结束一个完整的任务组,就算是 screen 新开的会话也会被强行关闭
    ys0290
        32
    ys0290  
       2017-05-22 18:13:48 +08:00 via iPhone
    换宽带
    wwqgtxx
        33
    wwqgtxx  
       2017-05-22 18:15:36 +08:00   ❤️ 1
    建议做法
    ```
    pi@raspberrypi:~ $ cat /usr/local/bin/dtunnel-up.sh
    #!/bin/bash
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl stop dtunnel-server
    sleep 3
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl start dtunnel-server
    /usr/local/bin/dog-tunnel -service $SERVER_IP:1234 -v -action 127.0.0.1:80 -encrypt -xor $XOR -local :80 -pipe 5 -r
    ```
    ```
    pi@raspberrypi:~ $ cat /usr/local/bin/dtunnel-down.sh
    #!/bin/bash
    #set -e
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl stop dtunnel-server
    ```
    ```
    pi@raspberrypi:~ $ cat /etc/systemd/system/http-dtunnel.service
    [Unit]
    Description=Dog tunnel for http
    After=network.target

    [Service]
    ExecStart=/usr/local/bin/dtunnel-up.sh
    ExecStop=/usr/local/bin/dtunnel-down.sh
    Restart=always
    RestartSec=60

    [Install]
    WantedBy=multi-user.target
    ```
    这样就够了,systemd 可以自行结束所有该结束的子进程的
    yangxuan8282
        34
    yangxuan8282  
    OP
       2017-05-22 18:52:09 +08:00
    @wwqgtxx 果真不放在 screen 会话里直接运行就好了,谢谢了,本来以为白忙活了
    刚才特意断网线试了一下好像能自动重连,也没看到端口已占用的报错
    再试几天看看是否稳定
    看来还是对 systemd 了解不够啊
    待会整理个完整的配置脚本出来
    yangxuan8282
        35
    yangxuan8282  
    OP
       2017-05-22 20:26:50 +08:00
    再附一张浏览器内访问用狗洞 lite 暴露到公网的 novnc 截图

    机器是搬瓦工的,延迟还是比较高,不过整体算能用
    wwqgtxx
        36
    wwqgtxx  
       2017-05-22 20:42:47 +08:00
    另外就是你文件中的
    ···
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl stop dtunnel-server
    sleep 3
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl start dtunnel-server
    ···
    可以直接换成
    ···
    ssh -f -i /home/pi/.ssh/$SERVER_SSH_KEY root@$SERVER_IP -p $SERVER_SSH_PORT sudo systemctl restart dtunnel-server
    ···
    这样还能省点时间
    wwqgtxx
        37
    wwqgtxx  
       2017-05-22 20:45:06 +08:00
    好吧,看开不用我说了,看了你的文件已经这样改过了
    fatedier
        38
    fatedier  
       2017-05-22 23:51:56 +08:00   ❤️ 2
    @yangxuan8282 Hi,我是 frp 的开发者,对于你所说的「 狗洞比 frp 快很多,如果网络稳定的话,狗洞 lite 应该是目前最合适的方案」,我比较好奇,因为从原理上来说 dog-tunnel lite 和 frp 应该是相同的,都是通过服务端来转发请求,所以性能上不应该存在太大差距。

    所以我忍不住自己做了一个非常简单的关于 http 页面的性能测试,并不是很严谨,仅供参考。

    客户端:mbp13 8GB 内存 100MB 下行,4MB 上行带宽
    服务端:阿里云 centos7,1 核 1G 内存,20MB 带宽
    工具:ab v2.3, 并发数 5, 不启用 keepalive
    测试页面:/op 2.9KB, /static/css/bootstrap.min.css 119KB
    网络延迟:30ms 左右

    frp v0.10.0 和 dog-tunnel lite v1.30 都使用最简单的 tcp 映射配置,5 个连接池。

    测试详细结果: https://gist.github.com/fatedier/59d0ed9252b5310ccd2a36632232488d

    简单写一下结果:

    10000 次请求 2.9KB 页面:
    frp: 耗时 61.851s QPS: 161.68
    dog-tunnel lite: 117.091s QPS: 85.40

    500 次请求 119KB 页面:
    frp: 103.603s QPS: 4.83
    dog-tunnel lite: 227.868s QPS: 2.19

    通过测试看出「 狗洞比 frp 快很多」并不是绝对的,也许和具体的使用场景相关,如果能给出详细的测试数据,我就可以有针对性的进行优化。

    注:这里所指的是「 狗洞 lite 」也就是 dog-tunnel lite,并非 p2p 模式,如果是 p2p 模式的 dog-tunnel,流量不经过服务器,性能必然会提升很多。
    pagxir
        39
    pagxir  
       2017-05-22 23:57:10 +08:00
    @fatedier 它是指下载吧,不是指响应速度。别人是暴力发包,没得比的。
    fatedier
        40
    fatedier  
       2017-05-23 00:09:15 +08:00
    @pagxir 我看他的描述有一句「 如果网络稳定的话」,网络稳定的情况下如果没有丢包,暴力发包的策略并没有什么效果,可以忽略。

    对于有丢包的情况下,确实会对于下载类请求会提升比较明显。当然,这个更像是 锐速,google bbr,kcptun 所做的事情。后面 frp 可能也会考虑底层支持 kcp 协议,这个和应用本身的性能关系不大。
    yangxuan8282
        41
    yangxuan8282  
    OP
       2017-05-23 00:37:21 +08:00 via iPhone
    @fatedier 我说的网络稳定只是指的不断线,我这里因为是用的 4G 网,晚上掉线的时候比较多,狗洞掉线重连会有端口已占用的报错,之前一直被这个这个困扰,想找个别的方式,今天在 v 友帮助下算是临时解决了这个问题,所以暂时先不换了
    yangxuan8282
        42
    yangxuan8282  
    OP
       2017-05-23 00:46:11 +08:00 via iPhone
    @fatedier 速度的话我没具体测,只是对比感觉狗洞明显快一些,服务器在国外,连国外线路丢包比较明显,所以 kcp 应该是有提升
    不知道以后 frp 有没有加入 kcp 的计划
    tinyproxy
        43
    tinyproxy  
       2017-05-23 09:23:19 +08:00 via iPad
    我图省事直接挂 tor hidden service,不过速度也就 ssh 还能接受吧,其他用途还是算了。
    yangxuan8282
        44
    yangxuan8282  
    OP
       2017-05-24 18:55:46 +08:00
    @wwqgtxx 问下如果想加一个类似 check if site down 的检测的话,是用 crontab 好还是用 systemd timer 合适
    大体的想法是每小时用 `curl -Is $URL | head -n 1` 查看 statuscode 是否是 "HTTP/1.1 200 OK",如果不是的话就说明连接断开了,那就重启狗洞的 systemd:systemctl restart http-dtunnel
    wwqgtxx
        45
    wwqgtxx  
       2017-05-24 19:13:21 +08:00
    @yangxuan8282 其实用哪个区别不大,你哪个顺手就用谁呗,反正回头还是要靠写 shell 脚本来完成
    yangxuan8282
        46
    yangxuan8282  
    OP
       2017-05-28 18:13:12 +08:00
    @wwqgtxx 再打扰问下 systemd 有办法同时运行两条命令吗,狗洞一次只能穿透一个端口,如果想同时把 80 和 443 暴露到互联网的话就需要运行两次,之前的 `dtunnel-up.sh` 脚本我改写了一下:

    **dtunnel-up.sh**

    ```
    #!/bin/bash

    #ssh -f -i $SERVER_SSH_KEY $SSH_USER@$SERVER_IP -p $SSH_PORT "sudo systemctl restart dtunnel-server"
    /usr/local/bin/dog-tunnel -service $SERVER_IP:1234 -v -action 127.0.0.1:80 -encrypt -xor $XOR -local :80 -pipe 5 -r &
    /usr/local/bin/dog-tunnel -service $SERVER_IP:1234 -v -action 127.0.0.1:443 -encrypt -xor $XOR -local :443 -pipe 5 -r &
    #wait
    ```

    单独运行脚本的话可以同时把 80 和 443 暴露到外网,但是如果用 systemd 去启动这个脚本的化行为会比较奇怪,按说应该在后台运行的,但是时不时输出就会跳到前台,而且按 ctrl + c 暂时退了之后还会出现,只能用 `ps -aux | grep dog-tunnel` 找出 PID,然后手动杀掉进程

    如果单个 systemd 不能管理两个端口的话只好单独写两个 systemd 分别对应 80 和 443,然后再另外写一个 systemd 去管这两个了
    wwqgtxx
        47
    wwqgtxx  
       2017-05-28 21:10:14 +08:00 via iPhone
    在我的记忆中是没有的,不过你可以用 python 的 popen 来跑多个子进程,然后记得调用 wait 就行,systemd 在调用 stop 的时候会连带子进程一起干掉的
    stonehe
        48
    stonehe  
       2017-06-24 20:20:49 +08:00
    我只使用过 ngrok 和 frp,vultr 洛杉矶的 vps 做服务器。家里组装 nas,安装 omv 做主系统,通过 web 访问。前期装 ngrok,使用路由器 openwrt 的 ngrok 客户端转发给 nas,外网访问 omv 的 web 界面,弹出错误频率比较高(可能是传输数据丢包导致),后面尝试 frp,用 nas 本身做客户端,几乎没有弹出错误,而且明显感觉加载流畅。因为一个是经过路由器转发,一个是 nas 本身,所以没办法断言 frp 和 ngrok 效率优劣。
    domwang
        49
    domwang  
       2018-04-22 15:59:53 +08:00
    Holer 很好用,是一个免费开源的内网穿透工具,它可以将局域网服务器代理到公网的内网穿透工具,支持转发基于 TCP 协议的报文。

    Holer 地址:
    https://github.com/Wisdom-Projects/holer
    probezy
        50
    probezy  
       2018-11-11 16:12:29 +08:00
    如果觉得自己搭建麻烦,可以使用 cpolar-安全内网穿透工具,用来做微信公众号接口联调,树莓派远程,内网 web 穿透都很方便,而且它是免费的,官网地址:www.cpolar.com
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1112 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:34 · PVG 07:34 · LAX 15:34 · JFK 18:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.