vlanforward
vlanforward
重要
默认关闭,谨慎使用。
功能简介
FortiGate 在不配置 VLAN 接口的情况下,默认不转发那些携带了 VLAN - TAG 的数据,携带了 VLAN - TAG 的数据会被认为是非 IP 数据,直接全部丢弃(set vlanforward disable)—— 默认 disable。
FortiGate_Transparent # config system interface
FortiGate_Transparent (interface) # edit port1
FortiGate_Transparent (port1) # show full-configuration | grep vlanforward
set vlanforward disable //默认即为disable假如 FortiGate 在不配置 VLAN 接口的情况下,默认转发那些携带了 VLAN - TAG 的数据(set vlanforward enable),也就是说 FortiGate(透明)上线一个新的环境,不清楚网络中是否跑了 VLAN,为了不影响那些不知道的 VLAN 的业务,于是开启 vlanforward,以便那些未知 VLAN 的业务可以正常通信。
听起来美好,但是实际上问题很大,考虑到 FortiGate 默认所有接口都是一个 forward-domain 0,如此的情况很容易引起广播风暴。因此在目前版本中 vlanforward 默认就为 disable 的状态。
通常来说我们上线 FortiGate 透明的时候需要详细的了解客户的业务情况,网络中是否有 VLAN 和 VLAN - ID 多少这些信息都是必须要去了解的,vlanforward enable 这种省事的方法不可取,非特别特别的情况下尽量不要使用,同时也是为了避免忘记配置 forward-domain 而引起广播风暴的风险。通常来说 vlanforward 保持在 disable 的状态就好了,不要 enable。
网络拓扑

