Beispiel #1
0
    def setUp(self):
        """
        Sets up a test version of the redirect server, mocks url_dict
        """
        app = setup_flask_server()
        app.config['TESTING'] = True

        test_dict = {
            '192.5.82.1':
            RedirectInformation(support=1,
                                address_type=2,
                                server_address='http://www.example.com/')
        }

        def get_resp(src_ip):
            if src_ip not in test_dict:
                return ServerResponse(NOT_FOUND_HTML, HTTP_NOT_FOUND)
            return ServerResponse(test_dict[src_ip].server_address,
                                  HTTP_REDIRECT)

        # Replaces all url_dict polls with a mocked dict (for all url rules)
        for rule in app.url_map._rules:
            if rule is not None and rule.defaults is not None:
                rule.defaults['get_redirect_response'] = get_resp
        self.client = app.test_client()
Beispiel #2
0
    def test_redirect_policy(self):
        """
        Add a redirect policy, verifies that EnforcementStatsController reports
        correct stats to sessiond

        Assert:
            1 Packet is matched and reported
        """
        fake_controller_setup(self.enforcement_controller,
                              self.enforcement_stats_controller)
        redirect_ips = ["185.128.101.5", "185.128.121.4"]
        self.enforcement_controller._redirect_manager._dns_cache.get(
            "about.sha.ddih.org", lambda: redirect_ips, max_age=42)
        imsi = 'IMSI010000000088888'
        sub_ip = '192.168.128.74'
        flow_list = [FlowDescription(match=FlowMatch())]
        policy = PolicyRule(id='redir_test',
                            priority=3,
                            flow_list=flow_list,
                            redirect=RedirectInformation(
                                support=1,
                                address_type=2,
                                server_address="http://about.sha.ddih.org/"))
        stat_name = imsi + '|redir_test' + '|' + sub_ip
        self.service_manager.session_rule_version_mapper.update_version(
            imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'redir_test')
        """ Setup subscriber, setup table_isolation to fwd pkts """
        self._static_rule_dict[policy.id] = policy
        sub_context = RyuDirectSubscriberContext(
            imsi, sub_ip, self.enforcement_controller, self._main_tbl_num,
            self.enforcement_stats_controller).add_dynamic_rule(policy)
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(), self.testing_controller)
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packet = TCPPacketBuilder() \
            .set_tcp_layer(42132, 80, 321) \
            .set_tcp_flags("S") \
            .set_ip_layer('151.42.41.122', sub_ip) \
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00") \
            .build()

        # =========================== Verification ===========================
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager)
        """ Send packet, wait until pkts are received by ovs and enf stats """
        with isolator, sub_context, snapshot_verifier:
            self.enforcement_stats_controller._report_usage.reset_mock()
            pkt_sender.send(packet)

        wait_for_enforcement_stats(self.enforcement_stats_controller,
                                   [stat_name])
        """ Send packets, wait until pkts are received by ovs and enf stats """
        stats = get_enforcement_stats(
            self.enforcement_stats_controller._report_usage.call_args_list)

        self.assertEqual(stats[stat_name].sid, imsi)
        self.assertEqual(stats[stat_name].rule_id, "redir_test")
        self.assertEqual(stats[stat_name].bytes_rx, 0)
        self.assertEqual(stats[stat_name].bytes_tx, len(packet))
Beispiel #3
0
 def _get_redirect_policies(self):
     """ Policy to redirect traffic to the captive portal """
     redirect_info = RedirectInformation(
         support=RedirectInformation.ENABLED,
         address_type=RedirectInformation.URL,
         server_address=self._captive_portal_address)
     return [
         PolicyRule(id='redirect',
                    priority=self.REDIRECT_PRIORITY,
                    redirect=redirect_info)
     ]
