自学内容网 自学内容网

反向路径转发(RPF)

本文介绍了反向路径转发(RPF)是如何在FortiGate上实现的。
它还解释了特定于VDOM的CLI设置“config system settings -> set strict-src-check”如何修改RPF行为。
测试场景中使用了以下设置
在这里插入图片描述
反向路径过滤器(又名RPF)是一种安全实施,允许根据其源IP地址丢弃传入数据包。
根据路由表检查数据包源IP地址的反向路径(即:路由到数据包的源IP地址)。
根据反向路径过滤器配置,数据包可能会被丢弃或转发。
FortiGate只实现了RFC 3704中引用的两种反向路径过滤器,即“严格反向路径转发”和“可行路径反向路径转发”。它不实现“松散反向路径转发”,也不实现“忽略默认路由的松散反向路径转发”。
VDOM CLI选项“strict-src-check enable|在 “配置系统设置”部分中的“禁用(默认:禁用)”允许在“严格”和“可行路径”之间进行选择。
设置strict-SRC-check禁用:(默认选项)选择“可行路径”行为
设置strict-src-check使能 :选择“严格”行为
“严格路径”和“可行路径”的区别:
‘strict’:对数据包源IP进行路由查找(最佳匹配)。如果数据包的传入接口与路由查找选择的接口不匹配,则数据包将被丢弃。
“可行路径”:不仅考虑最佳匹配路由。其他指向入站接口的路由也会被检查。如果其中一个包含数据包源IP地址(即使不是最佳匹配路由),则接受数据包。
黑洞路由是一个特例。“严格路径”和“可行路径”RPF路由查找都包括任何活动黑洞路由沿着传入接口路由。如果最佳匹配是黑洞路由,则会丢弃流量。在调试流程中,这会生成一条“反向路径检查失败”消息,类似于反向路径过滤器导致的其他丢弃。
在接口级别禁用RFP检查

config system interface
   edit <interface>
     set src-check disable
end
asymetric routing enable

在非对称模式下配置VDOM(set asymroute enable)是其中之一,但它也禁用了可能不需要的数据包状态检查。

'strict-src-check disable' +添加一个超网路由作为'可行补丁'

可以添加一个前缀较大的路由,指向数据包流出的接口。由于最佳匹配适用,因此将使用最具体的路由来路由数据包。添加此“非优先级”路由以提供“可行路径”。“strict-src-check”应设置为“disable”。
“strict-src-check disable”+添加与最佳匹配路由相同的路由(相同子网、相同前缀、相同距离),但优先级值高于最佳匹配路由。这将强制将该路由作为第二选择注入路由表。
注意事项:
优先级越低 越好。如果未定义,则默认情况下优先级设置为’0
验证

Examples:
The following examples are provided to highlight the "strict-src-check" setting.
These examples use several vdoms of the fortigate. Port1 and Port3 are connected with a cross-over cable for the inter-vdom communication.

Test traffic :
A telnet is issued from vdom client to vdom server ip address (192.168.3.1).
The flow is diverted by a policy route on vdom 'traffic' toward vdom 'snat' where packet is source-natted with an IP pool (192.168.5.1-10).
Packet is re-injected in 'traffic' vdom with a source ip address of 192.168.5.x

Flow :

packet leaves client vdom as "192.168.0.1 -> 192.168.3.1"
packet flows in vdom 'traffic' from interface (p3v84) to (p3v85) and reached vdom 'snat'
packet is source-natted in vdom 'snat' and re-injected to vdom 'traffic'. Packet is now like  192.168.5.X -> 192.168.3.1
RPF takes place in vdom 'traffic'.
Different cases are shown below:

A> vdom traffic configured with "strict-src-check disable" with a feasible path
RPF is neutralized by a "feasible path" route  192.168.0.0/16 and packet is expected to flow.

Telnet from client vdom is working :


FG3K8A-4 (client) # execute telnet 192.168.3.1
FG3K8A-4 login:


'traffic vdom' routing table:


FG3K8A-4 (traffic) # get router info routing-table all
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
       O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
       * - candidate default

S       192.168.0.0/16 [10/0] via 192.168.2.1, p3v86
C       192.168.0.0/24 is directly connected, p3v84
C       192.168.2.0/24 is directly connected, p3v86
C       192.168.3.0/24 is directly connected, p3v87
S       192.168.4.0/24 [10/0] via 192.168.0.1, p3v84
C       192.168.5.0/24 is directly connected, p3v85


Debug flow captured in traffic vdom shows the packet path up to server vdom :