场景一:关闭 vlanforward
基本配置
Router1 和 Router2 运行了子接口 E0/0.10 和 E0/0.20,FortiGate 透明模式运行与 Router1 和 Router2 之间,三者的基础配置如下:
Router1:
hostname Router1
!
interface Ethernet0/0
ip address 192.168.1.1 255.255.255.0
no shutdown
!
interface Ethernet0/0.10
encapsulation dot1Q 10
ip address 192.168.10.1 255.255.255.0
!
interface Ethernet0/0.20
encapsulation dot1Q 20
ip address 192.168.20.1 255.255.255.0Router2:
hostname Router2
!
interface Ethernet0/0
ip address 192.168.1.99 255.255.255.0
no shutdown
!
interface Ethernet0/0.10
encapsulation dot1Q 10
ip address 192.168.10.99 255.255.255.0
!
interface Ethernet0/0.20
encapsulation dot1Q 20
ip address 192.168.20.99 255.255.255.0FortiGate:
FortiGate-VM64-KVM # config system global
FortiGate-VM64-KVM (global) # set hostname FortiGate_Transparent
FortiGate_Transparent (global) # set timezone 55
FortiGate_Transparent (global) # set language simch
FortiGate-VM64-KVM (global) # end
FortiGate_Transparent #
FortiGate_Transparent # config system settings
FortiGate_Transparent (settings) # set opmode transparent // 修改FGT的运行模式为透明模式,默认为NAT路由模式。注意切换透明模式防火墙需要防火墙没有相关接口、策略、路由等配置。
FortiGate_Transparent (settings) # set manageip 192.168.1.100 255.255.255.0 // 配置可以管理防火墙的本地IP和网关,以便HTTP/SSH管理防火墙及防火墙的服务更新
FortiGate_Transparent (settings) # set gateway 192.168.1.99
FortiGate_Transparent (settings) # end
Changing to TP mode
(MGMT1或MGMT2口默认有管理权限),以要通过port1(LAN)接口管理设备为例,开启port1(LAN)管理FGT的命令如下:
FortiGate_Transparent # config system interface
FortiGate_Transparent (interface) # edit port1
FortiGate_Transparent (port1) # set allowaccess https http ping ssh //允许网管协议从Port1接口通过https/http/SSH/Ping访问透明模式的FortiGate
FortiGate_Transparent (port1) # end
port1和port2都是默认配置,同时也没有配置任何安全策略,纯透明防火墙初始化空配置。
FortiGate_Transparent # config system interface
FortiGate_Transparent (interface) # edit port1
FortiGate_Transparent (port1) # show full-configuration | grep vlanforward
set vlanforward disable //默认vlanforward是disable的实验步骤
首先测试 Router1 的 e0/0 192.168.1.1 到 192.168.1.99 类似于不带 vlan-tag 的本地 vlan vlan1 的业务。
Router1#ping 192.168.1.99 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.168.1.99, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)结果不通,在 FortiGate 上抓包,
FortiGate_Transparent # diagnose sniffer packet any "arp or icmp" 4 0 l interfaces=[any] filters=[arp or icmp] 2019-07-03 18:05:12.481488 port1 in arp who-has 192.168.1.99 (aa:bb:cc:0:20:0) tell 192.168.1.1 2019-07-03 18:05:12.481508 port2 out arp who-has 192.168.1.99 (aa:bb:cc:0:20:0) tell 192.168.1.1 2019-07-03 18:05:12.486286 port2 in arp reply 192.168.1.99 is-at aa:bb:cc:0:20:0 2019-07-03 18:05:12.486295 port1 out arp reply 192.168.1.99 is-at aa:bb:cc:0:20:0 2019-07-03 18:05:15.442315 port1 in 192.168.1.1 -> 192.168.1.99: icmp: echo request 2019-07-03 18:05:17.444526 port1 in 192.168.1.1 -> 192.168.1.99: icmp: echo request 2019-07-03 18:05:19.444349 port1 in 192.168.1.1 -> 192.168.1.99: icmp: echo request 2019-07-03 18:05:21.444162 port1 in 192.168.1.1 -> 192.168.1.99: icmp: echo request 2019-07-03 18:05:23.444217 port1 in 192.168.1.1 -> 192.168.1.99: icmp: echo requestARP 解析正常,但是 icmp 请求被防火墙丢弃,deubug flow 分析不通的原因。
diagnose debug flow filter addr 192.168.1.1 diagnose debug flow filter proto 1 diagnose debug flow show function-name enable diagnose debug flow trace start 10 diagnose debug enable id=20085 trace_id=1 func=print_pkt_detail line=5428 msg="vd-root:0 received a packet(proto=1, 192.168.1.1:10->192.168.1.99:2048) from port1. type=8, code=0, id=10, seq=0." id=20085 trace_id=1 func=init_ip_session_common line=5593 msg="allocate a new session-0000007d" id=20085 trace_id=1 func=br_fw_forward_handler line=565 msg="Denied by forward policy check" //没有配置安全策略允许,自然是会丢弃的。测试 Router1 的 E0/0.10 192.168.10.1 → 192.168.10.99 的业务,此业务携带了 VLAN - TAG 10。
Router1#ping 192.168.10.99 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.168.10.99, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)结果不通,在 FGT 上抓包。
FortiGate_Transparent # diagnose sniffer packet any "arp or icmp" 4 0 l interfaces=[any] filters=[arp or icmp]什么都抓不到,通过镜像抓包查看,发现携带了 vlan-tag 10 的 ARP 报文都无法被转发,也就是说接口下的这条命令:set vlanforward disable,且 FGT 本地没有对应 vlan-tag 10 的接口,会丢弃携带了 vlan-tag 10 的任何报文,包括 ARP 报文,甚至数据报文 CPU 都不上送,携带了 VLAN - TAG 的数据会被当做非 IP 流量数据直接丢弃。

测试 VLAN20 的数据和 vlan10 同样的效果。
Router1#ping 192.168.20.99 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.168.20.99, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)
查看 Router1 的 ARP 表,发现无法学习到相关的 ARP 条目。
Router1#show arp Protocol Address Age (min) Hardware Addr Type Interface ... Internet 192.168.10.99 0 Incomplete ARPA Internet 192.168.20.99 0 Incomplete ARPA ...在 FGT 的 Port1 和 Port2 上增加 Inside_VLAN10 和 Outside_VLAN10 的两个 VLAN 10 的接口。