Beispiel #4
0
    def test_subscriber_redirect_policy(self):
        """
        Add redirect policy to subscriber, send 4096 packets

        Assert:
            Packets are properly matched with the 'simple_match' policy
            Send /20 (4096) packets, match /16 (256) packets
        """
        fake_controller_setup(self.gy_controller)
        imsi = 'IMSI010000000088888'
        sub_ip = '192.168.128.74'
        redirect_ips = ["185.128.101.5", "185.128.121.4"]
        self.gy_controller._redirect_manager._dns_cache.get(
            "about.sha.ddih.org", lambda: redirect_ips, max_age=42,
        )
        flow_list = [FlowDescription(match=FlowMatch())]
        policy = VersionedPolicy(
            rule=PolicyRule(
                id='redir_test', priority=3, flow_list=flow_list,
                redirect=RedirectInformation(
                    support=1,
                    address_type=2,
                    server_address="http://about.sha.ddih.org/",
                ),
            ),
            version=1,
        )

        # ============================ Subscriber ============================
        sub_context = RyuDirectSubscriberContext(
            imsi, sub_ip, self.gy_controller, self._tbl_num,
        ).add_policy(policy)
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
                                     .build_requests(),
            self.testing_controller,
        )
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packet = TCPPacketBuilder()\
            .set_tcp_layer(42132, 80, 2)\
            .set_tcp_flags("S")\
            .set_ip_layer('151.42.41.122', sub_ip)\
            .set_ether_layer(self.MAC_DEST, "01:20:10:20:aa:bb")\
            .build()

        snapshot_verifier = SnapshotVerifier(
            self, self.BRIDGE,
            self.service_manager,
            include_stats=False,
        )

        with isolator, sub_context, snapshot_verifier:
            pkt_sender.send(packet)
Beispiel #5
0
def activate_gy_redirect(client, args):
    request = ActivateFlowsRequest(
        sid=SIDUtils.to_pb(args.imsi),
        ip_addr=args.ipv4,
        dynamic_rules=[
            PolicyRule(id=args.rule_id,
                       priority=999,
                       flow_list=[],
                       redirect=RedirectInformation(
                           support=1,
                           address_type=2,
                           server_address=args.redirect_addr))
        ],
        request_origin=RequestOriginType(type=RequestOriginType.GY))
    response = client.ActivateFlows(request)
    _print_rule_mod_results(response.dynamic_rule_results)
Beispiel #6
0
def activate_gy_redirect(client, args):
    request = ActivateFlowsRequest(
        sid=SIDUtils.to_pb(args.imsi),
        ip_addr=args.ipv4,
        policies=[
            VersionedPolicy(
                rule=PolicyRule(
                    id=args.rule_id,
                    priority=999,
                    flow_list=[],
                    redirect=RedirectInformation(
                        support=1,
                        address_type=2,
                        server_address=args.redirect_addr,
                    ),
                ),
                version=1,
            ),
        ],
        request_origin=RequestOriginType(type=RequestOriginType.GY),
        shard_id=args.shard_id,
    )
    response = client.ActivateFlows(request)
    _print_rule_mod_results(response.policy_results)