FG3K8A-4 (traffic) #
id=36871 trace_id=99 func=resolve_ip_tuple_fast line=3785 msg="vd-client received a packet(proto=6, 192.168.0.1:1111->192.168.3.1:23) from local."
id=36871 trace_id=99 func=resolve_ip_tuple line=3925 msg="allocate a new session-0000045b"
id=36871 trace_id=100 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.0.1:1111->192.168.3.1:23) from p3v84."
id=36871 trace_id=100 func=resolve_ip_tuple line=3925 msg="allocate a new session-0000045c"
id=36871 trace_id=100 func=vf_ip4_route_input line=1591 msg="Match policy routing: to 192.168.5.1 via ifindex-31"
id=36871 trace_id=100 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.5.1 via p3v85"
id=36871 trace_id=100 func=fw_forward_handler line=555 msg="Allowed by Policy-1:"
id=36871 trace_id=101 func=resolve_ip_tuple_fast line=3785 msg="vd-snat received a packet(proto=6, 192.168.0.1:1111->192.168.3.1:23) from p1v85."
id=36871 trace_id=101 func=resolve_ip_tuple line=3925 msg="allocate a new session-0000045d"
id=36871 trace_id=101 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.2.2 via p1v86"
id=36871 trace_id=101 func=get_new_addr line=1948 msg="find SNAT: IP-192.168.4.2(from IPPOOL), port-0(fixed port)"
id=36871 trace_id=101 func=fw_forward_handler line=555 msg="Allowed by Policy-1: SNAT"
id=36871 trace_id=101 func=__ip_session_run_tuple line=2116 msg="SNAT 192.168.0.1->192.168.4.2:1111"
id=36871 trace_id=102 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.4.2:1111->192.168.3.1:23) from p3v86."
id=36871 trace_id=102 func=resolve_ip_tuple line=3925 msg="allocate a new session-0000045e"
id=36871 trace_id=102 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.3.1 via p3v87"
id=36871 trace_id=102 func=fw_forward_handler line=555 msg="Allowed by Policy-2:"
id=36871 trace_id=103 func=resolve_ip_tuple_fast line=3785 msg="vd-server received a packet(proto=6, 192.168.4.2:1111->192.168.3.1:23) from p1v87."


B> vdom traffic configured with "strict-src-check enable".
Strict RPF is expected to drop the packets.

configuration is now changed:


FG3K8A-4 (traffic) # config system settings
FG3K8A-4 (settings) # set strict-src-check enable
FG3K8A-4 (settings) # end


Telnet from client vdom fails:


FG3K8A-4 (client) # execute telnet 192.168.3.1
Timeout!

Debug flow captured in traffic VDOM shows the packet dropped by the RPF filter.


FG3K8A-4 (traffic) #
id=36871 trace_id=91 func=resolve_ip_tuple_fast line=3785 msg="vd-client received a packet(proto=6, 192.168.0.1:1108->192.168.3.1:23) from local."
id=36871 trace_id=91 func=resolve_ip_tuple_fast line=3825 msg="Find an existing session, id-00000391, original direction"
id=36871 trace_id=92 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.0.1:1108->192.168.3.1:23) from p3v84."
id=36871 trace_id=92 func=resolve_ip_tuple_fast line=3825 msg="Find an existing session, id-00000392, original direction"
id=36871 trace_id=92 func=ipv4_fast_cb line=50 msg="enter fast path"
id=36871 trace_id=93 func=resolve_ip_tuple_fast line=3785 msg="vd-snat received a packet(proto=6, 192.168.0.1:1108->192.168.3.1:23) from p1v85."
id=36871 trace_id=93 func=resolve_ip_tuple_fast line=3825 msg="Find an existing session, id-00000393, original direction"
id=36871 trace_id=93 func=ipv4_fast_cb line=50 msg="enter fast path"
id=36871 trace_id=93 func=ip_session_run_all_tuple line=4819 msg="SNAT 192.168.0.1->192.168.4.2:1108"
id=36871 trace_id=94 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.4.2:1108->192.168.3.1:23) from p3v86."
id=36871 trace_id=94 func=resolve_ip_tuple line=3925 msg="allocate a new session-0000039e"
id=36871 trace_id=94 func=ip_route_input_slow line=1287 msg="reverse path check fail(by strict-src-check),drop"

 

C> vdom traffic configured with "strict-src-check disable" without a feasible path
strict-src-check is disabled and feasible path is removed. Packet is expected to be dropped by RPF because no feasible path exists.

Configuration change (feasible route deleted):


FG3K8A-4 (traffic) # config system settings
FG3K8A-4 (settings) # set strict-src-check disable
FG3K8A-4 (settings) # end
FG3K8A-4 (traffic) # config router static
FG3K8A-4 (static) # show
config router static
    edit 3
        set device "p3v86"
        set dst 192.168.0.0 255.255.0.0
        set gateway 192.168.2.1
    next
    edit 2
        set device "p3v84"
        set dst 192.168.4.0 255.255.255.0
        set gateway 192.168.0.1
    next
