Mini Shell
"""Captcha specific rules customization."""
from typing import AbstractSet, Iterator, Mapping
from im360.subsys.panels.hosting_panel import HostingPanel
from im360.contracts.config import Webshield
from im360.internals.core.firewall import FirewallRules, is_nat_available
from im360.subsys import webshield
from defence360agent.utils.validate import IPVersion, LocalhostIP
from .types_ import FirewallRule, WebshieldRuleBuilder
class CaptchaRuleBuilder(WebshieldRuleBuilder):
"""Implement steps specific to generating captcha related iptables
rules.
"""
def __init__(self, include_webshield_ports_rules=False): # type: ignore
self.__include_webshield_ports_rules = include_webshield_ports_rules
def open_webshield_ports_for_localhost_rules(
self,
ip_version: IPVersion,
) -> Iterator[FirewallRule]:
"""Return FirewallRule to open webshields ports for localhost."""
if not self.__include_webshield_ports_rules:
return
yield FirewallRule(
chain=FirewallRules.WEBSHIELD_PORTS_INPUT_CHAIN,
rule=FirewallRules.open_all_for_src_net(
LocalhostIP[ip_version].value
),
)
def block_webshield_ports_rules(
self, redirect_map: Mapping[int, int], dest_ports: AbstractSet
) -> Iterator[FirewallRule]:
"""Return FirewallRules to log redirected traffic."""
if not self.__include_webshield_ports_rules:
return
# insert rule to the bottom of WEBSHIELD_PORTS_INPUT_CHAIN
yield FirewallRule(
chain=FirewallRules.WEBSHIELD_PORTS_INPUT_CHAIN,
rule=FirewallRules.compose_action(
FirewallRules.LOG_BLOCK_PORT_CHAIN
),
priority=FirewallRules.LOWEST_PRIORITY,
)
def redirect_panel_ports(
self, ip_version: IPVersion
) -> Iterator[FirewallRule]:
"""
Used to create redirect to webshield for panel ports
for example 2082, 2083 for cPanel.
Turned on by config option panel_protection
"""
if not self.__include_webshield_ports_rules:
return
ports = HostingPanel().get_webshield_protected_ports()
if (
ports
and Webshield.PANEL_PROTECTION
and Webshield.ENABLE
and webshield.expects_traffic()
):
for dst_port, target_port in ports.items():
yield FirewallRule(
rule=FirewallRules.protected_by_webshield(
dst_port, target_port
),
chain=FirewallRules.IMUNIFY_INPUT_CHAIN,
table=FirewallRules.NAT
if is_nat_available(ip_version)
else FirewallRules.MANGLE,
priority=FirewallRules.HIGHEST_PRIORITY,
)
yield FirewallRule(
rule=FirewallRules.block_dst_port_list(
set(ports.values()),
policy=FirewallRules.ACCEPT,
),
chain=FirewallRules.WEBSHIELD_PORTS_INPUT_CHAIN,
table=FirewallRules.FILTER,
priority=FirewallRules.HIGHEST_PRIORITY,
)
def logdrop_chain_rules(self, ipset_name: str) -> Iterator[FirewallRule]:
"""Generator yield drop chain"""
yield FirewallRule(
rule=FirewallRules.ipset_rule(
ipset_name, FirewallRules.LOG_GRAYLIST_CHAIN
),
)
def drop_tproxy_rules(self, ipset_name: str) -> Iterator[FirewallRule]:
"""Generator yield firewall drop rule for tproxy"""
yield FirewallRule(
rule=FirewallRules.traffic_not_from_tproxy(ipset_name)
)