2021-10-26 10:05:58 -05:00
|
|
|
import socket
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
from util import ppp
|
2022-08-18 11:09:38 -04:00
|
|
|
from asfframework import VppTestRunner
|
2023-10-20 05:20:47 +00:00
|
|
|
from template_ipsec import IpsecDefaultTemplate
|
2021-10-26 10:05:58 -05:00
|
|
|
|
|
|
|
"""
|
|
|
|
When an IPSec SPD is configured on an interface, any inbound packets
|
|
|
|
not matching inbound policies, or outbound packets not matching outbound
|
|
|
|
policies, must be dropped by default as per RFC4301.
|
|
|
|
|
|
|
|
This test uses simple IPv4 forwarding on interfaces with IPSec enabled
|
|
|
|
to check if packets with no matching rules are dropped by default.
|
|
|
|
|
|
|
|
The basic setup is a single SPD bound to two interfaces, pg0 and pg1.
|
|
|
|
|
|
|
|
┌────┐ ┌────┐
|
|
|
|
│SPD1│ │SPD1│
|
|
|
|
├────┤ ─────> ├────┤
|
|
|
|
│PG0 │ │PG1 │
|
|
|
|
└────┘ └────┘
|
|
|
|
|
|
|
|
First, both inbound and outbound BYPASS policies are configured allowing
|
|
|
|
traffic to pass from pg0 -> pg1.
|
|
|
|
|
|
|
|
Packets are captured and verified at pg1.
|
|
|
|
|
|
|
|
Then either the inbound or outbound policies are removed and we verify
|
|
|
|
packets are dropped as expected.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
2023-10-20 05:20:47 +00:00
|
|
|
class IPSecInboundDefaultDrop(IpsecDefaultTemplate):
|
2022-04-26 19:02:15 +02:00
|
|
|
"""IPSec: inbound packets drop by default with no matching rule"""
|
2022-04-23 11:34:29 +02:00
|
|
|
|
2021-10-26 10:05:58 -05:00
|
|
|
def test_ipsec_inbound_default_drop(self):
|
|
|
|
# configure two interfaces and bind the same SPD to both
|
|
|
|
self.create_interfaces(2)
|
|
|
|
self.spd_create_and_intf_add(1, self.pg_interfaces)
|
|
|
|
pkt_count = 5
|
|
|
|
|
|
|
|
# catch-all inbound BYPASS policy, all interfaces
|
|
|
|
inbound_policy = self.spd_add_rem_policy(
|
2022-04-26 19:02:15 +02:00
|
|
|
1,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
socket.IPPROTO_UDP,
|
|
|
|
is_out=0,
|
|
|
|
priority=10,
|
|
|
|
policy_type="bypass",
|
|
|
|
all_ips=True,
|
|
|
|
)
|
2021-10-26 10:05:58 -05:00
|
|
|
|
|
|
|
# outbound BYPASS policy allowing traffic from pg0->pg1
|
|
|
|
outbound_policy = self.spd_add_rem_policy(
|
2022-04-26 19:02:15 +02:00
|
|
|
1,
|
|
|
|
self.pg0,
|
|
|
|
self.pg1,
|
|
|
|
socket.IPPROTO_UDP,
|
|
|
|
is_out=1,
|
|
|
|
priority=10,
|
|
|
|
policy_type="bypass",
|
|
|
|
)
|
2021-10-26 10:05:58 -05:00
|
|
|
|
|
|
|
# create a packet stream pg0->pg1 + add to pg0
|
|
|
|
packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
|
|
|
|
self.pg0.add_stream(packets0)
|
|
|
|
|
|
|
|
# with inbound BYPASS rule at pg0, we expect to see forwarded
|
|
|
|
# packets on pg1
|
|
|
|
self.pg_interfaces[1].enable_capture()
|
|
|
|
self.pg_start()
|
|
|
|
cap1 = self.pg1.get_capture()
|
|
|
|
for packet in cap1:
|
|
|
|
try:
|
|
|
|
self.logger.debug(ppp("SPD - Got packet:", packet))
|
|
|
|
except Exception:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.logger.error(ppp("Unexpected or invalid packet:", packet))
|
2021-10-26 10:05:58 -05:00
|
|
|
raise
|
|
|
|
self.logger.debug("SPD: Num packets: %s", len(cap1.res))
|
|
|
|
# verify captures on pg1
|
|
|
|
self.verify_capture(self.pg0, self.pg1, cap1)
|
|
|
|
# verify policies matched correct number of times
|
|
|
|
self.verify_policy_match(pkt_count, inbound_policy)
|
|
|
|
self.verify_policy_match(pkt_count, outbound_policy)
|
|
|
|
|
|
|
|
# remove inbound catch-all BYPASS rule, traffic should now be dropped
|
|
|
|
self.spd_add_rem_policy( # inbound, all interfaces
|
2022-04-26 19:02:15 +02:00
|
|
|
1,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
socket.IPPROTO_UDP,
|
|
|
|
is_out=0,
|
|
|
|
priority=10,
|
|
|
|
policy_type="bypass",
|
|
|
|
all_ips=True,
|
|
|
|
remove=True,
|
|
|
|
)
|
2021-10-26 10:05:58 -05:00
|
|
|
|
|
|
|
# create another packet stream pg0->pg1 + add to pg0
|
|
|
|
packets1 = self.create_stream(self.pg0, self.pg1, pkt_count)
|
|
|
|
self.pg0.add_stream(packets1)
|
|
|
|
self.pg_interfaces[1].enable_capture()
|
|
|
|
self.pg_start()
|
|
|
|
# confirm traffic has now been dropped
|
2022-04-26 19:02:15 +02:00
|
|
|
self.pg1.assert_nothing_captured(
|
|
|
|
remark="inbound pkts with no matching" "rules NOT dropped by default"
|
|
|
|
)
|
2021-10-26 10:05:58 -05:00
|
|
|
# both policies should not have matched any further packets
|
|
|
|
# since we've dropped at input stage
|
|
|
|
self.verify_policy_match(pkt_count, outbound_policy)
|
|
|
|
self.verify_policy_match(pkt_count, inbound_policy)
|
|
|
|
|
|
|
|
|
2023-10-20 05:20:47 +00:00
|
|
|
class IPSecOutboundDefaultDrop(IpsecDefaultTemplate):
|
2022-04-26 19:02:15 +02:00
|
|
|
"""IPSec: outbound packets drop by default with no matching rule"""
|
2022-04-23 11:34:29 +02:00
|
|
|
|
2021-10-26 10:05:58 -05:00
|
|
|
def test_ipsec_inbound_default_drop(self):
|
|
|
|
# configure two interfaces and bind the same SPD to both
|
|
|
|
self.create_interfaces(2)
|
|
|
|
self.spd_create_and_intf_add(1, self.pg_interfaces)
|
|
|
|
pkt_count = 5
|
|
|
|
|
|
|
|
# catch-all inbound BYPASS policy, all interfaces
|
|
|
|
inbound_policy = self.spd_add_rem_policy(
|
2022-04-26 19:02:15 +02:00
|
|
|
1,
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
socket.IPPROTO_UDP,
|
|
|
|
is_out=0,
|
|
|
|
priority=10,
|
|
|
|
policy_type="bypass",
|
|
|
|
all_ips=True,
|
|
|
|
)
|
2021-10-26 10:05:58 -05:00
|
|
|
|
|
|
|
# outbound BYPASS policy allowing traffic from pg0->pg1
|
|
|
|
outbound_policy = self.spd_add_rem_policy(
|
2022-04-26 19:02:15 +02:00
|
|
|
1,
|
|
|
|
self.pg0,
|
|
|
|
self.pg1,
|
|
|
|
socket.IPPROTO_UDP,
|
|
|
|
is_out=1,
|
|
|
|
priority=10,
|
|
|
|
policy_type="bypass",
|
|
|
|
)
|
2021-10-26 10:05:58 -05:00
|
|
|
|
|
|
|
# create a packet stream pg0->pg1 + add to pg0
|
|
|
|
packets0 = self.create_stream(self.pg0, self.pg1, pkt_count)
|
|
|
|
self.pg0.add_stream(packets0)
|
|
|
|
|
|
|
|
# with outbound BYPASS rule allowing pg0->pg1, we expect to see
|
|
|
|
# forwarded packets on pg1
|
|
|
|
self.pg_interfaces[1].enable_capture()
|
|
|
|
self.pg_start()
|
|
|
|
cap1 = self.pg1.get_capture()
|
|
|
|
for packet in cap1:
|
|
|
|
try:
|
|
|
|
self.logger.debug(ppp("SPD - Got packet:", packet))
|
|
|
|
except Exception:
|
2022-04-26 19:02:15 +02:00
|
|
|
self.logger.error(ppp("Unexpected or invalid packet:", packet))
|
2021-10-26 10:05:58 -05:00
|
|
|
raise
|
|
|
|
self.logger.debug("SPD: Num packets: %s", len(cap1.res))
|
|
|
|
# verify captures on pg1
|
|
|
|
self.verify_capture(self.pg0, self.pg1, cap1)
|
|
|
|
# verify policies matched correct number of times
|
|
|
|
self.verify_policy_match(pkt_count, inbound_policy)
|
|
|
|
self.verify_policy_match(pkt_count, outbound_policy)
|
|
|
|
|
|
|
|
# remove outbound rule
|
|
|
|
self.spd_add_rem_policy(
|
2022-04-26 19:02:15 +02:00
|
|
|
1,
|
|
|
|
self.pg0,
|
|
|
|
self.pg1,
|
|
|
|
socket.IPPROTO_UDP,
|
|
|
|
is_out=1,
|
|
|
|
priority=10,
|
|
|
|
policy_type="bypass",
|
|
|
|
remove=True,
|
|
|
|
)
|
2021-10-26 10:05:58 -05:00
|
|
|
|
|
|
|
# create another packet stream pg0->pg1 + add to pg0
|
|
|
|
packets1 = self.create_stream(self.pg0, self.pg1, pkt_count)
|
|
|
|
self.pg0.add_stream(packets1)
|
|
|
|
self.pg_interfaces[1].enable_capture()
|
|
|
|
self.pg_start()
|
|
|
|
# confirm traffic was dropped and not forwarded
|
2022-04-23 11:34:29 +02:00
|
|
|
self.pg1.assert_nothing_captured(
|
2022-04-26 19:02:15 +02:00
|
|
|
remark="outbound pkts with no matching rules NOT dropped " "by default"
|
|
|
|
)
|
2021-10-26 10:05:58 -05:00
|
|
|
# inbound rule should have matched twice the # of pkts now
|
2022-04-26 19:02:15 +02:00
|
|
|
self.verify_policy_match(pkt_count * 2, inbound_policy)
|
2021-10-26 10:05:58 -05:00
|
|
|
# as dropped at outbound, outbound policy is the same
|
|
|
|
self.verify_policy_match(pkt_count, outbound_policy)
|
|
|
|
|
2022-04-23 11:34:29 +02:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
if __name__ == "__main__":
|
2021-10-26 10:05:58 -05:00
|
|
|
unittest.main(testRunner=VppTestRunner)
|