diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/conf_mode/firewall.py | 3 | ||||
| -rw-r--r-- | src/etc/systemd/system/hostapd@.service.d/override.conf | 2 | ||||
| -rwxr-xr-x | src/helpers/vyos-failover.py | 69 | ||||
| -rwxr-xr-x | src/op_mode/openvpn.py | 23 | 
4 files changed, 74 insertions, 23 deletions
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index c41a442df..190587980 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -282,6 +282,9 @@ def verify_rule(firewall, rule_conf, ipv6):                  if rule_conf['protocol'] not in ['tcp', 'udp', 'tcp_udp']:                      raise ConfigError('Protocol must be tcp, udp, or tcp_udp when specifying a port or port-group') +            if 'port' in side_conf and dict_search_args(side_conf, 'group', 'port_group'): +                raise ConfigError(f'{side} port-group and port cannot both be defined') +      if 'log_options' in rule_conf:          if 'log' not in rule_conf or 'enable' not in rule_conf['log']:              raise ConfigError('log-options defined, but log is not enable') diff --git a/src/etc/systemd/system/hostapd@.service.d/override.conf b/src/etc/systemd/system/hostapd@.service.d/override.conf index bb8e81d7a..926c07f94 100644 --- a/src/etc/systemd/system/hostapd@.service.d/override.conf +++ b/src/etc/systemd/system/hostapd@.service.d/override.conf @@ -1,6 +1,8 @@  [Unit]  After=  After=vyos-router.service +ConditionFileNotEmpty= +ConditionFileNotEmpty=/run/hostapd/%i.conf  [Service]  WorkingDirectory=/run/hostapd diff --git a/src/helpers/vyos-failover.py b/src/helpers/vyos-failover.py index 0de945f20..03fb42f57 100755 --- a/src/helpers/vyos-failover.py +++ b/src/helpers/vyos-failover.py @@ -30,7 +30,7 @@ my_name = Path(__file__).stem  def is_route_exists(route, gateway, interface, metric):      """Check if route with expected gateway, dev and metric exists""" -    rc, data = rc_cmd(f'sudo ip --json route show protocol failover {route} ' +    rc, data = rc_cmd(f'ip --json route show protocol failover {route} '                        f'via {gateway} dev {interface} metric {metric}')      if rc == 0:          data = json.loads(data) @@ -72,6 +72,7 @@ def get_best_route_options(route, debug=False):                    f'best_metric: {best_metric}, best_iface: {best_interface}')          return best_gateway, best_interface, best_metric +  def is_port_open(ip, port):      """      Check connection to remote host and port @@ -91,32 +92,54 @@ def is_port_open(ip, port):      finally:          s.close() -def is_target_alive(target=None, iface='', proto='icmp', port=None, debug=False): -    """ -    Host availability check by ICMP, ARP, TCP -    Return True if target checks is successful -    % is_target_alive('192.0.2.1', 'eth1', proto='arp') -    True +def is_target_alive(target_list=None, iface='', proto='icmp', port=None, debug=False): +    """Check the availability of each target in the target_list using +    the specified protocol ICMP, ARP, TCP + +    Args: +        target_list (list): A list of IP addresses or hostnames to check. +        iface (str): The name of the network interface to use for the check. +        proto (str): The protocol to use for the check. Options are 'icmp', 'arp', or 'tcp'. +        port (int): The port number to use for the TCP check. Only applicable if proto is 'tcp'. +        debug (bool): If True, print debug information during the check. + +    Returns: +        bool: True if all targets are reachable, False otherwise. + +    Example: +        % is_target_alive(['192.0.2.1', '192.0.2.5'], 'eth1', proto='arp') +        True      """      if iface != '':          iface = f'-I {iface}' -    if proto == 'icmp': -        command = f'/usr/bin/ping -q {target} {iface} -n -c 2 -W 1' -        rc, response = rc_cmd(command) -        if debug: print(f'    [ CHECK-TARGET ]: [{command}] -- return-code [RC: {rc}]') -        if rc == 0: -            return True -    elif proto == 'arp': -        command = f'/usr/bin/arping -b -c 2 -f -w 1 -i 1 {iface} {target}' -        rc, response = rc_cmd(command) -        if debug: print(f'    [ CHECK-TARGET ]: [{command}] -- return-code [RC: {rc}]') -        if rc == 0: -            return True -    elif proto == 'tcp' and port is not None: -        return True if is_port_open(target, port) else False -    else: -        return False + +    for target in target_list: +        match proto: +            case 'icmp': +                command = f'/usr/bin/ping -q {target} {iface} -n -c 2 -W 1' +                rc, response = rc_cmd(command) +                if debug: +                    print(f'    [ CHECK-TARGET ]: [{command}] -- return-code [RC: {rc}]') +                if rc != 0: +                    return False + +            case 'arp': +                command = f'/usr/bin/arping -b -c 2 -f -w 1 -i 1 {iface} {target}' +                rc, response = rc_cmd(command) +                if debug: +                    print(f'    [ CHECK-TARGET ]: [{command}] -- return-code [RC: {rc}]') +                if rc != 0: +                    return False + +            case _ if proto == 'tcp' and port is not None: +                if not is_port_open(target, port): +                    return False + +            case _: +                return False + +    return True  if __name__ == '__main__': diff --git a/src/op_mode/openvpn.py b/src/op_mode/openvpn.py index 5a1a4914d..d9ae965c5 100755 --- a/src/op_mode/openvpn.py +++ b/src/op_mode/openvpn.py @@ -16,6 +16,7 @@  #  # +import json  import os  import sys  import typing @@ -25,6 +26,7 @@ import vyos.opmode  from vyos.util import bytes_to_human  from vyos.util import commit_in_progress  from vyos.util import call +from vyos.util import rc_cmd  from vyos.config import Config  ArgMode = typing.Literal['client', 'server', 'site_to_site'] @@ -142,6 +144,25 @@ def _get_interface_status(mode: str, interface: str) -> dict:      return data + +def _get_interface_state(iface): +    rc, out = rc_cmd(f'ip --json link show dev {iface}') +    try: +        data = json.loads(out) +    except: +        return 'DOWN' +    return data[0].get('operstate', 'DOWN') + + +def _get_interface_description(iface): +    rc, out = rc_cmd(f'ip --json link show dev {iface}') +    try: +        data = json.loads(out) +    except: +        return '' +    return data[0].get('ifalias', '') + +  def _get_raw_data(mode: str) -> list:      data: list = []      conf = Config() @@ -154,6 +175,8 @@ def _get_raw_data(mode: str) -> list:                    conf_dict[x]['mode'].replace('-', '_') == mode]      for intf in interfaces:          d = _get_interface_status(mode, intf) +        d['state'] = _get_interface_state(intf) +        d['description'] = _get_interface_description(intf)          d['local_host'] = conf_dict[intf].get('local-host', '')          d['local_port'] = conf_dict[intf].get('local-port', '')          if conf.exists(f'interfaces openvpn {intf} server client'):  | 