Beispiel #7
0
    def test_url_redirect(self):
        """
        Partial redirection test, checks if flows were added properly for url
        based redirection.

        Assert:
            1 Packet is matched
            Packet bypass flows are added
            Flow learn action is triggered - another flow is added to the table
        """
        fake_controller_setup(self.enforcement_controller)
        redirect_ips = ["185.128.101.5", "185.128.121.4"]
        self.enforcement_controller._redirect_manager._dns_cache.get(
            "about.sha.ddih.org", lambda: redirect_ips, max_age=42)
        imsi = 'IMSI010000000088888'
        sub_ip = '192.168.128.74'
        flow_list = [FlowDescription(match=FlowMatch())]
        policy = PolicyRule(id='redir_test',
                            priority=3,
                            flow_list=flow_list,
                            redirect=RedirectInformation(
                                support=1,
                                address_type=2,
                                server_address="http://about.sha.ddih.org/"))

        # ============================ Subscriber ============================
        sub_context = RyuDirectSubscriberContext(
            imsi, sub_ip, self.enforcement_controller,
            self._tbl_num).add_dynamic_rule(policy)
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(), self.testing_controller)
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packet = TCPPacketBuilder()\
            .set_tcp_layer(42132, 80, 321)\
            .set_tcp_flags("S")\
            .set_ip_layer('151.42.41.122', sub_ip)\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .build()

        # Check if these flows were added (queries should return flows)
        permit_outbound, permit_inbound = [], []
        for ip in redirect_ips:
            permit_outbound.append(
                FlowQuery(self._tbl_num,
                          self.testing_controller,
                          match=flow_match_to_magma_match(
                              FlowMatch(ipv4_dst=ip,
                                        direction=FlowMatch.UPLINK))))
            permit_inbound.append(
                FlowQuery(self._tbl_num,
                          self.testing_controller,
                          match=flow_match_to_magma_match(
                              FlowMatch(ipv4_src=ip,
                                        direction=FlowMatch.DOWNLINK))))

        learn_action_flow = flow_match_to_magma_match(
            FlowMatch(ip_proto=6,
                      direction=FlowMatch.DOWNLINK,
                      ipv4_src=self.BRIDGE_IP_ADDRESS,
                      ipv4_dst=sub_ip))
        learn_action_query = FlowQuery(self._tbl_num, self.testing_controller,
                                       learn_action_flow)

        # =========================== Verification ===========================
        # 1 packet sent, permit rules installed, learn action installed. Since
        # the enforcement table is entered via the DPI table and the scratch
        # enforcement table, the number of packets handled by the table is 2.
        flow_verifier = FlowVerifier(
            [
                FlowTest(FlowQuery(self._tbl_num, self.testing_controller), 2),
                FlowTest(learn_action_query, 0, flow_count=1)
            ] +
            [FlowTest(query, 0, flow_count=1) for query in permit_outbound] +
            [FlowTest(query, 0, flow_count=1) for query in permit_inbound],
            lambda: wait_after_send(self.testing_controller))

        with isolator, sub_context, flow_verifier:
            pkt_sender.send(packet)
            assert_bridge_snapshot_match(self, self.BRIDGE,
                                         self.service_manager)

        flow_verifier.verify()
    def test_url_redirect(self):
        """
        Partial redirection test, checks if flows were added properly for url
        based redirection.

        Assert:
            1 Packet is matched
            Packet bypass flows are added
            Flow learn action is triggered - another flow is added to the table
        """
        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
        )
        redirect_ips = ["185.128.101.5", "185.128.121.4"]
        self.enforcement_controller._redirect_manager._dns_cache.get(
            "about.sha.ddih.org",
            lambda: redirect_ips,
            max_age=42,
        )
        imsi = 'IMSI010000000088888'
        sub_ip = '192.168.128.74'
        flow_list = [FlowDescription(match=FlowMatch())]
        policy = PolicyRule(
            id='redir_test',
            priority=3,
            flow_list=flow_list,
            redirect=RedirectInformation(
                support=1,
                address_type=2,
                server_address="http://about.sha.ddih.org/",
            ),
        )

        # ============================ Subscriber ============================
        sub_context = RyuDirectSubscriberContext(
            imsi,
            sub_ip,
            self.enforcement_controller,
            self._tbl_num,
        )

        setup_flows_request = SetupFlowsRequest(
            requests=[
                ActivateFlowsRequest(
                    sid=SIDUtils.to_pb(imsi),
                    ip_addr=sub_ip,
                    policies=[VersionedPolicy(rule=policy, version=1)],
                ),
            ],
            epoch=global_epoch,
        )

        fake_controller_setup(
            enf_controller=self.enforcement_controller,
            enf_stats_controller=self.enforcement_stats_controller,
            startup_flow_controller=self.startup_flows_contoller,
            setup_flows_request=setup_flows_request,
        )

        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(
                sub_context.cfg).build_requests(),
            self.testing_controller,
        )
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packet = TCPPacketBuilder()\
            .set_tcp_layer(42132, 80, 321)\
            .set_tcp_flags("S")\
            .set_ip_layer('151.42.41.122', sub_ip)\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .build()

        snapshot_verifier = SnapshotVerifier(
            self,
            self.BRIDGE,
            self.service_manager,
        )

        with isolator, sub_context, snapshot_verifier:
            pkt_sender.send(packet)