将两个 VLAN 接口加入到 forward-domain 10 里。
FortiGate_Transparent # config system interface
FortiGate_Transparent (interface) # edit Inside_VLAN10
FortiGate_Transparent (Inside_VLAN10) # set forward-domain 10
FortiGate_Transparent (Inside_VLAN10) # next
FortiGate_Transparent (interface) # edit Outside_VLAN10
FortiGate_Transparent (Outside_VLAN10) # set forward-domain 10
FortiGate_Transparent (Outside_VLAN10) # end重要
配置 VLAN - ID 的场景下则必须配置“forward-domain”否则 FGT 的 MAC 地址表项会错乱翻转,业务不通,甚至存在广播风暴的风险。
重要
假设不配置 forward-domain,由于 port2、port2.10(Outside_VLAN10)都是属于同一个广播域,那么 192.168.10.1 请求 192.168.10.99 的 ARP 广播请求会被发送到 port2、port2.10(Outside_VLAN10)甚至 port1 都会被广播出去,同时由于 Router2 的 E0/0(192.168.1.99)和 E0/0.10(192.168.10.99)的 MAC 地址一样都是:aa:bb:cc:00:20:00,由于在同一个广播域中的不同接口不能存在相同的 MAC 地址,此时 port2 也可以学习到 aa:bb:cc:00:20:00, 同时 port2.10(Outside_VLAN10)也可以学习到 aa:bb:cc:00:20:00,这样会造成 MAC 地址表冲突,同时 MAC 表中只能存在一个 MAC 表项,会操作 MAC 表翻转,如果配置全通策略,甚至可能引起环路的风险。因此配置 VLAN - ID 务必将 forward-domain 配置上,这是一个很必要的配置操作。
查看配置了 forward-domain 的 FortiGate 的 MAC 表和 Router1 的 arp 表。
FortiGate_Transparent # diag netlink brctl name host root.b show bridge control interface root.b host. fdb: size=2048, used=6, num=10, depth=2 Bridge root.b host table port no device devname mac addr ttl attributes ... 6 14 Outside_VLAN10 aa:bb:cc:00:20:00 5 Hit(5) 2 4 port2 aa:bb:cc:00:20:00 0 Hit(0) ...Router1#show arp Protocol Address Age (min) Hardware Addr Type Interface ... Internet 192.168.1.99 0 aabb.cc00.2000 ARPA Ethernet0/0 Internet 192.168.10.99 0 aabb.cc00.2000 ARPA Ethernet0/0.10 ...此时再看 VLAN10 的业务,在 Router1 上使用 192.168.10.1 ping 192.168.10.99。
Router1#ping 192.168.10.99 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.168.10.99, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)虽然还是不通,但是情况已经不一样了,明显 VLAN10 的数据全部上送到了 CPU 进行处理,ARP 可正常学习,只是 ping 不通,原因是防火墙没有配置策略,所以匹配了默认的 drop 策略。
FortiGate_Transparent # diagnose sniffer packet any "arp or icmp" 4 0 l interfaces=[any] filters=[arp or icmp] 2019-07-03 18:24:49.697190 Inside_VLAN10 in arp who-has 192.168.10.99 tell 192.168.10.1 2019-07-03 18:24:49.697218 Outside_VLAN10 out arp who-has 192.168.10.99 tell 192.168.10.1 2019-07-03 18:24:49.698089 Outside_VLAN10 in arp reply 192.168.10.99 is-at aa:bb:cc:0:20:0 2019-07-03 18:24:49.698102 Inside_VLAN10 out arp reply 192.168.10.99 is-at aa:bb:cc:0:20: 2019-07-03 18:24:51.700405 Inside_VLAN10 in 192.168.10.1 -> 192.168.10.99: icmp: echo request 2019-07-03 18:24:53.700372 Inside_VLAN10 in 192.168.10.1 -> 192.168.10.99: icmp: echo request 2019-07-03 18:24:55.704350 Inside_VLAN10 in 192.168.10.1 -> 192.168.10.99: icmp: echo request 2019-07-03 18:24:57.704314 Inside_VLAN10 in 192.168.10.1 -> 192.168.10.99: icmp: echo requestRouter1#show arp Protocol Address Age (min) Hardware Addr Type Interface Internet 192.168.1.1 - aabb.cc00.6000 ARPA Ethernet0/0 Internet 192.168.1.99 5 aabb.cc00.2000 ARPA Ethernet0/0 Internet 192.168.10.1 - aabb.cc00.6000 ARPA Ethernet0/0.10 Internet 192.168.10.99 0 aabb.cc00.2000 ARPA Ethernet0/0.10 // arp可以学习到 Internet 192.168.20.1 - aabb.cc00.6000 ARPA Ethernet0/0.20diagnose debug flow filter addr 192.168.10.1 diagnose debug flow filter proto 1 diagnose debug flow show function-name enable diagnose debug flow trace start 10 diagnose debug enable id=20085 trace_id=2 func=print_pkt_detail line=5428 msg="vd-root:0 received a packet(proto=1, 192.168.10.1:17->192.168.10.99:2048) from Inside_VLAN10. type=8, code=0, id=17, seq=0." id=20085 trace_id=2 func=init_ip_session_common line=5593 msg="allocate a new session-00000244" id=20085 trace_id=2 func=br_fw_forward_handler line=565 msg="Denied by forward policy check"此时在 FortiGate 上配置 VLAN 10 的放通安全策略。

