예제 #1
0
def ifaceup():
    env.configure()
    logger.info(f'Running: {" ".join(sys.argv)}')
    libgw.load()

    if os.environ.get('IFACE'):
        ifname = os.environ['IFACE']
    elif len(sys.argv) >= 2:
        ifname = sys.argv[1]
    else:
        return

    iface = libgw.Interface.get(ifname)
    if not iface or not iface.exists:
        logger.error(f'iface does not found in libgw: {ifname}')
        return

    if iface.config and iface.config.devgroup:
        logger.info(
            f'setting iface group, iface={ifname} group={iface.config.devgroup}'
        )
        xcall([
            'ip', 'link', 'set', 'dev', ifname, 'group',
            str(iface.config.devgroup)
        ])

    from .setup import setup_firewall, setup_route
    setup_firewall()
    setup_route()
예제 #2
0
파일: config.py 프로젝트: StephenPCG/gwtool
    def __init__(self,
                 name,
                 link=None,
                 interface=None,
                 interfaces=None,
                 gateway=None,
                 **kwargs):
        self.name = name

        # TODO should check if the link name exists
        self.link = link

        if interface and interfaces:
            logger.error(
                '[GatewayConfigure] interface and interfaces are exclusive')
            raise ValueError(
                '"interface" and "interfaces" can not be used together')
        if gateway and interfaces:
            logger.error(
                '[GatewayConfigure] interface and interfaces are exclusive')
            raise ValueError(
                '"gateway" and "interfaces" can not be used together')

        # TODO should check if interface exists
        if interfaces:
            self.single_interface_mode = False
            self.interfaces = interfaces
        else:
            self.single_interface_mode = True
            self.interface = interface or name
            self.gateway = gateway
예제 #3
0
파일: config.py 프로젝트: StephenPCG/gwtool
    def __init__(self,
                 name,
                 devgroup=None,
                 gateway=None,
                 table=None,
                 **kwargs):
        self.name = name

        # TODO Support user defined group names in /etc/iproute2/group
        devgroup = {
            'wan': 1,
            'lan': 2,
            'guest': 3,
            'tunnel': 4
        }.get(devgroup, None)
        if not (devgroup is None or isinstance(devgroup, int)):
            logger.error(
                f'[InterfaceConfig] Invalid devgroup valud: {devgroup}')
            raise ValueError(f'Invalid devgroup value: {devgroup}')
        self.devgroup = devgroup

        # Gateway address must be valid ip address (not cidr).
        # ip_address() supports both v4 and v6, however we currently only consider v6.
        if gateway:
            try:
                ipaddress.ip_address(gateway)
            except ipaddress.AddressValueError:
                logger.error(
                    f'[InterfaceConfig] Invalid gateway value (must be valid ip address): {gateway}'
                )
                raise
        self.gateway = gateway
예제 #4
0
def xcall(command, **kwargs):
    from gwtool.env import logger

    logger.info(f'Call command: {" ".join(command)}')
    silence_error = kwargs.pop('silence_error', False)
    if silence_error:
        kwargs["stderr"] = DEVNULL
    ret = call(command, **kwargs)
    if ret != 0 and not silence_error:
        logger.error(f'ERROR: command exited with non-zero: {ret}')
예제 #5
0
파일: config.py 프로젝트: StephenPCG/gwtool
    def __init__(self, config_file):
        if config_file.exists():
            logger.info(f'Loading gateway config file: {config_file}')
            try:
                with config_file.open(encoding='utf8') as fp:
                    content = yaml.safe_load(fp)
            except Exception:
                logger.error(
                    f'Error loading gateway config file: {config_file}')
                raise
        else:
            logger.info(
                f'Config file does not exist: {config_file}, assume empty config'
            )
            content = {}

        self.interfaces = {}
        for name, config in content.get('interfaces', {}).items():
            self.interfaces[name] = InterfaceConfig(name, **config)

        self.gateways = {}
        for name, config in content.get('gateways', {}).items():
            self.gateways[name] = GatewayConfig(name, **config)

        self.route_tables = {}
        for table, entries in content.get('routing', {}).get('tables',
                                                             {}).items():
            self.route_tables[table] = RouteTableConfig(table, entries)

        self.route_rules = []
        for rule in content.get('routing', {}).get('rules', []):
            self.route_rules.append(RouteRuleConfig(rule=rule))

        netzone_search_path = []
        paths = content.get('netzone_search_path', [])
        if not isinstance(paths, list):
            logger.error(
                'Config Error: netzone_search_path must be list of paths')
            raise ValueError(
                'Invalid netzone_search_path, must be list of paths')
        for path in paths:
            netzone_search_path.append(Path(path))
        netzone_search_path.append(env.codespace / 'netzones')
        self.netzone_search_path = netzone_search_path

        self.firewall_script = content.get('firewall_entry', None)
예제 #6
0
def create_route_table(table, entries):
    iproute(f'flush table {table}')

    lines = []
    for (target, gateway_name) in entries:
        gateway = Gateway.get(gateway_name)
        if not gateway:
            logger.error(
                f'invalid gateway in route table {table}: {gateway_name}, rule skipped'
            )
            continue

        if not gateway.available:
            logger.error(
                f'gateway is not available: {gateway_name}, rule skipped')
            continue

        if is_valid_cidr(target):
            iproute(f'replace table {table} {target} {gateway.gwdef}')
            continue

        zone = NetZone.get(target)
        if not zone:
            logger.error(
                f'invalid target in route table {table}: {target}, rule skipped'
            )
            continue

        for prefix in zone.cidr_list:
            lines.append(
                f'route replace table {table} {prefix} {gateway.gwdef}\n')

    if not lines:
        logger.warning(f'No rules for table: {table}')
        return

    with tempfile.NamedTemporaryFile() as f:
        f.write(''.join(lines).encode('ascii'))
        f.flush()
        xcall(['ip', '-batch', '-'], stdin=open(f.name))