end
FG3K8A-4 (static) # delete 3
FG3K8A-4 (static) # end

 

Routing table:


FG3K8A-4 (traffic) # get router info routing-table all
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
       O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
       * - candidate default

C       192.168.0.0/24 is directly connected, p3v84
C       192.168.2.0/24 is directly connected, p3v86
C       192.168.3.0/24 is directly connected, p3v87
S       192.168.4.0/24 [10/0] via 192.168.0.1, p3v84
C       192.168.5.0/24 is directly connected, p3v85


Telnet from client vdom fails:


FG3K8A-4 (client) # execute telnet 192.168.3.1
Timeout!


Debug flow shows syn packet dropped by RPF because of no feasible path :


FG3K8A-4 (traffic) #
id=36871 trace_id=129 func=resolve_ip_tuple_fast line=3785 msg="vd-client received a packet(proto=6, 192.168.0.1:1113->192.168.3.1:23) from local."
id=36871 trace_id=129 func=resolve_ip_tuple line=3925 msg="allocate a new session-000005b7"
id=36871 trace_id=130 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.0.1:1113->192.168.3.1:23) from p3v84."
id=36871 trace_id=130 func=resolve_ip_tuple line=3925 msg="allocate a new session-000005b8"
id=36871 trace_id=130 func=vf_ip4_route_input line=1591 msg="Match policy routing: to 192.168.5.1 via ifindex-31"
id=36871 trace_id=130 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.5.1 via p3v85"
id=36871 trace_id=130 func=fw_forward_handler line=555 msg="Allowed by Policy-1:"
id=36871 trace_id=131 func=resolve_ip_tuple_fast line=3785 msg="vd-snat received a packet(proto=6, 192.168.0.1:1113->192.168.3.1:23) from p1v85."
id=36871 trace_id=131 func=resolve_ip_tuple line=3925 msg="allocate a new session-000005b9"
id=36871 trace_id=131 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.2.2 via p1v86"
id=36871 trace_id=131 func=get_new_addr line=1948 msg="find SNAT: IP-192.168.4.2(from IPPOOL), port-0(fixed port)"
id=36871 trace_id=131 func=fw_forward_handler line=555 msg="Allowed by Policy-1: SNAT"
id=36871 trace_id=131 func=__ip_session_run_tuple line=2116 msg="SNAT 192.168.0.1->192.168.4.2:1113"
id=36871 trace_id=132 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.4.2:1113->192.168.3.1:23) from p3v86."
id=36871 trace_id=132 func=resolve_ip_tuple line=3925 msg="allocate a new session-000005ba"
id=36871 trace_id=132 func=ip_route_input_slow line=1276 msg="reverse path check fail, drop"


D> vdom traffic configured with "strict-src-check disable" with a second non priority route
In this scenario, 2 routes for 192.168.4.0/24 exist :

The preferred one has priority 0 (default). This is the one used for routing and points to a different direction than the one the packet ingress from.
The second one has priority 10 (less preferred), not used for routing because a similar route with lower priority number exists. It points to the interface where our packet comes from. This is the one that neutralizes the RPF filter for the source natted packet.

Configuration :

config router static
    edit 2
        set device "p3v84"
        set dst 192.168.4.0 255.255.255.0
        set gateway 192.168.0.1
    next
    edit 3
        set comment "neutralize RPF for 192.168.4.0/24"
        set device "p3v86"
        set dst 192.168.4.0 255.255.255.0
        set gateway 192.168.2.1
        set priority 10
    next
end


Routing table:


FG3K8A-4 (static) # get router info routing-table all
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
       O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
       * - candidate default

C       192.168.0.0/24 is directly connected, p3v84
C       192.168.2.0/24 is directly connected, p3v86
C       192.168.3.0/24 is directly connected, p3v87
S       192.168.4.0/24 [10/0] via 192.168.0.1, p3v84
                       [10/0] via 192.168.2.1, p3v86, [10/0]
C       192.168.5.0/24 is directly connected, p3v85


Connection is OK:


FG3K8A-4 (client) # execute telnet 192.168.3.1
FG3K8A-4 login:


Flow shows packets transmitted :


