自家里的网络与公司的网络,相互隔离。现在下班后回到了家里,但是公司那边现在有一个业务需要自己去处理,这个时候自己就想要在家里访问公司内部的局域网了。
如果所有操作都通过公网ip绕,既不方便,也不安全。
如果拉专线,是最稳定可靠的办法。但是现在又没有多余的资金。
所以准备使用现有方案来解决这个需求。
自己家里的局域网是192.168.10.0/24,是通过PPOE拨号上网;
公网机里的局域网是10.100.0.0/24,有一个公网ip,通过公网ip进行上网;
这就遇到问题:自己家里的网络怎样能直接访问公司的内网?
这里有两个方案
1、点到点的虚拟专用网络。
2、GRE方案。
GRE是一种协议封装的格式,它规定了**如何用一种网络协议去封装另一种网络协议**。
将原来普通的包再封装一层GRE包,又**按照普通的ip包的路由方式进行路由**
**使用 tunnel(隧道)技术,数据报在tunnel的两端封装,并在这个通路上传输,到另外一端的时候解封装。**
**物理上的三层通信,虚拟上的二层通信**
0)gre建立turnel通道
1、 双方建立turnel的过程。
(1)局域网路由过程
1、主机MypC发送一个源为192.168.1.123,目的为10.100.0.123的包
(2)封装过程
1、根据默认路由网关,将之路由至192.168.1.1
2、192.168.1.1第1次封装包,增加增加gre包头,说明包的目的地址172.16.16.2和源地址172.16.16.1。
3、192.168.1.1第2次封装包,增加公网的包头(为了能在公网上传输),说明包的目的地址106.38.241.118和源地址221.234.230.1
4、192.168.1.1把所有到10.100.0.0/24的包,都地址转换为从172.16.16.1出(snat)
(3)公网路由过程
1、经过n个路由设备,该包最终路由到106.38.241.118
(4)拆包过程
1、CloudPC端的路由器检测到是到达自己的ip,就开始拆包
2、拆包之后发现有GRE协议,就进一步拆包
3、拆包之后发现目的地不是自己的内网ip、发现自己本地做了snat,就将至源ip替换为10.100.0.1
(5)到了局域网
1、数据包从源10.100.0.1到目标10.100.0.123,直接在局域网内广播。
2、10.100.0.123的主机经过确定后,发现是发送给自己的包,就接收。然后进一步处理。
(1)Tunnel 的数量问题
GRE 是一种点对点(point to point)标准。Neutron 中,所有计算和网络节点之间都会建立 GRE Tunnel。当节点不多的时候,这种组网方法没什么问题。但是,当有一个很大的数据中心,有 40000 个节点的时候,又会是怎样一种情形呢?使用标准 GRE的话,将会有 780 millions 个 tunnels。
(2)扩大的广播域
GRE 不支持组播,因此一个网络(同一个 GRE Tunnel ID)中的一个虚机发出一个广播帧后,GRE 会将其广播到所有与该节点有隧道连接的节点。
(3)GRE封装的IP包的过滤和负载均衡问题
目前还是有很多的防火墙和三层网络设备无法解析 GRE Header,因此它们无法对 GRE 封装包做合适的过滤和负载均衡。
VXLAN全称Virtual eXtensible LAN,是一种覆盖网络技术或隧道技术。
与GRE一样,封装、转发2层报文,物理上的三层通信,虚拟上的二层通信。
原始2层包+(1.vni id 2.组播地址)+udp报送+ip报头。
使用VXLAN网络模式,它会将主机发出的数据包封装在UDP中(vxlan建立的隧道都是无状态的了,这个做的好处是不用占用大量连接),并使用物理网络的IP/MAC在头部进行封装,然后在物理IP网上传输,到达目的地后由隧道终结点解封并将数据发送给目标主机。
具体参考
https://www.cnblogs.com/xingyun/p/4620727.html
https://www.sdnlab.com/11819.html
http://www.opencloudblog.com/?p=300
[root@controller /]# vim /etc/neutron/plugins/ml2/ml2_conf.ini
[ml2]
type_drivers=flat,vlan,vxlan,gre,local
tenant_network_types=vxlan
mechanism_drivers=openvswitch,l2population
[ml2_type_vxlan]
#指定vxlan的id范围,给普通租户用的
vni_ranges=1000:2000
[root@controller /]# systemctl restart neutron-server
[root@controller ~]# vim /etc/neutron/plugins/ml2/openvswitch_agent.ini
[ovs]
tenant_network_type=vxlan
#可以不要这一项了
bridge_mappings=
integration_bridge=br-int
tunnel_bridge=br-tun
#注意这个是本机的ip
local_ip=192.168.150.10
[root@computer /]# vim /etc/neutron/plugins/ml2/openvswitch_agent.ini
[ovs]
tenant_network_type=vxlan
bridge_mappings=
integration_bridge=br-int
tunnel_bridge=br-tun
local_ip=192.168.150.11
[root@controller /]# systemctl restart neutron-openvswitch-agent.service
[root@computer /]# systemctl restart neutron-openvswitch-agent.service
[root@controller ~(keystone_admin)]# openstack network create vxlan_net --project admin --provider-network-type vxlan --provider-segment 111
[root@controller ~(keystone_admin)]# openstack subnet create vxlan_subnet --project admin --network vxlan_net --subnet-range 172.16.166.0/24 --allocation-pool start=172.16.166.100,end=172.16.166.200
[root@controller ~(keystone_admin)]# openstack server create ServerA --image ciross --flavor web.ciross --nic net-id=2175ed07-99c9-4821-8cd8-3fd7148ab9f5 --availability-zone nova
[root@controller ~(keystone_admin)]# openstack server create ServerB --image ciross --flavor web.ciross --nic net-id=2175ed07-99c9-4821-8cd8-3fd7148ab9f5 --availability-zone cpu
ServerA->ping->ServerB
[root@controller opt]# virsh console instance-00000001
连接到域 instance-00000001
换码符为 ^]
login as 'cirros' user. default password: 'cubswin:)'. use 'sudo' for root.
cirros login: cirros
Password:
$ sudo su - root
# ifconfig eth0
eth0 Link encap:Ethernet HWaddr FA:16:3E:7A:F5:1D
inet addr:172.16.166.117 Bcast:172.16.166.255 Mask:255.255.255.0
inet6 addr: fe80::f816:3eff:fe7a:f51d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:92 errors:0 dropped:0 overruns:0 frame:0
TX packets:89 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5319 (5.1 KiB) TX bytes:5084 (4.9 KiB)
# ping 172.16.166.125
PING 172.16.166.125 (172.16.166.125): 56 data bytes
64 bytes from 172.16.166.125: seq=0 ttl=64 time=4.319 ms
64 bytes from 172.16.166.125: seq=1 ttl=64 time=1.883 ms
64 bytes from 172.16.166.125: seq=2 ttl=64 time=1.332 ms
--- 172.16.166.125 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.332/2.511/4.319 ms
ServerB->ping->ServerA
[root@computer /]# virsh console instance-00000002
连接到域 instance-00000002
换码符为 ^]
login as 'cirros' user. default password: 'cubswin:)'. use 'sudo' for root.
cirros login: cirros
Password:
$ sudo su - root
# ifconfig eth0
eth0 Link encap:Ethernet HWaddr FA:16:3E:29:99:6A
inet addr:172.16.166.125 Bcast:172.16.166.255 Mask:255.255.255.0
inet6 addr: fe80::f816:3eff:fe29:996a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:92 errors:0 dropped:0 overruns:0 frame:0
TX packets:89 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5311 (5.1 KiB) TX bytes:5084 (4.9 KiB)
# ping 172.16.166.117
PING 172.16.166.117 (172.16.166.117): 56 data bytes
64 bytes from 172.16.166.117: seq=0 ttl=64 time=25.137 ms
64 bytes from 172.16.166.117: seq=1 ttl=64 time=1.563 ms
64 bytes from 172.16.166.117: seq=2 ttl=64 time=1.587 ms
--- 172.16.166.117 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.563/9.429/25.137 ms
#进端口是qvo00a1bde0的arp请求就扔给table24
cookie=0xb188cb61096fc88b, duration=943.793s, table=0, n_packets=73, n_bytes=3066, priority=10,arp,in_port="qvo00a1bde0-be" actions=resubmit(,24)
#进端口是qvo00a1bde0的请求就扔给table25
cookie=0xb188cb61096fc88b, duration=943.798s, table=0, n_packets=27, n_bytes=2872, priority=9,in_port="qvo00a1bde0-be" actions=resubmit(,25)
#(table24)->进端口是qvo00a1bde0的arp请求,并且arp的源地址是172.16.166.117(ServerA)就扔给table25
cookie=0xb188cb61096fc88b, duration=943.794s, table=24, n_packets=73, n_bytes=3066, priority=2,arp,in_port="qvo00a1bde0-be",arp_spa=172.16.166.117 actions=resubmit(,25)
#(table24)->其他不符合table24匹配就丢掉
cookie=0xb188cb61096fc88b, duration=1898.495s, table=24, n_packets=0, n_bytes=0, priority=0 actions=drop
#(table25)->进端口是qvo00a1bde0并且MAC地址是ServerA的MAC地址,就扔给table60
cookie=0xb188cb61096fc88b, duration=943.801s, table=25, n_packets=98, n_bytes=5798, priority=2,in_port="qvo00a1bde0-be",dl_src=fa:16:3e:7a:f5:1d actions=resubmit(,60)
#(table60)->直接放行
cookie=0xb188cb61096fc88b, duration=1898.496s, table=60, n_packets=240, n_bytes=16454, priority=3 actions=NORMAL
根据serverA的MAC地址进行ARP的转发,同时也转发ipv4,ipv6的数据包
[root@controller opt]# ovs-ofctl dump-flows br-tun |grep table=0
cookie=0x49974807b8df046c, duration=2461.613s, table=0, n_packets=115, n_bytes=7801, idle_age=1020, priority=1,in_port=1 actions=resubmit(,2)
cookie=0x49974807b8df046c, duration=2456.202s, table=0, n_packets=0, n_bytes=0, idle_age=16008, priority=1,in_port=2 actions=resubmit(,3)
cookie=0x49974807b8df046c, duration=2456.154s, table=0, n_packets=98, n_bytes=5798, idle_age=1020, priority=1,in_port=3 actions=resubmit(,4)
cookie=0x49974807b8df046c, duration=2461.612s, table=0, n_packets=0, n_bytes=0, idle_age=16224, priority=0 actions=drop
发现一个有四条规则,分别从1,2,3口进来,其中最后一个是丢弃
[root@controller opt]# ovs-ofctl show br-tun
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000de7928e28a49
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1(patch-int): addr:4e:e7:e5:f0:48:28
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
2(gre-c0a8960b): addr:d6:7e:9e:b8:d5:0b
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
3(vxlan-c0a8960b): addr:ae:d0:fd:a0:9a:a6
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
LOCAL(br-tun): addr:de:79:28:e2:8a:49
config: PORT_DOWN
state: LINK_DOWN
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
得知2号口是gre可以不用管,看1和3口的规则就可以了 从1口(br-int,内部)进来的数据包转发到table2 从3口(vxlan-c0a,外部)进来的数据包转发到table4
[root@controller opt]# ovs-ofctl dump-flows br-tun |grep table=4
cookie=0x49974807b8df046c, duration=2524.908s, table=4, n_packets=98, n_bytes=5798, idle_age=1197, priority=1,tun_id=0x6f actions=mod_vlan_vid:1,resubmit(,10)
cookie=0x49974807b8df046c, duration=2638.056s, table=4, n_packets=0, n_bytes=0, idle_age=16400, priority=0 actions=drop
如果数据包的VXLAN tunnel ID为0x6f(十进制的111) 就添加内部VLAN ID 1(也就是br-int的tag),然后扔给table10去学习
[root@controller opt]# ovs-ofctl dump-flows br-tun |grep table=10
cookie=0x49974807b8df046c, duration=2723.722s, table=10, n_packets=98, n_bytes=5798, idle_age=1282, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,cookie=0x49974807b8df046c,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:OXM_OF_IN_PORT[]),output:1
学习从tunnel进来的包,往table20中添加对返程包的正常转发规则,然后从从port1(patch-int)转发到br-int
[root@controller /]# ovs-ofctl dump-flows br-tun |grep "\btable=2\b"
cookie=0x49974807b8df046c, duration=2795.990s, table=2, n_packets=23, n_bytes=2485, idle_age=1355, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)
cookie=0x49974807b8df046c, duration=2795.989s, table=2, n_packets=92, n_bytes=5316, idle_age=1724, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22)
br-int发过来的如果是单播包,扔给table20处理 br-int发过来的如果是多播或广播包,扔给table22处理
[root@controller opt]# ovs-ofctl dump-flows br-tun |grep "table=20"
cookie=0x49974807b8df046c, duration=15.750s, table=20, n_packets=17, n_bytes=1610, hard_timeout=300, idle_age=0, hard_age=0, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:29:99:6a actions=load:0->NXM_OF_VLAN_TCI[],load:0x6f->NXM_NX_TUN_ID[],output:3
cookie=0x49974807b8df046c, duration=2929.820s, table=20, n_packets=0, n_bytes=0, idle_age=16692, priority=0 actions=resubmit(,22)
第一条规则是table10学习来的结果。内部编号为4(tag=1),目标(ServerB)MAC地址是fa:16:3e:29:99:6a的数据包 处理动作是去掉VLAN号添加VXLAN tunnel ID 0x6f(111),并从port3(tunnel端口 vxlan-c0a8960b)发出 第二条规则是,对于没有学习到规则的数据包扔给table22处理
[root@controller /]# ovs-ofctl dump-flows br-tun |grep table=22
cookie=0x49974807b8df046c, duration=2955.336s, table=22, n_packets=80, n_bytes=4216, idle_age=154, priority=1,dl_vlan=1 actions=strip_vlan,load:0x6f->NXM_NX_TUN_ID[],output:3
cookie=0x49974807b8df046c, duration=3068.476s, table=22, n_packets=11, n_bytes=962, idle_age=2119, priority=0 actions=drop
如果数据包的内部VLAN号为(tag=1),处理动作就是去掉tag标记,添加VXLAN tunnel ID 0x6f(111),并从port3(tunnel端口 vxlan-c0a8960b)转发出去
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。