复杂网络下的linux隧道

187 views
Skip to first unread message

lumin

unread,
Sep 6, 2014, 10:30:22 AM9/6/14
to xidian_linux_user_group
-------------------------------------------------------
网络结构:
[Server A](公网IP地址) --- IPv6出口故障
|
|(可通过IPv4 学校内网连接)
|
[Server B](校园网,数层NAT)--- IPv6出口正常
-----------------------------------------------------
希望达成的目的:
让Server A能够通过使用Server B的IPv6 access,从外网获得数据。
-----------------------------------------------------、

依据:
在这个网络结构下:
[host A](ipv4 and ipv6)-- [router](ipv4 only) --- [host B](ipv4 and
ipv6]
可以在AB之间建立一个gre tunnel,然后分给合适的IPv6地址,接下来A和B就可以
进行IPv6通信了。亲自测试通过。
然后我开脑洞了,,
假如Server B也是公网IP,那么或许
```
A# ip tunnel add name tun0 mode gre local $A_ipv4 remote $B_ipv4 dev
eth0
B# ip tunnel add name tun0 mode gre local $B_ipv4 remote $A_ipv4 dev
eth0
```
即建立一个GRE隧道。然后按照我实验中的简单模型,添加ipv6地址:
A : e::1/64
B : e::e/64 (这个v6地址仅供参考)
那么再在B上添加ipv6 NAT,将A的v6 default route转移到tun0上:
A# ip -6 route add to 0/0 via e::e dev tun0
或许A就可以进行与外界的IPv6通信了。
但最大的问题是,事实上B是在NAT里边的机器,GRE的穿透能力方面我没有概念。

我想既然能ping通,那就应该存在可行的方案,可以在两台机器之间建立隧道。
我找到可能的方案还有SSH,它有VPN实现,但是[Server B](校园网,数层NAT)---
IPv6出口正常
看起来很奇怪的样子。
还有OpenVPN,或者L2TP等VPN方案,穿透能力应该是可以了,SSH和openVPN我还没
有继续研究。但是SSH或者OpenSSH能像gre/ip6gre隧道那样进行 4in6/6in4 通信
吗?

以上仅是我的想法,我个人并没有两个公网IP来测试大这个脑洞,但是能阐述我想
要做的事。
因此,是否有前辈/高人 愿意指出
1.这个想法是否能够实现?
2.指一条明路吧。

不胜感激。

#校园网真乱。#上个网容易吗。#实现了从ipv6到ipv4的历史性飞跃。
--
Regards,
C.D.Luminate


lumin

unread,
Sep 6, 2014, 10:38:36 AM9/6/14
to xidian...@googlegroups.com
On Sat, 2014-09-06 at 14:30 +0000, lumin wrote:
> 我找到可能的方案还有SSH,它有VPN实现,但是[Server B](校园网,数层
> NAT)---
> IPv6出口正常
> 看起来很奇怪的样子。

我写道这里的时候邮件客户端崩溃,所以这段话本身也很奇怪,我检查漏了。原文
应该是:

我找到可能的方案还有SSH,它有VPN实现,但是SSH隧道有绑定单个端口的特点,感
觉不够用,另外虽然网上有基于ssh的vpn方案,但是我还没搞懂这是要表达个什
么,同时不知道ipv4 ssh tunnel是否能过ipv6包,总之看起来很奇怪的样子。


曹丰宇

unread,
Sep 6, 2014, 10:44:46 AM9/6/14
to xidian...@googlegroups.com

根据我们的情况为何我觉得sit tunnel比gre tunnel更合适?
两端都有公网ip……

--
您收到此邮件是因为您订阅了“西电开源社区”邮件列表。
要向此邮件列表发帖,请发送电子邮件至 xidian...@googlegroups.com
要取消订阅,请发送电子邮件至 xidian_linux...@googlegroups.com
请通过 https://groups.google.com/group/xidian_linux?hl=zh-CN 访问此网上论坛。
通过 [ipv6 enabled] http://xdlinux.info/http://xdl.in/
     [ipv4 only] http://linux.xidian.edu.cn/
      [手机]:http://m.xdlinux.info/
访问西电开源社区。
---
您收到此邮件是因为您订阅了 Google 网上论坛的“西电开源社区邮件列表”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到xidian_linux...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/d/optout

lumin

unread,
Sep 6, 2014, 10:47:22 AM9/6/14
to xidian...@googlegroups.com
> 但是SSH或者OpenSSH能像gre/ip6gre隧道那样进行 4in6/6in4 通信吗?

还有,这种但疼的方式会不会成功。

第一层,通过ipv4网络建立VPN。
第二层,在VPN的基础上再建立ipv4 GRE tunnel。

然后通过这个 “基于VPN建立的ipv4 GRE隧道” 进行IPv6通信。
那样的话这个IP封包头部太美简直不敢看。
不过它能干活就好。。。。。。。。。。