Beispiel #9
0
    def test_ipv4_redirect(self):
        """
        Partial redirection test, checks if flows were added properly for ipv4
        based redirection.

        Assert:
            1 Packet is matched
            Packet bypass flows are added
            Flow learn action is triggered - another flow is added to the table
        """
        fake_controller_setup(self.enforcement_controller)
        redirect_ip = "54.12.31.42"
        imsi = 'IMSI012000000088888'
        sub_ip = '192.168.128.74'
        flow_list = [FlowDescription(match=FlowMatch())]
        policy = VersionedPolicy(
            rule=PolicyRule(
                id='redir_ip_test', priority=3, flow_list=flow_list,
                redirect=RedirectInformation(
                    support=1,
                    address_type=0,
                    server_address=redirect_ip,
                ),
            ),
            version=1,
        )

        # ============================ Subscriber ============================
        sub_context = RyuDirectSubscriberContext(
            imsi, sub_ip, self.enforcement_controller, self._tbl_num,
        ).add_policy(policy)
        isolator = RyuDirectTableIsolator(
            RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
                                     .build_requests(),
            self.testing_controller,
        )
        pkt_sender = ScapyPacketInjector(self.IFACE)
        packet = TCPPacketBuilder()\
            .set_tcp_layer(42132, 80, 321)\
            .set_tcp_flags("S")\
            .set_ip_layer('151.42.41.122', sub_ip)\
            .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\
            .build()

        # Check if these flows were added (queries should return flows)
        permit_outbound = FlowQuery(
            self._tbl_num, self.testing_controller,
            match=flow_match_to_magma_match(
                FlowMatch(
                    ip_dst=convert_ipv4_str_to_ip_proto(redirect_ip),
                    direction=FlowMatch.UPLINK,
                ),
            ),
        )
        permit_inbound = FlowQuery(
            self._tbl_num, self.testing_controller,
            match=flow_match_to_magma_match(
                FlowMatch(
                    ip_src=convert_ipv4_str_to_ip_proto(redirect_ip),
                    direction=FlowMatch.DOWNLINK,
                ),
            ),
        )
        learn_action_flow = flow_match_to_magma_match(
            FlowMatch(
                ip_proto=6, direction=FlowMatch.DOWNLINK,
                ip_src=convert_ipv4_str_to_ip_proto(self.BRIDGE_IP_ADDRESS),
                ip_dst=convert_ipv4_str_to_ip_proto(sub_ip),
            ),
        )
        learn_action_query = FlowQuery(
            self._tbl_num, self.testing_controller,
            learn_action_flow,
        )

        # =========================== Verification ===========================
        # 1 packet sent, permit rules installed, learn action installed. Since
        # the enforcement table is entered via the DPI table and the scratch
        # enforcement table, the number of packets handled by the table is 2.
        flow_verifier = FlowVerifier(
            [
                FlowTest(FlowQuery(self._tbl_num, self.testing_controller), 2),
                FlowTest(permit_outbound, 0, flow_count=1),
                FlowTest(permit_inbound, 0, flow_count=1),
                FlowTest(learn_action_query, 0, flow_count=1),
            ], lambda: wait_after_send(self.testing_controller),
        )

        with isolator, sub_context, flow_verifier:
            pkt_sender.send(packet)
            assert_bridge_snapshot_match(
                self, self.BRIDGE,
                self.service_manager,
            )

        flow_verifier.verify()