FG3K8A-4 (traffic) # id=36871 trace_id=145 func=resolve_ip_tuple_fast line=3785 msg="vd-client received a packet(proto=6, 192.168.0.1:1117->192.168.3.1:23) from local."
id=36871 trace_id=145 func=resolve_ip_tuple line=3925 msg="allocate a new session-00001d04"
id=36871 trace_id=146 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.0.1:1117->192.168.3.1:23) from p3v84."
id=36871 trace_id=146 func=resolve_ip_tuple line=3925 msg="allocate a new session-00001d05"
id=36871 trace_id=146 func=vf_ip4_route_input line=1591 msg="Match policy routing: to 192.168.5.1 via ifindex-31"
id=36871 trace_id=146 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.5.1 via p3v85"
id=36871 trace_id=146 func=fw_forward_handler line=555 msg="Allowed by Policy-1:"
id=36871 trace_id=147 func=resolve_ip_tuple_fast line=3785 msg="vd-snat received a packet(proto=6, 192.168.0.1:1117->192.168.3.1:23) from p1v85."
id=36871 trace_id=147 func=resolve_ip_tuple line=3925 msg="allocate a new session-00001d06"
id=36871 trace_id=147 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.2.2 via p1v86"
id=36871 trace_id=147 func=get_new_addr line=1948 msg="find SNAT: IP-192.168.4.2(from IPPOOL), port-0(fixed port)"
id=36871 trace_id=147 func=fw_forward_handler line=555 msg="Allowed by Policy-1: SNAT"
id=36871 trace_id=147 func=__ip_session_run_tuple line=2116 msg="SNAT 192.168.0.1->192.168.4.2:1117"
id=36871 trace_id=148 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.4.2:1117->192.168.3.1:23) from p3v86."
id=36871 trace_id=148 func=resolve_ip_tuple line=3925 msg="allocate a new session-00001d07"
id=36871 trace_id=148 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.3.1 via p3v87"
id=36871 trace_id=148 func=fw_forward_handler line=555 msg="Allowed by Policy-2:"
id=36871 trace_id=149 func=resolve_ip_tuple_fast line=3785 msg="vd-server received a packet(proto=6, 192.168.4.2:1117->192.168.3.1:23) from p1v87."


Now, if enabling strict-src-check, RPF drops the packet :

configuration :


FG3K8A-4 (traffic) # config system settings
FG3K8A-4 (settings) # set strict-src-check enable
FG3K8A-4 (settings) # end


Flow showing packet is dropped:


FG3K8A-4 (traffic) #
 id=36871 trace_id=175 func=resolve_ip_tuple_fast line=3785 msg="vd-client received a packet(proto=6, 192.168.0.1:1119->192.168.3.1:23) from local."
id=36871 trace_id=175 func=resolve_ip_tuple line=3925 msg="allocate a new session-00001dd3"
id=36871 trace_id=176 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.0.1:1119->192.168.3.1:23) from p3v84."
id=36871 trace_id=176 func=resolve_ip_tuple line=3925 msg="allocate a new session-00001dd4"
id=36871 trace_id=176 func=vf_ip4_route_input line=1591 msg="Match policy routing: to 192.168.5.1 via ifindex-31"
id=36871 trace_id=176 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.5.1 via p3v85"
id=36871 trace_id=176 func=fw_forward_handler line=555 msg="Allowed by Policy-1:"
id=36871 trace_id=177 func=resolve_ip_tuple_fast line=3785 msg="vd-snat received a packet(proto=6, 192.168.0.1:1119->192.168.3.1:23) from p1v85."
id=36871 trace_id=177 func=resolve_ip_tuple line=3925 msg="allocate a new session-00001dd5"
id=36871 trace_id=177 func=vf_ip4_route_input line=1599 msg="find a route: gw-192.168.2.2 via p1v86"
id=36871 trace_id=177 func=get_new_addr line=1948 msg="find SNAT: IP-192.168.4.2(from IPPOOL), port-0(fixed port)"
id=36871 trace_id=177 func=fw_forward_handler line=555 msg="Allowed by Policy-1: SNAT"
id=36871 trace_id=177 func=__ip_session_run_tuple line=2116 msg="SNAT 192.168.0.1->192.168.4.2:1119"
id=36871 trace_id=178 func=resolve_ip_tuple_fast line=3785 msg="vd-traffic received a packet(proto=6, 192.168.4.2:1119->192.168.3.1:23) from p3v86."
id=36871 trace_id=178 func=resolve_ip_tuple line=3925 msg="allocate a new session-00001dd6"

id=36871 trace_id=178 func=ip_route_input_slow line=1287 msg="reverse path check fail(by strict-src-check),drop"

 

Reverse path Forwarding failure drops counter:

Below CLI command has a new counter to track and check packet drops due to RPF failures, and is available in FortiOS 7.6 & later versions.


FortiGate-1# diagnose ip rtcache stats
in_hit: 2483
in_slow_tot: 162
in_slow_mc: 0
in_no_route: 0
in_brd: 4
in_martian_dst: 0
in_martian_src: 2
out_hit: 21813
out_slow_tot: 127
out_slow_mc: 0
gc_total: 0
gc_ignored: 0
gc_goal_miss: 0
gc_dst_overflow: 0
in_hlist_search: 0
out_hlist_search: 12484
reverse_path_check_fail: 875 <- RFP failure counter, check if this is incrementing.

原文地址:https://blog.csdn.net/m0_37888039/article/details/144315576

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!