嗯。。。隧道中的隧道。
--
Regards,
C.D.Luminate


lumin

unread,
Sep 6, 2014, 10:50:25 AM9/6/14
to xidian...@googlegroups.com
On Sat, 2014-09-06 at 22:44 +0800, 曹丰宇 wrote:
> 根据我们的情况为何我觉得sit tunnel比gre tunnel更合适?
> 两端都有公网ip……

sit tunnel 我还没有了解到。
你不是说B端是动态地址么?


曹丰宇

unread,
Sep 6, 2014, 10:52:57 AM9/6/14
to xidian...@googlegroups.com

动态地址不代表这个IP不能是公网IP吧………我也是服你了,走回来路上我才想起来两台机器都没有NAT

Zhang Cheng

unread,
Sep 6, 2014, 12:34:58 PM9/6/14
to xidian...@googlegroups.com
回答你几个问题。

*基于 ipv4 的 gre tunnel 为什么能够通过 ipv6 数据?
这里面对几种常见的 tunnel 都有介绍,其中有个表格对此解释的很清楚,这里也顺道贴过来:

Inline image 1

*关于 ssh 的 tunnel,ssh 支持多种方式的 forward,常用的 -L、-R 和 -D,其中 -L 和 -R 都只涉及到一个端口,而 -D 从名字就可以看出 dynamic,是动态的,常说的通过 ssh socks 代理一般就是 -D ,这里forward 的内容包括 ipv4 和 ipv6。

* 还是 ssh tunnel,是的,即使 -D,本地也只能绑定一个端口,但是可以用 tun2socks 来虚拟一个 tun 设备,所有发往这个设备的包都可以设置通过一个socks代理转发出去。这个东西也支持ipv6,但是可惜仅支持tcp。但ssh socks代理本身是支持udp的。

*sit tunnel 和 gre tunnel 的比较,sit 跟 ipip 其实很像,不过sit仅支持ipv6。我个人觉得如果能用gre,并且没有特殊理由,那么没有必要使用sit。另外,gre和sit我都在用,我使用sit仅仅是因为另一端的机器不支持gre。

另外算是打个广告,我的博客上写了5篇关于我自己家里网关搭建的文章,欢迎围观:https://onebitbug.me/2014/05/28/building-a-gateway/

*openvpn也支持ipv6,无论tun模式还是tap模式。tap模式,其实就是个交换机,所以如果你的B是通过自动配置获取ipv6地址的话,那么与A连接tap模式的openvpn之后,A可以直接通过自动配置的方式获取ipv6,并且不需要配置NAT。如果是tun模式,那么需要像gre/sit那样,手动配置ipv6地址。这时候可以在B端配置arp proxy,并在两端设置合适的路由,使得不必配置ipv6的NAT。举例说,B自动获得的IP地址是:1234:5678::10/64,手动给A配置一个ip,例如 1234:5678::11/64,这时,在B的网络里其他设备是不知道有 ::11 这个主机的,所以可以在B上配置一个arp proxy:

    ip neigh add proxy 1234:5678::11/64 dev eth0

这样在B的网络里,如果有人问(arp)who has proxy 1234:5678::11 时,B就会说,我这里有这个ip,你把包往我这边送吧,等包送过来之后,路由给A即可。

*关于NAT,不知道B端的NAT设备你是否能够控制?如果你能控制这个NAT设备,那么你也可以直接使用gre tunnel:

    iptables -t nat -A PREROUTING -s $B-NAT-PUBLIC-IP -p 47 -j DNAT --to-destination $B-NAT-PRIVATE-IP

这样之后,A端配置时remote直接用B NAT之后的公网IP即可。

*最后,可能是你都知道的一些东西。建立隧道的命令,其实在linux下,建立ipip、sit、gre、isatap这几种隧道的命令都完全一样。(这四种都是走v4的隧道,还有走v6的隧道:ip6ip6、ipip6、ip6gre等,详见 `man ip tunnel`。)

    ip tunnel add $name mode $mode remote $remote-ip [local $local-ip] ttl 255
    # 这里面,$name可以是任何东西,不必要时tun0这种,如果系统里的tunnel比较多,建议取不同的名字,比如我家里有联通和宽带通两个出口,我通过联通出口连接科大某服务器的tunnel名字为 gre-lt-ustc,这样的名字比较容易管理。
    # local参数可以省略,这个参数有点类似于listen的功能,但是如果系统里有多个公网出口,那么还是写上好
    # ttl 这个参数,ipip可以不写,但是gre一定要写,后面的数字多少看自己的喜好。
    
    ip addr add $local-virtual-ip/32 dev $name
    # 这是给本地绑一个虚拟ip地址,由于是/32的,所以两边完全可以长的都不一样,比如一边是1.2.3.4,另一边是5.6.7.8,完全没有问题。不过其实除了诊断的作用外,完全不需要虚拟ip地址。

    ip link set $name up
    # 这句话其实等价于 ifconfig $name up,就是把这个网卡up起来

    ip route add default dev $name
    # 配置路由,这里不一定要default,按需配置。注意,这里配置路由时没有写 via $gw-ip,原因是,tunnel 跟eth不一样,通常eth都是连接在交换机上,从eth出去之后可能有许多直接相连的主机,因此必须指定网关的地址,以确定将包发给谁。而point-2-point的tunnel对端一定只有一个主机,所以就不需要via了,从这个口出去的包肯定给那个主机了。

