1import ipaddress
2from mitmproxy import ctx
3
4
5class Block:
6    def load(self, loader):
7        loader.add_option(
8            "block_global", bool, True,
9            """
10            Block connections from public IP addresses.
11            """
12        )
13        loader.add_option(
14            "block_private", bool, False,
15            """
16            Block connections from local (private) IP addresses.
17            This option does not affect loopback addresses (connections from the local machine),
18            which are always permitted.
19            """
20        )
21
22    def client_connected(self, client):
23        parts = client.peername[0].rsplit("%", 1)
24        address = ipaddress.ip_address(parts[0])
25        if isinstance(address, ipaddress.IPv6Address):
26            address = address.ipv4_mapped or address
27
28        if address.is_loopback:
29            return
30
31        if ctx.options.block_private and address.is_private:
32            ctx.log.warn(f"Client connection from {client.peername[0]} killed by block_private option.")
33            client.error = "Connection killed by block_private."
34
35        if ctx.options.block_global and address.is_global:
36            ctx.log.warn(f"Client connection from {client.peername[0]} killed by block_global option.")
37            client.error = "Connection killed by block_global."
38