前言
本文会紧接着《网络操作系统VyOS应用实践(二)》进一步在模拟环境中体验VyOS的功能。
BGP
BGP协议与OSPF、RIP等协议不同,是一个用于AS间的路由协议,一般用在大型网络中,比如Provider Network之间。
BGP用于路由的管理,有丰富的路由属性,提高管理的灵活性。
BGP协议中下一跳是一个AS,而AS内部协议一般是下一个路由。
BGP分为EBGP和IBGP,EBGP用于AS间,IBGP用于AS内的BGP路由的连接。这个实验仅展示如何配置EBGP
在VyOS上,进行基本的BGP设置的流程为:
1.为选定的要作为边界路由的路由器设置AS号。
2.设置邻居和ebgp-multihop的值,ebgp-multihop可以简单理解为限制它在多少跳内进行交流。
3.设置本边界路由的update-source。
4.宣告管理的网络。
5.设置路由ID,这一点和配置OSPF时是一样需要的。
首先我们必须先设置号vm1和vm2的网关,vm1的网关为192.168.225.2,而vm2的网关为192.168.10.5,这两个VM将会用于测试路由配置是否成功。
为了配置BGP路由,有以下几个重要的命令:
1.set protocols bgp SELF-AS neighbor ADDR ebgp-multihop NUM:这条命令设置本边界路由的AS号并设置ebgp-multihop的值。
2.set protocols bgp SELF-AS neighbor ADDR remote-as AS:设置邻居的AS号,一般要事先规划好AS号再对VyOS进行设置。remote-as所指定的就是邻居的AS号。在本次试验中,vyos1与vm1在AS65537中,而vyos2和vm2在AS65538中。
3.set protocols bgp SELF-AS neighbor ADDR update-source SELF-ADDR:用这条命令设置更新源,实际上这条命令的意思是“邻居的更新源是我自己”,因此update-source后跟的是本路由的地址。
4.set protocols bgp SELF-AS network CIDR:宣告自己管理的网络,OSPF和RIP有类似功能的命令,可以参考本系列前一篇文章。
5.set protocols bgp SELF-AS parameters router-id ID:为该BGP路由器设置router id。
下面展示试验的具体操作:
进入vyos1,进行BGP设置:
1 2 |
vyos@vyos:~$ configure [edit] |
限制在2跳内交流:
1 2 |
vyos@vyos# set protocols bgp 65537 neighbor 192.168.202.4 ebgp-multihop '2' [edit] |
设置邻居vyos2的as号:
1 2 |
vyos@vyos# set protocols bgp 65537 neighbor 192.168.202.4 remote-as '65538' [edit] |
设置更新源:
1 2 |
vyos@vyos# set protocols bgp 65537 neighbor 192.168.202.4 update-source '192.168.202.3' [edit] |
宣告负责的网络,这里是vyos1与vm1相连的网络:
1 2 |
vyos@vyos# set protocols bgp 65537 network '192.168.225.0/24' [edit] |
最后用一个略与OSPF设置不同的方法设置路由ID:
1 2 3 4 |
vyos@vyos# set protocols bgp 65537 parameters router-id '192.168.202.3' [edit] vyos@vyos# commit [edit] |
在vyos2上也进行同样的设置:
1 2 3 4 5 6 7 8 9 10 11 12 |
vyos@vyos:~$ configure [edit] vyos@vyos# set protocols bgp 65538 neighbor 192.168.202.3 ebgp-multihop '2' [edit] vyos@vyos# set protocols bgp 65538 neighbor 192.168.202.3 remote-as '65537' [edit] vyos@vyos# set protocols bgp 65538 neighbor 192.168.202.3 update-source '192.168.202.4' [edit] vyos@vyos# set protocols bgp 65538 network '192.168.10.0/24' [edit] vyos@vyos# set protocols bgp 65538 parameters router-id '192.168.202.4' [edit] |
最后,在每个vyos系统上设置一个blackhole路由:
指向vm1的:
1 2 |
vyos@vyos# set protocols static route 192.168.225.0/24 blackhole distance '254' [edit] |
指向vm2的:
1 2 |
vyos@vyos# set protocols static route 192.168.10.0/24 blackhole distance '254' [edit] |
最后检查连通性:
1 2 3 4 5 6 7 8 9 10 |
root@test1:~# ping -c 4 192.168.10.10 PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data. 64 bytes from 192.168.10.10: icmp_seq=1 ttl=62 time=0.621 ms 64 bytes from 192.168.10.10: icmp_seq=2 ttl=62 time=0.601 ms 64 bytes from 192.168.10.10: icmp_seq=3 ttl=62 time=1.40 ms 64 bytes from 192.168.10.10: icmp_seq=4 ttl=62 time=0.832 ms --- 192.168.10.10 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3002ms rtt min/avg/max/mdev = 0.601/0.865/1.406/0.325 ms |
用Wireshark抓包,首先就看到BGP的keepalive消息:
备注:在win10环境下似乎必须使用管理员身份才能对网络接口实现抓包,否则Wireshark会直接提示找不到网口。
Route-map
在《网络操作系统VyOS应用实践(二)》的最后一个例子(OSPF)中,最后提到要设置route-map,这里只引用官方文档的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
set policy prefix-list AS65537-IN rule 10 action 'permit' set policy prefix-list AS65537-IN rule 10 prefix '2.0.0.0/16' set policy prefix-list AS65537-OUT rule 10 action 'deny' set policy prefix-list AS65537-OUT rule 10 prefix '2.0.0.0/16' set policy prefix-list6 AS65537-IN rule 10 action 'permit' set policy prefix-list6 AS65537-IN rule 10 prefix '2a00:100:2::/48' set policy prefix-list6 AS65537-OUT rule 10 action 'deny' set policy prefix-list6 AS65537-OUT rule 10 prefix '2a00:100:2::/48' set policy route-map AS65537-IN rule 10 action 'permit' set policy route-map AS65537-IN rule 10 match ip address prefix-list 'AS65537-IN' set policy route-map AS65537-IN rule 10 match ipv6 address prefix-list 'AS65537-IN' set policy route-map AS65537-IN rule 20 action 'deny' set policy route-map AS65537-OUT rule 10 action 'deny' set policy route-map AS65537-OUT rule 10 match ip address prefix-list 'AS65537-OUT' set policy route-map AS65537-OUT rule 10 match ipv6 address prefix-list 'AS65537-OUT' set policy route-map AS65537-OUT rule 20 action 'permit' set protocols bgp 65536 neighbor 2a00:100::2 route-map export 'AS65537-OUT' set protocols bgp 65536 neighbor 2a00:100::2 route-map import 'AS65537-IN' |
有兴趣的研究者,可以参考brocade提供的vyatta路由策略手册:
本文就不再多对这个内容进行探讨。
基于区域的防火墙
在这个实验中,采取和前一篇文章中简单路由中一样的网络结构,只不过vyos不仅起路由器的作用,还起防火墙的作用。
网络结构:
读者可以参考前面《网络操作系统VyOS应用实践(二)》中的设置方式设置虚拟机和操作系统。
这里省略其他设定,直接登录vyos进行防火墙的设置。在VyOS中,配置防火墙时可以让一系列需要应用同样规则的网络、端口或地址组成一个组。而在配置防火墙时,可以通过将网络划分为多个区域,并将防火墙规则应用到区域与区域之间的数据流动策略。在网络工具Calico中,也是采取了类似的策略,通过分组应用策略,从而简化配置手续。
本实验目标:
为machine1所在的10.20.10.0/24划分为internal区域,machine2所在的192.168.10.0/24划分为external区域。
最终的防火墙规则是只允许来自192.168.10.10,访问machine1的1300和1400端口的TCP数据。默认的行动为reject。
在VyOS上设置基于区域的防火墙的流程一般是:
1.先规划网络,考虑怎样划分区域。
2.创建区域,并将不同的网络接口划分给不同区域。
3.有需要时,创建port-group,address-group和network-group。
4.创建具体的防火墙规则,并把需要的组别与其绑定,一个端口组可以和多条规则绑定。
5.对区域间的数据流动方向应用不同的策略。
VyOS的防火墙规则设置相比iptables更加直观,因此很容易上手。
登陆vyos,开始进行设置:
1 2 3 4 5 |
vyos@vyos:~$ show firewall ----------------------------- Rulesets Information ----------------------------- |
可以看到此时并没有任何防火墙规则。
1 2 3 4 5 6 7 8 9 10 |
vyos@vyos:~$ show interfaces Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down Interface IP Address S/L Description --------- ---------- --- ----------- eth0 172.16.77.184/24 u/u manage eth1 10.20.10.11/24 u/u eth2 192.168.10.11/24 u/u eth3 192.168.202.11/24 u/u lo 127.0.0.1/8 u/u ::1/128 |
设定好eth1和eth2,并把machine1和machine2的网关设为eth1和eth2的地址。
先创建区域:
1 2 3 4 5 6 |
vyos@vyos:~$ configure [edit] vyos@vyos# set zone-policy zone INTERNAL description "internal network" [edit] vyos@vyos# set zone-policy zone EXTERNAL description "external network" [edit] |
上面创建了一个internal和external network,实际上,如果要求更多,可以创建更多的区域。
划分网络接口给不同区域:
1 2 3 4 |
vyos@vyos# set zone-policy zone INTERNAL interface eth1 [edit] vyos@vyos# set zone-policy zone EXTERNAL interface eth2 [edit] |
先commit一下:
1 2 |
vyos@vyos# commit [edit] |
可以看到zone的信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
vyos@vyos# run show zone ------------------- Name: EXTERNAL [external network] Interfaces: eth2 From Zone: name firewall ---- -------- ------------------- Name: INTERNAL [internal network] Interfaces: eth1 From Zone: name firewall ---- -------- [edit] |
实际上,一旦设定了zone,原本可以ping通的两个vm现在就无法ping通,因为没有设置任何防火墙策略,任何包都会drop,所以如果你尝试在machine1上ping machine2,是不会得到任何回应的。
因为允许TCP数据经过1300和1400端口,我们可以为这两个端口设置一个port group:
1 2 3 4 |
vyos@vyos# set firewall group port-group PG1 port 1300 [edit] vyos@vyos# set firewall group port-group PG1 port 1400 [edit] |
可以在普通模式下查看已经设置成功的PG1,类型为port group,还没关联到任何规则上:
1 2 3 4 5 6 7 |
vyos@vyos:~$ show firewall group Name : PG1 Type : port References : none Members : 1300 1400 |
开始根据前面的目的设置防火墙规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
vyos@vyos# set firewall name EX-TO-IN default-action reject [edit] vyos@vyos# set firewall name EX-TO-IN rule 1 action accept [edit] vyos@vyos# set firewall name EX-TO-IN rule 1 state established enable [edit] vyos@vyos# set firewall name EX-TO-IN rule 1 state related enable [edit] vyos@vyos# set firewall name EX-TO-IN rule 10 action accept [edit] vyos@vyos# set firewall name EX-TO-IN rule 10 destination group port-group PG1 [edit] vyos@vyos# set firewall name EX-TO-IN rule 10 source address 192.168.10.10 [edit] vyos@vyos# set firewall name EX-TO-IN rule 10 protocol tcp [edit] vyos@vyos# commit [edit] |
默认规则为拒绝,如果设置了drop,外部网络将不会得到任何回应,尽管drop能令性能有所提高。
上面的操作只是完成了防火墙配置的第一步,即external网络中的数据流入internal的规则,下面还要创建internal网络中的数据返回external的规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
vyos@vyos# set firewall name IN-TO-EX default-action reject [edit] vyos@vyos# set firewall name IN-TO-EX rule 1 action accept [edit] vyos@vyos# set firewall name IN-TO-EX rule 1 state established enable [edit] vyos@vyos# set firewall name IN-TO-EX rule 1 state related enable [edit] vyos@vyos# set firewall name IN-TO-EX rule 10 action accept [edit] vyos@vyos# set firewall name IN-TO-EX rule 10 source group port-group PG1 [edit] vyos@vyos# set firewall name IN-TO-EX rule 10 source address 10.20.10.10 [edit] vyos@vyos# set firewall name IN-TO-EX rule 10 protocol tcp [edit] vyos@vyos# commit [edit] |
上面的设置中,比较重要的设置语法是设置rule 10时的source group,要指定group类型和名称(VyOS中有port group,address group和network group)。如果在设组时想直接指定一个范围可以这样(此例子来源官方文档):
1 |
set firewall group port-group PORT-TCP-SERVER1 port 5000-5010 |
最后,我们把规则EX-TO-IN应用在来自external网络的通往internal网络的数据流动策略:
1 2 |
vyos@vyos# set zone-policy zone INTERNAL from EXTERNAL firewall name EX-TO-IN [edit] |
应用IN-TO-EX:
1 2 |
vyos@vyos# set zone-policy zone EXTERNAL from INTERNAL firewall name IN-TO-EX [edit] |
commit并保存,退出configure模式。
我们可以看到目前的防火墙策略:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
vyos@vyos:~$ show firewall ----------------------------- Rulesets Information ----------------------------- -------------------------------------------------------------------------------- IPv4 Firewall "EX-TO-IN": Active on traffic to - zone [INTERNAL] from zone [EXTERNAL] rule action proto packets bytes ---- ------ ----- ------- ----- 1 accept all 0 0 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 state RELATED,ESTABLISHED 10 accept tcp 0 0 condition - saddr 192.168.10.10 daddr 0.0.0.0/0 match-set PG1 dst 10000 reject all 0 0 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 -------------------------------------------------------------------------------- IPv4 Firewall "IN-TO-EX": Active on traffic to - zone [EXTERNAL] from zone [INTERNAL] rule action proto packets bytes ---- ------ ----- ------- ----- 1 accept all 0 0 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 state RELATED,ESTABLISHED 10 accept tcp 0 0 condition - saddr 10.20.10.10 daddr 0.0.0.0/0 match-set PG1 src 10000 reject all 0 0 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 |
尝试在machine1上ping machine2:
在machine2上ping machine1:
因为防火墙没有允许icmp包的通过,并且默认action为reject,所以会显示destination port unreachable。
经过ping之后,防火墙记录了被拒绝的包数量:
1 2 |
10000 reject all 4 336 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 |
下面会用一个python xmlrpc程序验证我们的配置是否正确,在machine1上创建server.py:
1 2 3 4 5 6 7 8 9 |
from SimpleXMLRPCServer import SimpleXMLRPCServer def is_even(n): return n%2 == 0 server = SimpleXMLRPCServer(('0.0.0.0',1300)) print 'listen' server.register_function(is_even,'is_even') server.serve_forever() |
xmlrpc使用TCP协议,程序一开始的端口为1300,在machine1上启动server.py,再在machine2上测试:
1 2 |
root@machine1:~# python server.py listen |
先用netcat:
1 2 3 4 5 6 |
root@machine2:~# nc -v -w 1 10.20.10.10 -z 1300 Connection to 10.20.10.10 1300 port [tcp/wipld] succeeded! root@machine2:~# nc -v -w 1 10.20.10.10 -z 1400 nc: connect to 10.20.10.10 port 1400 (tcp) failed: Connection refused root@machine2:~# nc -v -w 1 10.20.10.10 -z 22 nc: connect to 10.20.10.10 port 22 (tcp) failed: Connection refused |
在python shell中测试一下:
1 2 3 4 5 6 7 8 9 10 |
root@machine2:~# python Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import xmlrpclib >>> proxy = xmlrpclib.ServerProxy("http://10.20.10.10:1300/") >>> print proxy.is_even(4) True >>> print proxy.is_even(3) False |
最后看一下EX-TO-IN的计数器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
IPv4 Firewall "EX-TO-IN": Active on traffic to - zone [INTERNAL] from zone [EXTERNAL] rule action proto packets bytes ---- ------ ----- ------- ----- 1 accept all 12 1262 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 state RELATED,ESTABLISHED 10 accept tcp 6 360 condition - saddr 192.168.10.10 daddr 0.0.0.0/0 match-set PG1 dst 10000 reject all 5 396 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 |
修改server.py的端口为1400,再进行测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
>>> proxy = xmlrpclib.ServerProxy("http://10.20.10.10:1400/") >>> print proxy.is_even(3) False --------------------分隔线------------------- root@machine2:~# nc -v -w 1 10.20.10.10 -z 1400 Connection to 10.20.10.10 1400 port [tcp/*] succeeded! --------------------分隔线------------------- zone [INTERNAL] from zone [EXTERNAL] rule action proto packets bytes ---- ------ ----- ------- ----- 1 accept all 20 2003 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 state RELATED,ESTABLISHED 10 accept tcp 8 480 condition - saddr 192.168.10.10 daddr 0.0.0.0/0 match-set PG1 dst 10000 reject all 5 396 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 |
可以看到防火墙的规则正在起效,经过刚才的操作,rule10的计数器加了2。
最后修改server.py的端口为1500,nc的结果是拒接连接
1 2 |
root@machine2:~# nc -v -w 1 10.20.10.10 -z 1500 nc: connect to 10.20.10.10 port 1500 (tcp) failed: Connection refused |
可以看到被拒绝了一个包:
1 2 |
10000 reject all 6 456 condition - saddr 0.0.0.0/0 daddr 0.0.0.0/0 |
至此,防火墙实验大功告成,也正确地完成了实验目标。
有关VyRoute
在前一篇文章我介绍了自己开发的VyRoute库,目前该库的完整度已经比较高,不过还差BGP协议的支持。目前,笔者已正式加入VyOS项目,因此Vyroute的代码库已经迁移到VyOS Development Group的Github下,地址:https://github.com/vyos/python-vyos-mgmt
重新选择了MIT协议开源并对代码的某些地方进行修改,实现对python3的支持(但是VyRoute所依赖的Exscript库在对python3的支持上还比较慢),对代码目录进行了规范化处理,在正式发布到PyPI之前,请直接clone python-vyos-mgmt的代码,可以选择编译为egg文件用easy_install安装。接下来还可能对API样式进行修改,具体的修改会通过文档反馈。虽然VyOS团队正在做向Debian8迁移的工作,迁移完成后,软件源丰富了,用户可以根据需求设计不同架构的API,但这个进展不是太快。因此等VyRoute完善后,成为VyOS的官方python API,可以一次性解决目前的基于Debian6的VyOS自动化管理问题和新系统的管理。
结语
本文通过实验介绍了VyOS的OSPF路由和防火墙功能,因为中文资料真的很少,希望能为各位VyOS研究者或潜在的使用者提供帮助。在后面的文章还会介绍它的其他功能。本人水平有限,如有缺点和漏洞,还请各位读者指出。
参考资料:
http://vyos.net/wiki/User_Guide
http://os.51cto.com/art/201108/285209.htm
http://itservice-bg.net/?p=105
https://www.fir3net.com/Routers/Brocade/vyatta-how-to-create-a-firewall-policy.html
作者简介:
何智刚,2015至今,准大学生一枚,主要研究Docker,OpenStack,SDN,对各种领域都有所涉猎,目标是迈向full stack。在保持其他领域的研究的同时,近期向数据中心领域进击。
qq:1097225749
github:https://github.com/Hochikong
注:投稿文章仅出于传递更多信息之目的,系SDNLAB《原创文章奖励计划》的投稿文章,仅供参考,不代表证实其描述或赞同其观点,投资者据此操作,风险自担;技术问题请留言指正。