OK,就分享这么多。



--
您收到此邮件是因为您订阅了“西电开源社区”邮件列表。
要向此邮件列表发帖,请发送电子邮件至 xidian...@googlegroups.com
要取消订阅,请发送电子邮件至 xidian_linux...@googlegroups.com
请通过 https://groups.google.com/group/xidian_linux?hl=zh-CN 访问此网上论坛。
通过 [ipv6 enabled] http://xdlinux.info/http://xdl.in/
     [ipv4 only] http://linux.xidian.edu.cn/
      [手机]:http://m.xdlinux.info/
访问西电开源社区。
---
您收到此邮件是因为您订阅了 Google 网上论坛的“西电开源社区邮件列表”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到xidian_linux...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/d/optout



--
Cheng,
Best Regards

Zhang Cheng

unread,
Sep 6, 2014, 12:42:28 PM9/6/14
to xidian...@googlegroups.com

2014-09-07 0:34 GMT+08:00 Zhang Cheng <steph...@gmail.com>:
*关于NAT,不知道B端的NAT设备你是否能够控制?如果你能控制这个NAT设备,那么你也可以直接使用gre tunnel:

    iptables -t nat -A PREROUTING -s $B-NAT-PUBLIC-IP -p 47 -j DNAT --to-destination $B-NAT-PRIVATE-IP

这样之后,A端配置时remote直接用B NAT之后的公网IP即可。

*最后,可能是你都知道的一些东西。建立隧道的命令,其实在linux下,建立ipip、sit、gre、isatap这几种隧道的命令都完全一样。(这四种都是走v4的隧道,还有走v6的隧道:ip6ip6、ipip6、ip6gre等,详见 `man ip tunnel`。)

    ip tunnel add $name mode $mode remote $remote-ip [local $local-ip] ttl 255
    # 这里面,$name可以是任何东西,不必要时tun0这种,如果系统里的tunnel比较多,建议取不同的名字,比如我家里有联通和宽带通两个出口,我通过联通出口连接科大某服务器的tunnel名字为 gre-lt-ustc,这样的名字比较容易管理。
    # local参数可以省略,这个参数有点类似于listen的功能,但是如果系统里有多个公网出口,那么还是写上好
    # ttl 这个参数,ipip可以不写,但是gre一定要写,后面的数字多少看自己的喜好。
    
    ip addr add $local-virtual-ip/32 dev $name
    # 这是给本地绑一个虚拟ip地址,由于是/32的,所以两边完全可以长的都不一样,比如一边是1.2.3.4,另一边是5.6.7.8,完全没有问题。不过其实除了诊断的作用外,完全不需要虚拟ip地址。

    ip link set $name up
    # 这句话其实等价于 ifconfig $name up,就是把这个网卡up起来

    ip route add default dev $name
    # 配置路由,这里不一定要default,按需配置。注意,这里配置路由时没有写 via $gw-ip,原因是,tunnel 跟eth不一样,通常eth都是连接在交换机上,从eth出去之后可能有许多直接相连的主机,因此必须指定网关的地址,以确定将包发给谁。而point-2-point的tunnel对端一定只有一个主机,所以就不需要via了,从这个口出去的包肯定给那个主机了。

​哦,刚才想到了但是漏说了,如果使用debian/ubuntu这系列的系统,使用interfaces文件来管理网络的话,tunnel也可以用interfaces文件来管理:

iface $name inet tunnel
    mode gre
    endpoint $remote-public-ip
    dstaddr $remote-virtual-ip
    address $local-virtual-ip
    local $local-public-ip​
​    gateway $remote-virtual-ip   # <- 这句话等价于 ip route add default dev $name,如果不想要配置全局路由的话,就不要这一行
    ttl 255
    up ip route add 1.0.0.0/24 dev $name
    up ip route add 2.0.0.0/24 dev $name  # <- post up脚本,如果不想配置全局路由,只想要部分路由,那么可以这样写,可以写多个up命令,也可以将所有路由配置写到一个脚本里,然后up后面跟这个脚本即可。​



--
Cheng,
Best Regards

lumin

unread,
Sep 6, 2014, 11:30:55 PM9/6/14
to xidian...@googlegroups.com
To Zhang Cheng:
非常感谢你如此详尽的回答。
不过我看了一部分就发现知识储备枯竭了 orz


Reply all
Reply to author
Forward
0 new messages