VLAN10 的数据可以正常通信。
Router1#ping 192.168.10.99 repeat 100 Type escape sequence to abort. Sending 100, 100-byte ICMP Echos to 192.168.10.99, timeout is 2 seconds: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Success rate is 100 percent (100/100), round-trip min/avg/max = 1/1/2 msFortiGate_Transparent # diagnose sniffer packet any "icmp or arp" 4 0 l interfaces=[any] filters=[icmp or arp] 2019-07-03 18:57:39.090299 Inside_VLAN10 in 192.168.10.1 -> 192.168.10.99: icmp: echo request 2019-07-03 18:57:39.090376 Outside_VLAN10 out 192.168.10.1 -> 192.168.10.99: icmp: echo request 2019-07-03 18:57:39.090379 port2 out 192.168.10.1 -> 192.168.10.99: icmp: echo request 2019-07-03 18:57:39.091154 Outside_VLAN10 in 192.168.10.99 -> 192.168.10.1: icmp: echo reply 2019-07-03 18:57:39.091166 Inside_VLAN10 out 192.168.10.99 -> 192.168.10.1: icmp: echo reply 2019-07-03 18:57:39.091168 port1 out 192.168.10.99 -> 192.168.10.1: icmp: echo reply
总结
在默认的“set vlanforward disable”的情况下:
- 如果 FGT 本地存在 VLAN - ID 接口(此处为类似 VLAN1 的接口 port1)则数据会上送 CPU 处理,如果配置 VLAN10 的接口,则接收到了 VLAN - TAG10 的 VLAN 数据也会上送 CPU 处理,那么通不通就完全看安全策略是否放通了。
- 如果 FGT 本地不存在 VLAN - ID 的接口,收到了 VLAN - TAG 的数据,且本地并没有相应的 VLAN 接口,那么这样的数据将会被 FGT 底层当做非 IP 数据丢弃,上送 CPU 的机会都没有,直接丢弃,连 arp 都不处理,直接丢弃。
场景二:开启 vlanforward
实验步骤
在 port1 和 port2 上开启 vlanforward(不配置任何 VLAN 接口和安全策略)。
config system interface edit "port1" set vdom "root" set allowaccess ping https ssh http set vlanforward enable set type physical set alias "LAN_Inside" set snmp-index 1 next edit "port2" set vdom "root" set allowaccess ping https ssh http set vlanforward enable set type physical set alias "WAN_Outside" set snmp-index 2 next end

再次测试一下 Router1 到 Router2 的 VLAN 20 的业务,VLAN 20 的数据是通的。
Router1#ping 192.168.20.99 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.168.20.99, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms但是在 FGT 上抓取不到任何的 VLAN20 相关的数据,数据没有上送到 CPU 处理,直接被 bypass 掉了。
FortiGate_Transparent # diagnose sniffer packet any "icmp or arp" 4 0 l interfaces=[any] filters=[icmp or arp]
总结
如果 FGT 上没有创建 VLAN20 的这个接口,同时接口开启了 vlanforward,那么相当于这些未知的携带了 VLAN - TAG 的数据,将会统统 bypass 掉,不上 CPU 处理直接转发走。
如果不熟悉 vlanforward 和 forward-domain 的工作原理,这样的 bypass 流量风险比较大,因为那些 bypass 的流量 FGT 完全不可控,也不可见,一旦出问题完全无法掌控,因此 vlanforward 不建议开启,保持默认 disable 即可。